diff options
author | Raymond Hettinger <python@rcn.com> | 2009-08-04 19:13:37 +0000 |
---|---|---|
committer | Raymond Hettinger <python@rcn.com> | 2009-08-04 19:13:37 +0000 |
commit | 99a13eeed18f533100489e7ca42a89de4e8ec07d (patch) | |
tree | 5fbb478db8caca11615841de464bf1c8f5712477 | |
parent | d935976d7021ddaee728d8e018a4688e85ebd8c7 (diff) | |
download | cpython-git-99a13eeed18f533100489e7ca42a89de4e8ec07d.tar.gz |
Issue 6637: defaultdict.copy() failed with an empty factory.
-rw-r--r-- | Lib/test/test_defaultdict.py | 7 | ||||
-rw-r--r-- | Misc/NEWS | 4 | ||||
-rw-r--r-- | Modules/_collectionsmodule.c | 5 |
3 files changed, 15 insertions, 1 deletions
diff --git a/Lib/test/test_defaultdict.py b/Lib/test/test_defaultdict.py index 00bd9dc516..76fc6a6e33 100644 --- a/Lib/test/test_defaultdict.py +++ b/Lib/test/test_defaultdict.py @@ -60,6 +60,7 @@ class TestDefaultDict(unittest.TestCase): d1 = defaultdict() self.assertEqual(d1.default_factory, None) self.assertEqual(repr(d1), "defaultdict(None, {})") + self.assertEqual(eval(repr(d1)), d1) d1[11] = 41 self.assertEqual(repr(d1), "defaultdict(None, {11: 41})") d2 = defaultdict(int) @@ -112,6 +113,12 @@ class TestDefaultDict(unittest.TestCase): d4[12] self.assertEqual(d4, {42: [], 12: []}) + # Issue 6637: Copy fails for empty default dict + d = defaultdict() + d['a'] = 42 + e = d.copy() + self.assertEqual(e['a'], 42) + def test_shallow_copy(self): d1 = defaultdict(foobar, {1: 1}) d2 = copy.copy(d1) @@ -42,6 +42,10 @@ C-API Library ------- +- Issue #6637: defaultdict.copy() did not work when the default factory + was left unspecified. Also, the eval/repr round-trip would fail when + the default_factory was None. + - Issue #2715: Remove remnants of Carbon.File from binhex module. - Issue #6595: The Decimal constructor now allows arbitrary Unicode diff --git a/Modules/_collectionsmodule.c b/Modules/_collectionsmodule.c index f8d656cccb..68e01836cb 100644 --- a/Modules/_collectionsmodule.c +++ b/Modules/_collectionsmodule.c @@ -1170,6 +1170,9 @@ defdict_copy(defdictobject *dd) whose class constructor has the same signature. Subclasses that define a different constructor signature must override copy(). */ + + if (dd->default_factory == NULL) + return PyObject_CallFunctionObjArgs((PyObject*)Py_TYPE(dd), Py_None, dd, NULL); return PyObject_CallFunctionObjArgs((PyObject*)Py_TYPE(dd), dd->default_factory, dd, NULL); } @@ -1316,7 +1319,7 @@ defdict_init(PyObject *self, PyObject *args, PyObject *kwds) Py_ssize_t n = PyTuple_GET_SIZE(args); if (n > 0) { newdefault = PyTuple_GET_ITEM(args, 0); - if (!PyCallable_Check(newdefault)) { + if (!PyCallable_Check(newdefault) && newdefault != Py_None) { PyErr_SetString(PyExc_TypeError, "first argument must be callable"); return -1; |