Skip to content

C API: copying a PyStatus emits -Wdeprecated-declarations in C++ with clang since gh-158080 #160436

Open

Description

@davidnich

Bug description:

Since gh-158080 (GH-158085), PyStatus.exitcode is declared with Py_DEPRECATED(3.16) in Include/cpython/initconfig.h. Because the C API passes and returns PyStatus by value (PyStatus_Exception(), PyStatus_IsError(), Py_InitializeFromConfig(), ...), C++ code that uses the API in the documented way makes clang generate the implicit copy constructor / move assignment operator of PyStatus. These use the deprecated member, so clang emits -Wdeprecated-declarations even though the code never touches exitcode. With -Werror, the build fails.

The usage pattern of the Doc/c-api/init_config.rst examples (ex: init_python()), compiled as C++, is enough to reproduce:

#include <Python.h>

int main(int argc, char** argv) {
    PyStatus status;
    PyConfig config;
    PyConfig_InitPythonConfig(&config);
    status = PyConfig_SetBytesString(&config, &config.program_name, argv[0]);
    if (PyStatus_Exception(status)) {
        goto exception;
    }
    status = Py_InitializeFromConfig(&config);
    if (PyStatus_Exception(status)) {
        goto exception;
    }
    PyConfig_Clear(&config);
    return Py_RunMain();
exception:
    PyConfig_Clear(&config);
    Py_ExitStatusException(status);
}
$ clang++ -std=c++17 -Wall -Werror -I<cpython>/Include -I<build> -c embed.cpp
Include/cpython/initconfig.h:10:9: error: 'exitcode' is deprecated [-Werror,-Wdeprecated-declarations]
embed.cpp:7:12: note: in implicit move assignment operator for 'PyStatus' first required here
Include/cpython/initconfig.h:10:9: error: 'exitcode' is deprecated [-Werror,-Wdeprecated-declarations]
Include/cpython/initconfig.h:10:9: error: 'exitcode' is deprecated [-Werror,-Wdeprecated-declarations]
embed.cpp:8:28: note: in implicit copy constructor for 'PyStatus' first required here
  • Reproduced with 3.16.0a1, with Ubuntu clang 21.1.8 (Linux aarch64) and Apple clang 21.0.0 (macOS arm64); the PyStatus definition is unchanged on current main.
  • g++ 15, and clang compiling the same file as C, emit no warning.
  • The diagnostic is reported at the definition of the structure in initconfig.h, so users cannot silence it locally with a pragma around their own calls; they have to wrap the #include <Python.h> itself.

Possible fix

Suppress the warning around the definition of the structure, with the existing _Py_COMP_DIAG_* macros of pyport.h:

 /* --- PyStatus ----------------------------------------------- */

+_Py_COMP_DIAG_PUSH
+_Py_COMP_DIAG_IGNORE_DEPR_DECLS
 typedef struct {
     enum {
         _PyStatus_TYPE_OK=0,
         _PyStatus_TYPE_ERROR=1,
         _PyStatus_TYPE_EXIT=2  // deprecated
     } _type;
     const char *func;
     const char *err_msg;
     Py_DEPRECATED(3.16) int exitcode;
 } PyStatus;
+_Py_COMP_DIAG_POP

With this change the example above compiles cleanly with clang++ -Werror, while real uses (status.exitcode, PyStatus_Exit(), PyStatus_IsExit()) still emit the deprecation warning. (Alternatively, only the functions could be marked deprecated and the member documented as deprecated.)

A C++ test in Lib/test/test_cppext that copies a PyStatus would catch regressions of this kind.

CPython versions tested on:

3.16, CPython main branch

Operating systems tested on:

Linux, macOS

Activity

  1. added
    buildThe build process and cross-build
    3.16new features, bugs and security fixes
    on Oct 23, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    3.16new features, bugs and security fixesbuildThe build process and cross-buildinterpreter-core(Objects, Python, Grammar, and Parser dirs)topic-C-API

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions