Skip to content

Commit

Permalink
Deliver dict added event only after it's guaranteed to succeed
Browse files Browse the repository at this point in the history
Summary:
Back port of: python/cpython#122207 fixing python/cpython#122208

The current dictionary watchers implementation delivers the added event before it checks to see if we need to re-size the dictionary. This resize can fail so the value isn't added, and then the tracker is out of sync with the true state of the dictionary.

This moves the delivery of the event to after any necessary allocations have happened.

Reviewed By: jbower-fb

Differential Revision: D60182094

fbshipit-source-id: f34940e98ce1caadeee364f9d126d35839661961
  • Loading branch information
DinoV authored and facebook-github-bot committed Jul 24, 2024
1 parent bb3aca2 commit fee7d79
Showing 1 changed file with 7 additions and 7 deletions.
14 changes: 7 additions & 7 deletions Objects/dictobject.c
Original file line number Diff line number Diff line change
Expand Up @@ -1349,15 +1349,15 @@ insertdict(PyDictObject *mp, PyObject *key, Py_hash_t hash, PyObject *value)
}

if (ix == DKIX_EMPTY) {
uint64_t new_version = _PyDict_NotifyEvent(
PyDict_EVENT_ADDED, mp, key, value);
/* Insert into new slot. */
assert(old_value == NULL);
if (mp->ma_keys->dk_usable <= 0) {
/* Need to resize. */
if (insertion_resize(mp) < 0)
goto Fail;
}
uint64_t new_version = _PyDict_NotifyEvent(
PyDict_EVENT_ADDED, mp, key, value);
if (!PyUnicode_CheckExact(key)) {
if (mp->ma_keys->dk_lookup == lookdict_with_lazy_imports_unicode) {
mp->ma_keys->dk_lookup = lookdict_with_lazy_imports;
Expand Down Expand Up @@ -1428,13 +1428,13 @@ insert_to_emptydict(PyDictObject *mp, PyObject *key, Py_hash_t hash,
{
assert(mp->ma_keys == Py_EMPTY_KEYS);

uint64_t new_version = _PyDict_NotifyEvent(
PyDict_EVENT_ADDED, mp, key, value);

PyDictKeysObject *newkeys = new_keys_object(PyDict_MINSIZE);
if (newkeys == NULL) {
return -1;
}
uint64_t new_version = _PyDict_NotifyEvent(
PyDict_EVENT_ADDED, mp, key, value);

dictkeys_decref(Py_EMPTY_KEYS);
mp->ma_keys = newkeys;
mp->ma_values = NULL;
Expand Down Expand Up @@ -3517,14 +3517,14 @@ PyDict_SetDefault(PyObject *d, PyObject *key, PyObject *defaultobj)

if (ix == DKIX_EMPTY) {
PyDictKeyEntry *ep, *ep0;
uint64_t new_version = _PyDict_NotifyEvent(
PyDict_EVENT_ADDED, mp, key, defaultobj);
value = defaultobj;
if (mp->ma_keys->dk_usable <= 0) {
if (insertion_resize(mp) < 0) {
return NULL;
}
}
uint64_t new_version = _PyDict_NotifyEvent(
PyDict_EVENT_ADDED, mp, key, defaultobj);
if (!PyUnicode_CheckExact(key) && mp->ma_keys->dk_lookup != lookdict) {
mp->ma_keys->dk_lookup = lookdict;
}
Expand Down

0 comments on commit fee7d79

Please sign in to comment.