Skip to content

Commit

Permalink
borrowed references
Browse files Browse the repository at this point in the history
  • Loading branch information
vstinner committed Sep 4, 2018
1 parent 51d6a91 commit 3708300
Show file tree
Hide file tree
Showing 4 changed files with 53 additions and 9 deletions.
41 changes: 32 additions & 9 deletions doc/bad_api.rst
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,10 @@ See also :ref:`Remove functions <remove-funcs>`.
Borrowed references
===================

CPython 3.7 has 36 functions and macros which return borrowed references.
CPython 3.7 has many functions and macros which return or use borrowed
references. For example, ``PyTuple_GetItem()`` returns a borrowed reference,
whereas ``PyTuple_SetItem()`` stores a borrowed reference (store an item into a
tuple without increasing the reference counter).

CPython contains ``Doc/data/refcounts.dat`` (file is edited manually) which
documents how functions handle reference count.
Expand All @@ -40,6 +43,7 @@ Functions
* ``Py_InitModule4()``
* ``PyImport_GetModuleDict()``
* ``PyList_GetItem()``
* ``PyList_SetItem()``
* ``PyMethod_Class()``
* ``PyMethod_Function()``
* ``PyMethod_Self()``
Expand All @@ -50,20 +54,28 @@ Functions
* ``PySys_GetXOptions()``
* ``PyThreadState_GetDict()``
* ``PyTuple_GetItem()``
* ``PyTuple_SetItem()``
* ``PyWeakref_GetObject()``

Macros
------

* ``PyCell_GET()``: access directly ``PyCellObject.ob_ref``
* ``PyList_GET_ITEM()``: access directly ``PyListObject.ob_item``
* ``PyCell_GET()``
* ``PyList_GET_ITEM()``
* ``PyList_SET_ITEM()``
* ``PyMethod_GET_CLASS()``
* ``PyMethod_GET_FUNCTION()``: access directly ``PyMethodObject.im_func``
* ``PyMethod_GET_SELF()``: access directly ``PyMethodObject.im_self``
* ``PySequence_Fast_GET_ITEM()``: use ``PyList_GET_ITEM()``
or ``PyTuple_GET_ITEM()``
* ``PyTuple_GET_ITEM()``: access directly ``PyTupleObject.ob_item``
* ``PyWeakref_GET_OBJECT()``: access directly ``PyWeakReference.wr_object``
* ``PyMethod_GET_FUNCTION()``
* ``PyMethod_GET_SELF()``
* ``PySequence_Fast_GET_ITEM()``
* ``PyTuple_GET_ITEM()``
* ``PyTuple_SET_ITEM()``
* ``PyWeakref_GET_OBJECT()``
* ``Py_TYPE()``

Border line:

* ``Py_SETREF()``, ``Py_XSETREF()``: the caller has to manually increment the
reference counter of the new value

Borrowed references: PyEval_GetFuncName()
=========================================
Expand Down Expand Up @@ -121,6 +133,17 @@ Don't leak the structures like ``PyObject`` or ``PyTupleObject`` to not
access directly fields, to not use fixed offset at the ABI level. Replace
macros with functions calls. PyPy already does this in its C API (``cpyext``).

Example of macros:

* ``PyCell_GET()``: access directly ``PyCellObject.ob_ref``
* ``PyList_GET_ITEM()``: access directly ``PyListObject.ob_item``
* ``PyMethod_GET_FUNCTION()``: access directly ``PyMethodObject.im_func``
* ``PyMethod_GET_SELF()``: access directly ``PyMethodObject.im_self``
* ``PySequence_Fast_GET_ITEM()``: use ``PyList_GET_ITEM()``
or ``PyTuple_GET_ITEM()``
* ``PyTuple_GET_ITEM()``: access directly ``PyTupleObject.ob_item``
* ``PyWeakref_GET_OBJECT()``: access directly ``PyWeakReference.wr_object``

PyType_Ready() and setting directly PyTypeObject fields
=======================================================

Expand Down
2 changes: 2 additions & 0 deletions doc/consumers.rst
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@ Popular modules using Cython

* uvloop

.. _debug-tools:

Debugging tools
===============

Expand Down
11 changes: 11 additions & 0 deletions doc/remove_functions.rst
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,17 @@ C extensions should call abstract functions like ``PyObject_GetItem()``.

See :ref:`Bad C API <bad-c-api>`.

Functions and macros removed from the new CAPI
==============================================

Removed functions and macros which use :ref:`borrowed references
<borrowed-ref>`:

* ``PyTuple_GET_ITEM()``
* ``PyTuple_GetItem()``
* ``PyTuple_SetItem()``
* ``PyTuple_SET_ITEM()``

Only keep abstract functions
============================

Expand Down
8 changes: 8 additions & 0 deletions doc/roadmap.rst
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,14 @@ Roadmap
the :ref:`new C API <new-c-api>` as the default in CPython and add an option
for **opt-out** to stick with the :ref:`old C API <old-c-api>`.

Open questions
==============

* Remove or deprecate APIs using borrowed references? If ``PyTuple_GetItem()``
must be replaced with ``PyTuple_GetItemRef()``, how do we provide
``PyTuple_GetItemRef()`` for Python 3.7 and older? See :ref:`Backward
compatibility <back-compat>`.

Status
======

Expand Down

0 comments on commit 3708300

Please sign in to comment.