Skip to content

Commit

Permalink
gh-89653: PEP 670: Convert PyCell macros to functions (#92653)
Browse files Browse the repository at this point in the history
Convert the following macros to static inline functions:

* PyCell_GET()
* PyCell_SET()

Limited C API version 3.12 no longer casts arguments.

Fix also usage of PyCell_SET(): only delete the old value after
setting the new value.
  • Loading branch information
vstinner authored May 11, 2022
1 parent da5727a commit 897f14d
Show file tree
Hide file tree
Showing 3 changed files with 25 additions and 11 deletions.
19 changes: 17 additions & 2 deletions Include/cpython/cellobject.h
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,23 @@ PyAPI_FUNC(PyObject *) PyCell_New(PyObject *);
PyAPI_FUNC(PyObject *) PyCell_Get(PyObject *);
PyAPI_FUNC(int) PyCell_Set(PyObject *, PyObject *);

#define PyCell_GET(op) (((PyCellObject *)(op))->ob_ref)
#define PyCell_SET(op, v) _Py_RVALUE(((PyCellObject *)(op))->ob_ref = (v))
static inline PyObject* PyCell_GET(PyObject *op) {
assert(PyCell_Check(op));
PyCellObject *cell = _Py_CAST(PyCellObject*, op);
return cell->ob_ref;
}
#if !defined(Py_LIMITED_API) || Py_LIMITED_API+0 < 0x030c0000
# define PyCell_GET(op) PyCell_GET(_PyObject_CAST(op))
#endif

static inline void PyCell_SET(PyObject *op, PyObject *value) {
assert(PyCell_Check(op));
PyCellObject *cell = _Py_CAST(PyCellObject*, op);
cell->ob_ref = value;
}
#if !defined(Py_LIMITED_API) || Py_LIMITED_API+0 < 0x030c0000
# define PyCell_SET(op, value) PyCell_SET(_PyObject_CAST(op), (value))
#endif

#ifdef __cplusplus
}
Expand Down
15 changes: 7 additions & 8 deletions Objects/cellobject.c
Original file line number Diff line number Diff line change
Expand Up @@ -56,22 +56,21 @@ PyCell_Get(PyObject *op)
PyErr_BadInternalCall();
return NULL;
}
Py_XINCREF(((PyCellObject*)op)->ob_ref);
return PyCell_GET(op);
PyObject *value = PyCell_GET(op);
return Py_XNewRef(value);
}

int
PyCell_Set(PyObject *op, PyObject *obj)
PyCell_Set(PyObject *op, PyObject *value)
{
PyObject* oldobj;
if (!PyCell_Check(op)) {
PyErr_BadInternalCall();
return -1;
}
oldobj = PyCell_GET(op);
Py_XINCREF(obj);
PyCell_SET(op, obj);
Py_XDECREF(oldobj);
PyObject *old_value = PyCell_GET(op);
Py_XINCREF(value);
PyCell_SET(op, value);
Py_XDECREF(old_value);
return 0;
}

Expand Down
2 changes: 1 addition & 1 deletion Objects/frameobject.c
Original file line number Diff line number Diff line change
Expand Up @@ -1086,9 +1086,9 @@ _PyFrame_LocalsToFast(_PyInterpreterFrame *frame, int clear)
if (cell != NULL) {
oldvalue = PyCell_GET(cell);
if (value != oldvalue) {
Py_XDECREF(oldvalue);
Py_XINCREF(value);
PyCell_SET(cell, value);
Py_XDECREF(oldvalue);
}
}
else if (value != oldvalue) {
Expand Down

0 comments on commit 897f14d

Please sign in to comment.