gh-106572: Convert PyObject_DelAttr() to a function (#106611)

* Convert PyObject_DelAttr() and PyObject_DelAttrString() macros to
  functions.
* Add PyObject_DelAttr() and PyObject_DelAttrString() functions to
  the stable ABI.
* Replace PyObject_SetAttr(obj, name, NULL) with
  PyObject_DelAttr(obj, name).
This commit is contained in:
Victor Stinner 2023-07-11 11:38:22 +02:00 committed by GitHub
parent e6379f72cb
commit 1f2921b72c
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
12 changed files with 33 additions and 8 deletions

View file

@ -490,6 +490,8 @@ function,PyObject_Calloc,3.7,,
function,PyObject_CheckBuffer,3.11,, function,PyObject_CheckBuffer,3.11,,
function,PyObject_ClearWeakRefs,3.2,, function,PyObject_ClearWeakRefs,3.2,,
function,PyObject_CopyData,3.11,, function,PyObject_CopyData,3.11,,
function,PyObject_DelAttr,3.13,,
function,PyObject_DelAttrString,3.13,,
function,PyObject_DelItem,3.2,, function,PyObject_DelItem,3.2,,
function,PyObject_DelItemString,3.2,, function,PyObject_DelItemString,3.2,,
function,PyObject_Dir,3.2,, function,PyObject_Dir,3.2,,

View file

@ -80,7 +80,7 @@ extern "C" {
This is the equivalent of the Python statement o.attr_name=v. */ This is the equivalent of the Python statement o.attr_name=v. */
/* Implemented as a macro: /* Implemented elsewhere:
int PyObject_DelAttrString(PyObject *o, const char *attr_name); int PyObject_DelAttrString(PyObject *o, const char *attr_name);
@ -88,17 +88,15 @@ extern "C" {
-1 on failure. -1 on failure.
This is the equivalent of the Python statement: del o.attr_name. */ This is the equivalent of the Python statement: del o.attr_name. */
#define PyObject_DelAttrString(O, A) PyObject_SetAttrString((O), (A), NULL)
/* Implemented as a macro: /* Implemented elsewhere:
int PyObject_DelAttr(PyObject *o, PyObject *attr_name); int PyObject_DelAttr(PyObject *o, PyObject *attr_name);
Delete attribute named attr_name, for object o. Returns -1 Delete attribute named attr_name, for object o. Returns -1
on failure. This is the equivalent of the Python on failure. This is the equivalent of the Python
statement: del o.attr_name. */ statement: del o.attr_name. */
#define PyObject_DelAttr(O, A) PyObject_SetAttr((O), (A), NULL)
/* Implemented elsewhere: /* Implemented elsewhere:

View file

@ -391,9 +391,11 @@ PyAPI_FUNC(PyObject *) PyObject_RichCompare(PyObject *, PyObject *, int);
PyAPI_FUNC(int) PyObject_RichCompareBool(PyObject *, PyObject *, int); PyAPI_FUNC(int) PyObject_RichCompareBool(PyObject *, PyObject *, int);
PyAPI_FUNC(PyObject *) PyObject_GetAttrString(PyObject *, const char *); PyAPI_FUNC(PyObject *) PyObject_GetAttrString(PyObject *, const char *);
PyAPI_FUNC(int) PyObject_SetAttrString(PyObject *, const char *, PyObject *); PyAPI_FUNC(int) PyObject_SetAttrString(PyObject *, const char *, PyObject *);
PyAPI_FUNC(int) PyObject_DelAttrString(PyObject *v, const char *name);
PyAPI_FUNC(int) PyObject_HasAttrString(PyObject *, const char *); PyAPI_FUNC(int) PyObject_HasAttrString(PyObject *, const char *);
PyAPI_FUNC(PyObject *) PyObject_GetAttr(PyObject *, PyObject *); PyAPI_FUNC(PyObject *) PyObject_GetAttr(PyObject *, PyObject *);
PyAPI_FUNC(int) PyObject_SetAttr(PyObject *, PyObject *, PyObject *); PyAPI_FUNC(int) PyObject_SetAttr(PyObject *, PyObject *, PyObject *);
PyAPI_FUNC(int) PyObject_DelAttr(PyObject *v, PyObject *name);
PyAPI_FUNC(int) PyObject_HasAttr(PyObject *, PyObject *); PyAPI_FUNC(int) PyObject_HasAttr(PyObject *, PyObject *);
PyAPI_FUNC(PyObject *) PyObject_SelfIter(PyObject *); PyAPI_FUNC(PyObject *) PyObject_SelfIter(PyObject *);
PyAPI_FUNC(PyObject *) PyObject_GenericGetAttr(PyObject *, PyObject *); PyAPI_FUNC(PyObject *) PyObject_GenericGetAttr(PyObject *, PyObject *);

View file

@ -509,6 +509,8 @@ SYMBOL_NAMES = (
"PyObject_CheckReadBuffer", "PyObject_CheckReadBuffer",
"PyObject_ClearWeakRefs", "PyObject_ClearWeakRefs",
"PyObject_CopyData", "PyObject_CopyData",
"PyObject_DelAttr",
"PyObject_DelAttrString",
"PyObject_DelItem", "PyObject_DelItem",
"PyObject_DelItemString", "PyObject_DelItemString",
"PyObject_Dir", "PyObject_Dir",

View file

@ -0,0 +1,2 @@
Convert :c:func:`PyObject_DelAttr` and :c:func:`PyObject_DelAttrString`
macros to functions. Patch by Victor Stinner.

View file

@ -2432,3 +2432,7 @@
added = '3.13' added = '3.13'
[function.PyWeakref_GetRef] [function.PyWeakref_GetRef]
added = '3.13' added = '3.13'
[function.PyObject_DelAttr]
added = '3.13'
[function.PyObject_DelAttrString]
added = '3.13'

View file

@ -942,6 +942,12 @@ PyObject_SetAttrString(PyObject *v, const char *name, PyObject *w)
return res; return res;
} }
int
PyObject_DelAttrString(PyObject *v, const char *name)
{
return PyObject_SetAttrString(v, name, NULL);
}
int int
_PyObject_IsAbstract(PyObject *obj) _PyObject_IsAbstract(PyObject *obj)
{ {
@ -1185,6 +1191,12 @@ PyObject_SetAttr(PyObject *v, PyObject *name, PyObject *value)
return -1; return -1;
} }
int
PyObject_DelAttr(PyObject *v, PyObject *name)
{
return PyObject_SetAttr(v, name, NULL);
}
PyObject ** PyObject **
_PyObject_ComputedDictPointer(PyObject *obj) _PyObject_ComputedDictPointer(PyObject *obj)
{ {

2
PC/python3dll.c generated
View file

@ -447,6 +447,8 @@ EXPORT_FUNC(PyObject_CheckBuffer)
EXPORT_FUNC(PyObject_CheckReadBuffer) EXPORT_FUNC(PyObject_CheckReadBuffer)
EXPORT_FUNC(PyObject_ClearWeakRefs) EXPORT_FUNC(PyObject_ClearWeakRefs)
EXPORT_FUNC(PyObject_CopyData) EXPORT_FUNC(PyObject_CopyData)
EXPORT_FUNC(PyObject_DelAttr)
EXPORT_FUNC(PyObject_DelAttrString)
EXPORT_FUNC(PyObject_DelItem) EXPORT_FUNC(PyObject_DelItem)
EXPORT_FUNC(PyObject_DelItemString) EXPORT_FUNC(PyObject_DelItemString)
EXPORT_FUNC(PyObject_Dir) EXPORT_FUNC(PyObject_Dir)

View file

@ -1567,8 +1567,9 @@ static PyObject *
builtin_delattr_impl(PyObject *module, PyObject *obj, PyObject *name) builtin_delattr_impl(PyObject *module, PyObject *obj, PyObject *name)
/*[clinic end generated code: output=85134bc58dff79fa input=164865623abe7216]*/ /*[clinic end generated code: output=85134bc58dff79fa input=164865623abe7216]*/
{ {
if (PyObject_SetAttr(obj, name, (PyObject *)NULL) != 0) if (PyObject_DelAttr(obj, name) < 0) {
return NULL; return NULL;
}
Py_RETURN_NONE; Py_RETURN_NONE;
} }

View file

@ -1240,7 +1240,7 @@ dummy_func(
inst(DELETE_ATTR, (owner --)) { inst(DELETE_ATTR, (owner --)) {
PyObject *name = GETITEM(FRAME_CO_NAMES, oparg); PyObject *name = GETITEM(FRAME_CO_NAMES, oparg);
int err = PyObject_SetAttr(owner, name, (PyObject *)NULL); int err = PyObject_DelAttr(owner, name);
DECREF_INPUTS(); DECREF_INPUTS();
ERROR_IF(err, error); ERROR_IF(err, error);
} }

View file

@ -1018,7 +1018,7 @@
PyObject *owner = stack_pointer[-1]; PyObject *owner = stack_pointer[-1];
#line 1242 "Python/bytecodes.c" #line 1242 "Python/bytecodes.c"
PyObject *name = GETITEM(FRAME_CO_NAMES, oparg); PyObject *name = GETITEM(FRAME_CO_NAMES, oparg);
int err = PyObject_SetAttr(owner, name, (PyObject *)NULL); int err = PyObject_DelAttr(owner, name);
#line 1023 "Python/executor_cases.c.h" #line 1023 "Python/executor_cases.c.h"
Py_DECREF(owner); Py_DECREF(owner);
#line 1245 "Python/bytecodes.c" #line 1245 "Python/bytecodes.c"

View file

@ -1696,7 +1696,7 @@
PyObject *owner = stack_pointer[-1]; PyObject *owner = stack_pointer[-1];
#line 1242 "Python/bytecodes.c" #line 1242 "Python/bytecodes.c"
PyObject *name = GETITEM(FRAME_CO_NAMES, oparg); PyObject *name = GETITEM(FRAME_CO_NAMES, oparg);
int err = PyObject_SetAttr(owner, name, (PyObject *)NULL); int err = PyObject_DelAttr(owner, name);
#line 1701 "Python/generated_cases.c.h" #line 1701 "Python/generated_cases.c.h"
Py_DECREF(owner); Py_DECREF(owner);
#line 1245 "Python/bytecodes.c" #line 1245 "Python/bytecodes.c"