[Python-checkins] bpo-42262: Add Py_NewRef() and Py_XNewRef() (GH-23152)

vstinner webhook-mailer at python.org
Thu Nov 5 09:02:41 EST 2020


https://github.com/python/cpython/commit/53a03aafd5812018a3821a2e83063fd3d6cd2576
commit: 53a03aafd5812018a3821a2e83063fd3d6cd2576
branch: master
author: Victor Stinner <vstinner at python.org>
committer: vstinner <vstinner at python.org>
date: 2020-11-05T15:02:12+01:00
summary:

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.

files:
A Misc/NEWS.d/next/C API/2020-11-04-17-22-36.bpo-42262.fCWzBb.rst
M Doc/c-api/refcounting.rst
M Doc/whatsnew/3.10.rst
M Include/boolobject.h
M Include/object.h
M Objects/object.c
M PC/python3dll.c

diff --git a/Doc/c-api/refcounting.rst b/Doc/c-api/refcounting.rst
index 0df12c67f40bc..b15c0e6aecc89 100644
--- a/Doc/c-api/refcounting.rst
+++ b/Doc/c-api/refcounting.rst
@@ -16,12 +16,43 @@ objects.
    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`.
 
+   See also :c:func:`Py_NewRef`.
+
 
 .. c:function:: void Py_XINCREF(PyObject *o)
 
    Increment the reference count for object *o*.  The object may be ``NULL``, in
    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)
 
diff --git a/Doc/whatsnew/3.10.rst b/Doc/whatsnew/3.10.rst
index 9d9284897be8a..bac1a2e678309 100644
--- a/Doc/whatsnew/3.10.rst
+++ b/Doc/whatsnew/3.10.rst
@@ -379,6 +379,10 @@ New Features
   success.
   (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
 ----------------------
diff --git a/Include/boolobject.h b/Include/boolobject.h
index bb8044a2b02cf..6673d7206c0b3 100644
--- a/Include/boolobject.h
+++ b/Include/boolobject.h
@@ -22,8 +22,8 @@ PyAPI_DATA(struct _longobject) _Py_FalseStruct, _Py_TrueStruct;
 #define Py_True ((PyObject *) &_Py_TrueStruct)
 
 /* Macros for returning Py_True or Py_False, respectively */
-#define Py_RETURN_TRUE return Py_INCREF(Py_True), Py_True
-#define Py_RETURN_FALSE return Py_INCREF(Py_False), Py_False
+#define Py_RETURN_TRUE return Py_NewRef(Py_True)
+#define Py_RETURN_FALSE return Py_NewRef(Py_False)
 
 /* Function to return a bool from a C long */
 PyAPI_FUNC(PyObject *) PyBool_FromLong(long);
diff --git a/Include/object.h b/Include/object.h
index 6ee4ee7848551..835d9de01fb72 100644
--- a/Include/object.h
+++ b/Include/object.h
@@ -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_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
 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)
 
 /* 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
@@ -546,8 +571,7 @@ PyAPI_DATA(PyObject) _Py_NotImplementedStruct; /* Don't use this directly */
 #define Py_NotImplemented (&_Py_NotImplementedStruct)
 
 /* Macro for returning Py_NotImplemented from a function */
-#define Py_RETURN_NOTIMPLEMENTED \
-    return Py_INCREF(Py_NotImplemented), Py_NotImplemented
+#define Py_RETURN_NOTIMPLEMENTED return Py_NewRef(Py_NotImplemented)
 
 /* Rich comparison opcodes */
 #define Py_LT 0
diff --git a/Misc/NEWS.d/next/C API/2020-11-04-17-22-36.bpo-42262.fCWzBb.rst b/Misc/NEWS.d/next/C API/2020-11-04-17-22-36.bpo-42262.fCWzBb.rst
new file mode 100644
index 0000000000000..8c1e4f418443b
--- /dev/null
+++ b/Misc/NEWS.d/next/C API/2020-11-04-17-22-36.bpo-42262.fCWzBb.rst	
@@ -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.
diff --git a/Objects/object.c b/Objects/object.c
index 7bc3e48d40a6f..be7790eefd118 100644
--- a/Objects/object.c
+++ b/Objects/object.c
@@ -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
 }
 #endif
diff --git a/PC/python3dll.c b/PC/python3dll.c
index 7e4a510177304..d1fdd0ac54ca8 100644
--- a/PC/python3dll.c
+++ b/PC/python3dll.c
@@ -40,8 +40,8 @@ EXPORT_FUNC(Py_AddPendingCall)
 EXPORT_FUNC(Py_AtExit)
 EXPORT_FUNC(Py_BuildValue)
 EXPORT_FUNC(Py_CompileString)
-EXPORT_FUNC(Py_DecodeLocale)
 EXPORT_FUNC(Py_DecRef)
+EXPORT_FUNC(Py_DecodeLocale)
 EXPORT_FUNC(Py_EncodeLocale)
 EXPORT_FUNC(Py_EndInterpreter)
 EXPORT_FUNC(Py_EnterRecursiveCall)
@@ -72,6 +72,7 @@ EXPORT_FUNC(Py_LeaveRecursiveCall)
 EXPORT_FUNC(Py_Main)
 EXPORT_FUNC(Py_MakePendingCalls)
 EXPORT_FUNC(Py_NewInterpreter)
+EXPORT_FUNC(Py_NewRef)
 EXPORT_FUNC(Py_ReprEnter)
 EXPORT_FUNC(Py_ReprLeave)
 EXPORT_FUNC(Py_SetPath)
@@ -80,6 +81,7 @@ EXPORT_FUNC(Py_SetPythonHome)
 EXPORT_FUNC(Py_SetRecursionLimit)
 EXPORT_FUNC(Py_SymtableString)
 EXPORT_FUNC(Py_VaBuildValue)
+EXPORT_FUNC(Py_XNewRef)
 EXPORT_FUNC(PyArg_Parse)
 EXPORT_FUNC(PyArg_ParseTuple)
 EXPORT_FUNC(PyArg_ParseTupleAndKeywords)



More information about the Python-checkins mailing list