Conditionally specify type for TypeVar with typing.overload #2042
-
I'm wondering how to type the following situation. From what I gather this case might be type-checker dependent so I thought I'd ask this here but please let me know if this isn't the right place to be asking. SetupLet's say I had a function that read bytes from some stream, deserialized them into an object, then put that object in a queue. I'd type that like so: from somewhere import Queue, read_bytes_from_somewhere
from typing import Callable, NoReturn, TypeVar
T = TypeVar("T")
def my_func(q: Queue[T], deserialize: Callable[[bytes], T]) -> NoReturn:
while True:
value = read_bytes_from_somewhere()
obj = deserialize(value)
q.put(obj) to hint that the return type of the Now, I'd like to make from typing import Callable, Literal, NoReturn, TypeVar, overload
# if deserialize is None, q must be Queue[bytes]...
@overload
def my_func(q: Queue[bytes], deserialize: Literal[None]) -> NoReturn: ...
# if deserialize is not None, it must return T (to match Queue[T])
@overload
def my_func(q: Queue[T], deserialize: Callable[[bytes], T]) -> NoReturn: ... Attempt 1: don't type the implementation
Attempt 2: type the implementation with Union?
Attempt 3: throw more typing.Any at the problem
This seems to work the best: I get no warnings in the implementation or when using q: Queue[MyClass] = Queue()
# good -- can't pass None if queue doesn't take bytes
my_func(q, None) # no overloads for "my_func" match the provided arguments
# good -- can't pass a callable returning the wrong type
my_func(q, lambda b: YourClass()) # no overloads for "my_func" match the provided arguments
# good -- even though the implementation used Any I don't actually accept Any
my_func(1, "1") # no overloads for "my_func"... good, can't pass Any If I hover over the function for help info, however, I see |
Beta Was this translation helpful? Give feedback.
Replies: 2 comments 2 replies
-
I don't see a perfect solution, but here's the best I can offer: def my_func(q: Queue[Any], deserialize: Optional[Callable[[bytes], Any]]) -> NoReturn: |
Beta Was this translation helpful? Give feedback.
-
Would having it be optional with a default callable that is the identity function let it work fully typed? Something like,
|
Beta Was this translation helpful? Give feedback.
I don't see a perfect solution, but here's the best I can offer: