-
-
Notifications
You must be signed in to change notification settings - Fork 32.3k
gh-111506: Add _Py_OPAQUE_PYOBJECT to hide PyObject layout & related API #136505
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
Conversation
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.
We can also test this (with a workaround/hack in the test for the missing part). |
🤖 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. |
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. |
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.
I like the overall approach of the _Py_OPAQUE_PYOBJECT macro. I'm fine with testing it in test_cext.
Lib/test/test_cext/__init__.py
Outdated
# 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): |
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.
I suggest to rename "opaque" to "opaque_pyobject" (also in _check_build).
Lib/test/test_cext/setup.py
Outdated
@@ -45,6 +45,9 @@ def main(): | |||
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", "")) |
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.
I suggest to rename opaque to opaque_pyobject.
Lib/test/test_cext/setup.py
Outdated
@@ -75,6 +78,12 @@ def main(): | |||
version = sys.hexversion | |||
cflags.append(f'-DPy_LIMITED_API={version:#x}') | |||
|
|||
# Define _Py_OPAQUE_PYOBJECT macro | |||
if opaque: | |||
version = sys.hexversion |
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.
version is not used, it can be removed.
Make it so that defining
_Py_OPAQUE_PYOBJECT
before including<Python.h>
will make thePyObject
struct opaque, and hide all limited-API structs & functions that need access to it.Also, allow
Py_LIMITED_API
withPy_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.--disable-gil
builds are not compatible with the limited API #111506