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 single line declaration gives error "Too many arguments for NamedTuple() [misc] #11047

Open
yesthesoup opened this issue Sep 2, 2021 · 3 comments · May be fixed by #11206
Open

NamedTuple single line declaration gives error "Too many arguments for NamedTuple() [misc] #11047

yesthesoup opened this issue Sep 2, 2021 · 3 comments · May be fixed by #11206
Labels
bug mypy got something wrong semantic-analyzer Problems that happen during semantic analysis topic-named-tuple

Comments

@yesthesoup
Copy link

Bug Report

typing.NamedTuple one line declaration gives incorrect error

To Reproduce

# test.py
from typing import NamedTuple

ExampleClass = NamedTuple('ExampleClass', test_id=str, timestamp=str)
mypy --show-error-codes test.py

test.py:[line-no]: error: Too many arguments for NamedTuple()  [misc]

Expected Behavior

mypy doesn't give this error

given the above syntax is valid python and works fine, I would expect it to not throw an error, like the following old structure declaration does not, which is labeled as "back-ward compatible usage" in the official doc

ExampleClass = NamedTuple('ExampleClass', [(test_id, str), (timestamp, str)])

Actual Behavior

error: Too many arguments for NamedTuple()  [misc]

Your Environment

mypy --version
mypy 0.910

python --version
3.8.10
@yesthesoup yesthesoup added the bug mypy got something wrong label Sep 2, 2021
@sobolevn
Copy link
Member

Working on it. It might take some time though.

JukkaL pushed a commit that referenced this issue Sep 22, 2021
While working on #11047 I've noticed that mypy reports the same error 
for both collection.namedtuple() and typing.NamedTuple().

I've tried to fix to report the correct name.
@sobolevn
Copy link
Member

sobolevn commented Sep 22, 2021

There are multiple other bugs / missing features.

  1. fullname must be str only, right now bytes is allowed by mypy, but not cpython:
>>> import collections
>>> collections.namedtuple(b'custom', ['x'])
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/Users/sobolev/.pyenv/versions/3.9.1/lib/python3.9/collections/__init__.py", line 390, in namedtuple
    raise ValueError('Type names and field names must be valid '
ValueError: Type names and field names must be valid identifiers: "b'custom'"
  1. rename=True is not supported:
>>> N = namedtuple(typename='N', field_names=['raise'], rename=True)
>>> N = namedtuple(typename='N', field_names=['raise'])
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/Users/sobolev/.pyenv/versions/3.9.1/lib/python3.9/collections/__init__.py", line 393, in namedtuple
    raise ValueError('Type names and field names cannot be a '
ValueError: Type names and field names cannot be a keyword: 'raise'
  1. module= is not supported

@sobolevn
Copy link
Member

sobolevn commented Sep 26, 2021

Status update: I am rewritting argument parsing in semanal_namedtuple completely. It was way to complicated.

Right now I can parse all possible valid combinations of NamedTuple and its arguments.
Something like:

def _parse_typing_namedtuple(self, typename: str) -> NamedTupleStructure:
        """Parsing ``typing.NamedTuple()`` call.

        In all of the examples below arguments can be named or positional.

        Possible valid cases:
        1. ``N = NamedTuple('N')`` - empty namedtuple,
        2. ``N = NamedTuple('N', [('a', int)])``
        3. ``N = NamedTuple(typename='N', fields=(('a', int),))``
        4. ``N = NamedTuple('N', a=int)`` with kwargs

        Corner cases, but still valid:
        7. ``N = NamedTuple('N', ())``, - empty namedtuple,
           we also count ``[]`` here, ``fields`` can be named or positional
        6. ``N = NamedTuple('N', fields=None, a=int)``,
           in this case ``fields`` will not be present as a namedtuple field
        7. ``N = NamedTuple('N', None, a=int)``
        8. ``N = NamedTuple(a=int, typename='N')``
           kw-arguments can be in a different order, that's fine

        Everything else is considered **invalid**.
        We only accept statically known types.
        """

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug mypy got something wrong semantic-analyzer Problems that happen during semantic analysis topic-named-tuple
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants