From 0f1da5d0e631d593d2e2eb6c29523c415642402e Mon Sep 17 00:00:00 2001 From: Victor Stinner Date: Thu, 12 Feb 2026 16:35:41 +0100 Subject: [PATCH 1/4] Build C and C++ extensions with /W4 on Windows Remove also -Wno-typedef-redefinition flag. --- tests/setup.py | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/tests/setup.py b/tests/setup.py index e394bce..b71ffe8 100755 --- a/tests/setup.py +++ b/tests/setup.py @@ -32,9 +32,6 @@ '-Wall', '-Wextra', # Extra warnings '-Wconversion', - # /usr/lib64/pypy3.7/include/pyport.h:68:20: error: redefinition of typedef - # 'Py_hash_t' is a C11 feature - '-Wno-typedef-redefinition', # Formatting checks '-Wformat', '-Wformat-nonliteral', @@ -44,6 +41,8 @@ else: # C compiler flags for MSVC COMMON_FLAGS.extend(( + # Display warnings level 1 to 4 + '/W4', # Treat all compiler warnings as compiler errors '/WX', )) From dd835ff6ee1ba0ff73dcef1ab27d3c9b279dc2ca Mon Sep 17 00:00:00 2001 From: Victor Stinner Date: Thu, 12 Feb 2026 16:44:20 +0100 Subject: [PATCH 2/4] Only use /W4 on Python 3.12 and newer --- tests/setup.py | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/tests/setup.py b/tests/setup.py index b71ffe8..b25bc8d 100755 --- a/tests/setup.py +++ b/tests/setup.py @@ -41,11 +41,17 @@ else: # C compiler flags for MSVC COMMON_FLAGS.extend(( - # Display warnings level 1 to 4 - '/W4', # Treat all compiler warnings as compiler errors '/WX', )) + # Python 3.11 and older emits C4100 "unreferenced parameter" warnings + # on Py_UNUSED() parameters. Py_UNUSED() was modified in Python 3.12 + # to support MSVC. + if sys.version_info >= (3, 12): + COMMON_FLAGS.extend(( + # Display warnings level 1 to 4 + '/W4', + )) CFLAGS = list(COMMON_FLAGS) CXXFLAGS = list(COMMON_FLAGS) From 5db5b811cdc4a6f2a151e1da0652cfa3af5cfc43 Mon Sep 17 00:00:00 2001 From: Victor Stinner Date: Thu, 12 Feb 2026 16:47:26 +0100 Subject: [PATCH 3/4] Fix C4210 warning --- pythoncapi_compat.h | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/pythoncapi_compat.h b/pythoncapi_compat.h index e26185c..afbd811 100644 --- a/pythoncapi_compat.h +++ b/pythoncapi_compat.h @@ -2664,6 +2664,10 @@ PyUnstable_Unicode_GET_CACHED_HASH(PyObject *op) // to make objects immortal until 3.14 which has _Py_SetImmortal(). Since // immortal objects are primarily needed for free-threading, this API is implemented // for 3.14 using _Py_SetImmortal() and uses private macros on 3.13. +#if 0x030E0000 <= PY_VERSION_HEX +PyAPI_FUNC(void) _Py_SetImmortal(PyObject *op); +#endif + static inline int PyUnstable_SetImmortal(PyObject *op) { @@ -2672,7 +2676,6 @@ PyUnstable_SetImmortal(PyObject *op) return 0; } #if 0x030E0000 <= PY_VERSION_HEX - PyAPI_FUNC(void) _Py_SetImmortal(PyObject *op); _Py_SetImmortal(op); #else // Python 3.13 doesn't export _Py_SetImmortal() function From ae51cba80a88b842a94e761784f3c97a6467ae0d Mon Sep 17 00:00:00 2001 From: Victor Stinner Date: Thu, 12 Feb 2026 16:52:07 +0100 Subject: [PATCH 4/4] Move all PyAPI_FUNC() definitions to the file level --- pythoncapi_compat.h | 21 +++++++++++++++------ 1 file changed, 15 insertions(+), 6 deletions(-) diff --git a/pythoncapi_compat.h b/pythoncapi_compat.h index afbd811..99970f6 100644 --- a/pythoncapi_compat.h +++ b/pythoncapi_compat.h @@ -1569,6 +1569,11 @@ static inline int PyLong_IsZero(PyObject *obj) // gh-124502 added PyUnicode_Equal() to Python 3.14.0a0 #if PY_VERSION_HEX < 0x030E00A0 + +#if PY_VERSION_HEX >= 0x030d0000 && !defined(PYPY_VERSION) +PyAPI_FUNC(int) _PyUnicode_Equal(PyObject *str1, PyObject *str2); +#endif + static inline int PyUnicode_Equal(PyObject *str1, PyObject *str2) { if (!PyUnicode_Check(str1)) { @@ -1583,8 +1588,6 @@ static inline int PyUnicode_Equal(PyObject *str1, PyObject *str2) } #if PY_VERSION_HEX >= 0x030d0000 && !defined(PYPY_VERSION) - PyAPI_FUNC(int) _PyUnicode_Equal(PyObject *str1, PyObject *str2); - return _PyUnicode_Equal(str1, str2); #elif PY_VERSION_HEX >= 0x03060000 && !defined(PYPY_VERSION) return _PyUnicode_EQ(str1, str2); @@ -1607,11 +1610,14 @@ static inline PyObject* PyBytes_Join(PyObject *sep, PyObject *iterable) #if PY_VERSION_HEX < 0x030E00A0 + +#if PY_VERSION_HEX >= 0x03000000 && !defined(PYPY_VERSION) +PyAPI_FUNC(Py_hash_t) _Py_HashBytes(const void *src, Py_ssize_t len); +#endif + static inline Py_hash_t Py_HashBuffer(const void *ptr, Py_ssize_t len) { #if PY_VERSION_HEX >= 0x03000000 && !defined(PYPY_VERSION) - PyAPI_FUNC(Py_hash_t) _Py_HashBytes(const void *src, Py_ssize_t len); - return _Py_HashBytes(ptr, len); #else Py_hash_t hash; @@ -1948,11 +1954,14 @@ PyLongWriter_Finish(PyLongWriter *writer) // gh-127350 added Py_fopen() and Py_fclose() to Python 3.14a4 #if PY_VERSION_HEX < 0x030E00A4 + +#if 0x030400A2 <= PY_VERSION_HEX && !defined(PYPY_VERSION) +PyAPI_FUNC(FILE*) _Py_fopen_obj(PyObject *path, const char *mode); +#endif + static inline FILE* Py_fopen(PyObject *path, const char *mode) { #if 0x030400A2 <= PY_VERSION_HEX && !defined(PYPY_VERSION) - PyAPI_FUNC(FILE*) _Py_fopen_obj(PyObject *path, const char *mode); - return _Py_fopen_obj(path, mode); #else FILE *f;