8000 gh-91052: Add C API for watching dictionaries by carljm · Pull Request #31787 · python/cpython · GitHub
[go: up one dir, main page]

Skip to content

gh-91052: Add C API for watching dictionaries #31787

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 9 commits into from
Oct 7, 2022
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Address further review comments
  • Loading branch information
carljm committed Oct 6, 2022
commit cc1d0b7711dc3692c6287a097a99d2b3418eda7e
20 changes: 10 additions & 10 deletions Doc/c-api/dict.rst
Original file line number Diff line number Diff line change
Expand Up @@ -262,30 +262,30 @@ Dictionary Objects

Enumeration of possible dictionary watcher events: ``PyDict_EVENT_ADDED``,
``PyDict_EVENT_MODIFIED``, ``PyDict_EVENT_DELETED``, ``PyDict_EVENT_CLONED``,
``PyDict_EVENT_CLEARED``, or ``PyDict_EVENT_DEALLOCED``.
``PyDict_EVENT_CLEARED``, or ``PyDict_EVENT_DEALLOCATED``.

.. c:type:: int (*PyDict_WatchCallback)(PyDict_WatchEvent event, PyObject *dict, PyObject *key, PyObject *new_value)

Type of a dict watcher callback function.

If *event* is ``PyDict_EVENT_CLEARED`` or ``PyDict_EVENT_DEALLOCED``, both
*key* and *new_value* will be ``NULL``. If *event* is
``PyDict_EVENT_ADDED`` or ``PyDict_EVENT_MODIFIED``, *new_value* will be the
new value for *key*. If *event* is ``PyDict_EVENT_DELETED``, *key* is being
deleted from the dictionary and *new_value* will be ``NULL``.
If *event* is ``PyDict_EVENT_CLEARED`` or ``PyDict_EVENT_DEALLOCATED``, both
*key* and *new_value* will be ``NULL``. If *event* is ``PyDict_EVENT_ADDED``
or ``PyDict_EVENT_MODIFIED``, *new_value* will be the new value for *key*.
If *event* is ``PyDict_EVENT_DELETED``, *key* is being deleted from the
dictionary and *new_value* will be ``NULL``.

``PyDict_EVENT_CLONED`` occurs when *dict* was previously empty and another
dict is merged into it. To maintain efficiency of this operation, per-key
``PyDict_EVENT_ADDED`` events are not issued in this case; instead a
single ``PyDict_EVENT_CLONED`` is issued, and *key* will be the source
dictionary.

The callback may inspect but should not modify *dict*; doing so could have
The callback may inspect but must not modify *dict*; doing so could have
unpredictable effects, including infinite recursion.

Callbacks occur before the notified modification to *dict* takes place, so
the prior state of *dict* can be inspected.

If an error occurs in the callback, it may return ``-1`` with an exception
set; this exception will be printed as an unraisable exception using
:c:func:`PyErr_WriteUnraisable`. On success it should return ``0``.
If the callback returns with an exception set, it must return ``-1``; this
exception will be printed as an unraisable exception using
:c:func:`PyErr_WriteUnraisable`. Otherwise it should return ``0``.
2 changes: 1 addition & 1 deletion Include/cpython/dictobject.h
Original file line number Diff line number Diff line change
Expand Up @@ -92,7 +92,7 @@ typedef enum {
PyDict_EVENT_DELETED,
PyDict_EVENT_CLONED,
PyDict_EVENT_CLEARED,
PyDict_EVENT_DEALLOCED,
PyDict_EVENT_DEALLOCATED,
} PyDict_WatchEvent;

// Callback to be invoked when a watched dict is cleared, dealloced, or modified.
Expand Down
2 changes: 1 addition & 1 deletion Modules/_testcapimodule.c
Original file line number Diff line number Diff line change
Expand Up @@ -5184,7 +5184,7 @@ dict_watch_callback(PyDict_WatchEvent event,
case PyDict_EVENT_CLEARED:
msg = PyUnicode_FromString("clear");
break;
case PyDict_EVENT_DEALLOCED:
case PyDict_EVENT_DEALLOCATED:
msg = PyUnicode_FromString("dealloc");
break;
case PyDict_EVENT_CLONED:
Expand Down
2 changes: 1 addition & 1 deletion Objects/dictobject.c
Original file line number Diff line number Diff line change
Expand Up @@ -2330,7 +2330,7 @@ _PyDict_FromKeys(PyObject *cls, PyObject *iterable, PyObject *value)
static void
dict_dealloc(PyDictObject *mp)
{
_PyDict_NotifyEvent(PyDict_EVENT_DEALLOCED, mp, NULL, NULL);
_PyDict_NotifyEvent(PyDict_EVENT_DEALLOCATED, mp, NULL, NULL);
PyDictValues *values = mp->ma_values;
PyDictKeysObject *keys = mp->ma_keys;
Py_ssize_t i, n;
Expand Down
0