diff --git a/Lib/test/test_dict.py b/Lib/test/test_dict.py index 8da0915346c..41446925274 100644 --- a/Lib/test/test_dict.py +++ b/Lib/test/test_dict.py @@ -454,6 +454,17 @@ class DictTest(unittest.TestCase): else: self.fail("missing KeyError") + def test_empty_presized_dict_in_freelist(self): + # Bug #3537: if an empty but presized dict with a size larger + # than 7 was in the freelist, it triggered an assertion failure + try: + d = {'a': 1/0, 'b': None, 'c': None, 'd': None, 'e': None, + 'f': None, 'g': None, 'h': None} + except ZeroDivisionError: + pass + d = {} + + from test import mapping_tests diff --git a/Misc/NEWS b/Misc/NEWS index 273e294097f..c8d45108b1d 100644 --- a/Misc/NEWS +++ b/Misc/NEWS @@ -12,6 +12,9 @@ What's New in Python 2.5.3? Core and builtins ----------------- +- Issue #3537: Fix an assertion failure when an empty but presized dict + object was stored in the freelist. + - Apply security patches from Apple. - Issue #2620: Overflow checking when allocating or reallocating memory diff --git a/Objects/dictobject.c b/Objects/dictobject.c index 412d5f2e315..8c8a2f92e70 100644 --- a/Objects/dictobject.c +++ b/Objects/dictobject.c @@ -208,6 +208,10 @@ PyDict_New(void) _Py_NewReference((PyObject *)mp); if (mp->ma_fill) { EMPTY_TO_MINSIZE(mp); + } else { + /* At least set ma_table and ma_mask; these are wrong + if an empty but presized dict is added to freelist */ + INIT_NONZERO_DICT_SLOTS(mp); } assert (mp->ma_used == 0); assert (mp->ma_table == mp->ma_smalltable);