Skip to content

Commit 53a03aa

Browse files
authored
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.
1 parent 80449f2 commit 53a03aa

File tree

7 files changed

+85
-6
lines changed

7 files changed

+85
-6
lines changed

Doc/c-api/refcounting.rst

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,12 +16,43 @@ objects.
1616
Increment the reference count for object *o*. The object must not be ``NULL``; if
1717
you aren't sure that it isn't ``NULL``, use :c:func:`Py_XINCREF`.
1818
19+
See also :c:func:`Py_NewRef`.
20+
1921
2022
.. c:function:: void Py_XINCREF(PyObject *o)
2123
2224
Increment the reference count for object *o*. The object may be ``NULL``, in
2325
which case the macro has no effect.
2426
27+
See also :c:func:`Py_XNewRef`.
28+
29+
30+
.. c:function:: PyObject* Py_NewRef(PyObject *o)
31+
32+
Increment the reference count of the object *o* and return the object *o*.
33+
34+
The object *o* must not be ``NULL``.
35+
36+
For example::
37+
38+
Py_INCREF(obj);
39+
self->attr = obj;
40+
41+
can be written as::
42+
43+
self->attr = Py_NewRef(obj);
44+
45+
.. versionadded:: 3.10
46+
47+
48+
.. c:function:: PyObject* Py_XNewRef(PyObject *o)
49+
50+
Similar to :c:func:`Py_NewRef`, but the object *o* can be NULL.
51+
52+
If the object *o* is ``NULL``, the function just returns ``NULL``.
53+
54+
.. versionadded:: 3.10
55+
2556
2657
.. c:function:: void Py_DECREF(PyObject *o)
2758

Doc/whatsnew/3.10.rst

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -379,6 +379,10 @@ New Features
379379
success.
380380
(Contributed by Victor Stinner in :issue:`1635741`.)
381381

382+
* Added :c:func:`Py_NewRef` and :c:func:`Py_XNewRef` functions to increment the
383+
reference count of an object and return the object.
384+
(Contributed by Victor Stinner in :issue:`42262`.)
385+
382386

383387
Porting to Python 3.10
384388
----------------------

Include/boolobject.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -22,8 +22,8 @@ PyAPI_DATA(struct _longobject) _Py_FalseStruct, _Py_TrueStruct;
2222
#define Py_True ((PyObject *) &_Py_TrueStruct)
2323

2424
/* Macros for returning Py_True or Py_False, respectively */
25-
#define Py_RETURN_TRUE return Py_INCREF(Py_True), Py_True
26-
#define Py_RETURN_FALSE return Py_INCREF(Py_False), Py_False
25+
#define Py_RETURN_TRUE return Py_NewRef(Py_True)
26+
#define Py_RETURN_FALSE return Py_NewRef(Py_False)
2727

2828
/* Function to return a bool from a C long */
2929
PyAPI_FUNC(PyObject *) PyBool_FromLong(long);

Include/object.h

Lines changed: 27 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -526,6 +526,31 @@ they can have object code that is not dependent on Python compilation flags.
526526
PyAPI_FUNC(void) Py_IncRef(PyObject *);
527527
PyAPI_FUNC(void) Py_DecRef(PyObject *);
528528

529+
// Increment the reference count of the object and return the object.
530+
PyAPI_FUNC(PyObject*) Py_NewRef(PyObject *obj);
531+
532+
// Similar to Py_NewRef() but the object can be NULL.
533+
PyAPI_FUNC(PyObject*) Py_XNewRef(PyObject *obj);
534+
535+
static inline PyObject* _Py_NewRef(PyObject *obj)
536+
{
537+
Py_INCREF(obj);
538+
return obj;
539+
}
540+
541+
static inline PyObject* _Py_XNewRef(PyObject *obj)
542+
{
543+
Py_XINCREF(obj);
544+
return obj;
545+
}
546+
547+
// Py_NewRef() and Py_XNewRef() are exported as functions for the stable ABI.
548+
// Names overriden with macros by static inline functions for best
549+
// performances.
550+
#define Py_NewRef(obj) _Py_NewRef(obj)
551+
#define Py_XNewRef(obj) _Py_XNewRef(obj)
552+
553+
529554
/*
530555
_Py_NoneStruct is an object of undefined type which can be used in contexts
531556
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 */
536561
#define Py_None (&_Py_NoneStruct)
537562

538563
/* Macro for returning Py_None from a function */
539-
#define Py_RETURN_NONE return Py_INCREF(Py_None), Py_None
564+
#define Py_RETURN_NONE return Py_NewRef(Py_None)
540565

541566
/*
542567
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 */
546571
#define Py_NotImplemented (&_Py_NotImplementedStruct)
547572

548573
/* Macro for returning Py_NotImplemented from a function */
549-
#define Py_RETURN_NOTIMPLEMENTED \
550-
return Py_INCREF(Py_NotImplemented), Py_NotImplemented
574+
#define Py_RETURN_NOTIMPLEMENTED return Py_NewRef(Py_NotImplemented)
551575

552576
/* Rich comparison opcodes */
553577
#define Py_LT 0
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
Added :c:func:`Py_NewRef` and :c:func:`Py_XNewRef` functions to increment the
2+
reference count of an object and return the object. Patch by Victor Stinner.

Objects/object.c

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2208,6 +2208,22 @@ PyObject_GET_WEAKREFS_LISTPTR(PyObject *op)
22082208
}
22092209

22102210

2211+
#undef Py_NewRef
2212+
#undef Py_XNewRef
2213+
2214+
// Export Py_NewRef() and Py_XNewRef() as regular functions for the stable ABI.
2215+
PyObject*
2216+
Py_NewRef(PyObject *obj)
2217+
{
2218+
return _Py_NewRef(obj);
2219+
}
2220+
2221+
PyObject*
2222+
Py_XNewRef(PyObject *obj)
2223+
{
2224+
return _Py_XNewRef(obj);
2225+
}
2226+
22112227
#ifdef __cplusplus
22122228
}
22132229
#endif

PC/python3dll.c

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,8 +40,8 @@ EXPORT_FUNC(Py_AddPendingCall)
4040
EXPORT_FUNC(Py_AtExit)
4141
EXPORT_FUNC(Py_BuildValue)
4242
EXPORT_FUNC(Py_CompileString)
43-
EXPORT_FUNC(Py_DecodeLocale)
4443
EXPORT_FUNC(Py_DecRef)
44+
EXPORT_FUNC(Py_DecodeLocale)
4545
EXPORT_FUNC(Py_EncodeLocale)
4646
EXPORT_FUNC(Py_EndInterpreter)
4747
EXPORT_FUNC(Py_EnterRecursiveCall)
@@ -72,6 +72,7 @@ EXPORT_FUNC(Py_LeaveRecursiveCall)
7272
EXPORT_FUNC(Py_Main)
7373
EXPORT_FUNC(Py_MakePendingCalls)
7474
EXPORT_FUNC(Py_NewInterpreter)
75+
EXPORT_FUNC(Py_NewRef)
7576
EXPORT_FUNC(Py_ReprEnter)
7677
EXPORT_FUNC(Py_ReprLeave)
7778
EXPORT_FUNC(Py_SetPath)
@@ -80,6 +81,7 @@ EXPORT_FUNC(Py_SetPythonHome)
8081
EXPORT_FUNC(Py_SetRecursionLimit)
8182
EXPORT_FUNC(Py_SymtableString)
8283
EXPORT_FUNC(Py_VaBuildValue)
84+
EXPORT_FUNC(Py_XNewRef)
8385
EXPORT_FUNC(PyArg_Parse)
8486
EXPORT_FUNC(PyArg_ParseTuple)
8587
EXPORT_FUNC(PyArg_ParseTupleAndKeywords)

0 commit comments

Comments
 (0)