def _pytype_to_shape_fn_pytype(pytype: str) -> str:
    """Convert a JitOperator pytype to the type relevant in shape functions.

    In particular, this converts `Tensor` to `List[int]`, along with a few
    other special cases.
    """
    # `Scalar` operands (which are represented with pytype "number") can
    # be either `int` or `float`. TorchScript has no way to represent a
    # signature of this type, so we hardcode it to `float`. `Scalar`
    # operands don't participate in shape functions (since they are
    # logically real-valued), so it doesn't really matter much, and
    # `float` helps make it clearer that it's not part of the shape
    # function.
    if pytype == "number":
        return "float"
    if pytype == "Optional[number]":
        return "Optional[float]"
    # `torch.device` is lowercase.
    if pytype == "Device":
        return "device"
    if pytype == "Optional[Device]":
        return "Optional[device]"
    # Shape functions only care about the shape of tensors.
    if pytype == "Tensor":
        return "List[int]"
    if pytype == "Optional[Tensor]":
        return "Optional[List[int]]"
    if pytype == "List[Tensor]":
        return "List[List[int]]"
    if pytype == "List[Optional[Tensor]]":
        return "List[Optional[List[int]]]"
    # Generators don't contribute to shapes, and are not scriptable currently.
    # So just hack them to be passed as "Any".
    if pytype == "Generator":
        return "Any"
    if pytype == "Optional[Generator]":
        return "Any"
    return pytype