From 557d1eb0f3ccb9b0bea685a1883dd249cbe6d23a Mon Sep 17 00:00:00 2001 From: Guido van Rossum Date: Thu, 19 Nov 2015 08:16:31 -0800 Subject: [PATCH] Issue #25665: Make NamedTuple picklable. --- Lib/test/test_typing.py | 8 ++++++++ Lib/typing.py | 5 +++++ 2 files changed, 13 insertions(+) diff --git a/Lib/test/test_typing.py b/Lib/test/test_typing.py index ae138c65989..6ddaba94d54 100644 --- a/Lib/test/test_typing.py +++ b/Lib/test/test_typing.py @@ -1163,6 +1163,14 @@ class NamedTupleTests(TestCase): assert Emp._fields == ('name', 'id') assert Emp._field_types == dict(name=str, id=int) + def test_pickle(self): + global Emp # pickle wants to reference the class by name + Emp = NamedTuple('Emp', [('name', str), ('id', int)]) + jane = Emp('jane', 37) + z = pickle.dumps(jane) + jane2 = pickle.loads(z) + assert jane == jane2 + class IOTests(TestCase): diff --git a/Lib/typing.py b/Lib/typing.py index 49c4a069735..1757f138220 100644 --- a/Lib/typing.py +++ b/Lib/typing.py @@ -1479,6 +1479,11 @@ def NamedTuple(typename, fields): fields = [(n, t) for n, t in fields] cls = collections.namedtuple(typename, [n for n, t in fields]) cls._field_types = dict(fields) + # Set the module to the caller's module (otherwise it'd be 'typing'). + try: + cls.__module__ = sys._getframe(1).f_globals.get('__name__', '__main__') + except (AttributeError, ValueError): + pass return cls