]> granicus.if.org Git - python/commitdiff
Issue 6637: defaultdict.copy() failed with an empty factory.
authorRaymond Hettinger <python@rcn.com>
Tue, 4 Aug 2009 19:08:05 +0000 (19:08 +0000)
committerRaymond Hettinger <python@rcn.com>
Tue, 4 Aug 2009 19:08:05 +0000 (19:08 +0000)
Lib/test/test_defaultdict.py
Modules/_collectionsmodule.c

index 71d69c35d24d86f1f8249e42b924bab18d8f2d78..f9a6a17ad18baf7b40811ee0481133e658527bd8 100644 (file)
@@ -59,6 +59,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)
@@ -111,6 +112,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)
index a4fdf76c04ec79aaf9e903a72f302750f99ea5ab..1873cabc5b6b7e352565fd7618cef7d9e081e1f1 100644 (file)
@@ -1228,6 +1228,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);
 }
@@ -1391,7 +1394,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;