`Unpack` should work on generics that are bound to a `TypedDict`
from typing import TypedDict, Unpack
class TDict(TypedDict):
pass
def f[T: TDict](**kwargs: Unpack[T]) -> T: ...
reveal_type(f(a=1))
reveal_type(f(b="a"))
because TypedDict is structural, this should allow all TypedDicts to work
doesn't necessarily need to be a TypedDict, i don't see why it shouldn't work if oit's bound to Mapping[str, object]:
from typing import Unpack
from collections.abc import Mapping
class Foo[T: Mapping[str, object]]:
def f(self, **kwargs: Unpack[T]) -> T: ...
_ = Foo[Mapping[str, object]]().f(a='asdf')
doesn't necessarily need to be a
TypedDict, i don't see why it shouldn't work if oit's bound toMapping[str, object]:from typing import Unpack from collections.abc import Mapping class Foo[T: Mapping[str, object]]: def f(self, **kwargs: Unpack[T]) -> T: ... _ = Foo[Mapping[str, object]]().f(a='asdf')
class AmongusMapping(Mapping[str, str]):...
Foo[AmongusMapping]().f(a="asdf")
it should still be able to unpack them even if it's a different subtype of mapping imo
pyright (and hence basedpyright) already unofficially (and temporarily) supports Unpacking tuple-bound TypeVars (see https://github.com/microsoft/pyright/discussions/10012):
from typing import Any, Unpack
def concat[S: tuple[Any, ...], T: tuple[Any, ...]](_x: S, _y: T, /) -> tuple[Unpack[S], Unpack[T]]: ...
a: tuple[int] = (42,)
b: tuple[str] = ("hi",)
z: tuple[()] = ()
reveal_type(concat(a, a)) # tuple[int, int]
reveal_type(concat(a, b)) # tuple[int, str]
reveal_type(concat(a, z)) # tuple[int]
(playground - basedpyright even propagates literal types down the line)
This works for variadic positional arguments as well:
from typing import Any, Unpack
def pack[T: tuple[Any, ...]](*args: Unpack[T]) -> tuple[Unpack[T]]:
return args
reveal_type(pack("3", 14)) # tuple[Literal['3'], Literal[14]]
IMHO, this (Unpack[T] where T is a TypeVar with an Unpack-able bound) would be a very useful type system feature to have and support officially.
Edit: I'm using the latest basedpyright version available on the playground as of now, i.e., 1.32.0
let us know if that functionality ever gets removed and we'll add it back :)
Upstream issue for the original proposal (Unpack[TD] where TD: TypedDict): https://github.com/python/typing/issues/1399
Upstream issue for the original proposal (
Unpack[TD]whereTD: TypedDict): python/typing#1399
mine was earlier https://github.com/python/typing/issues/1395