Skip to content

TypedDict keys(), items(), and values() #7845

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

Closed
crusaderky opened this issue Nov 1, 2019 · 4 comments
Closed

TypedDict keys(), items(), and values() #7845

crusaderky opened this issue Nov 1, 2019 · 4 comments

Comments

@crusaderky
Copy link
Contributor

crusaderky commented Nov 1, 2019

mypy 0.750+dev.78f2df9d46198563106dd32cb4494678e97d71eb

mypy thinks that the values of a TypedDict yielded by items() or values() are of type object, instead of the Union of all possible values.
As for the keys yielded by keys() or items(), they are upcast to str whereas a Union of Literal would be more precise.
Finally, keys() and items() are incorrectly reported as an AbstractSet instead of KeysView and ItemsView respectively.

from typing_extensions import TypedDict

class C(TypedDict):
    x: float
    y: int
    z: str


c: C
reveal_type(c.keys())
reveal_type(c.items())
reveal_type(c.values())

Actual output:

note: Revealed type is 'typing.AbstractSet[builtins.str*]'
note: Revealed type is 'typing.AbstractSet[Tuple[builtins.str*, builtins.object*]]'
note: Revealed type is 'typing.ValuesView[builtins.object*]'

Expected output:

note: Revealed type is 'typing.KeysView[Literal["x", "y", "z"]]'
note: Revealed type is 'typing.ItemsView[Literal["x", "y", "z"], Union[float, int, str]]'
note: Revealed type is 'typing.ValuesView[Union[float, int, str]]'
@crusaderky crusaderky changed the title TypeDict items() and values() wrongly upcasts to object TypeDict items() and values() wrongly upcasted to object Nov 1, 2019
@crusaderky crusaderky changed the title TypeDict items() and values() wrongly upcasted to object TypeDict items() and values() wrongly upcast to object Nov 1, 2019
@crusaderky crusaderky changed the title TypeDict items() and values() wrongly upcast to object TypeDict keys(), items(), and values() Nov 1, 2019
@crusaderky crusaderky changed the title TypeDict keys(), items(), and values() TypedDict keys(), items(), and values() Nov 1, 2019
@JukkaL
Copy link
Collaborator

JukkaL commented Nov 1, 2019

Mypy is behaving as designed, since TypedDicts support structural subtyping. The type C can hide arbitrary additional values that are accessible through values() and and items(). For example, there could be a derived TypedDict D of C that adds item 'foo' with the value type object.

@JukkaL JukkaL closed this as completed Nov 1, 2019
@crusaderky
Copy link
Contributor Author

@JukkaL how do you justify AbstractSet instead of KeysView/ItemsView?

@crusaderky
Copy link
Contributor Author

@JukkaL adding the @final decorator should remove your objection. However, the output does not change; please reopen:

from typing_extensions import final, TypedDict

@final
class C(TypedDict):
    x: float
    y: int
    z: str


c: C
reveal_type(c.keys())
reveal_type(c.items())
reveal_type(c.values())

Output:


11: note: Revealed type is 'typing.AbstractSet[builtins.str*]'
12: note: Revealed type is 'typing.AbstractSet[Tuple[builtins.str*, builtins.object*]]'
13: note: Revealed type is 'typing.ValuesView[builtins.object*]'

@JukkaL
Copy link
Collaborator

JukkaL commented Nov 1, 2019

AbstractSet is derived from the return type of the relevant Mapping methods. Switching them to narrower types sounds like a reasonable idea, however. Can you create a separate issue about the AbstractSet/KeysView/ItemsView distinction?

@final isn't actually supported with TypedDicts. It's a bug that mypy doesn't generate an error about using it with a TypedDict. Supporting it with TypedDicts might make sense in the future, however. Feel free to create an issue about this. I'll create an issue about the missing error message.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants