Skip to content

Commit 87db4d3

Browse files
[3.7] bpo-38405: Make nested subclasses of typing.NamedTuple pickleable. (GH-16641). (GH-16674)
(cherry picked from commit 13abda4)
1 parent 056fa7f commit 87db4d3

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
@@ -2441,6 +2441,9 @@ class D(UserName):
24412441

24422442

24432443
class NamedTupleTests(BaseTestCase):
2444+
class NestedEmployee(NamedTuple):
2445+
name: str
2446+
cool: int
24442447

24452448
def test_basics(self):
24462449
Emp = NamedTuple('Emp', [('name', str), ('id', int)])
@@ -2564,14 +2567,25 @@ def test_namedtuple_errors(self):
25642567
self.assertEqual(Emp.__name__, 'Emp')
25652568
self.assertEqual(Emp._fields, ('name', 'id'))
25662569

2567-
def test_pickle(self):
2570+
def test_copy_and_pickle(self):
25682571
global Emp # pickle wants to reference the class by name
2569-
Emp = NamedTuple('Emp', [('name', str), ('id', int)])
2570-
jane = Emp('jane', 37)
2571-
for proto in range(pickle.HIGHEST_PROTOCOL + 1):
2572-
z = pickle.dumps(jane, proto)
2573-
jane2 = pickle.loads(z)
2574-
self.assertEqual(jane2, jane)
2572+
Emp = NamedTuple('Emp', [('name', str), ('cool', int)])
2573+
for cls in Emp, CoolEmployee, self.NestedEmployee:
2574+
with self.subTest(cls=cls):
2575+
jane = cls('jane', 37)
2576+
for proto in range(pickle.HIGHEST_PROTOCOL + 1):
2577+
z = pickle.dumps(jane, proto)
2578+
jane2 = pickle.loads(z)
2579+
self.assertEqual(jane2, jane)
2580+
self.assertIsInstance(jane2, cls)
2581+
2582+
jane2 = copy(jane)
2583+
self.assertEqual(jane2, jane)
2584+
self.assertIsInstance(jane2, cls)
2585+
2586+
jane2 = deepcopy(jane)
2587+
self.assertEqual(jane2, jane)
2588+
self.assertIsInstance(jane2, cls)
25752589

25762590

25772591
class IOTests(BaseTestCase):

Lib/typing.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1343,7 +1343,7 @@ def _make_nmtuple(name, types):
13431343
'_fields', '_field_defaults', '_field_types',
13441344
'_make', '_replace', '_asdict', '_source')
13451345

1346-
_special = ('__module__', '__name__', '__qualname__', '__annotations__')
1346+
_special = ('__module__', '__name__', '__annotations__')
13471347

13481348

13491349
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)