Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Proper type hint for a listify function

I'm using VS Code with Pylance, and having problems correctly writing type hints for the following function. To me, the semantics seem clear, but Pylance disagrees. How can I fix this without resorting to cast() or # type ignore? Pylance warnings are given in the comments.

I am fully committed to typing in Python, but it is often a struggle.

T = TypeVar("T")

def listify(item: T | list[T] | tuple[T, ...] | None) -> list[T]:
    if item is None:
        return []
    elif isinstance(item, list):
        return item             # Return type, "List[Unknown]* | List[T@listify]", 
                                # is partially unknown
    elif isinstance(item, tuple):
        return list(item)       # Return type, "List[Unknown]* | List[T@listify]",
                                # is partially unknown
    else:
        return [item]
like image 803
Watusimoto Avatar asked Oct 16 '25 16:10

Watusimoto


1 Answers

This is just fundamentally unsafe, due to ambiguity.

Suppose you have a generic function that uses listify:

def caller[T](x: T):
    y = listify(x)

What's the proper annotation for y?

The obvious answer is list[T]. But there's no guarantee listify will return a list[T]. If T is list[Something], or tuple[Something, ...], or None, listify can return something completely different.


There is no way to make a fully generic listify safe. Pylance does a stricter job than mypy of reporting this kind of ambiguity, but the fundamental ambiguity is there no matter what type checker you use.

And even if you completely strip out the implementation, and simplify it down to

def f[T](x: T | list[T]) -> list[T]:
    raise NotImplementedError

reveal_type(f([3]))

mypy will report the following:

main.py:4: note: Revealed type is "builtins.list[Never]"
main.py:4: error: Argument 1 to "f" has incompatible type "list[int]"; expected "list[Never]"  [arg-type]
Found 1 error in 1 file (checked 1 source file)

because the ambiguity is causing it to deduce conflicting type requirements.

like image 107
user2357112 supports Monica Avatar answered Oct 18 '25 20:10

user2357112 supports Monica



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!