Skip to content
Merged
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
Check that the ignore list is sorted
  • Loading branch information
vstinner committed Sep 18, 2026
commit d2347d953d8d5b721150e7b775fad5df087201a4
50 changes: 35 additions & 15 deletions Tools/build/check_capi_macros.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
* pyconfig.h.in
"""

import difflib
import glob
import os.path
import re
Expand Down Expand Up @@ -52,21 +53,22 @@ def parse_file(filename, names):


def get_ignored_names():
ignored = set()
ignored = []
with open(IGNORED_FILENAME, encoding='utf8') as fp:
for line in fp:
name = line.strip()
if name.startswith('#'):
# Ignore comment
continue
if name:
ignored.add(name)
ignored.append(name)
return ignored


def main():
failure = False

# Parse header files
include_dir = os.path.join(SRC_DIR, 'Include')
files = glob.glob(os.path.join(include_dir, '*.h'))

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

(Forgot to post this yesterday)

Include/opcode_ids.h contains generated opcodes, we could exclude these:

Suggested change
files = glob.glob(os.path.join(include_dir, '*.h'))
files = glob.glob(os.path.join(include_dir, '*.h'))
files.remove(os.path.join(include_dir, 'opcode_ids.h'))

And then remove the 245 generated names from check_capi_macros_ignored.txt. This will make maintenance easier so we don't need to add/remove future ones.

files.extend(glob.glob(os.path.join(include_dir, 'cpython', '*.h')))
Expand All @@ -75,24 +77,26 @@ def main():
for filename in files:
parse_file(filename, names)

names_set = {name for name, filename, undef in names}
# Parse ignore list
ignored = get_ignored_names()

new_macros = names_set - ignored
if new_macros:
print('ERROR: the Python C API defines the following new macros:')
# Check if the sorted list is sorted
ignored_sorted = sorted(ignored)
if ignored_sorted != ignored:
print(f"ERROR: {IGNORED_FILENAME} list is not sorted")
print()
count = 0
for name, filename, undef in sorted(names):
if name in ignored:
continue
define = "undefined" if undef else "defined"
print(f"- {name} {define} by {filename}")
count += 1
diff = difflib.unified_diff(ignored, ignored_sorted,
fromfile=IGNORED_FILENAME,
tofile=IGNORED_FILENAME,
lineterm='')
for line in diff:
print(line)
print()
print(f"Total: {count} macros")
failure = True

# Check for outdated ignore list
names_set = {name for name, filename, undef in names}
ignored = set(ignored)
outdated = ignored - names_set
if outdated:
print(f"ERROR: {IGNORED_FILENAME} is outdated, "
Expand All @@ -105,10 +109,26 @@ def main():
print()
failure = True

# Check for new macros
new_macros = names_set - ignored
if new_macros:
print('ERROR: the Python C API defines the following new macros:')
print()
count = 0
for name, filename, undef in sorted(names):
if name in ignored:
continue
define = "undefined" if undef else "defined"
print(f"- {name} {define} by {filename}")
count += 1
print()
print(f"Total: {count} macros")
failure = True

if not failure:
print("OK: the ignore list is up to date and sorted")
print("OK: the Python C API only defines macros with names "
f"starting with Py (ignoring {len(ignored)} macros)")
print("OK: the ignore list is up to date")
sys.exit(0)

sys.exit(1)
Expand Down
Loading