Skip to content

Fix __init__ type of typing.NamedTuple #6079

Closed

Description

@sobolevn

While working on python/mypy#11047 I've noticed that there's an issue with typing.NamedTuple

Right now __init__ of typing.NamedTuple has type: def __init__(self, typename: str, fields: Iterable[Tuple[str, Any]] = ..., **kwargs: Any) -> None: ... which is not correct.

Why? Let's try to add both fields and kwargs:

>>> from typing import NamedTuple
>>> NamedTuple('a', (), f=int)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/Users/sobolev/.pyenv/versions/3.9.1/lib/python3.9/typing.py", line 1864, in NamedTuple
    raise TypeError("Either list of fields or keywords"
TypeError: Either list of fields or keywords can be provided to NamedTuple, not both

Source: https://github.com/python/cpython/blob/f56268a2cd38b3fe2be1e4361d3d8b581e73559b/Lib/typing.py#L2290-L2294

So, it should be an overload instead:

    @overload
    def __init__(self, typename: str, fields: Iterable[Tuple[str, Any]] = ...) -> None: ...
    @overload
    def __init__(self, typename: str, **kwargs: Any) -> None: ...

Notice, that fields=None is still allowed:

>>> NamedTuple('a', fields=None, f=int)

But, I don't think that we should have def __init__(self, typename: str, fields: None = ..., **kwargs: Any) -> None: ... instead.

One more thing: is it Tuple[str, Any] or Tuple[str, type]? It is supposed to be types. But, it is not enforced anywhere (except mypy) as far as I know.

I will send a PR with the fix.

Activity

  1. added a commit that references this issue on Sep 29, 2021
    4ac969a
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

    No labels
    No labels

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions