Skip to content

Commit 0a64085

Browse files
RyanClark2kogrisel
andauthored
Fix Python 3.9+ NamedTuple issues (#495)
Co-authored-by: Olivier Grisel <[email protected]>
1 parent 68a4230 commit 0a64085

File tree

3 files changed

+26
-5
lines changed

3 files changed

+26
-5
lines changed

CHANGES.md

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,8 @@
1-
2.3.0 (in development)
2-
======================
1+
2.2.1
2+
=====
33

4-
- TODO
4+
- Fix pickling of NamedTuple in Python 3.9+.
5+
([issue #460](https://github.com/cloudpipe/cloudpickle/issues/460))
56

67
2.2.0
78
=====

cloudpickle/cloudpickle_fast.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -111,8 +111,8 @@ def dumps(obj, protocol=None):
111111

112112
def _class_getnewargs(obj):
113113
type_kwargs = {}
114-
if "__slots__" in obj.__dict__:
115-
type_kwargs["__slots__"] = obj.__slots__
114+
if "__module__" in obj.__dict__:
115+
type_kwargs["__module__"] = obj.__module__
116116

117117
__dict__ = obj.__dict__.get('__dict__', None)
118118
if isinstance(__dict__, property):

tests/cloudpickle_test.py

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1597,6 +1597,24 @@ def test_namedtuple(self):
15971597
assert isinstance(depickled_t2, MyTuple)
15981598
assert depickled_t2 == t2
15991599

1600+
def test_NamedTuple(self):
1601+
class MyTuple(typing.NamedTuple):
1602+
a: int
1603+
b: int
1604+
c: int
1605+
1606+
t1 = MyTuple(1, 2, 3)
1607+
t2 = MyTuple(3, 2, 1)
1608+
1609+
depickled_t1, depickled_MyTuple, depickled_t2 = pickle_depickle(
1610+
[t1, MyTuple, t2], protocol=self.protocol)
1611+
1612+
assert isinstance(depickled_t1, MyTuple)
1613+
assert depickled_t1 == t1
1614+
assert depickled_MyTuple is MyTuple
1615+
assert isinstance(depickled_t2, MyTuple)
1616+
assert depickled_t2 == t2
1617+
16001618
def test_interactively_defined_function(self):
16011619
# Check that callables defined in the __main__ module of a Python
16021620
# script (or jupyter kernel) can be pickled / unpickled / executed.
@@ -2096,6 +2114,8 @@ def __init__(self):
20962114
depickled_obj = pickle_depickle(
20972115
initial_obj, protocol=self.protocol)
20982116

2117+
assert depickled_obj.__class__.__slots__ == slots
2118+
20992119
for obj in [initial_obj, depickled_obj]:
21002120
self.assertEqual(obj.registered_attribute, 42)
21012121
with pytest.raises(AttributeError):

0 commit comments

Comments
 (0)