GV

GeezerVison

The World Wide Web, restored to 800 pixels of glory.

Home|About|Gaming cabinet|Archives|How it works|Starter sites

On this site

  • Sign in
  • ActionsCI/CD and automation
  • CodespacesCloud development environments
  • All Features
  • Documentation
  • Training
  • Certifications
  • Build with Copilot
  • Customize Copilot
  • Integrations
  • Trending repos
  • GitHub Sponsors
  • Developer articles
  • Enterprises

This view

  • Original page
  • New address

GeezerVison is showing github.com — gh-146636: Improve ABI/feature selection, add new header for it by encukou · Pull Request #148302 · python/cpython

Conversation

@encukou

@encukou encukou commented Apr 9, 2026

Copy link
Copy Markdown
Member

Feature/ABI selection headers (Py_BUILD_CORE, Py_LIMITED_API, Py_GIL_DISABLED) need to be defined early (so they affect all definitions), but after the version (patchlevel.h) and configuration (pyconfig.h).
Put them in their own header to make this more obvious, and easier for contributors to keep them in the proper place.

Add a test that Python headers themselves don't use Py_GIL_DISABLED, since abi3 and abi3t ought to be identical except for the _Py_OPAQUE_PYOBJECT differences.
This is done using the GCC-only poison pragma, which tells the compiler/preprocessor to error if it ever sees the identifier after the pragma.
This needs some rewriting: #if defined(Py_LIMITED_API) && defined(Py_GIL_DISABLED) needs to be split into two lines, as the poisoning doesn't honour short-circuiting.

This should fix gh-148267, but I'm attaching the PR to the abi3t issue, gh-146636, as it continues that effort (GH-148142 specifically).

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

All reactions
encukou added 6 commits April 9, 2026 13:44
@encukou
pythongh-146636: abi3t: Test that Python.h avoids checking Py_GIL_DIS…
1116e1e
…ABLED

Add a test that Python headers themselves don't use
Py_GIL_DISABLED in abi3t: abi3 and abi3t ought to be the
same except the _Py_OPAQUE_PYOBJECT differences.
This is done using the GCC-only poison pragma.
@encukou
Move ABI/feature selection macros to their own header
4581298
@encukou
Update check for <intrin.h>
e1b7500
@encukou
Typo
247bd46
@encukou
Move Py_BUILD_CORE undefines, and include exports.h directly from Pyt…
7835449
…hon.h
@encukou
Comments
2ad80d8
@encukou
encukou requested a review from vstinner April 9, 2026 14:35
@encukou
encukou requested review from a team, AA-Turner, emmatyping and erlend-aasland as code owners April 9, 2026 14:35
@bedevere-app bedevere-app Bot added the awaiting core review label Apr 9, 2026
@bedevere-app bedevere-app Bot mentioned this pull request Apr 9, 2026
Implement PEP 803 -- abi3t #146636
Closed
8 of 9 tasks
vstinner
vstinner reviewed Apr 9, 2026
View reviewed changes
Comment thread Include/pyabi.h Resolved

Uh oh!

There was an error while loading. Please reload this page.

Comment thread Include/pyabi.h
// whether they need extra synchronization.
# define Py_GIL_DISABLED
# endif
# if defined(_Py_IS_TESTCEXT)

@vstinner vstinner Apr 9, 2026

Copy link
Copy Markdown
Member

There was a problem hiding this comment.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You may move #ifdef __GNUC__ here:

Suggested change
# if defined(_Py_IS_TESTCEXT)
# if defined(_Py_IS_TESTCEXT) && defined(__GNUC__)

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

All reactions

@encukou encukou Apr 10, 2026

Copy link
Copy Markdown
Member Author

There was a problem hiding this comment.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This subtle style detail is intentional: I'm inviting #elifs for other compilers.

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

All reactions
Comment thread Include/pyabi.h Resolved

Uh oh!

There was an error while loading. Please reload this page.

Comment thread Include/pyabi.h

/* The internal C API must not be used with the limited C API: make sure
* that Py_BUILD_CORE* macros are not defined in this case.
* But, keep the "original" values, under different names, for "exports.h"

@vstinner vstinner Apr 9, 2026

Copy link
Copy Markdown
Member

There was a problem hiding this comment.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's surprising that _PyEXPORTS_CORE and _PyEXPORTS_CORE_MODULE are defined even if Py_LIMITED_API is defined. I tried to undefine Py_BUILD_CORE if Py_LIMITED_API is defined before _PyEXPORTS_CORE code, but I got linker errors on Windows. Examples:

LINK : warning LNK4217: symbol 'PyType_GetFlags' defined in 'typeobject.obj' is imported by '_stat.obj' in fu 
nction '_PyLong_AsMode_t' [C:\victor\python\main\PCbuild\pythoncore.vcxproj]
LINK : warning LNK4217: symbol '_Py_DecRef' defined in 'object.obj' is imported by '_stat.obj' in function '_ 
PyLong_AsMode_t' [C:\victor\python\main\PCbuild\pythoncore.vcxproj]
LINK : warning LNK4286: symbol '_Py_DecRef' defined in 'object.obj' is imported by 'errnomodule.obj' [C:\vict 
or\python\main\PCbuild\pythoncore.vcxproj]
LINK : warning LNK4217: symbol 'PyUnicode_FromStringAndSize' defined in 'unicodeobject.obj' is imported by '_ 
stat.obj' in function 'stat_filemode' [C:\victor\python\main\PCbuild\pythoncore.vcxproj]

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

All reactions

@encukou encukou Apr 10, 2026

Copy link
Copy Markdown
Member Author

There was a problem hiding this comment.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes; these select whether PyAPI_FUNC sumbols are exported or imported. Anything compiled into the main binary needs to be exported, regardless of the API it uses.

(This is currently done by including "exports.h" in the middle of pyport.h, right before Py_BUILD_CORE is undefined -- which is IMO confusing, as it makes the meaning of Py_BUILD_CORE depend on where you are in the header.)

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

All reactions
@encukou @vstinner
Apply suggestions from code review
7c9d920
Co-authored-by: Victor Stinner <[email protected]>
@encukou encukou mentioned this pull request Apr 14, 2026
PEP 803: Py_GIL_DISABLED is tested prior to setting, in patchlevel.h #148267
Closed
@encukou encukou added the 🔨 test-with-buildbots Test PR w/ buildbots; report in status section label Apr 16, 2026
@bedevere-bot

bedevere-bot commented Apr 16, 2026

Copy link
Copy Markdown

🤖 New build scheduled with the buildbot fleet by @encukou for commit 7c9d920 🤖

Results will be shown at:

https://buildbot.python.org/all/#/grid?branch=refs%2Fpull%2F148302%2Fmerge

If you want to schedule another build, you need to add the 🔨 test-with-buildbots label again.

All reactions

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

@bedevere-bot bedevere-bot removed the 🔨 test-with-buildbots Test PR w/ buildbots; report in status section label Apr 16, 2026
@ngoldbaum

ngoldbaum commented Apr 16, 2026 •
edited
Loading

Uh oh!

There was an error while loading. Please reload this page.

Copy link
Copy Markdown
Contributor

I ran into an issue similar to gh-148267 while working on CFFI (see https://github.com/python-cffi/cffi/actions/runs/24516133542/job/71660551119?pr=232) and was curious if this PR fixes it. It doesn't. The compiler error I see on this branch is:

In file included from /Users/goldbaum/.pyenv/versions/3.15t-dev-encukoupr/include/python3.15t/Python.h:16:
/Users/goldbaum/.pyenv/versions/3.15t-dev-encukoupr/include/python3.15t/pyabi.h:55:24: error: invalid
      token at start of a preprocessor expression
   55 | #  elif Py_LIMITED_API > Py_TARGET_ABI3T
      |                        ^

I think this is happening because my CFFI branch was using _Py_OPAQUE_PYOBJECT directly and the header doesn't handle someone setting that outside of CPython's headers. Probably unlikely to happen in practice, not sure if it's worth explicitly guarding against so I thought I'd share. On the CFFI side I'll fix this by defining Py_TARGET_ABI3T.

encukou reacted with thumbs up emoji
All reactions
  • 👍 1 reaction

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

@ngoldbaum

ngoldbaum commented Apr 16, 2026

Copy link
Copy Markdown
Contributor

Looking again, maybe it's because CFFI's headers define Py_LIMITED_API but don't set a value:

https://github.com/python-cffi/cffi/blob/5285ae32c9cc1e34b1dd7d50aa6f5294feb4c0d0/src/cffi/_cffi_include.h#L52

All reactions

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

@vstinner

vstinner commented Apr 16, 2026

Copy link
Copy Markdown
Member

buildbot/AMD64 FreeBSD PR
buildbot/AMD64 FreeBSD14 PR
buildbot/s390x Fedora Stable Clang Installed PR
buildbot/s390x Fedora Stable Clang PR
buildbot/x86-64 MacOS Intel NoGIL PR

test_cext.test_build_abi3t() failed. All of these buildbot workers use Clang as the C compiler.

I suppose that the issue can be reproduced with CC=clang CXX=clang++ ./python -m test test_cext -u all -v -m test_build_abi3t.

Example on "buildbot/AMD64 FreeBSD PR":

Building wheels for collected packages: internal__test_abi3t
  Building wheel for internal__test_abi3t (pyproject.toml): started
  Running command Building wheel for internal__test_abi3t (pyproject.toml)
  CC env var: 'cc -pthread'
  CFLAGS env var: <missing>
  CPPFLAGS env var: <missing>
  extra_compile_args: ['-Werror', '-D_Py_IS_TESTCEXT', '-Wcast-qual', '-pedantic-errors', '-Werror=declaration-after-statement', '-DMODULE_NAME=_test_abi3t', '-DPy_TARGET_ABI3T=0x30f00a8']
  running bdist_wheel
  running build
  running build_ext
  building '_test_abi3t' extension
  creating build/temp.freebsd-13.5-RELEASE-p10-amd64-cpython-315-pydebug
  cc -pthread -fno-strict-overflow -Wsign-compare -g -Og -Wall -fPIC -I/buildbot/buildarea/pull_request.ware-freebsd/build/build/test_python_81305æ/tempcwd/env/include -I/buildbot/buildarea/pull_request.ware-freebsd/build/Include -I/buildbot/buildarea/pull_request.ware-freebsd/build -c extension.c -o build/temp.freebsd-13.5-RELEASE-p10-amd64-cpython-315-pydebug/extension.o -Werror -D_Py_IS_TESTCEXT -Wcast-qual -pedantic-errors -Werror=declaration-after-statement -DMODULE_NAME=_test_abi3t -DPy_TARGET_ABI3T=0x30f00a8
  In file included from extension.c:13:
  In file included from /buildbot/buildarea/pull_request.ware-freebsd/build/Include/Python.h:79:
  /buildbot/buildarea/pull_request.ware-freebsd/build/Include/object.h:126:16: error: attempt to use a poisoned identifier
    126 | #elif !defined(Py_GIL_DISABLED)
        |                ^
  In file included from extension.c:13:
  In file included from /buildbot/buildarea/pull_request.ware-freebsd/build/Include/Python.h:80:
  /buildbot/buildarea/pull_request.ware-freebsd/build/Include/refcount.h:342:15: error: attempt to use a poisoned identifier
    342 | #elif defined(Py_GIL_DISABLED) && defined(Py_REF_DEBUG)
        |               ^
  In file included from extension.c:13:
  In file included from /buildbot/buildarea/pull_request.ware-freebsd/build/Include/Python.h:128:
  /buildbot/buildarea/pull_request.ware-freebsd/build/Include/modsupport.h:117:15: error: attempt to use a poisoned identifier
    117 | #elif defined(Py_GIL_DISABLED)
        |               ^
  3 errors generated.
  error: command '/usr/local/libexec/ccache/cc' failed with exit code 1
  error: subprocess-exited-with-error

I can reproduce the issue on Fedora with Clang on this short program:

#define Py_TARGET_ABI3T 0x30f00a8
#pragma GCC poison Py_GIL_DISABLED

#ifdef Py_TARGET_ABI3T
#  define _Py_OPAQUE_PYOBJECT
#endif

int main()
{
#ifdef _Py_OPAQUE_PYOBJECT
    // All good
    return 0;
#elif defined(Py_GIL_DISABLED)
    // Not good
    return 1;
#endif
    return 0;
}

Clang output:

x.c:13:15: error: attempt to use a poisoned identifier
   13 | #elif defined(Py_GIL_DISABLED)
      |               ^
1 error generated.

The workaround is to write:

#ifdef _Py_OPAQUE_PYOBJECT
    // All good
    return 0;
#else
#  if defined(Py_GIL_DISABLED)
    // Not good
    return 1;
#  endif
#endif

ARM Raspbian PR

test.test_io.test_fileio failed: waiting for #148648 fix.

All reactions

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

@vstinner

vstinner commented Apr 16, 2026

Copy link
Copy Markdown
Member

Looking again, maybe it's because CFFI's headers define Py_LIMITED_API but don't set a value:
https://github.com/python-cffi/cffi/blob/5285ae32c9cc1e34b1dd7d50aa6f5294feb4c0d0/src/cffi/_cffi_include.h#L52

Oh, maybe we can set the Py_LIMITED_API macro value to 3 if the macro is empty or if its value is smaller than 3, with a warning:

#if Py_LIMITED_API+0 < 3
#  warning "Py_LIMITED_API macro value must be at least 3"
#  undef Py_LIMITED_API
#  define Py_LIMITED_API 3
#endif
All reactions

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

@ngoldbaum

ngoldbaum commented Apr 16, 2026 •
edited
Loading

Uh oh!

There was an error while loading. Please reload this page.

Copy link
Copy Markdown
Contributor

@mgorny and I were also looking at the stable-abi-testing repo and got into a situation where "weird" things happen if you define Py_TARGET_ABI3T but don't define Py_LIMITED_API. IMO it'd be more helpful if Python's headers could trigger a build error if you don't explicitly set Py_LIMITED_API when Py_TARGET_ABI3T is set.

All reactions

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

encukou added 4 commits April 17, 2026 15:22
@encukou
Merge in the main branch
38950b8
@encukou
Don't poison on clang
c477a14
@encukou
Error out if _Py_OPAQUE_PYOBJECT is defined by user
05e7c90
@encukou
Require version in Py_LIMITED_API & Py_TARGET_ABI3T
72b1637
@encukou encukou added the 🔨 test-with-buildbots Test PR w/ buildbots; report in status section label Apr 21, 2026
@bedevere-bot

bedevere-bot commented Apr 21, 2026

Copy link
Copy Markdown

🤖 New build scheduled with the buildbot fleet by @encukou for commit 72b1637 🤖

Results will be shown at:

https://buildbot.python.org/all/#/grid?branch=refs%2Fpull%2F148302%2Fmerge

If you want to schedule another build, you need to add the 🔨 test-with-buildbots label again.

All reactions

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

@bedevere-bot bedevere-bot removed the 🔨 test-with-buildbots Test PR w/ buildbots; report in status section label Apr 21, 2026
@encukou

encukou commented Apr 22, 2026

Copy link
Copy Markdown
Member Author

RHEL8 changes are unrelated. (I'll remove them from the 🔨 test-with-buildbots set, but probably not before beta.)

I'm planning to merge this PR soon, and base Windows changes & further tests on it.

ngoldbaum reacted with thumbs up emoji
All reactions
  • 👍 1 reaction

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

@encukou
encukou merged commit ab41a34 into python:main Apr 23, 2026
117 of 124 checks passed

Uh oh!

There was an error while loading. Please reload this page.

@bedevere-app bedevere-app Bot removed the awaiting core review label Apr 23, 2026
@encukou
encukou deleted the abi3t-pygildisabled branch April 23, 2026 09:52
ljfp pushed a commit to ljfp/cpython that referenced this pull request Apr 25, 2026
@encukou @vstinner @ljfp
pythongh-146636: Improve ABI/feature selection, add new header for it (…
8abf101
…pythonGH-148302)

Improve ABI/feature selection, add new header for it.

Add a test that Python headers themselves don't use
Py_GIL_DISABLED in abi3t: abi3 and abi3t ought to be the
same except the _Py_OPAQUE_PYOBJECT differences.
This is done using the GCC-only poison pragma.

Co-authored-by: Victor Stinner <[email protected]>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Reviewers

@vstinner vstinner vstinner left review comments
@erlend-aasland erlend-aasland Awaiting requested review from erlend-aasland erlend-aasland is a code owner
@AA-Turner AA-Turner Awaiting requested review from AA-Turner AA-Turner is a code owner
@emmatyping emmatyping Awaiting requested review from emmatyping emmatyping is a code owner

Uh oh!

There was an error while loading. Please reload this page.

Assignees

No one assigned

Labels

None yet

Projects

None yet

Milestone

No milestone

Development

Successfully merging this pull request may close these issues.

PEP 803: Py_GIL_DISABLED is tested prior to setting, in patchlevel.h

Uh oh!

There was an error while loading. Please reload this page.

4 participants

@encukou @bedevere-bot @ngoldbaum @vstinner
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
You are visitor 01402503 — GeezerVison does not store the pages you look up.
Best viewed with Netscape Navigator 4.7 or Internet Explorer 6 at 800×600. No cookies required.