Skip to content

Conversation

@encukou
Copy link
Member

@encukou encukou commented Jul 10, 2025

Make it so that defining _Py_OPAQUE_PYOBJECT before including <Python.h> will make the PyObject struct opaque, and hide all limited-API structs & functions that need access to it.

Also, allow Py_LIMITED_API with Py_GIL_DISABLED if _Py_OPAQUE_PYOBJECT is defined.

Opaque PyObject will be needed for most alternatives we have of defining a Stable ABI for free-threaded builds. See Discourse thread for discussion. (We may want to either expose this to users as Py_OPAQUE_PYOBJECT, or define it implicitly for limited-API free-threaded builds.)
And if I'm wrong -- this is easy to remove, like like Py_GIL_DISABLED.

As I mentioned, I'd like to put this in main to avoid rebasing a fork and to make it easier to build on top.

encukou added 2 commits July 10, 2025 13:12
API that's removed when _Py_OPAQUE_PYOBJECT is defined:

    - PyObject_HEAD
    - _PyObject_EXTRA_INIT
    - PyObject_HEAD_INIT
    - PyObject_VAR_HEAD
    - struct _object (i.e. PyObject) (opaque)
    - struct PyVarObject (opaque)
    - Py_SIZE
    - Py_SET_TYPE
    - Py_SET_SIZE
    - PyModuleDef_Base (opaque)
    - PyModuleDef_HEAD_INIT
    - PyModuleDef (opaque)
    - _Py_IsImmortal
    - _Py_IsStaticImmortal

Note that the `_Py_IsImmortal` removal means _Py_OPAQUE_PYOBJECT
only works with limited API 3.14+ now.
@encukou
Copy link
Member Author

encukou commented Jul 11, 2025

We can also test this (with a workaround/hack in the test for the missing part).

@bedevere-bot
Copy link

🤖 New build scheduled with the buildbot fleet by @encukou for commit 33d9ae7 🤖

Results will be shown at:

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

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

@bedevere-bot bedevere-bot removed the 🔨 test-with-buildbots Test PR w/ buildbots; report in status section label Jul 11, 2025
@encukou
Copy link
Member Author

encukou commented Jul 11, 2025

The tests aren't that straightforward, but the workaround can still be removed if we either scrap the “opaque PyObject” idea or implement PEP 793.
@vstinner, are you OK with having this workaround in tests in main, it order to test that Python.h compiles with opaque PyObject (and except for PyModuleDef, it can produce working extensions)?

Copy link
Member

@vstinner vstinner left a comment

Choose a reason for hiding this comment

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

I like the overall approach of the _Py_OPAQUE_PYOBJECT macro. I'm fine with testing it in test_cext.

# Test with _Py_OPAQUE_PYOBJECT
self.check_build('_test_limited_opaque_cext', limited=True, opaque=True)

def check_build(self, extension_name, std=None, limited=False, opaque=False):
Copy link
Member

Choose a reason for hiding this comment

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

I suggest to rename "opaque" to "opaque_pyobject" (also in _check_build).

std = os.environ.get("CPYTHON_TEST_STD", "")
module_name = os.environ["CPYTHON_TEST_EXT_NAME"]
limited = bool(os.environ.get("CPYTHON_TEST_LIMITED", ""))
opaque = bool(os.environ.get("CPYTHON_TEST_OPAQUE_PYOBJECT", ""))
Copy link
Member

Choose a reason for hiding this comment

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

I suggest to rename opaque to opaque_pyobject.


# Define _Py_OPAQUE_PYOBJECT macro
if opaque:
version = sys.hexversion
Copy link
Member

Choose a reason for hiding this comment

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

version is not used, it can be removed.

@encukou encukou merged commit c7d24b8 into python:main Jul 12, 2025
39 checks passed
@encukou encukou deleted the opaque-pyobject-priv branch July 12, 2025 07:55
Pranjal095 pushed a commit to Pranjal095/cpython that referenced this pull request Jul 12, 2025
…lated API (pythonGH-136505)

Allow Py_LIMITED_API for (Py_GIL_DISABLED && _Py_OPAQUE_PYOBJECT)


API that's removed when _Py_OPAQUE_PYOBJECT is defined:

    - PyObject_HEAD
    - _PyObject_EXTRA_INIT
    - PyObject_HEAD_INIT
    - PyObject_VAR_HEAD
    - struct _object (i.e. PyObject) (opaque)
    - struct PyVarObject (opaque)
    - Py_SIZE
    - Py_SET_TYPE
    - Py_SET_SIZE
    - PyModuleDef_Base (opaque)
    - PyModuleDef_HEAD_INIT
    - PyModuleDef (opaque)
    - _Py_IsImmortal
    - _Py_IsStaticImmortal

Note that the `_Py_IsImmortal` removal (and a few other issues)
 means _Py_OPAQUE_PYOBJECT only works with limited
API 3.14+ now.


Co-authored-by: Victor Stinner <vstinner@python.org>
picnixz pushed a commit to picnixz/cpython that referenced this pull request Jul 13, 2025
…lated API (pythonGH-136505)

Allow Py_LIMITED_API for (Py_GIL_DISABLED && _Py_OPAQUE_PYOBJECT)


API that's removed when _Py_OPAQUE_PYOBJECT is defined:

    - PyObject_HEAD
    - _PyObject_EXTRA_INIT
    - PyObject_HEAD_INIT
    - PyObject_VAR_HEAD
    - struct _object (i.e. PyObject) (opaque)
    - struct PyVarObject (opaque)
    - Py_SIZE
    - Py_SET_TYPE
    - Py_SET_SIZE
    - PyModuleDef_Base (opaque)
    - PyModuleDef_HEAD_INIT
    - PyModuleDef (opaque)
    - _Py_IsImmortal
    - _Py_IsStaticImmortal

Note that the `_Py_IsImmortal` removal (and a few other issues)
 means _Py_OPAQUE_PYOBJECT only works with limited
API 3.14+ now.


Co-authored-by: Victor Stinner <vstinner@python.org>
taegyunkim pushed a commit to taegyunkim/cpython that referenced this pull request Aug 4, 2025
…lated API (pythonGH-136505)

Allow Py_LIMITED_API for (Py_GIL_DISABLED && _Py_OPAQUE_PYOBJECT)


API that's removed when _Py_OPAQUE_PYOBJECT is defined:

    - PyObject_HEAD
    - _PyObject_EXTRA_INIT
    - PyObject_HEAD_INIT
    - PyObject_VAR_HEAD
    - struct _object (i.e. PyObject) (opaque)
    - struct PyVarObject (opaque)
    - Py_SIZE
    - Py_SET_TYPE
    - Py_SET_SIZE
    - PyModuleDef_Base (opaque)
    - PyModuleDef_HEAD_INIT
    - PyModuleDef (opaque)
    - _Py_IsImmortal
    - _Py_IsStaticImmortal

Note that the `_Py_IsImmortal` removal (and a few other issues)
 means _Py_OPAQUE_PYOBJECT only works with limited
API 3.14+ now.


Co-authored-by: Victor Stinner <vstinner@python.org>
Agent-Hellboy pushed a commit to Agent-Hellboy/cpython that referenced this pull request Aug 19, 2025
…lated API (pythonGH-136505)

Allow Py_LIMITED_API for (Py_GIL_DISABLED && _Py_OPAQUE_PYOBJECT)


API that's removed when _Py_OPAQUE_PYOBJECT is defined:

    - PyObject_HEAD
    - _PyObject_EXTRA_INIT
    - PyObject_HEAD_INIT
    - PyObject_VAR_HEAD
    - struct _object (i.e. PyObject) (opaque)
    - struct PyVarObject (opaque)
    - Py_SIZE
    - Py_SET_TYPE
    - Py_SET_SIZE
    - PyModuleDef_Base (opaque)
    - PyModuleDef_HEAD_INIT
    - PyModuleDef (opaque)
    - _Py_IsImmortal
    - _Py_IsStaticImmortal

Note that the `_Py_IsImmortal` removal (and a few other issues)
 means _Py_OPAQUE_PYOBJECT only works with limited
API 3.14+ now.


Co-authored-by: Victor Stinner <vstinner@python.org>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants