diff options
author | Carl Meyer <carl@oddbird.net> | 2022-10-07 00:08:00 (GMT) |
---|---|---|
committer | GitHub <noreply@github.com> | 2022-10-07 00:08:00 (GMT) |
commit | a4b7794887929f82c532fcd055326954ff1197ce (patch) | |
tree | 257e2dc783858251f893d75c17663913b05a0fad /Python | |
parent | 683ab859554c34831fcecc854de35745d7fd603c (diff) | |
download | cpython-a4b7794887929f82c532fcd055326954ff1197ce.zip cpython-a4b7794887929f82c532fcd055326954ff1197ce.tar.gz cpython-a4b7794887929f82c532fcd055326954ff1197ce.tar.bz2 |
GH-91052: Add C API for watching dictionaries (GH-31787)
Diffstat (limited to 'Python')
-rw-r--r-- | Python/ceval.c | 5 | ||||
-rw-r--r-- | Python/pystate.c | 4 |
2 files changed, 8 insertions, 1 deletions
diff --git a/Python/ceval.c b/Python/ceval.c index c08c794..ee1baba 100644 --- a/Python/ceval.c +++ b/Python/ceval.c @@ -3252,6 +3252,7 @@ handle_eval_breaker: uint16_t hint = cache->index; DEOPT_IF(hint >= (size_t)dict->ma_keys->dk_nentries, STORE_ATTR); PyObject *value, *old_value; + uint64_t new_version; if (DK_IS_UNICODE(dict->ma_keys)) { PyDictUnicodeEntry *ep = DK_UNICODE_ENTRIES(dict->ma_keys) + hint; DEOPT_IF(ep->me_key != name, STORE_ATTR); @@ -3259,6 +3260,7 @@ handle_eval_breaker: DEOPT_IF(old_value == NULL, STORE_ATTR); STACK_SHRINK(1); value = POP(); + new_version = _PyDict_NotifyEvent(PyDict_EVENT_MODIFIED, dict, name, value); ep->me_value = value; } else { @@ -3268,6 +3270,7 @@ handle_eval_breaker: DEOPT_IF(old_value == NULL, STORE_ATTR); STACK_SHRINK(1); value = POP(); + new_version = _PyDict_NotifyEvent(PyDict_EVENT_MODIFIED, dict, name, value); ep->me_value = value; } Py_DECREF(old_value); @@ -3277,7 +3280,7 @@ handle_eval_breaker: _PyObject_GC_TRACK(dict); } /* PEP 509 */ - dict->ma_version_tag = DICT_NEXT_VERSION(); + dict->ma_version_tag = new_version; Py_DECREF(owner); JUMPBY(INLINE_CACHE_ENTRIES_STORE_ATTR); DISPATCH(); diff --git a/Python/pystate.c b/Python/pystate.c index 50ae0ce..c74868d 100644 --- a/Python/pystate.c +++ b/Python/pystate.c @@ -451,6 +451,10 @@ interpreter_clear(PyInterpreterState *interp, PyThreadState *tstate) Py_CLEAR(interp->sysdict); Py_CLEAR(interp->builtins); + for (int i=0; i < DICT_MAX_WATCHERS; i++) { + interp->dict_watchers[i] = NULL; + } + // XXX Once we have one allocator per interpreter (i.e. // per-interpreter GC) we must ensure that all of the interpreter's // objects have been cleaned up at the point. |