From ab6131d6a4ffbaa7f665d18119f1cf332777b8d3 Mon Sep 17 00:00:00 2001 From: bswck Date: Tue, 4 Mar 2025 08:01:29 +0100 Subject: [PATCH 1/3] Raise a clear error message when `__classcell__` is seen in `typing.NamedTuple` subclasses --- Doc/library/typing.rst | 4 ++++ Lib/test/test_typing.py | 17 +++++++++++++++++ Lib/typing.py | 3 +++ ...025-02-13-15-10-56.gh-issue-85795.jeXXI9.rst | 3 +++ 4 files changed, 27 insertions(+) create mode 100644 Misc/NEWS.d/next/Library/2025-02-13-15-10-56.gh-issue-85795.jeXXI9.rst diff --git a/Doc/library/typing.rst b/Doc/library/typing.rst index 0fee782121b0af..0cc76c99be7d48 100644 --- a/Doc/library/typing.rst +++ b/Doc/library/typing.rst @@ -2359,6 +2359,10 @@ types. # A functional syntax is also supported Employee = NamedTuple('Employee', [('name', str), ('id', int)]) + .. note:: + Using :func:`super` (and the ``__class__`` :term:`closure variable`) in methods of ``NamedTuple`` subclasses + is unsupported and causes a :class:`RuntimeError`. + .. versionchanged:: 3.6 Added support for :pep:`526` variable annotation syntax. diff --git a/Lib/test/test_typing.py b/Lib/test/test_typing.py index f002d28df60e9c..059748bb74650b 100644 --- a/Lib/test/test_typing.py +++ b/Lib/test/test_typing.py @@ -8359,6 +8359,23 @@ class VeryAnnoying(metaclass=Meta): pass class Foo(NamedTuple): attr = very_annoying + def test_super_explicitly_disallowed(self): + expected_message = ( + "uses of super() and __class__ are unsupported " + "in methods of NamedTuple subclasses" + ) + + with self.assertRaises(RuntimeError, msg=expected_message): + class ThisWontWork(NamedTuple): + def __repr__(self): + return super().__repr__() + + with self.assertRaises(RuntimeError, msg=expected_message): + class ThisWontWorkEither(NamedTuple): + @property + def name(self): + return __class__.__name__ + class TypedDictTests(BaseTestCase): def test_basics_functional_syntax(self): diff --git a/Lib/typing.py b/Lib/typing.py index 66570db7a5bd74..a7b70e621db849 100644 --- a/Lib/typing.py +++ b/Lib/typing.py @@ -2961,6 +2961,9 @@ def annotate(format): class NamedTupleMeta(type): def __new__(cls, typename, bases, ns): assert _NamedTuple in bases + if "__classcell__" in ns: + raise RuntimeError( + "uses of super() and __class__ are unsupported in methods of NamedTuple subclasses") for base in bases: if base is not _NamedTuple and base is not Generic: raise TypeError( diff --git a/Misc/NEWS.d/next/Library/2025-02-13-15-10-56.gh-issue-85795.jeXXI9.rst b/Misc/NEWS.d/next/Library/2025-02-13-15-10-56.gh-issue-85795.jeXXI9.rst new file mode 100644 index 00000000000000..6191035dc22132 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2025-02-13-15-10-56.gh-issue-85795.jeXXI9.rst @@ -0,0 +1,3 @@ +Using :func:`super` and ``__class__`` :term:`closure variable` in +user-defined methods of :class:`typing.NamedTuple` subclasses is now +explicitly prevented at runtime. From 8f2ebc8147e7d4ab70165fbc2032e6a054e1f1bd Mon Sep 17 00:00:00 2001 From: bswck Date: Tue, 4 Mar 2025 08:07:46 +0100 Subject: [PATCH 2/3] Raise `TypeError` instead of `RuntimeError` if `__classcell__` is used in typed namedtuples --- Doc/library/typing.rst | 8 ++++---- Lib/test/test_typing.py | 4 ++-- Lib/typing.py | 2 +- .../Library/2025-02-13-15-10-56.gh-issue-85795.jeXXI9.rst | 2 +- 4 files changed, 8 insertions(+), 8 deletions(-) diff --git a/Doc/library/typing.rst b/Doc/library/typing.rst index 0cc76c99be7d48..3c65d9d62ce3c4 100644 --- a/Doc/library/typing.rst +++ b/Doc/library/typing.rst @@ -2359,10 +2359,6 @@ types. # A functional syntax is also supported Employee = NamedTuple('Employee', [('name', str), ('id', int)]) - .. note:: - Using :func:`super` (and the ``__class__`` :term:`closure variable`) in methods of ``NamedTuple`` subclasses - is unsupported and causes a :class:`RuntimeError`. - .. versionchanged:: 3.6 Added support for :pep:`526` variable annotation syntax. @@ -2380,6 +2376,10 @@ types. .. versionchanged:: 3.11 Added support for generic namedtuples. + .. versionchanged:: next + Using :func:`super` (and the ``__class__`` :term:`closure variable`) in methods of ``NamedTuple`` subclasses + is unsupported and causes a :class:`TypeError`. + .. deprecated-removed:: 3.13 3.15 The undocumented keyword argument syntax for creating NamedTuple classes (``NT = NamedTuple("NT", x=int)``) is deprecated, and will be disallowed diff --git a/Lib/test/test_typing.py b/Lib/test/test_typing.py index 059748bb74650b..acbdaf6db0dc58 100644 --- a/Lib/test/test_typing.py +++ b/Lib/test/test_typing.py @@ -8365,12 +8365,12 @@ def test_super_explicitly_disallowed(self): "in methods of NamedTuple subclasses" ) - with self.assertRaises(RuntimeError, msg=expected_message): + with self.assertRaises(TypeError, msg=expected_message): class ThisWontWork(NamedTuple): def __repr__(self): return super().__repr__() - with self.assertRaises(RuntimeError, msg=expected_message): + with self.assertRaises(TypeError, msg=expected_message): class ThisWontWorkEither(NamedTuple): @property def name(self): diff --git a/Lib/typing.py b/Lib/typing.py index a7b70e621db849..68b8be44d1f55b 100644 --- a/Lib/typing.py +++ b/Lib/typing.py @@ -2962,7 +2962,7 @@ class NamedTupleMeta(type): def __new__(cls, typename, bases, ns): assert _NamedTuple in bases if "__classcell__" in ns: - raise RuntimeError( + raise TypeError( "uses of super() and __class__ are unsupported in methods of NamedTuple subclasses") for base in bases: if base is not _NamedTuple and base is not Generic: diff --git a/Misc/NEWS.d/next/Library/2025-02-13-15-10-56.gh-issue-85795.jeXXI9.rst b/Misc/NEWS.d/next/Library/2025-02-13-15-10-56.gh-issue-85795.jeXXI9.rst index 6191035dc22132..3f9320d74244c1 100644 --- a/Misc/NEWS.d/next/Library/2025-02-13-15-10-56.gh-issue-85795.jeXXI9.rst +++ b/Misc/NEWS.d/next/Library/2025-02-13-15-10-56.gh-issue-85795.jeXXI9.rst @@ -1,3 +1,3 @@ Using :func:`super` and ``__class__`` :term:`closure variable` in user-defined methods of :class:`typing.NamedTuple` subclasses is now -explicitly prevented at runtime. +explicitly prohibited at runtime. From e5539be32e601bb5655576f4d4bbcba9a449a2c6 Mon Sep 17 00:00:00 2001 From: bswck Date: Tue, 4 Mar 2025 08:13:19 +0100 Subject: [PATCH 3/3] Add attribution --- .../next/Library/2025-02-13-15-10-56.gh-issue-85795.jeXXI9.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Misc/NEWS.d/next/Library/2025-02-13-15-10-56.gh-issue-85795.jeXXI9.rst b/Misc/NEWS.d/next/Library/2025-02-13-15-10-56.gh-issue-85795.jeXXI9.rst index 3f9320d74244c1..dec162bb624a15 100644 --- a/Misc/NEWS.d/next/Library/2025-02-13-15-10-56.gh-issue-85795.jeXXI9.rst +++ b/Misc/NEWS.d/next/Library/2025-02-13-15-10-56.gh-issue-85795.jeXXI9.rst @@ -1,3 +1,3 @@ Using :func:`super` and ``__class__`` :term:`closure variable` in user-defined methods of :class:`typing.NamedTuple` subclasses is now -explicitly prohibited at runtime. +explicitly prohibited at runtime. Contributed by Bartosz Sławecki in :gh:`130082`.