Skip to content

Commit 10b475a

Browse files
bpo-38405: Make nested subclasses of typing.NamedTuple pickleable. (GH-16641)
(cherry picked from commit 13abda4) Co-authored-by: Serhiy Storchaka <[email protected]>
1 parent 364532f commit 10b475a

File tree

3 files changed

+23
-8
lines changed

3 files changed

+23
-8
lines changed

Lib/test/test_typing.py

Lines changed: 21 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -3468,6 +3468,9 @@ class D(UserName):
34683468

34693469

34703470
class NamedTupleTests(BaseTestCase):
3471+
class NestedEmployee(NamedTuple):
3472+
name: str
3473+
cool: int
34713474

34723475
def test_basics(self):
34733476
Emp = NamedTuple('Emp', [('name', str), ('id', int)])
@@ -3593,14 +3596,25 @@ def test_namedtuple_errors(self):
35933596
self.assertEqual(Emp.__name__, 'Emp')
35943597
self.assertEqual(Emp._fields, ('name', 'id'))
35953598

3596-
def test_pickle(self):
3599+
def test_copy_and_pickle(self):
35973600
global Emp # pickle wants to reference the class by name
3598-
Emp = NamedTuple('Emp', [('name', str), ('id', int)])
3599-
jane = Emp('jane', 37)
3600-
for proto in range(pickle.HIGHEST_PROTOCOL + 1):
3601-
z = pickle.dumps(jane, proto)
3602-
jane2 = pickle.loads(z)
3603-
self.assertEqual(jane2, jane)
3601+
Emp = NamedTuple('Emp', [('name', str), ('cool', int)])
3602+
for cls in Emp, CoolEmployee, self.NestedEmployee:
3603+
with self.subTest(cls=cls):
3604+
jane = cls('jane', 37)
3605+
for proto in range(pickle.HIGHEST_PROTOCOL + 1):
3606+
z = pickle.dumps(jane, proto)
3607+
jane2 = pickle.loads(z)
3608+
self.assertEqual(jane2, jane)
3609+
self.assertIsInstance(jane2, cls)
3610+
3611+
jane2 = copy(jane)
3612+
self.assertEqual(jane2, jane)
3613+
self.assertIsInstance(jane2, cls)
3614+
3615+
jane2 = deepcopy(jane)
3616+
self.assertEqual(jane2, jane)
3617+
self.assertIsInstance(jane2, cls)
36043618

36053619

36063620
class TypedDictTests(BaseTestCase):

Lib/typing.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1593,7 +1593,7 @@ def _make_nmtuple(name, types):
15931593
'_fields', '_field_defaults', '_field_types',
15941594
'_make', '_replace', '_asdict', '_source')
15951595

1596-
_special = ('__module__', '__name__', '__qualname__', '__annotations__')
1596+
_special = ('__module__', '__name__', '__annotations__')
15971597

15981598

15991599
class NamedTupleMeta(type):
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Nested subclasses of :class:`typing.NamedTuple` are now pickleable.

0 commit comments

Comments
 (0)