Commit d6119ef8 authored by Raymond Hettinger's avatar Raymond Hettinger

Issue 6637: defaultdict.copy() failed with an empty factory.

parent 6416f810
...@@ -59,6 +59,7 @@ class TestDefaultDict(unittest.TestCase): ...@@ -59,6 +59,7 @@ class TestDefaultDict(unittest.TestCase):
d1 = defaultdict() d1 = defaultdict()
self.assertEqual(d1.default_factory, None) self.assertEqual(d1.default_factory, None)
self.assertEqual(repr(d1), "defaultdict(None, {})") self.assertEqual(repr(d1), "defaultdict(None, {})")
self.assertEqual(eval(repr(d1)), d1)
d1[11] = 41 d1[11] = 41
self.assertEqual(repr(d1), "defaultdict(None, {11: 41})") self.assertEqual(repr(d1), "defaultdict(None, {11: 41})")
d2 = defaultdict(int) d2 = defaultdict(int)
...@@ -111,6 +112,12 @@ class TestDefaultDict(unittest.TestCase): ...@@ -111,6 +112,12 @@ class TestDefaultDict(unittest.TestCase):
d4[12] d4[12]
self.assertEqual(d4, {42: [], 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): def test_shallow_copy(self):
d1 = defaultdict(foobar, {1: 1}) d1 = defaultdict(foobar, {1: 1})
d2 = copy.copy(d1) d2 = copy.copy(d1)
......
...@@ -70,6 +70,10 @@ Core and Builtins ...@@ -70,6 +70,10 @@ Core and Builtins
Library 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 #1424152: Fix for httplib, urllib2 to support SSL while working through - Issue #1424152: Fix for httplib, urllib2 to support SSL while working through
proxy. Original patch by Christopher Li, changes made by Senthil Kumaran. proxy. Original patch by Christopher Li, changes made by Senthil Kumaran.
......
...@@ -1191,6 +1191,9 @@ defdict_copy(defdictobject *dd) ...@@ -1191,6 +1191,9 @@ defdict_copy(defdictobject *dd)
whose class constructor has the same signature. Subclasses that whose class constructor has the same signature. Subclasses that
define a different constructor signature must override copy(). 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), return PyObject_CallFunctionObjArgs((PyObject*)Py_TYPE(dd),
dd->default_factory, dd, NULL); dd->default_factory, dd, NULL);
} }
...@@ -1354,7 +1357,7 @@ defdict_init(PyObject *self, PyObject *args, PyObject *kwds) ...@@ -1354,7 +1357,7 @@ defdict_init(PyObject *self, PyObject *args, PyObject *kwds)
Py_ssize_t n = PyTuple_GET_SIZE(args); Py_ssize_t n = PyTuple_GET_SIZE(args);
if (n > 0) { if (n > 0) {
newdefault = PyTuple_GET_ITEM(args, 0); newdefault = PyTuple_GET_ITEM(args, 0);
if (!PyCallable_Check(newdefault)) { if (!PyCallable_Check(newdefault) && newdefault != Py_None) {
PyErr_SetString(PyExc_TypeError, PyErr_SetString(PyExc_TypeError,
"first argument must be callable"); "first argument must be callable");
return -1; return -1;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment