diff options
-rw-r--r-- | Doc/library/stdtypes.rst | 4 | ||||
-rw-r--r-- | Doc/whatsnew/3.3.rst | 7 | ||||
-rw-r--r-- | Lib/test/test_dict.py | 7 | ||||
-rw-r--r-- | Misc/NEWS | 3 | ||||
-rw-r--r-- | Objects/dictobject.c | 17 |
5 files changed, 15 insertions, 23 deletions
diff --git a/Doc/library/stdtypes.rst b/Doc/library/stdtypes.rst index 212fd5e..a34b1cf 100644 --- a/Doc/library/stdtypes.rst +++ b/Doc/library/stdtypes.rst @@ -2210,10 +2210,6 @@ pairs within braces, for example: ``{'jack': 4098, 'sjoerd': 4127}`` or ``{4098: See :class:`collections.Counter` for a complete implementation including other methods helpful for accumulating and managing tallies. - .. versionchanged:: 3.3 - If the dict is modified during the lookup, a :exc:`RuntimeError` - exception is now raised. - .. describe:: d[key] = value Set ``d[key]`` to *value*. diff --git a/Doc/whatsnew/3.3.rst b/Doc/whatsnew/3.3.rst index 35920b9..148324e 100644 --- a/Doc/whatsnew/3.3.rst +++ b/Doc/whatsnew/3.3.rst @@ -557,13 +557,6 @@ Some smaller changes made to the core Python language are: (:issue:`12170`) -* A dict lookup now raises a :exc:`RuntimeError` if the dict is modified during - the lookup. If you implement your own comparison function for objects used - as dict keys and the dict is shared by multiple threads, access to the dict - should be protected by a lock. - - (:issue:`14205`) - * New methods have been added to :class:`list` and :class:`bytearray`: ``copy()`` and ``clear()``. diff --git a/Lib/test/test_dict.py b/Lib/test/test_dict.py index 426f76e..dd4d552 100644 --- a/Lib/test/test_dict.py +++ b/Lib/test/test_dict.py @@ -411,7 +411,7 @@ class DictTest(unittest.TestCase): d[i+1] = 1 def test_mutating_lookup(self): - # changing dict during a lookup + # changing dict during a lookup (issue #14417) class NastyKey: mutate_dict = None @@ -433,9 +433,8 @@ class DictTest(unittest.TestCase): key2 = NastyKey(2) d = {key1: 1} NastyKey.mutate_dict = (d, key1) - with self.assertRaisesRegex(RuntimeError, - 'dictionary changed size during lookup'): - d[key2] = 2 + d[key2] = 2 + self.assertEqual(d, {key2: 2}) def test_repr(self): d = {} @@ -10,6 +10,9 @@ What's New in Python 3.3.0 Alpha 4? Core and Builtins ----------------- +- Issue #14417: Mutating a dict during lookup now restarts the lookup instead + of raising a RuntimeError (undoes issue #14205). + - Issue #14738: Speed-up UTF-8 decoding on non-ASCII data. Patch by Serhiy Storchaka. diff --git a/Objects/dictobject.c b/Objects/dictobject.c index 077f3cd..fd1d46c 100644 --- a/Objects/dictobject.c +++ b/Objects/dictobject.c @@ -439,12 +439,15 @@ lookdict(PyDictObject *mp, PyObject *key, register size_t i; register size_t perturb; register PyDictKeyEntry *freeslot; - register size_t mask = DK_MASK(mp->ma_keys); - PyDictKeyEntry *ep0 = &mp->ma_keys->dk_entries[0]; + register size_t mask; + PyDictKeyEntry *ep0; register PyDictKeyEntry *ep; register int cmp; PyObject *startkey; +top: + mask = DK_MASK(mp->ma_keys); + ep0 = &mp->ma_keys->dk_entries[0]; i = (size_t)hash & mask; ep = &ep0[i]; if (ep->me_key == NULL || ep->me_key == key) { @@ -468,9 +471,8 @@ lookdict(PyDictObject *mp, PyObject *key, } } else { - PyErr_SetString(PyExc_RuntimeError, - "dictionary changed size during lookup"); - return NULL; + /* The dict was mutated, restart */ + goto top; } } freeslot = NULL; @@ -510,9 +512,8 @@ lookdict(PyDictObject *mp, PyObject *key, } } else { - PyErr_SetString(PyExc_RuntimeError, - "dictionary changed size during lookup"); - return NULL; + /* The dict was mutated, restart */ + goto top; } } else if (ep->me_key == dummy && freeslot == NULL) |