8000 Issue 6637: defaultdict.copy() failed with an empty factory. · python/cpython@99a13ee · GitHub
[go: up one dir, main page]

Skip to content

Commit 99a13ee

Browse files
committed
Issue 6637: defaultdict.copy() failed with an empty factory.
1 parent d935976 commit 99a13ee

File tree

3 files changed

+15
-1
lines changed

3 files changed

+15
-1
lines changed

Lib/test/test_defaultdict.py

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,7 @@ def test_repr(self):
6060
d1 = defaultdict()
6161
self.assertEqual(d1.default_factory, None)
6262
self.assertEqual(repr(d1), "defaultdict(None, {})")
63+
self.assertEqual(eval(repr(d1)), d1)
6364
d1[11] = 41
6465
self.assertEqual(repr(d1), "defaultdict(None, {11: 41})")
6566
d2 = defaultdict(int)
@@ -112,6 +113,12 @@ def test_copy(self):
112113
d4[12]
113114
self.assertEqual(d4, {42: [], 12: []})
114115

116+
# Issue 6637: Copy fails for empty default dict
117+
d = defaultdict()
118+
d['a'] = 42
119+
e = d.copy()
120+
self.assertEqual(e['a'], 42)
121+
115122
def test_shallow_copy(self):
116123
d1 = defaultdict(foobar, {1: 1})
117124
d2 = copy.copy(d1)

Misc/NEWS

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,10 @@ C-API
4242
Library
4343
-------
4444

45+
- Issue #6637: defaultdict.copy() did not work when the default factory
46+
was left unspecified. Also, the eval/repr round-trip would fail when
47+
the default_factory was None.
48+
4549
- Issue #2715: Remove remnants of Carbon.File from binhex module.
4650

4751
- Issue #6595: The Decimal constructor now allows arbitrary Unicode

Modules/_collectionsmodule.c

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1170,6 +1170,9 @@ defdict_copy(defdictobject *dd)
11701170
whose class constructor has the same signature. Subclasses that
11711171
define a different constructor signature must override copy().
11721172
*/
1173+
1174+
if (dd->default_factory == NULL)
1175+
return PyObject_CallFunctionObjArgs((PyObject*)Py_TYPE(dd), Py_None, dd, NULL);
11731176
return PyObject_CallFunctionObjArgs((PyObject*)Py_TYPE(dd),
11741177
dd->default_factory, dd, NULL);
11751178
}
@@ -1316,7 +1319,7 @@ defdict_init(PyObject *self, PyObject *args, PyObject *kwds)
13161319
Py_ssize_t n = PyTuple_GET_SIZE(args);
13171320
if (n > 0) {
13181321
newdefault = PyTuple_GET_ITEM(args, 0);
1319-
if (!PyCallable_Check(newdefault)) {
1322+
if (!PyCallable_Check(newdefault) && newdefault != Py_None) {
13201323
PyErr_SetString(PyExc_TypeError,
13211324
"first argument must be callable");
13221325
return -1;

0 commit comments

Comments
 (0)
0