Statistics on the Python C API¶
Line Numbers¶
Number of C API line numbers per Python version:
Python | Limited API | CPython API | Internal API | Total |
---|---|---|---|---|
2.7 | 12,686 (100%) | 0 (0%) | 0 (0%) | 12,686 |
3.6 | 15,984 (100%) | 0 (0%) | 0 (0%) | 15,984 |
3.7 | 16,517 (96%) | 0 (0%) | 717 (4%) | 17,234 |
3.8 | 13,166 (70%) | 3,417 (18%) | 2,242 (12%) | 18,825 |
3.9 | 12,265 (62%) | 4,358 (22%) | 3,093 (16%) | 19,716 |
3.10 | 10,396 (51%) | 4,613 (22%) | 5,533 (27%) | 20,542 |
3.11 | 9,255 (37%) | 5,387 (22%) | 10,107 (41%) | 24,749 |
3.12 | 9,189 (37%) | 5,246 (21%) | 10,176 (41%) | 24,611 |
File Numbers¶
Number of header file numbers per Python version:
Python | Limited API | CPython API | Internal API | Total |
---|---|---|---|---|
2.7 | 91 | 0 | 0 | 91 |
3.6 | 99 (+8) | 0 (same) | 0 (same) | 99 (+8) |
3.7 | 99 (same) | 0 (same) | 11 (+11) | 110 (+11) |
3.8 | 97 (-2) | 15 (+15) | 21 (+10) | 133 (+23) |
3.9 | 98 (+1) | 24 (+9) | 33 (+12) | 155 (+22) |
3.10 | 81 (-17) | 32 (+8) | 48 (+15) | 161 (+6) |
3.11 | 72 (-9) | 46 (+14) | 68 (+20) | 186 (+25) |
3.12 | 72 (same) | 46 (same) | 69 (+1) | 187 (+1) |
Symbols¶
Symbols exported with PyAPI_FUNC() and PyAPI_DATA():
Python | Public | Private | Internal | Total |
---|---|---|---|---|
2.7 | 891 | 207 | 0 | 1,098 |
3.6 | 1,041 (+150) | 419 (+212) | 0 (same) | 1,460 (+362) |
3.7 | 1,068 (+27) | 479 (+60) | 22 (+22) | 1,569 (+109) |
3.8 | 1,105 (+37) | 456 (-23) | 91 (+69) | 1,652 (+83) |
3.9 | 1,115 (+10) | 439 (-17) | 124 (+33) | 1,678 (+26) |
3.10 | 1,080 (-35) | 439 (same) | 129 (+5) | 1,648 (-30) |
3.11 | 1,087 (+7) | 381 (-58) | 188 (+59) | 1,656 (+8) |
3.12 | 1,081 (-6) | 378 (-3) | 192 (+4) | 1,651 (-5) |
Since Python 3.9, Python is now built with -fvisibility=hidden
to avoid
exporting symbols which are not explicitly exported.
The make smelly
command checks for public symbols of libpython and C
extension which are prefixed by Py
or _Py
. See
the Tools/scripts/smelly.py
script.
Functions defined as macros and static inline functions¶
Functions defined as macros (only public) and static inline functions (public or private):
Python | Macro | Static inline | Total |
---|---|---|---|
2.7 | 396 | 0 | 396 |
3.6 | 394 (-2) | 0 (same) | 394 (-2) |
3.7 | 403 (+9) | 0 (same) | 403 (+9) |
3.8 | 399 (-4) | 14 (+14) | 413 (+10) |
3.9 | 406 (+7) | 30 (+16) | 436 (+23) |
3.10 | 412 (+6) | 36 (+6) | 448 (+12) |
3.11 | 400 (-12) | 66 (+30) | 466 (+18) |
3.12 | 385 (-15) | 75 (+9) | 460 (-6) |
If a function is defined as a private static inline function and exposed as a public macro, it is counted twice in this table. For example, the public Py_INCREF() macro and the private _Py_INCREF() static inline functions are counted as 2 functions, whereas only the “Py_INCREF” name is public.
Structures¶
Public structures in the Python C API:
Python | Structures |
---|---|
2.7 | 97 |
3.6 | 124 (+27) |
3.7 | 137 (+13) |
3.8 | 127 (-10) |
3.9 | 125 (-2) |
3.10 | 104 (-21) |
3.11 | 106 (+2) |
3.12 | 111 (+5) |
These numbers exclude opaque structures like PyInterpreterState (since Python 3.8). The grep command is not exact. For example, PyODictObject is seen as public, whereas the structure is opaque:
typedef struct _odictobject PyODictObject;
The _odictobject structure is only defined in Objects/odictobject.c.