diff --git a/Lib/test/test_defaultdict.py b/Lib/test/test_defaultdict.py index 134b5a8cb2f..1834f9071ae 100644 --- a/Lib/test/test_defaultdict.py +++ b/Lib/test/test_defaultdict.py @@ -47,6 +47,7 @@ class TestDefaultDict(unittest.TestCase): self.assertEqual(err.args, (15,)) else: self.fail("d2[15] didn't raise KeyError") + self.assertRaises(TypeError, defaultdict, 1) def test_missing(self): d1 = defaultdict() @@ -60,10 +61,10 @@ class TestDefaultDict(unittest.TestCase): self.assertEqual(repr(d1), "defaultdict(None, {})") d1[11] = 41 self.assertEqual(repr(d1), "defaultdict(None, {11: 41})") - d2 = defaultdict(0) - self.assertEqual(d2.default_factory, 0) + d2 = defaultdict(int) + self.assertEqual(d2.default_factory, int) d2[12] = 42 - self.assertEqual(repr(d2), "defaultdict(0, {12: 42})") + self.assertEqual(repr(d2), "defaultdict(, {12: 42})") def foo(): return 43 d3 = defaultdict(foo) self.assert_(d3.default_factory is foo) diff --git a/Misc/NEWS b/Misc/NEWS index 1f216f75cb6..e628f449792 100644 --- a/Misc/NEWS +++ b/Misc/NEWS @@ -103,6 +103,8 @@ Core and builtins Extension Modules ----------------- +- collections.defaultdict() now verifies that the factory function is callable. + - Bug #1486663: don't reject keyword arguments for subclasses of builtin types. diff --git a/Modules/collectionsmodule.c b/Modules/collectionsmodule.c index a4cdcfaf52d..f98bd490323 100644 --- a/Modules/collectionsmodule.c +++ b/Modules/collectionsmodule.c @@ -1252,8 +1252,14 @@ defdict_init(PyObject *self, PyObject *args, PyObject *kwds) newargs = PyTuple_New(0); else { Py_ssize_t n = PyTuple_GET_SIZE(args); - if (n > 0) + if (n > 0) { newdefault = PyTuple_GET_ITEM(args, 0); + if (!PyCallable_Check(newdefault)) { + PyErr_SetString(PyExc_TypeError, + "first argument must be callable"); + return -1; + } + } newargs = PySequence_GetSlice(args, 1, n); } if (newargs == NULL)