Skip to content

gh-129666: Add C11/C++11 to docs and -pedantic-errors to GCC/clang test_c[pp]ext tests #130692

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 2 commits into from
Mar 4, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
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
10 changes: 10 additions & 0 deletions Doc/c-api/intro.rst
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,16 @@ familiar with writing an extension before attempting to embed Python in a real
application.


Language version compatibility
==============================

Python's C API is compatible with C11 and C++11 versions of C and C++.

This is a lower limit: the C API does not require features from later
C/C++ versions.
You do *not* need to enable your compiler's "c11 mode".


Coding standards
================

Expand Down
2 changes: 1 addition & 1 deletion Include/object.h
Original file line number Diff line number Diff line change
Expand Up @@ -683,7 +683,7 @@ PyAPI_DATA(PyObject) _Py_NotImplementedStruct; /* Don't use this directly */
typedef enum {
PYGEN_RETURN = 0,
PYGEN_ERROR = -1,
PYGEN_NEXT = 1,
PYGEN_NEXT = 1
} PySendResult;
#endif

Expand Down
3 changes: 3 additions & 0 deletions Lib/test/test_cext/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,9 @@ def test_build_c11(self):

@unittest.skipIf(support.MS_WINDOWS, "MSVC doesn't support /std:c99")
def test_build_c99(self):
# In public docs, we say C API is compatible with C11. However,
# in practice we do maintain C99 compatibility in public headers.
# Please ask the C API WG before adding a new C11-only feature.
self.check_build('_test_c99_cext', std='c99')

@support.requires_gil_enabled('incompatible with Free Threading')
Expand Down
13 changes: 13 additions & 0 deletions Lib/test/test_cext/extension.c
Original file line number Diff line number Diff line change
Expand Up @@ -58,11 +58,24 @@ _testcext_exec(
return 0;
}

// Converting from function pointer to void* has undefined behavior, but
// works on all known platforms, and CPython's module and type slots currently
// need it.
// (GCC doesn't have a narrower category for this than -Wpedantic.)
_Py_COMP_DIAG_PUSH
#if defined(__GNUC__)
#pragma GCC diagnostic ignored "-Wpedantic"
#elif defined(__clang__)
#pragma clang diagnostic ignored "-Wpedantic"
#endif

static PyModuleDef_Slot _testcext_slots[] = {
{Py_mod_exec, (void*)_testcext_exec},
{0, NULL}
};

_Py_COMP_DIAG_POP


PyDoc_STRVAR(_testcext_doc, "C test extension.");

Expand Down
3 changes: 3 additions & 0 deletions Lib/test/test_cext/setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,9 @@

# gh-120593: Check the 'const' qualifier
'-Wcast-qual',

# Ask for strict(er) compliance with the standard
'-pedantic-errors',
]
if not support.Py_GIL_DISABLED:
CFLAGS.append(
Expand Down
7 changes: 7 additions & 0 deletions Lib/test/test_cppext/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -29,8 +29,15 @@ def test_build(self):
self.check_build('_testcppext')

def test_build_cpp03(self):
# In public docs, we say C API is compatible with C++11. However,
# in practice we do maintain C++03 compatibility in public headers.
# Please ask the C API WG before adding a new C++11-only feature.
self.check_build('_testcpp03ext', std='c++03')

@support.requires_gil_enabled('incompatible with Free Threading')
def test_build_limited_cpp03(self):
self.check_build('_test_limited_cpp03ext', std='c++03', limited=True)

@unittest.skipIf(support.MS_WINDOWS, "MSVC doesn't support /std:c++11")
def test_build_cpp11(self):
self.check_build('_testcpp11ext', std='c++11')
Expand Down
22 changes: 22 additions & 0 deletions Lib/test/test_cppext/extension.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -161,11 +161,24 @@ class VirtualPyObject : public PyObject {

int VirtualPyObject::instance_count = 0;

// Converting from function pointer to void* has undefined behavior, but
// works on all known platforms, and CPython's module and type slots currently
// need it.
// (GCC doesn't have a narrower category for this than -Wpedantic.)
_Py_COMP_DIAG_PUSH
#if defined(__GNUC__)
#pragma GCC diagnostic ignored "-Wpedantic"
#elif defined(__clang__)
#pragma clang diagnostic ignored "-Wpedantic"
#endif

PyType_Slot VirtualPyObject_Slots[] = {
{Py_tp_free, (void*)VirtualPyObject::dealloc},
{0, _Py_NULL},
};

_Py_COMP_DIAG_POP

PyType_Spec VirtualPyObject_Spec = {
/* .name */ STR(MODULE_NAME) ".VirtualPyObject",
/* .basicsize */ sizeof(VirtualPyObject),
Expand Down Expand Up @@ -241,11 +254,20 @@ _testcppext_exec(PyObject *module)
return 0;
}

// Need to ignore "-Wpedantic" warnings; see VirtualPyObject_Slots above
_Py_COMP_DIAG_PUSH
#if defined(__GNUC__)
#pragma GCC diagnostic ignored "-Wpedantic"
#elif defined(__clang__)
#pragma clang diagnostic ignored "-Wpedantic"
#endif

static PyModuleDef_Slot _testcppext_slots[] = {
{Py_mod_exec, reinterpret_cast<void*>(_testcppext_exec)},
{0, _Py_NULL}
};

_Py_COMP_DIAG_POP

PyDoc_STRVAR(_testcppext_doc, "C++ test extension.");

Expand Down
16 changes: 16 additions & 0 deletions Lib/test/test_cppext/setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,17 @@
# warnings
'-Werror',
]

CPPFLAGS_PEDANTIC = [
# Ask for strict(er) compliance with the standard.
# We cannot do this for c++03 unlimited API, since several headers in
# Include/cpython/ use commas at end of `enum` declarations, a C++11
# feature for which GCC has no narrower option than -Wpedantic itself.
'-pedantic-errors',

# We also use `long long`, a C++11 feature we can enable individually.
'-Wno-long-long',
]
else:
# MSVC compiler flags
CPPFLAGS = [
Expand All @@ -27,6 +38,7 @@
# Treat all compiler warnings as compiler errors
'/WX',
]
CPPFLAGS_PEDANTIC = []


def main():
Expand All @@ -45,6 +57,10 @@ def main():
else:
cppflags.append(f'-std={std}')

if limited or (std != 'c++03'):
# See CPPFLAGS_PEDANTIC docstring
cppflags.extend(CPPFLAGS_PEDANTIC)

# gh-105776: When "gcc -std=11" is used as the C++ compiler, -std=c11
# option emits a C++ compiler warning. Remove "-std11" option from the
# CC command.
Expand Down
Loading