Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feature request: Allow unpacking of type variable bound to typed dict #1399

Open
NeilGirdhar opened this issue May 3, 2023 · 5 comments
Open
Labels
topic: feature Discussions about new features for Python's type annotations

Comments

@NeilGirdhar
Copy link

I'd like to have a family of classes where overrides have additional parameters to various methods:

from typing import Generic, Unpack

from typing_extensions import TypedDict, TypeVar, override


class EmptyDict(TypedDict, total=True):
    pass


Extra = TypeVar('Extra', bound=TypedDict, default=EmptyDict)


class C(Generic[Extra]):
    def f(self, **kwargs: Unpack[Extra]) -> None:  # error: Expected TypedDict type argument for Unpack (reportGeneralTypeIssues)
        pass


class D(C):
    @override
    def f(self) -> None:  # error: Method "f" overrides class "C" in an incompatible manner
        pass


class HasName(TypedDict, total=True):
    name: str


class E(C[HasName]):
    @override
    def f(self, name: str) -> None:  # This doesn't work.
        print(name)



D().f()
E().f("a")

See @erictraut's instructive comment on the issue here.

@NeilGirdhar NeilGirdhar added the topic: feature Discussions about new features for Python's type annotations label May 3, 2023
@hmc-cs-mdrissi
Copy link

This would be kwargs equivalent of being able to unpack TypeVarTuple. This would I think solve this request to be able to use Paramspec kwargs only.

I have a couple small use cases where this would be nice although they mostly follow other issue of more flexibility with preserving just args/kwargs/similar manipulation.

@jaywonchung
Copy link

jaywonchung commented Sep 8, 2023

I believe I hit this issue when I was trying to write a type stub for networkx (or nx).

nx.Graph and its variants allow arbitrary attributes to be associated with nodes, edges, and graphs. For example, adding a node has signature (ref):

class Graph:
    def add_node(self, node_for_adding, **attr): ...

I was trying to do this:

N = TypeVar("N")  # type for node ID
A = TypeVar("A", bound=TypedDict)  # type for node attribute

class Graph(Generic[N, A]):
    def add_node(self, node_for_adding: N, **attr: Unpack[A]) -> None: ...

@NeilGirdhar
Copy link
Author

Yup, perfect example.

@paveldedik
Copy link

Is there something I could help with to speed this up? Probably only possible way to halp is to draft a PEP?

Anyway, it would be really useful for a framework I'm building - https://github.com/paveldedik/ludic/blob/main/ludic/base.py#L293-L308

It seems I can already bound a subclass of a TypedDict in TypeVar and it works in mypy at least:

from typing import TypedDict, TypeVar

class Attrs(TypedDict):
    key: str

T = TypeVar("T", bound=Attrs)  # does not complain

This seems to work in mypy but I'm afraid there is not PEP for it.

@sennalen
Copy link

sennalen commented Jan 7, 2025

T = TypeVar("T", bound=Attrs)  # does not complain

The trouble is Unpack[T] does not accept a TypeVar in place of a concrete TypedDict, regardless of being bounded by a TypedDict

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
topic: feature Discussions about new features for Python's type annotations
Projects
None yet
Development

No branches or pull requests

5 participants