Skip to content

gh-157695: Check that C API macros start with "Py" - #157696

Open
vstinner wants to merge 5 commits into
python:mainfrom
vstinner:check_capi_macros
Open

vstinner wants to merge 5 commits into
python:mainfrom
vstinner:check_capi_macros

Conversation

@vstinner

@vstinner vstinner commented Sep 17, 2026

Copy link
Copy Markdown
Member

Add "make check-capi-macros". Ignore existing macros which don't start with "Py", only prevent adding new names which don't respect this convention.

Run "make check-capi-macros" in the GitHub Action "Check if generated files are up to date" job.

Add "make check-capi-macros". Ignore existing macros which don't
start with "Py", only prevent adding new names which don't respect
this convention.

Run "make check-capi-macros" in the GitHub Action "Check if generated
files are up to date" job.

@ZeroIntensity ZeroIntensity left a comment

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.

I think this is a great idea. For clarity, do we already run similar checks for actual symbols? (For example, it should be impossible to add a new function to our headers that isn't prefixed with Py.)

Comment thread Misc/NEWS.d/next/C_API/2026-09-17-20-50-56.gh-issue-157695.06UH5M.rst Outdated
Comment thread Tools/build/check_capi_macros.py
@vstinner

Copy link
Copy Markdown
Member Author

I think this is a great idea. For clarity, do we already run similar checks for actual symbols? (For example, it should be impossible to add a new function to our headers that isn't prefixed with Py.)

We do already have make smelly which fails if Python exports a symbol which doesn't start with Py. The check is run by the CI.

So I'm not sure that it's useful to parse the public C API to check if PyAPI_FUNC() and PyAPI_DATA() use the Py prefix.

Last year, I found exported symbols which doesn't with Py prefix: issue gh-141376. It was a bug in the make smelly check (now fixed).

@ZeroIntensity

Copy link
Copy Markdown
Member

We do already have make smelly which fails if Python exports a symbol which doesn't start with Py. The check is run by the CI.

Yeah, as long as we have something, then I'm happy.

@vstinner

Copy link
Copy Markdown
Member Author

I wrote a quick patch to test "make smelly":

diff --git a/Include/pyerrors.h b/Include/pyerrors.h
index cfabbc5fe8d..f74534da7e6 100644
--- a/Include/pyerrors.h
+++ b/Include/pyerrors.h
@@ -326,6 +326,8 @@ PyAPI_FUNC(int) PyOS_snprintf(char *str, size_t size, const char  *format, ...)
 PyAPI_FUNC(int) PyOS_vsnprintf(char *str, size_t size, const char  *format, va_list va)
                         Py_GCC_ATTRIBUTE((format(printf, 3, 0)));
 
+PyAPI_FUNC(int) test_dummy_func(void);
+
 #ifndef Py_LIMITED_API
 #  define Py_CPYTHON_ERRORS_H
 #  include "cpython/pyerrors.h"
diff --git a/Python/errors.c b/Python/errors.c
index eb148998fc4..df7d3241dcc 100644
--- a/Python/errors.c
+++ b/Python/errors.c
@@ -2091,3 +2091,9 @@ PyErr_ProgramTextObject(PyObject *filename, int lineno)
 {
     return _PyErr_ProgramDecodedTextObject(filename, lineno, NULL);
 }
+
+int
+test_dummy_func(void)
+{
+    return 4;
+}

With this change, "make smelly" fails as expected with:

Found 1 smelly symbols in total!
    - test_dummy_func from libpython3.16td.a
make: *** [Makefile:3528: smelly] Error 1

- name: Check for unsupported C global variables
if: github.event_name == 'pull_request' # $GITHUB_EVENT_NAME
run: make check-c-globals
- name: Check C ABI macros

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.

Should this be "API" instead of "ABI"? I think it's weird to refer to the ABI when we're not actually dealing with exported symbols.

Suggested change
- name: Check C ABI macros
- name: Check C API macros

names.sort()

if not names:
print("OK: the Python C API only defines macros with name "

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.

Suggested change
print("OK: the Python C API only defines macros with name "
print("OK: the Python C API only defines macros with names "

Comment on lines +72 to +74
print('ERROR: the Python C API defines the following macros '
'with a name not starting with "Py":')
print()

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.

Up to you, but it'd be nice to have colorful output with _colorize (the C API docs check script does this).

Comment on lines +62 to +64
names = []
for filename in files:
parse_file(filename, names, ignored)

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.

Consider using a set instead of a list here. Currently, this will contain duplicated names if a #define is used twice, such as in an #ifdef.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants