From 51f46b1209a7c9a7a3d938fe8379f43d86c07645 Mon Sep 17 00:00:00 2001 From: sobolevn Date: Sat, 29 Jul 2023 11:40:41 +0300 Subject: [PATCH 1/3] [stubtest] Test `NamedTuple` definitions with default fields --- mypy/test/teststubtest.py | 38 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 38 insertions(+) diff --git a/mypy/test/teststubtest.py b/mypy/test/teststubtest.py index 661d46e9fd8a..5fdbc270b199 100644 --- a/mypy/test/teststubtest.py +++ b/mypy/test/teststubtest.py @@ -68,6 +68,7 @@ class Mapping(Generic[_K, _V]): ... class Match(Generic[AnyStr]): ... class Sequence(Iterable[_T_co]): ... class Tuple(Sequence[_T_co]): ... +class NamedTuple(tuple[Any, ...]): ... def overload(func: _T) -> _T: ... """ @@ -82,6 +83,7 @@ def overload(func: _T) -> _T: ... class object: __module__: str def __init__(self) -> None: pass + def __repr__(self) -> str: pass class type: ... class tuple(Sequence[T_co], Generic[T_co]): ... @@ -1599,6 +1601,42 @@ class Y(TypedDict): error=None, ) + @collect_cases + def test_named_tuple(self) -> Iterator[Case]: + yield Case( + stub="from typing import NamedTuple", + runtime="from typing import NamedTuple", + error=None, + ) + yield Case( + stub=""" + class X1(NamedTuple): + bar: int + foo: str = ... + """, + runtime=""" + class X1(NamedTuple): + bar: int + foo: str = 'a' + """, + error=None, + ) + yield Case( + stub=""" + class X2(NamedTuple): + bar: int + foo: str + """, + runtime=""" + class X2(NamedTuple): + bar: int + foo: str = 'a' + """, + # `__new__` will miss a deafult value for a `foo` parameter, + # but we don't generate special errors for `foo` missing `...` part. + error="X2.__new__", + ) + @collect_cases def test_type_var(self) -> Iterator[Case]: yield Case( From 6257ff934e5ffc80307aebcef2d6b38ce5b53cd2 Mon Sep 17 00:00:00 2001 From: sobolevn Date: Sat, 29 Jul 2023 11:47:05 +0300 Subject: [PATCH 2/3] Typo! --- mypy/test/teststubtest.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mypy/test/teststubtest.py b/mypy/test/teststubtest.py index 5fdbc270b199..e2b2e7fd8d5e 100644 --- a/mypy/test/teststubtest.py +++ b/mypy/test/teststubtest.py @@ -1632,7 +1632,7 @@ class X2(NamedTuple): bar: int foo: str = 'a' """, - # `__new__` will miss a deafult value for a `foo` parameter, + # `__new__` will miss a default value for a `foo` parameter, # but we don't generate special errors for `foo` missing `...` part. error="X2.__new__", ) From e4d96569f8d5f5b208af113e96c9d0e909756393 Mon Sep 17 00:00:00 2001 From: sobolevn Date: Sat, 29 Jul 2023 13:47:08 +0300 Subject: [PATCH 3/3] Add `collections.namedtuple` to the test --- mypy/test/teststubtest.py | 30 ++++++++++++++++++++++++++++++ 1 file changed, 30 insertions(+) diff --git a/mypy/test/teststubtest.py b/mypy/test/teststubtest.py index e2b2e7fd8d5e..cd72bd9300d1 100644 --- a/mypy/test/teststubtest.py +++ b/mypy/test/teststubtest.py @@ -1637,6 +1637,36 @@ class X2(NamedTuple): error="X2.__new__", ) + @collect_cases + def test_named_tuple_typing_and_collections(self) -> Iterator[Case]: + yield Case( + stub="from typing import NamedTuple", + runtime="from collections import namedtuple", + error=None, + ) + yield Case( + stub=""" + class X1(NamedTuple): + bar: int + foo: str = ... + """, + runtime=""" + X1 = namedtuple('X1', ['bar', 'foo'], defaults=['a']) + """, + error=None, + ) + yield Case( + stub=""" + class X2(NamedTuple): + bar: int + foo: str + """, + runtime=""" + X2 = namedtuple('X1', ['bar', 'foo'], defaults=['a']) + """, + error="X2.__new__", + ) + @collect_cases def test_type_var(self) -> Iterator[Case]: yield Case(