Commit 9a234903 authored by Antoine Pitrou's avatar Antoine Pitrou

Issue #14417: Mutating a dict during lookup now restarts the lookup instead of...

Issue #14417: Mutating a dict during lookup now restarts the lookup instead of raising a RuntimeError (undoes issue #14205).
parent 7feb9f42
......@@ -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*.
......
......@@ -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()``.
......
......@@ -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.
......
......@@ -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)
......
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