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

Unable to pass values from TypedDict into dict #9117

Closed
PeterJCLaw opened this issue Jul 9, 2020 · 2 comments
Closed

Unable to pass values from TypedDict into dict #9117

PeterJCLaw opened this issue Jul 9, 2020 · 2 comments
Labels
bug mypy got something wrong false-positive mypy gave an error on correct code topic-typed-dict topic-usability

Comments

@PeterJCLaw
Copy link
Contributor

Not sure if this is strictly a bug, however it's not a behaviour I expected and I can't see anything in mypy's docs either way.

If you have a TypedDict such as:

Foo = TypedDict('Foo', {
    'bar': int,
})
foo = Foo({'bar': 42})

and you want to combine that mapping with another using either spray or .update() forms then this is considered an error:

d = {
    'other': 2,
    **foo,  # Argument 1 to "update" of "dict" has incompatible type "Foo"; expected "Mapping[str, int]"
    **dict(foo),  # Argument 1 to "dict" has incompatible type "Foo"; expected "Mapping[str, int]"
}
d.update(foo)  # Argument 1 to "update" of "dict" has incompatible type "Foo"; expected "Mapping[str, int]"

note however that passing only into a dict works:

x = dict(foo)  # Revealed type is 'builtins.dict[builtins.str*, builtins.object*]'

Given the type of x here I can see why the d.update(..) form doesn't work, though I would have expected that mypy would be able to merge the types when using spray notation.

Is this expected behaviour? If so, what is the expected way to combine a TypedDict with additional keys like this?

Aside: I would also expect that the signature of x be Dict[str, int] rather than Dict[str, object] since the type details of the TypedDict are essentially that. (I would expect a Union in the value type of more complicated TypedDicts).

My use-case is preparing a dict for conversion to JSON for a web API, so I'm currently working around this by annotating d as being Dict[str, Any] which I end up doing anyway for JSON and which sidesteps the inference of the dict members to find the type for d.

I'm using mypy 0.782 on Python 3.6.

PeterJCLaw added a commit to PeterJCLaw/srcomp-http that referenced this issue Jul 9, 2020
It doesn't seem to enjoy merging TypedDicts with other keys like
this, see python/mypy#9117.
@JukkaL
Copy link
Collaborator

JukkaL commented Sep 11, 2020

Here's a self-contained example:

from typing_extensions import TypedDict

Foo = TypedDict('Foo', {'bar': int})
foo: Foo = {'bar': 42}

x = {'x': 1, **foo}  # Error here

It would be nice to infer Dict[str, object] as the type of d instead of generating the confusing error message.

As a workaround, you can add an explicit Dict[str, object] type annotation for d.

@JukkaL JukkaL added bug mypy got something wrong false-positive mypy gave an error on correct code topic-typed-dict topic-usability labels Sep 11, 2020
@erictraut
Copy link

This bug was recently fixed. Mypy 1.5 no longer emits an error for any of the above samples.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug mypy got something wrong false-positive mypy gave an error on correct code topic-typed-dict topic-usability
Projects
None yet
Development

No branches or pull requests

4 participants