Description
[Not sure if this is the right place to file issues like this, feel free to tell me to go somewhere else :-)]
I have two generic types:
class SendChannel(Generic[T]):
...
class ReceiveChannel(Generic[T]):
...
I have a factory function that creates a linked pair of these objects:
def open_channel_pair(buffer_size: int) -> Tuple[SendChannel[T], ReceiveChannel[T]]:
# ... construct some objects ...
return (s, r)
I would like to allow people to call it like:
s, r = open_channel_pair[str](0)
# Now 's' is a SendChannel[str], and 'r' is a ReceiveChannel[str]
This works for the factory callables built into the language, e.g. calling SendChannel[str]()
returns an object of type SendChannel[str]
. This is basically the same thing, but since I have to construct two objects in a single operation, the regular thing doesn't work.
I did come up with a sneaky hack:
# Complete cut-and-pasteable example
from typing import Generic, TypeVar, Tuple
T = TypeVar("T")
class SendChannel(Generic[T]):
pass
class ReceiveChannel(Generic[T]):
pass
class open_channel_pair(Tuple[SendChannel[T], ReceiveChannel[T]]):
def __new__(self, buffer_size: int):
return (SendChannel[T](), ReceiveChannel[T]())
# Note: this function is unreachable, but we have to define it, and keep
# its signature in sync with __new__'s signature, to make mypy happy.
def __init__(self, buffer_size: int) -> None:
assert False
s, r = open_channel_pair[str](0)
# Confirms that it works:
reveal_type(s)
reveal_type(r)
This is gross, though. Is there any way to define a regular callable that has the same type as a generic class constructor, but is less gross than this?
What even is the type of a generic class constructor? reveal_type(SendChannel)
prints def [T] () -> SendChannel[T`1]
, which is a very strange looking type.