Skip to content

Commit 7aa4163

Browse files
committed
Get types
1 parent 49f33c0 commit 7aa4163

4 files changed

Lines changed: 114 additions & 53 deletions

File tree

‎doc/list_structs.py‎

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
#!/usr/bin/python
2+
import os.path
3+
import re
4+
import sys
5+
6+
from pythoncapi import PATH_LIMITED_API, PATH_CPYTHON_API, get_types
7+
8+
9+
def main():
10+
if not os.path.exists('pyconfig.h.in'):
11+
print("program must be run in the Python source code directory")
12+
sys.exit(1)
13+
14+
limited = get_types(PATH_LIMITED_API)
15+
cpython = get_types(PATH_CPYTHON_API)
16+
names = sorted(set(limited) | set(cpython))
17+
for name in names:
18+
print("*", name)
19+
print()
20+
print("Total:", len(names))
21+
22+
main()

‎doc/pythoncapi.py‎

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
import glob
2+
import os.path
3+
import re
4+
5+
6+
# Checkout of Python Git repository, one directory per branch:
7+
#
8+
# - 2.7/ = Python 2.7 branch
9+
# - 3.6/ = Python 3.6 branch
10+
# - main/ = Python main branch
11+
# - etc.
12+
PYTHON_ROOT = '/home/vstinner/python'
13+
14+
15+
PATH_LIMITED_API = 'Include'
16+
PATH_CPYTHON_API = os.path.join('Include', 'cpython')
17+
PATH_INTERNAL_API = os.path.join('Include', 'internal')
18+
19+
RE_STRUCT_START = re.compile(r'^(?:typedef +)?struct(?: +([A-Za-z0-9_]+))? *{', re.MULTILINE)
20+
RE_STRUCT_END = re.compile(r'^}(?: +([A-Za-z0-9_]+))? *;', re.MULTILINE)
21+
22+
23+
def files(path):
24+
return glob.glob(os.path.join(path, '*.h'))
25+
26+
27+
def _get_types(filename, names):
28+
if 'pthread_stubs.h' in filename:
29+
# skip special header file used by WASM
30+
return
31+
32+
with open(filename, encoding="utf-8") as fp:
33+
content = fp.read()
34+
35+
for match in RE_STRUCT_START.finditer(content):
36+
struct_name = match.group(1)
37+
match2 = RE_STRUCT_END.search(content, match.end())
38+
if not match2:
39+
raise Exception(f"cannot find end of: {filename}: {match.group()}")
40+
name = match2.group(1)
41+
if not name:
42+
name = struct_name
43+
if not name:
44+
raise Exception(f"structure has no name: {filename}: {match.group()})")
45+
names.add(name)
46+
47+
48+
def get_types(directory):
49+
names = set()
50+
for filename in files(directory):
51+
_get_types(filename, names)
52+
return sorted(names)

‎doc/stats.py‎

Lines changed: 7 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -7,13 +7,7 @@
77
import subprocess
88
import sys
99

10-
11-
# Checkout of Python Git repository, one directory per branch:
12-
# 2.7/ = Python 2.7 branch
13-
# 3.6/ = Python 3.6 branch
14-
# main/ = Python main branch
15-
# etc.
16-
PYTHON_ROOT = '/home/vstinner/python'
10+
from pythoncapi import files, PYTHON_ROOT, PATH_LIMITED_API, PATH_CPYTHON_API, PATH_INTERNAL_API, get_types
1711

1812

1913
RST_FILENAME = 'stats.rst'
@@ -32,20 +26,11 @@
3226
TABLE_SPACE = ' '
3327

3428

35-
PATH_LIMITED_API = 'Include'
36-
PATH_CPYTHON_API = os.path.join('Include', 'cpython')
37-
PATH_INTERNAL_API = os.path.join('Include', 'internal')
38-
39-
4029
output = []
4130
def log(msg=''):
4231
output.append(msg)
4332

4433

45-
def files(path):
46-
return glob.glob(os.path.join(path, '*.h'))
47-
48-
4934
def get_output(cmd):
5035
proc = subprocess.run(cmd,
5136
shell=True,
@@ -266,12 +251,14 @@ def static_inline_func():
266251

267252
def structures():
268253
display_title('Structures')
269-
paragraph('Public structures in the Python C API:')
254+
paragraph('Structures in the Python C API:')
270255

271-
lines = [('Python', 'Structures')]
256+
lines = [COLUMNS]
272257
for name in iter_branches():
273-
count = get_int("grep 'typedef struct' Include/*.h Include/cpython/*.h|wc -l")
274-
line = [name, count]
258+
limited = len(get_types(PATH_LIMITED_API))
259+
cpython = len(get_types(PATH_CPYTHON_API))
260+
internal = len(get_types(PATH_INTERNAL_API))
261+
line = [name, limited, cpython, internal, limited + cpython + internal]
275262
lines.append(line)
276263
table_compute_diff(lines)
277264
render_table(lines)

‎doc/stats.rst‎

Lines changed: 33 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -11,13 +11,13 @@ Number of C API line numbers per Python version:
1111
Python Limited API CPython API Internal API Total
1212
====== ============= =========== ============ ======
1313
2.7 12,686 (100%) 0 (0%) 0 (0%) 12,686
14-
3.6 15,984 (100%) 0 (0%) 0 (0%) 15,984
15-
3.7 16,517 (96%) 0 (0%) 717 (4%) 17,234
16-
3.8 13,166 (70%) 3,417 (18%) 2,242 (12%) 18,825
17-
3.9 12,265 (62%) 4,358 (22%) 3,093 (16%) 19,716
18-
3.10 10,396 (51%) 4,613 (22%) 5,533 (27%) 20,542
19-
3.11 9,255 (37%) 5,387 (22%) 10,107 (41%) 24,749
20-
3.12 9,189 (37%) 5,246 (21%) 10,176 (41%) 24,611
14+
3.6 16,051 (100%) 0 (0%) 0 (0%) 16,051
15+
3.7 16,517 (96%) 0 (0%) 772 (4%) 17,289
16+
3.8 13,166 (70%) 3,417 (18%) 2,295 (12%) 18,878
17+
3.9 12,265 (62%) 4,358 (22%) 3,146 (16%) 19,769
18+
3.10 10,396 (51%) 4,616 (22%) 5,572 (27%) 20,584
19+
3.11 9,232 (37%) 5,495 (22%) 10,046 (41%) 24,773
20+
3.12 9,227 (29%) 5,308 (17%) 17,633 (55%) 32,168
2121
====== ============= =========== ============ ======
2222

2323
File Numbers
@@ -30,12 +30,12 @@ Python Limited API CPython API Internal API Total
3030
====== =========== =========== ============ =========
3131
2.7 91 0 0 91
3232
3.6 99 (+8) 0 (same) 0 (same) 99 (+8)
33-
3.7 99 (same) 0 (same) 11 (+11) 110 (+11)
34-
3.8 97 (-2) 15 (+15) 21 (+10) 133 (+23)
35-
3.9 98 (+1) 24 (+9) 33 (+12) 155 (+22)
36-
3.10 81 (-17) 32 (+8) 48 (+15) 161 (+6)
37-
3.11 72 (-9) 46 (+14) 68 (+20) 186 (+25)
38-
3.12 72 (same) 46 (same) 69 (+1) 187 (+1)
33+
3.7 99 (same) 0 (same) 12 (+12) 111 (+12)
34+
3.8 97 (-2) 15 (+15) 22 (+10) 134 (+23)
35+
3.9 98 (+1) 24 (+9) 34 (+12) 156 (+22)
36+
3.10 81 (-17) 32 (+8) 48 (+14) 161 (+5)
37+
3.11 72 (-9) 48 (+16) 68 (+20) 188 (+27)
38+
3.12 72 (same) 48 (same) 71 (+3) 191 (+3)
3939
====== =========== =========== ============ =========
4040

4141
Symbols
@@ -47,13 +47,13 @@ Symbols exported with PyAPI_FUNC() and PyAPI_DATA():
4747
Python Public Private Internal Total
4848
====== ============ ========== ========= ============
4949
2.7 891 207 0 1,098
50-
3.6 1,041 (+150) 419 (+212) 0 (same) 1,460 (+362)
51-
3.7 1,068 (+27) 479 (+60) 22 (+22) 1,569 (+109)
50+
3.6 1,041 (+150) 420 (+213) 0 (same) 1,461 (+363)
51+
3.7 1,068 (+27) 479 (+59) 22 (+22) 1,569 (+108)
5252
3.8 1,105 (+37) 456 (-23) 91 (+69) 1,652 (+83)
5353
3.9 1,115 (+10) 439 (-17) 124 (+33) 1,678 (+26)
54-
3.10 1,080 (-35) 439 (same) 129 (+5) 1,648 (-30)
55-
3.11 1,087 (+7) 381 (-58) 188 (+59) 1,656 (+8)
56-
3.12 1,081 (-6) 378 (-3) 192 (+4) 1,651 (-5)
54+
3.10 1,080 (-35) 441 (+2) 129 (+5) 1,650 (-28)
55+
3.11 1,113 (+33) 383 (-58) 187 (+58) 1,683 (+33)
56+
3.12 1,116 (+3) 382 (-1) 186 (-1) 1,684 (+1)
5757
====== ============ ========== ========= ============
5858

5959
Since Python 3.9, Python is now built with ``-fvisibility=hidden`` to avoid
@@ -78,7 +78,7 @@ Python Macro Static inline Total
7878
3.9 406 (+7) 30 (+16) 436 (+23)
7979
3.10 412 (+6) 36 (+6) 448 (+12)
8080
3.11 400 (-12) 66 (+30) 466 (+18)
81-
3.12 385 (-15) 75 (+9) 460 (-6)
81+
3.12 390 (-10) 77 (+11) 467 (+1)
8282
====== ========= ============= =========
8383

8484
If a function is defined as a private static inline function and exposed as a
@@ -89,20 +89,20 @@ counted as 2 functions, whereas only the "Py_INCREF" name is public.
8989
Structures
9090
==========
9191

92-
Public structures in the Python C API:
93-
94-
====== ==========
95-
Python Structures
96-
====== ==========
97-
2.7 97
98-
3.6 124 (+27)
99-
3.7 137 (+13)
100-
3.8 127 (-10)
101-
3.9 125 (-2)
102-
3.10 104 (-21)
103-
3.11 106 (+2)
104-
3.12 111 (+5)
105-
====== ==========
92+
Structures in the Python C API:
93+
94+
====== =========== =========== ============ =========
95+
Python Limited API CPython API Internal API Total
96+
====== =========== =========== ============ =========
97+
2.7 92 0 0 92
98+
3.6 110 (+18) 0 (same) 0 (same) 110 (+18)
99+
3.7 114 (+4) 0 (same) 18 (+18) 132 (+22)
100+
3.8 81 (-33) 34 (+34) 28 (+10) 143 (+11)
101+
3.9 68 (-13) 46 (+12) 38 (+10) 152 (+9)
102+
3.10 41 (-27) 53 (+7) 91 (+53) 185 (+33)
103+
3.11 19 (-22) 75 (+22) 112 (+21) 206 (+21)
104+
3.12 24 (+5) 75 (same) 113 (+1) 212 (+6)
105+
====== =========== =========== ============ =========
106106

107107
These numbers exclude opaque structures like PyInterpreterState (since Python
108108
3.8). The grep command is not exact. For example, PyODictObject is seen as

0 commit comments

Comments
 (0)