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

NamedTuple.__init__(**kwargs) doesn't type check #6823

Closed
csingley opened this issue May 12, 2019 · 2 comments
Closed

NamedTuple.__init__(**kwargs) doesn't type check #6823

csingley opened this issue May 12, 2019 · 2 comments

Comments

@csingley
Copy link

  • Are you reporting a bug, or opening a feature request?
    • Bug
  • Please insert below the code you are checking with mypy,
from typing import NamedTuple, Optional
from collections import OrderedDict

class Datum(NamedTuple):
    id: Optional[str] = None
    value: Optional[int] = None

# This passes type checking
# datum = Datum(value=1, id="foo")

# This fails to type check
attrs = {"id": "foo", "value": 1}

# This passes type checking
# attrs = OrderedDict([("id", "bar"), ("value", 1)])

datum = Datum(**attrs)
  • What is the actual behavior/output?
test.py:19: error: Argument 1 to "Datum" has incompatible type "**Dict[str, object]"; expected "Optional[str]"
test.py:19: error: Argument 1 to "Datum" has incompatible type "**Dict[str, object]"; expected "Optional[int]"
  • What is the behavior/output you expect?
    • mypy should treat dict unpacking the same as keyword assignment for NamedTuple.__init__()
  • What are the versions of mypy and Python you are using?
    • Python 3.7.3
    • mypy 0.701
  • Do you see the same issue after installing mypy from Git master?
    • yes
  • What are the mypy flags you are using? (For example --strict-optional)
    • none

I didn't see this issue reported; sorry if I overlooked. Using **OrderedDict is a workaround. as shown in the code sample above.

@antonagestam
Copy link
Contributor

To clarify: this is a false positive. This is the smallest piece of code I managed to reproduce it with. Having a NamedTuple with only one field does not trigger this.

from typing import NamedTuple


class A(NamedTuple):
    a: str
    b: int


A(**{"b": 1, "a": "foo"})

Output:

test-namedtuple-fail.py:9: error: Argument 1 to "A" has incompatible type "**Dict[str, object]"; expected "str"
test-namedtuple-fail.py:9: error: Argument 1 to "A" has incompatible type "**Dict[str, object]"; expected "int"

I also see the same behavior with master (mypy-0.710+dev.b3420c8b31875fac74895d4024ad9f8f0bd2240d), and with --new-semantic-analyzer.

@ilevkivskyi
Copy link
Member

This is not specific to named tuples, duplicate of #5382

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

3 participants