bpo-42262: Add Py_NewRef() and Py_XNewRef() (GH-23152)

Added Py_NewRef() and Py_XNewRef() functions to increment the reference
count of an object and return the object.
This commit is contained in:
Victor Stinner 2020-11-05 15:02:12 +01:00 committed by GitHub
parent 80449f243b
commit 53a03aafd5
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 85 additions and 6 deletions

View File

@ -16,12 +16,43 @@ objects.
Increment the reference count for object *o*. The object must not be ``NULL``; if Increment the reference count for object *o*. The object must not be ``NULL``; if
you aren't sure that it isn't ``NULL``, use :c:func:`Py_XINCREF`. you aren't sure that it isn't ``NULL``, use :c:func:`Py_XINCREF`.
See also :c:func:`Py_NewRef`.
.. c:function:: void Py_XINCREF(PyObject *o) .. c:function:: void Py_XINCREF(PyObject *o)
Increment the reference count for object *o*. The object may be ``NULL``, in Increment the reference count for object *o*. The object may be ``NULL``, in
which case the macro has no effect. which case the macro has no effect.
See also :c:func:`Py_XNewRef`.
.. c:function:: PyObject* Py_NewRef(PyObject *o)
Increment the reference count of the object *o* and return the object *o*.
The object *o* must not be ``NULL``.
For example::
Py_INCREF(obj);
self->attr = obj;
can be written as::
self->attr = Py_NewRef(obj);
.. versionadded:: 3.10
.. c:function:: PyObject* Py_XNewRef(PyObject *o)
Similar to :c:func:`Py_NewRef`, but the object *o* can be NULL.
If the object *o* is ``NULL``, the function just returns ``NULL``.
.. versionadded:: 3.10
.. c:function:: void Py_DECREF(PyObject *o) .. c:function:: void Py_DECREF(PyObject *o)

View File

@ -379,6 +379,10 @@ New Features
success. success.
(Contributed by Victor Stinner in :issue:`1635741`.) (Contributed by Victor Stinner in :issue:`1635741`.)
* Added :c:func:`Py_NewRef` and :c:func:`Py_XNewRef` functions to increment the
reference count of an object and return the object.
(Contributed by Victor Stinner in :issue:`42262`.)
Porting to Python 3.10 Porting to Python 3.10
---------------------- ----------------------

View File

@ -22,8 +22,8 @@ PyAPI_DATA(struct _longobject) _Py_FalseStruct, _Py_TrueStruct;
#define Py_True ((PyObject *) &_Py_TrueStruct) #define Py_True ((PyObject *) &_Py_TrueStruct)
/* Macros for returning Py_True or Py_False, respectively */ /* Macros for returning Py_True or Py_False, respectively */
#define Py_RETURN_TRUE return Py_INCREF(Py_True), Py_True #define Py_RETURN_TRUE return Py_NewRef(Py_True)
#define Py_RETURN_FALSE return Py_INCREF(Py_False), Py_False #define Py_RETURN_FALSE return Py_NewRef(Py_False)
/* Function to return a bool from a C long */ /* Function to return a bool from a C long */
PyAPI_FUNC(PyObject *) PyBool_FromLong(long); PyAPI_FUNC(PyObject *) PyBool_FromLong(long);

View File

@ -526,6 +526,31 @@ they can have object code that is not dependent on Python compilation flags.
PyAPI_FUNC(void) Py_IncRef(PyObject *); PyAPI_FUNC(void) Py_IncRef(PyObject *);
PyAPI_FUNC(void) Py_DecRef(PyObject *); PyAPI_FUNC(void) Py_DecRef(PyObject *);
// Increment the reference count of the object and return the object.
PyAPI_FUNC(PyObject*) Py_NewRef(PyObject *obj);
// Similar to Py_NewRef() but the object can be NULL.
PyAPI_FUNC(PyObject*) Py_XNewRef(PyObject *obj);
static inline PyObject* _Py_NewRef(PyObject *obj)
{
Py_INCREF(obj);
return obj;
}
static inline PyObject* _Py_XNewRef(PyObject *obj)
{
Py_XINCREF(obj);
return obj;
}
// Py_NewRef() and Py_XNewRef() are exported as functions for the stable ABI.
// Names overriden with macros by static inline functions for best
// performances.
#define Py_NewRef(obj) _Py_NewRef(obj)
#define Py_XNewRef(obj) _Py_XNewRef(obj)
/* /*
_Py_NoneStruct is an object of undefined type which can be used in contexts _Py_NoneStruct is an object of undefined type which can be used in contexts
where NULL (nil) is not suitable (since NULL often means 'error'). where NULL (nil) is not suitable (since NULL often means 'error').
@ -536,7 +561,7 @@ PyAPI_DATA(PyObject) _Py_NoneStruct; /* Don't use this directly */
#define Py_None (&_Py_NoneStruct) #define Py_None (&_Py_NoneStruct)
/* Macro for returning Py_None from a function */ /* Macro for returning Py_None from a function */
#define Py_RETURN_NONE return Py_INCREF(Py_None), Py_None #define Py_RETURN_NONE return Py_NewRef(Py_None)
/* /*
Py_NotImplemented is a singleton used to signal that an operation is Py_NotImplemented is a singleton used to signal that an operation is
@ -546,8 +571,7 @@ PyAPI_DATA(PyObject) _Py_NotImplementedStruct; /* Don't use this directly */
#define Py_NotImplemented (&_Py_NotImplementedStruct) #define Py_NotImplemented (&_Py_NotImplementedStruct)
/* Macro for returning Py_NotImplemented from a function */ /* Macro for returning Py_NotImplemented from a function */
#define Py_RETURN_NOTIMPLEMENTED \ #define Py_RETURN_NOTIMPLEMENTED return Py_NewRef(Py_NotImplemented)
return Py_INCREF(Py_NotImplemented), Py_NotImplemented
/* Rich comparison opcodes */ /* Rich comparison opcodes */
#define Py_LT 0 #define Py_LT 0

View File

@ -0,0 +1,2 @@
Added :c:func:`Py_NewRef` and :c:func:`Py_XNewRef` functions to increment the
reference count of an object and return the object. Patch by Victor Stinner.

View File

@ -2208,6 +2208,22 @@ PyObject_GET_WEAKREFS_LISTPTR(PyObject *op)
} }
#undef Py_NewRef
#undef Py_XNewRef
// Export Py_NewRef() and Py_XNewRef() as regular functions for the stable ABI.
PyObject*
Py_NewRef(PyObject *obj)
{
return _Py_NewRef(obj);
}
PyObject*
Py_XNewRef(PyObject *obj)
{
return _Py_XNewRef(obj);
}
#ifdef __cplusplus #ifdef __cplusplus
} }
#endif #endif

View File

@ -40,8 +40,8 @@ EXPORT_FUNC(Py_AddPendingCall)
EXPORT_FUNC(Py_AtExit) EXPORT_FUNC(Py_AtExit)
EXPORT_FUNC(Py_BuildValue) EXPORT_FUNC(Py_BuildValue)
EXPORT_FUNC(Py_CompileString) EXPORT_FUNC(Py_CompileString)
EXPORT_FUNC(Py_DecodeLocale)
EXPORT_FUNC(Py_DecRef) EXPORT_FUNC(Py_DecRef)
EXPORT_FUNC(Py_DecodeLocale)
EXPORT_FUNC(Py_EncodeLocale) EXPORT_FUNC(Py_EncodeLocale)
EXPORT_FUNC(Py_EndInterpreter) EXPORT_FUNC(Py_EndInterpreter)
EXPORT_FUNC(Py_EnterRecursiveCall) EXPORT_FUNC(Py_EnterRecursiveCall)
@ -72,6 +72,7 @@ EXPORT_FUNC(Py_LeaveRecursiveCall)
EXPORT_FUNC(Py_Main) EXPORT_FUNC(Py_Main)
EXPORT_FUNC(Py_MakePendingCalls) EXPORT_FUNC(Py_MakePendingCalls)
EXPORT_FUNC(Py_NewInterpreter) EXPORT_FUNC(Py_NewInterpreter)
EXPORT_FUNC(Py_NewRef)
EXPORT_FUNC(Py_ReprEnter) EXPORT_FUNC(Py_ReprEnter)
EXPORT_FUNC(Py_ReprLeave) EXPORT_FUNC(Py_ReprLeave)
EXPORT_FUNC(Py_SetPath) EXPORT_FUNC(Py_SetPath)
@ -80,6 +81,7 @@ EXPORT_FUNC(Py_SetPythonHome)
EXPORT_FUNC(Py_SetRecursionLimit) EXPORT_FUNC(Py_SetRecursionLimit)
EXPORT_FUNC(Py_SymtableString) EXPORT_FUNC(Py_SymtableString)
EXPORT_FUNC(Py_VaBuildValue) EXPORT_FUNC(Py_VaBuildValue)
EXPORT_FUNC(Py_XNewRef)
EXPORT_FUNC(PyArg_Parse) EXPORT_FUNC(PyArg_Parse)
EXPORT_FUNC(PyArg_ParseTuple) EXPORT_FUNC(PyArg_ParseTuple)
EXPORT_FUNC(PyArg_ParseTupleAndKeywords) EXPORT_FUNC(PyArg_ParseTupleAndKeywords)