Skip to content

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

Open

Description

@yesthesoup

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

Activity

  1. sobolevn commented on Sep 17, 2021

    @sobolevn
    Member

    Working on it. It might take some time though.

  2. sobolevn commented on Sep 22, 2021

    @sobolevn
    Member

    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
  3. sobolevn commented on Sep 26, 2021

    @sobolevn
    Member

    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

Metadata

Metadata

Assignees

No one assigned

    Labels

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions