| FazBrowse GitHub Viewer | Trending | | Home |
| Tools: [Download Repo ZIP] [Original HTTPS Page] |
Sorry, something went wrong.
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.
There was a problem hiding this comment.
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.)
Sorry, something went wrong.
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). |
Sorry, something went wrong.
Yeah, as long as we have something, then I'm happy. |
Sorry, something went wrong.
|
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
|
Sorry, something went wrong.
| print('ERROR: the Python C API defines the following macros ' | ||
| 'with a name not starting with "Py":') | ||
| print() |
There was a problem hiding this comment.
Up to you, but it'd be nice to have colorful output with _colorize (the C API docs check script does this).
Sorry, something went wrong.
There was a problem hiding this comment.
I'm not sure that it's needed to add colors to this script.
Sorry, something went wrong.
|
In the issue gh-149685, @encukou was concerned about new macros defined by pyconfig.h which doesn't start with Py. Well, yes, pyconfig.h is included by Python.h, so it's also part of the (public) Python C API. I updated my PR to parse also pyconfig.h.in. |
Sorry, something went wrong.
Co-authored-by: Peter Bierma <zintensitydev@gmail.com>
Co-authored-by: Peter Bierma <zintensitydev@gmail.com>
|
Is our configure script capable of generating HAVE_ macros with a _Py/Py prefix? |
Sorry, something went wrong.
Some recently added "HAVE" macros start with a _Py_ prefix. Example from configure.ac: AS_VAR_IF([ac_cv_have_libgcc_eh_frame_registration], [yes], [
AC_DEFINE([_Py_HAVE_LIBGCC_EH_FRAME_REGISTRATION], [1],
[Define to 1 if libgcc __register_frame and __deregister_frame are linkable.])
])
On the other hand, high-level functions like AC_CHECK_FUNCS always generate HAVE_xxx macro if the function xxx is available. I don't know how to add a prefix to the macro name. Python 3.16 adds the following macros to pyconfig.h.in compared to Python 3.15: HAVE_ACOSPI HAVE_ASINPI HAVE_ATAN2PI HAVE_ATANPI HAVE_COSPI HAVE_CURSES_DEFINE_KEY HAVE_CURSES_HAS_MOUSE HAVE_CURSES_IS_KEYPAD HAVE_CURSES_IS_LEAVEOK HAVE_CURSES_KEYOK HAVE_CURSES_KEY_DEFINED HAVE_CURSES_NEW_PRESCR HAVE_CURSES_NOFILTER HAVE_CURSES_SCR_DUMP HAVE_CURSES_SCR_SET HAVE_CURSES_SLK_ATTR_OFF HAVE_CURSES_SLK_ATTR_ON HAVE_CURSES_SLK_ATTR_SET HAVE_CURSES_SLK_COLOR HAVE_CURSES_TERM_ATTRS HAVE_CURSES_USE_SCREEN HAVE_CURSES_USE_WINDOW HAVE_CURSES_WATTR_GET HAVE_CURSES_WATTR_OFF HAVE_CURSES_WATTR_ON HAVE_CURSES_WATTR_SET HAVE_CURSES_WCOLOR_SET HAVE_FLOAT16 HAVE_GETDENTS64 HAVE_GETTID HAVE_ICONV HAVE_ICONV_H HAVE_IF_INDEXTONAME HAVE_IF_NAMETOINDEX HAVE_PIDFD_GETFD HAVE_PIDFD_OPEN HAVE_PIDFD_SEND_SIGNAL HAVE_RL_CHANGE_ENVIRONMENT HAVE_SINPI HAVE_TANPI _ISOC23_SOURCE HAVE_FLOAT16 can be easily modified to add a _Py prefix. |
Sorry, something went wrong.
There was a problem hiding this comment.
We have two other scripts with somewhat similar functionality to check things against ignore lists, and they both also verify the opposite: that the ignore file has no stale entries.
If a stale entry is found, the script also fails. This makes sure we keep it clean and relevant.
Let's add a similar check here, it would find the unnecessary FVC_ALT_REPR. And can also identify the generated ones from opcode_ids.h.
For reference:
cpython/Doc/tools/check-warnings.py
Lines 237 to 251 in 659e262
cpython/Tools/build/check_warnings.py
Lines 195 to 225 in 659e262
Sorry, something went wrong.
|
Ok, I made multiple changes to address reviews:
I also added a check to make sure that the ignore list is sorted. Is it overkill? I'm aware of Python 3.15 re.prefixprefix(), but my system Python is Python 3.14 and it's convenient for me to be able to use it :-) |
Sorry, something went wrong.
I wrote PR gh-157752 to rename HAVE_FLOAT16 macro to _Py_HAVE_FLOAT16. |
Sorry, something went wrong.
|
I added the following header to the ignore list: # Old C API macros with a name which doesn't start with "Py". If a macro
# is removed from the C API, it should be removed from this list as well.
#
# Adding a new macro to this ignore list requires the approval of the C API
# Working Group. Open an issue at:
# https://github.com/capi-workgroup/decisions/issues/"Adding a new macro to this ignore list requires approval" is a bold rule. Do we need exceptions? Or can we decide what are these exceptions later? AC_CHECK_FUNCS(), AC_CHECK_HEADERS() and PY_CHECK_FUNC() always define HAVE_xxx macros. Should we say that new HAVE_xxx macros defined by these functions are fine? Or should we already add new functions defining _Py_HAVE_xxx macros instead? |
Sorry, something went wrong.
There was a problem hiding this comment.
I also added a check to make sure that the ignore list is sorted. Is it overkill?
I think it's worth it, it's easier to manually search a sorted list, and it's a simple check.
(prek/pre-commit have a built-in sorter lint (file-contents-sorter) but that would require moving the ignore file's header into the .py)
Sorry, something went wrong.
|
|
||
| # Parse header files | ||
| include_dir = os.path.join(SRC_DIR, 'Include') | ||
| files = glob.glob(os.path.join(include_dir, '*.h')) |
There was a problem hiding this comment.
(Forgot to post this yesterday)
Include/opcode_ids.h contains generated opcodes, we could exclude these:
| 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.
Sorry, something went wrong.
Co-authored-by: Hugo van Kemenade <1324225+hugovk@users.noreply.github.com>
Even if it's generated, it's part of the public Python C API and so we should care about these macros. Ignoring them only because they are generated doesn't look correct to me. |
Sorry, something went wrong.
|
I updated the PR to address @hugovk's latest review. |
Sorry, something went wrong.
Hum. I didn't take in account that opcode.h is not included by Python.h. Maybe we should/can ignore the following Include/ header files which are not included by Python.h:
I don't know. I'm now confused :-) See details in my comment on the issue. |
Sorry, something went wrong.
|
Ok, I changed my mind. I excluded 7 header files which are not included by Python.h:
They define multiple macros without Py prefix. The following header files are still parsed by the script even if they are not included by Python.h:
I wrote this script to list header files not included by Python.h: import re, glob, sys, os
INCLUDE = re.compile(r'\s*#\s*include\s+["<]([a-z0-9_./]+)[">]')
os.chdir("Include")
headers = set(glob.glob("*.h"))
headers.discard("Python.h")
os.chdir("..")
with open("Include/Python.h") as fp:
for line in fp:
match = INCLUDE.match(line)
if match:
name = match.group(1)
headers.discard(name)
elif line.startswith("// "):
continue
elif "include" in line:
print(f"failed to parse: {line!r}")
sys.exit(1)
print("Not included by Python.h:")
for name in sorted(headers):
print(f"- {name}") |
Sorry, something went wrong.
|
I also wrote PR gh-157821 to rename HAVE_ICONV macro to _Py_HAVE_ICONV. |
Sorry, something went wrong.
There was a problem hiding this comment.
Thanks! Looks good, can always exclude generated ones later if we decide to do so.
Sorry, something went wrong.
|
Thank you! I collected some nitpicks as I was reading this and sent them in vstinner#19. Otherwise LGTM |
Sorry, something went wrong.
Add line numbers. With this, some editors can jump directly to the definition. For regex groups, use names & subsciption API. I prefer using a string rather than a bool for the "cause"; it allows more easily adding another option later.
|
@encukou: I applied your PR, thanks. I tested manually by adding two macros using #define and #undef: they are properly detected and the script gives the correct line numbers. |
Sorry, something went wrong.
|
I merged my change. Thanks for useful reviews! |
Sorry, something went wrong.
|
Oh, in my PR #159604, I need to check if the <pthread_np.h> header file is available. I added a code like this to configure.ac: AC_CHECK_HEADERS([pthread_np.h]) This code defines a new HAVE_PTHREAD_NP_H macro that I had to add to Tools/build/check_capi_macros_ignored.txt. Is there a way to check for a header file and define a _Py_HAVE_xxx_H macro instead? |
Sorry, something went wrong.
AFAIK there is: AC_CHECK_HEADER with AC_DEFINE. I'm not sure about the details though. |
Sorry, something went wrong.
| Back | FazBrowse Home | New Git URL |
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.