Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit f43ee81

Browse files
committed
#4170: Fix segfault when pickling a defauldict object.
The 2.x dict.iteritems() returns an iterator, whereas the 3.0 dict.items() returns a "view", which is iterable, but not an iterator with its __next__ method. Patch by Hirokazu Yamamoto.
1 parent 73b90a8 commit f43ee81

3 files changed

Lines changed: 20 additions & 1 deletion

File tree

Lib/test/test_defaultdict.py

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
import os
44
import copy
5+
import pickle
56
import tempfile
67
import unittest
78
from test import support
@@ -164,6 +165,13 @@ def _factory(self):
164165
finally:
165166
os.remove(tfn)
166167

168+
def test_pickleing(self):
169+
d = defaultdict(int)
170+
d[1]
171+
for proto in range(pickle.HIGHEST_PROTOCOL + 1):
172+
s = pickle.dumps(d, proto)
173+
o = pickle.loads(s)
174+
self.assertEqual(d, o)
167175

168176
def test_main():
169177
support.run_unittest(TestDefaultDict)

Misc/NEWS

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,9 @@ What's New in Python 3.0 beta 5
1515
Core and Builtins
1616
-----------------
1717

18+
- Issue #4170: Pickling a collections.defaultdict object would crash the
19+
interpreter.
20+
1821
- Issue #4146: Compilation on OpenBSD has been restored.
1922

2023
- Issue #3574: compile() incorrectly handled source code encoded as Latin-1.

Modules/_collectionsmodule.c

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1155,6 +1155,7 @@ defdict_reduce(defdictobject *dd)
11551155
*/
11561156
PyObject *args;
11571157
PyObject *items;
1158+
PyObject *iter;
11581159
PyObject *result;
11591160
if (dd->default_factory == NULL || dd->default_factory == Py_None)
11601161
args = PyTuple_New(0);
@@ -1167,8 +1168,15 @@ defdict_reduce(defdictobject *dd)
11671168
Py_DECREF(args);
11681169
return NULL;
11691170
}
1171+
iter = PyObject_GetIter(items);
1172+
if (iter == NULL) {
1173+
Py_DECREF(items);
1174+
Py_DECREF(args);
1175+
return NULL;
1176+
}
11701177
result = PyTuple_Pack(5, Py_TYPE(dd), args,
1171-
Py_None, Py_None, items);
1178+
Py_None, Py_None, iter);
1179+
Py_DECREF(iter);
11721180
Py_DECREF(items);
11731181
Py_DECREF(args);
11741182
return result;

0 commit comments

Comments
 (0)