Thanks to visit codestin.com
Credit goes to github.com

Skip to content

bpo-42262: Add Py_NewRef() function #23152

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 3 commits into from
Nov 5, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
31 changes: 31 additions & 0 deletions Doc/c-api/refcounting.rst
Original file line number Diff line number Diff line change
Expand Up @@ -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)

Expand Down
4 changes: 4 additions & 0 deletions Doc/whatsnew/3.10.rst
Original file line number Diff line number Diff line change
Expand Up @@ -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
----------------------
Expand Down
4 changes: 2 additions & 2 deletions Include/boolobject.h
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down
30 changes: 27 additions & 3 deletions Include/object.h
Original file line number Diff line number Diff line change
Expand Up @@ -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').
Expand All @@ -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
Expand All @@ -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
Expand Down
Original file line number Diff line number Diff line change
@@ -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.
16 changes: 16 additions & 0 deletions Objects/object.c
Original file line number Diff line number Diff line change
Expand Up @@ -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
4 changes: 3 additions & 1 deletion PC/python3dll.c
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down Expand Up @@ -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)
Expand All @@ -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)
Expand Down