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

bound methods of a TypedDict don't retain type information #6490

Closed
mikeshardmind opened this issue Nov 18, 2023 · 2 comments
Closed

bound methods of a TypedDict don't retain type information #6490

mikeshardmind opened this issue Nov 18, 2023 · 2 comments
Labels
as designed Not a bug, working as intended bug Something isn't working

Comments

@mikeshardmind
Copy link

Describe the bug
A clear and concise description of the behavior you are seeing and the expected behavior along with steps to reproduce it.

Code or Screenshots

from typing import TypedDict, reveal_type


class QuickExample(TypedDict):
    key1: int
    key2: str


ex = QuickExample(key1=1, key2="this")

reveal_type(ex)
reveal_type(ex.__getitem__("key1"))
reveal_type(ex["key1"])
reveal_type(ex.__getitem__)

and the corresponding informational messages:

Type of "ex" is "QuickExample"
Type of "ex.__getitem__("key1")" is "object"
Type of "ex["key1"]" is "int"
Type of "ex.__getitem__" is "(__key: str, /) -> object"

VS Code extension or command-line

Initially pylance, also confirmed on the playground

@mikeshardmind mikeshardmind added the bug Something isn't working label Nov 18, 2023
@erictraut
Copy link
Collaborator

This is the intended behavior, not a bug.

The _TypedDict type in typing.pyi defines the class as deriving from Mapping[str, object], and the __getitem__ method comes from the Mapping class. Neither pyright nor mypy synthesize overrides for the TypedDict __getitem__ method. FWIW, mypy is the reference implementation for PEP 589, which introduced TypedDicts.

Both pyright and mypy handle special-casing for TypedDict indexing at a higher level than __getitem__. In the case of pyright, this is especially important because pyright also supports narrowing of TypedDict keys based on existence checks.

class QuickExample(TypedDict, total=False):
    key1: int
    key2: str

def func(x: QuickExample):
    print(x["key1"])  # Error: "key1" is not a required key

    if "key1" in x:
        print(x["key1"])  # No type error

This is done by internally tracking which keys in the TypedDict have been verified — and are therefore guaranteed to exist. This analysis wouldn't be possible if the type checker synthesized static __getitem__ methods.

@erictraut erictraut added the as designed Not a bug, working as intended label Nov 18, 2023
@erictraut erictraut closed this as not planned Won't fix, can't repro, duplicate, stale Nov 18, 2023
@mikeshardmind
Copy link
Author

That's unfortunate, as it breaks reasonable assumptions about function composition. I'll just add this to the growing list of "things to bring up with the typing council" since you've placed this as due to the definition coming from Mapping

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
as designed Not a bug, working as intended bug Something isn't working
Projects
None yet
Development

No branches or pull requests

2 participants