summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRaymond Hettinger <python@rcn.com>2009-08-04 19:16:39 +0000
committerRaymond Hettinger <python@rcn.com>2009-08-04 19:16:39 +0000
commit54628fa7c093c0734240a99d04b923acdf9e1e9b (patch)
treea37f4b59a856595cb6554f953910f45188bb5591
parentfe800a3437b55333dd5d4c21d071c699126830a8 (diff)
downloadcpython-git-54628fa7c093c0734240a99d04b923acdf9e1e9b.tar.gz
Issue 6637: defaultdict.copy() failed with an empty factory.
-rw-r--r--Lib/test/test_defaultdict.py7
-rw-r--r--Modules/_collectionsmodule.c5
2 files changed, 11 insertions, 1 deletions
diff --git a/Lib/test/test_defaultdict.py b/Lib/test/test_defaultdict.py
index 35468b4b4f..e5a9bd5df7 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)
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;