Skip to content

Issue with PyObject_DelAttr[String] in stable ABI builds targeting older CPython versions #134989

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

Closed
wjakob opened this issue Jun 1, 2025 · 8 comments
Labels
interpreter-core (Objects, Python, Grammar, and Parser dirs) topic-C-API type-bug An unexpected behavior, bug, or error

Comments

@wjakob
Copy link
Contributor

wjakob commented Jun 1, 2025

Bug report

Bug description:

To my knowledge, one can use newer Python version (e.g. Python 3.13) to build C extensions for older Python versions (e.g. 3.12) when targeting the stable ABI. This is accomplished by setting Py_LIMITED_API to a suitable number like 0x030b0000, which simply disables all features beyond this cutoff.

If this understanding is correct, then I would like to report a bug:

Python 3.13 added an new C API function for PyObject_DelAttr(). In contrast, Python 3.12 realized this operation using a macro wrapping PyObject_SetAttr():

#define  PyObject_DelAttr(O, A) PyObject_SetAttr((O), (A), NULL)

This change is problematic: extensions built on 3.13 targeting 3.12 stable ABI will now call a function that does not exist on Python 3.12, and such extensions will fail to load with a linker error. The change to the new C API entry point should have been guarded with #ifdefs.

This issue also affects PyObject_DelAttrString().

CPython versions tested on:

3.13

Operating systems tested on:

Linux

Linked PRs

@ZeroIntensity
Copy link
Member

cc @vstinner

@somik861
Copy link

somik861 commented Jun 2, 2025

Same behaviour also on Windows 11.

@vstinner
Copy link
Member

vstinner commented Jun 2, 2025

I wrote PR #135021 to fix the regression.

@wjakob: Do you think that you can try the PR to see if it does fix your issue?

@wjakob
Copy link
Contributor Author

wjakob commented Jun 2, 2025

This works! However, would it not be safer to also wrap the declaration of PyObject_DelAttr "elsewhere" so that it is entirely avoided if the following preprocessor condition holds: defined(Py_LIMITED_API) && Py_LIMITED_API+0 < 0x030d0000?

I am concerned that a user might include files in such a way that the macro rewrites the declaration. Maybe you already thought about this, and it is not possible.

@vstinner
Copy link
Member

vstinner commented Jun 2, 2025

This works!

Cool. Thanks for testing!

However, would it not be safer to also wrap the declaration of PyObject_DelAttr "elsewhere" so that it is entirely avoided if the following preprocessor condition holds: defined(Py_LIMITED_API) && Py_LIMITED_API+0 < 0x030d0000?
I am concerned that a user might include files in such a way that the macro rewrites the declaration. Maybe you already thought about this, and it is not possible.

The Python C API requires to only include <Python.h>. Including other header files is not supported. My PR changes Include/abstract.h which is included by <Python.h>.

miss-islington pushed a commit to miss-islington/cpython that referenced this issue Jun 4, 2025
…ed C API (pythonGH-135021)

(cherry picked from commit c211130)

Co-authored-by: Victor Stinner <vstinner@python.org>
vstinner added a commit to vstinner/cpython that referenced this issue Jun 4, 2025
vstinner added a commit that referenced this issue Jun 4, 2025
…ted C API (GH-135021) (#135133)

gh-134989: Implement PyObject_DelAttr() as a macro in the limited C API (GH-135021)
(cherry picked from commit c211130)

Co-authored-by: Victor Stinner <vstinner@python.org>
@colesbury
Copy link
Contributor

To my knowledge, one can use newer Python version ... to build C extensions for older Python versions when targeting the stable ABI

The Py_RETURN_NONE and similar macros are broken if you are building with 3.12+ and targeting <=3.11 because they are missing the required Py_INCREF/Py_NewRef calls when running on Python versions that don't have immortal Py_None, etc. objects.

vstinner added a commit that referenced this issue Jun 4, 2025
…ted C API (GH-135021) (#135134)

gh-134989: Implement PyObject_DelAttr() as a macro in the limited C API (GH-135021)

(cherry picked from commit c211130)
vstinner added a commit to vstinner/cpython that referenced this issue Jun 5, 2025
Don't treat Py_None, Py_True and Py_False as immortal in the limited
C API 3.11 and older.
vstinner added a commit to vstinner/cpython that referenced this issue Jun 5, 2025
Don't treat Py_None, Py_True and Py_False as immortal in the limited
C API 3.11 and older.
@vstinner
Copy link
Member

vstinner commented Jun 5, 2025

The Py_RETURN_NONE and similar macros are broken if you are building with 3.12+ and targeting <=3.11 because they are missing the required Py_INCREF/Py_NewRef calls when running on Python versions that don't have immortal Py_None, etc. objects.

Oh right, I wrote #135165 to fix these macros.

vstinner added a commit to vstinner/cpython that referenced this issue Jun 5, 2025
Fix Py_RETURN_NONE, Py_RETURN_TRUE and Py_RETURN_FALSE macros in the
limited C API 3.11 and older: don't treat Py_None, Py_True and
Py_False as immortal.
encukou pushed a commit that referenced this issue Jun 5, 2025
Fix Py_RETURN_NONE, Py_RETURN_TRUE and Py_RETURN_FALSE macros in the
limited C API 3.11 and older:
Don't treat Py_None, Py_True and Py_False as immortal.
miss-islington pushed a commit to miss-islington/cpython that referenced this issue Jun 5, 2025
…5165)

Fix Py_RETURN_NONE, Py_RETURN_TRUE and Py_RETURN_FALSE macros in the
limited C API 3.11 and older:
Don't treat Py_None, Py_True and Py_False as immortal.
(cherry picked from commit 9258f3d)

Co-authored-by: Victor Stinner <vstinner@python.org>
vstinner added a commit that referenced this issue Jun 5, 2025
…#135178)

gh-134989: Fix Py_RETURN_NONE in the limited C API (GH-135165)

Fix Py_RETURN_NONE, Py_RETURN_TRUE and Py_RETURN_FALSE macros in the
limited C API 3.11 and older:
Don't treat Py_None, Py_True and Py_False as immortal.
(cherry picked from commit 9258f3d)

Co-authored-by: Victor Stinner <vstinner@python.org>
vstinner added a commit to vstinner/cpython that referenced this issue Jun 5, 2025
…5165)

Fix Py_RETURN_NONE, Py_RETURN_TRUE and Py_RETURN_FALSE macros in the
limited C API 3.11 and older:
Don't treat Py_None, Py_True and Py_False as immortal.

(cherry picked from commit 9258f3d)
vstinner added a commit that referenced this issue Jun 5, 2025
…#135182)

gh-134989: Fix Py_RETURN_NONE in the limited C API (GH-135165)

Fix Py_RETURN_NONE, Py_RETURN_TRUE and Py_RETURN_FALSE macros in the
limited C API 3.11 and older:
Don't treat Py_None, Py_True and Py_False as immortal.

(cherry picked from commit 9258f3d)
@vstinner vstinner closed this as completed Jun 6, 2025
@vstinner
Copy link
Member

vstinner commented Jun 6, 2025

Fixed. Thanks for the report @wjakob.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
interpreter-core (Objects, Python, Grammar, and Parser dirs) topic-C-API type-bug An unexpected behavior, bug, or error
Projects
None yet
Development

No branches or pull requests

6 participants