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

TypedDict of X and Y not compatible with Mapping[str, Union[X, Y]] #8994

Closed
JosiahKane opened this issue Jun 12, 2020 · 2 comments
Closed

TypedDict of X and Y not compatible with Mapping[str, Union[X, Y]] #8994

JosiahKane opened this issue Jun 12, 2020 · 2 comments

Comments

@JosiahKane
Copy link

JosiahKane commented Jun 12, 2020

Feature request: track the common type in a TypedDict.

It has been established (#4976 ) that TypedDict is compatible with Mapping[str, Any] (although not with Dict) because it hides mutating operations. However, it is not compatible with any more specific Mapping Types, even though it clearly has all the information needed to identify the possible value types.

class T(TypedDict):
    a: int
    b: int

def foo(x: Mapping[str, int]):
    ...

def bar(y: Mapping[str, str]):
    ...

def qux(z: Mapping[str, Any]):
    ...

s = {"a": 5, "b": 3}
foo(s)
bar(s)
qux(s)
t: T = {"a": 5, "b": 3}
foo(t)
bar(t)
qux(t)

Expected behaviour:
bar(s) and bar(t) should fail.
qux(s) and qux(t) should pass.
foo(s) and foo(t) should pass.

Observed behaviour (MyPy 0.780 on Windows):
bar(s) and bar(t) fail.
qux(s) and qux(t) pass.
foo(s) passes but foo(t) fails.

A TypedDict can safely be considered a Mapping from str to the Union of the types of the presented entries. A significant implication of this is that it is safe to iterate over a TypedDict and use information common to all represented types.

@ilevkivskyi
Copy link
Member

This is intentional, TypedDicts behave as Mapping[str, object] to be safe w.r.t. structural subtyping, namely TypedDict({'x': X, 'y': Y, 'z': Z}) is a subtype TypedDict({'x': X, 'y': Y}).

@JosiahKane
Copy link
Author

JosiahKane commented Jun 12, 2020

I see! Should have read the PEP instead of just the docs.

I took "expects all of its instances to have a certain set of keys" to mean that the set of keys was fixed: all (except as explicit with the totality flag) and only those keys would feature and all would have the corresponding type.

I still think that this would be useful if it could be supported, perhaps by interaction with the final decorator or something similar to imply the set of keys is indeed exhaustive . However, that would clearly take rather more thought.

Ah, I see someone has beaten me to it with #7981

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