Skip to content

Commit

Permalink
Count private macros
Browse files Browse the repository at this point in the history
  • Loading branch information
vstinner committed Jul 18, 2023
1 parent b452d3d commit 3d7810e
Show file tree
Hide file tree
Showing 3 changed files with 83 additions and 34 deletions.
27 changes: 20 additions & 7 deletions doc/pythoncapi.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,14 @@
import subprocess


EXCLUDE_HEADERS = frozenset((
# Don't parse pthread_stubs.h: special header file used by WASM
'pthread_stubs.h',
# Don't parse dynamic_annotations.h: not included by Python.h.
'dynamic_annotations.h',
))


# Checkout of Python Git repository
CPYTHON_URL = 'https://github.com/python/cpython'
GIT_DIR = os.path.normpath(os.path.join(os.path.dirname(__file__), '..', 'cpython_git'))
Expand Down Expand Up @@ -90,9 +98,8 @@ def list_files(path):
if not os.path.exists(path):
return []
files = glob.glob(os.path.join(path, '*.h'))
# Don't parse pthread_stubs.h: special header file used by WASM
for index, name in enumerate(files):
if os.path.basename(name) == 'pthread_stubs.h':
if os.path.basename(name) in EXCLUDE_HEADERS:
del files[index]
break
return files
Expand Down Expand Up @@ -157,7 +164,7 @@ def get_macros_static_inline_funcs():

# Match '#define func('
# Don't match '#define constant (&obj)': space before '('
regex = re.compile(fr'^ *# *define (P[Yy][A-Za-z_]+)\(', re.MULTILINE)
regex = re.compile(fr'^ *# *define (_?P[Yy][A-Za-z_]+)\(', re.MULTILINE)
macros = set(grep(regex, files, group=1))

regex = re.compile(fr'^static inline [^(\n]+ ({RE_IDENTIFIER}) *\(', re.MULTILINE)
Expand All @@ -166,12 +173,14 @@ def get_macros_static_inline_funcs():
# Remove macros only used to cast arguments types. Like:
# "static inline void Py_INCREF(...) { ...}"
# "#define Py_INCREF(obj) Py_INCREF(_PyObject_CAST(obj))"
# Only count 1 static inline function, ignore the macro.
# Only count the static inline function, ignore the macro.
macros = macros - funcs

# In Python 3.10, the Py_INCREF() was wrapping the _Py_INCREF() static
# inline function.
# In Python 3.11, Py_NewRef() macro just calls _Py_NewRef() static inline
# function.
for name in list(macros):
# In Python 3.10, the Py_INCREF() was wrapping the _Py_INCREF() static
# inline function.
if f"_{name}" in funcs:
macros.discard(name)

Expand All @@ -181,14 +190,18 @@ def get_macros_static_inline_funcs():
funcs.discard(name)

# Remove private static inline functions
private_macros = set()
private_funcs = set()
for name in list(macros):
if not is_function_public(name):
macros.discard(name)
private_macros.add(name)
for name in list(funcs):
if not is_function_public(name):
funcs.discard(name)
private_funcs.add(name)

return (macros, funcs)
return (macros, funcs, private_macros, private_funcs)


def get_functions():
Expand Down
27 changes: 21 additions & 6 deletions doc/stats.py
Original file line number Diff line number Diff line change
Expand Up @@ -207,22 +207,37 @@ def list_variables(results):
render_table(lines)


def static_inline_func(results):
display_title('Functions defined as macros and static inline functions')
paragraph('Functions defined as macros and static inline functions:')
def _static_inline_func(results, public):
if public:
display_title('Public functions defined as macros and static inline functions')
paragraph('Public functions defined as macros and static inline functions:')
else:
display_title('Private functions defined as macros and static inline functions')
paragraph('Private functions defined as macros and static inline functions:')

lines = [('Python', 'Macro', 'Static inline', 'Total')]
for name, data in results:
macros, static_inline = data.macro_static_inline_funcs
if public:
macros, static_inline = data.macro_static_inline_funcs[:2]
else:
macros, static_inline = data.macro_static_inline_funcs[2:]

line = [name, len(macros), len(static_inline),
len(macros) + len(static_inline)]
lines.append(line)
table_compute_diff(lines)
render_table(lines)

paragraph('Only count public macros and public static inline functions '
'(name starting with "Py" or "PY").')
if public:
paragraph('Only count public macros and public static inline functions '
'(names starting with "Py" or "PY").')
else:
paragraph('Only count private macros and public static inline functions '
'(ignore names starting with "Py" or "PY").')

def static_inline_func(results):
_static_inline_func(results, True)
_static_inline_func(results, False)


def structures(results):
Expand Down
63 changes: 42 additions & 21 deletions doc/stats.rst
Original file line number Diff line number Diff line change
Expand Up @@ -11,14 +11,14 @@ Number of C API line numbers per Python version:
Python Limited API CPython API Internal API Total
=========== ============= =========== ============ ======
2.7.0 12,392 (100%) 0 (0%) 0 (0%) 12,392
3.6.0 15,829 (100%) 0 (0%) 0 (0%) 15,829
3.7.0 16,442 (96%) 0 (0%) 678 (4%) 17,120
3.8.0 13,147 (70%) 3,418 (18%) 2,207 (12%) 18,772
3.9.0 12,243 (62%) 4,359 (22%) 3,084 (16%) 19,686
3.10.0 10,408 (51%) 4,584 (22%) 5,519 (27%) 20,511
3.11.0 9,232 (37%) 5,407 (22%) 10,047 (41%) 24,686
3.12 (dev) 9,598 (29%) 5,815 (18%) 17,631 (53%) 33,044
main (3.13) 9,397 (27%) 4,750 (14%) 20,455 (59%) 34,602
3.6.0 15,330 (100%) 0 (0%) 0 (0%) 15,330
3.7.0 15,943 (96%) 0 (0%) 678 (4%) 16,621
3.8.0 12,648 (69%) 3,418 (19%) 2,207 (12%) 18,273
3.9.0 11,744 (61%) 4,359 (23%) 3,084 (16%) 19,187
3.10.0 9,909 (50%) 4,584 (23%) 5,519 (28%) 20,012
3.11.0 8,733 (36%) 5,407 (22%) 10,047 (42%) 24,187
3.12 (dev) 9,099 (28%) 5,815 (18%) 17,631 (54%) 32,545
main (3.13) 8,904 (26%) 4,754 (14%) 20,459 (60%) 34,117
=========== ============= =========== ============ ======

File Numbers
Expand All @@ -30,14 +30,14 @@ Number of header file numbers per Python version:
Python Limited API CPython API Internal API Total
=========== =========== =========== ============ =========
2.7.0 91 0 0 91
3.6.0 99 (+8) 0 (same) 0 (same) 99 (+8)
3.7.0 99 (same) 0 (same) 11 (+11) 110 (+11)
3.8.0 97 (-2) 15 (+15) 21 (+10) 133 (+23)
3.9.0 98 (+1) 24 (+9) 33 (+12) 155 (+22)
3.10.0 81 (-17) 32 (+8) 48 (+15) 161 (+6)
3.11.0 72 (-9) 47 (+15) 68 (+20) 187 (+26)
3.12 (dev) 72 (same) 48 (+1) 91 (+23) 211 (+24)
main (3.13) 72 (same) 50 (+2) 96 (+5) 218 (+7)
3.6.0 98 (+7) 0 (same) 0 (same) 98 (+7)
3.7.0 98 (same) 0 (same) 11 (+11) 109 (+11)
3.8.0 96 (-2) 15 (+15) 21 (+10) 132 (+23)
3.9.0 97 (+1) 24 (+9) 33 (+12) 154 (+22)
3.10.0 80 (-17) 32 (+8) 48 (+15) 160 (+6)
3.11.0 71 (-9) 47 (+15) 68 (+20) 186 (+26)
3.12 (dev) 71 (same) 48 (+1) 91 (+23) 210 (+24)
main (3.13) 71 (same) 50 (+2) 96 (+5) 217 (+7)
=========== =========== =========== ============ =========

Functions
Expand All @@ -56,7 +56,7 @@ Python Public Private Internal Total
3.10.0 885 (-34) 412 (same) 115 (+6) 1,412 (-28)
3.11.0 891 (+6) 360 (-52) 176 (+61) 1,427 (+15)
3.12 (dev) 928 (+37) 385 (+25) 177 (+1) 1,490 (+63)
main (3.13) 925 (-3) 209 (-176) 253 (+76) 1,387 (-103)
main (3.13) 929 (+1) 209 (-176) 253 (+76) 1,391 (-99)
=========== ========== ========== ========= ============

Since Python 3.9, Python is now built with ``-fvisibility=hidden`` to avoid
Expand Down Expand Up @@ -85,10 +85,10 @@ Python Public Private Internal Total
main (3.13) 176 (same) 30 (-1) 12 (same) 218 (-1)
=========== ========== ======== ========= ==========

Functions defined as macros and static inline functions
=======================================================
Public functions defined as macros and static inline functions
==============================================================

Functions defined as macros and static inline functions:
Public functions defined as macros and static inline functions:

=========== ========== ============= ==========
Python Macro Static inline Total
Expand All @@ -104,7 +104,28 @@ Python Macro Static inline Total
main (3.13) 246 (-5) 63 (-1) 309 (-6)
=========== ========== ============= ==========

Only count public macros and public static inline functions (name starting with "Py" or "PY").
Only count public macros and public static inline functions (names starting with "Py" or "PY").

Private functions defined as macros and static inline functions
===============================================================

Private functions defined as macros and static inline functions:

=========== ======== ============= ========
Python Macro Static inline Total
=========== ======== ============= ========
2.7.0 21 0 21
3.6.0 60 (+39) 0 (same) 60 (+39)
3.7.0 70 (+10) 0 (same) 70 (+10)
3.8.0 57 (-13) 7 (+7) 64 (-6)
3.9.0 43 (-14) 11 (+4) 54 (-10)
3.10.0 44 (+1) 18 (+7) 62 (+8)
3.11.0 53 (+9) 4 (-14) 57 (-5)
3.12 (dev) 66 (+13) 7 (+3) 73 (+16)
main (3.13) 61 (-5) 7 (same) 68 (-5)
=========== ======== ============= ========

Only count private macros and public static inline functions (ignore names starting with "Py" or "PY").

Structures
==========
Expand Down

0 comments on commit 3d7810e

Please sign in to comment.