8000 bad C API · adamtheturtle/pythoncapi@2e2a3cf · GitHub
[go: up one dir, main page]

Skip to content

Commit 2e2a3cf

Browse files
committed
bad C API
1 parent 6d8ea97 commit 2e2a3cf

File tree

3 files changed

+37
-17
lines changed

3 files changed

+37
-17
lines changed

doc/bad_api.rst

Lines changed: 30 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -15,9 +15,14 @@ See also :ref:`Remove functions <remove-funcs>`.
1515Borrowed references
1616
===================
1717

18-
CPython 3.7 has 36 functions and macros which return borrowed references:
18+
CPython 3.7 has 36 functions and macros which return borrowed references.
19+
20+
CPython contains ``Doc/data/refcounts.dat`` (file is edited manually) which
21+
documents how functions handle reference count.
22+
23+
Functions
24+
---------
1925

20-
* ``PyCell_GET()``
2126
* ``PyDict_GetItem()``
2227
* ``PyDict_GetItemWithError()``
2328
* ``PyDict_GetItemString()``
@@ -34,47 +39,50 @@ CPython 3.7 has 36 functions and macros which return borrowed references:
3439
* ``Py_InitModule3()``
3540
* ``Py_InitModule4()``
3641
* ``PyImport_GetModuleDict()``
37-
* ``PyList_GET_ITEM()``
3842
* ``PyList_GetItem()``
3943
* ``PyMethod_Class()``
4044
* ``PyMethod_Function()``
41-
* ``PyMethod_GET_CLASS()``
42-
* ``PyMethod_GET_FUNCTION()``
43-
* ``PyMethod_GET_SELF()``
4445
* ``PyMethod_Self()``
4546
* ``PyModule_GetDict()``
4647
* ``PyNumber_Check()``
4748
* ``PyObject_Init()``
48-
* ``PySequence_Fast_GET_ITEM()``
4949
* ``PySys_GetObject()``
5050
* ``PySys_GetXOptions()``
5151
* ``PyThreadState_GetDict()``
52-
* ``PyTuple_GET_ITEM()``
5352
* ``PyTuple_GetItem()``
54-
* ``PyWeakref_GET_OBJECT()``
5553
* ``PyWeakref_GetObject()``
5654

57-
CPython contains ``Doc/data/refcounts.dat`` (file is edited manually) which
58-
documents how functions handle reference count.
55+
Macros
56+
------
5957

58+
* ``PyCell_GET()``: access directly ``PyCellObject.ob_ref``
59+
* ``PyList_GET_ITEM()``: access directly ``PyListObject.ob_item``
60+
* ``PyMethod_GET_CLASS()``
61+
* ``PyMethod_GET_FUNCTION()``: access directly ``PyMethodObject.im_func``
62+
* ``PyMethod_GET_SELF()``: access directly ``PyMethodObject.im_self``
63+
* ``PySequence_Fast_GET_ITEM()``: use ``PyList_GET_ITEM()``
64+
or ``PyTuple_GET_ITEM()``
65+
* ``PyTuple_GET_ITEM()``: access directly ``PyTupleObject.ob_item``
66+
* ``PyWeakref_GET_OBJECT()``: access directly ``PyWeakReference.wr_object``
6067

61-
``PyObject**``
62-
==============
68+
69+
Array of pointers to Python objects (``PyObject**``)
70+
====================================================
6371

6472
``PyObject**`` must not be exposed: ``PyObject** PySequence_Fast_ITEMS(ob)``
6573
has to go.
6674

67-
Evil PyDict_GetItem()
68-
=====================
75+
PyDict_GetItem()
76+
================
6977

7078
The ``PyDict_GetItem()`` API is one of the most commonly called function but
7179
it has multiple flaws:
7280

7381
* it returns a :ref:`borrowed reference <borrowed-ref>`
7482
* it ignores any kind of error: it calls ``PyErr_Clear()``
7583

76-
The lookup is surrounded by ``PyErr_Fetch()`` and ``PyErr_Restore()`` to ignore
77-
any exception.
84+
The dictionary lookup is surrounded by ``PyErr_Fetch()`` and
85+
``PyErr_Restore()`` to ignore any exception.
7886

7987
If hash(key) raises an exception, it clears the exception and just returns
8088
``NULL``.
@@ -120,12 +128,17 @@ See also ``PyLong_AsLongAndOverflow()``.
120128
Open questions
121129
==============
122130

131+
.. _refcount:
132+
123133
Reference counting
124134
------------------
125135

126136
Should we do something for reference counting, Py_INCREF and Py_DECREF?
127137
Replace them with function calls at least?
128138

139+
See :ref:`Change the garbage collector <change-gc>` and :ref:`Py_INCREF
140+
<incref>`.
141+
129142
``PyObject_CallFunction("O")``
130143
------------------------------
131144

doc/new_api.rst

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,9 @@ Py_INCREF()
7979
The open question remains if it will be possible to replace ``Py_INCREF()`` and
8080
``Py_DECREF()`` with function calls without killing performances.
8181

82+
See :ref:`Reference counting <refcount>` and :ref:`Change the garbage collector
83+
<change-gc>`.
84+
8285
Hide C structures
8386
-----------------
8487

doc/optimization_ideas.rst

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,8 @@ Remove debug checks
1616
See :ref:`Regular runtime <regular-runtime>`: since a debug runtime will be
1717
provided by default, many sanity checks can be removed from the release build.
1818

19+
.. _change-gc:
20+
1921
Change the garbage collector: unlikely
2022
======================================
2123

@@ -30,6 +32,8 @@ the C API, which is out of the scope of the :ref:`new C API project
3032
<new-c-api>`. The main risk is to break too many C extensions which would make
3133
this idea unsuable in practice.
3234

35+
See also :ref:`Reference counting <refcount>`.
36+
3337
Remove the GIL: unlikely
3438
========================
3539

0 commit comments

Comments
 (0)
0