Skip to content

Provide a variant of PyDict_SetDefault that returns a new reference (instead of a borrowed reference) #112066

Closed
@colesbury

Description

@colesbury

The PyDict_SetDefault(mp, key, defaultobj) function returns a borrowed reference to the value corresponding to key. This poses a thread-safety issue particularly for the case where key is already in the dict. In the --disable-gil builds, the returned value may no longer be valid if another thread concurrently modifies the dict.

Proposal (from Victor)

int PyDict_SetDefaultRef(PyObject *dict, PyObject *key, PyObject *default_value, PyObject **value);

The **value pointer is optional. If it is NULL, it is not used.

  • If the key is present in the dict, set *value to a new reference to the current value (if value is not NULL), and return 1.
  • If the key is missing from the dict, insert the key and default_value, and set *value to a new reference to default_value (if value is not NULL), and return 0.
  • On error, set *value to NULL if value is not NULL, and return -1.

Ideally, this new function would be public and part of the stable ABI so that it could be used by all extensions, but even an internal-only function would unblock some of the nogil changes.

EDIT: Updated with @vstinner's proposal

Linked PRs

Metadata

Metadata

Assignees

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions