You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
C API: PyType_FromSpec(): __vectorcalloffset__ (and other special offset members) does not support Py_RELATIVE_OFFSET #123465
When declaring members of custom types via PyType_FromSpec(), it is advisable to rely on Py_RELATIVE_OFFSET to declare their position using a relative byte offset.
This is needed to create portable stable API / limited ABI extensions since we don't need to make assumptions about the layout of the base type, and how Python concatenates the two (e.g. is there intermediate padding/alignment?)
In addition, one can specify a special member called __vectorcalloffset__ to declare the byte offset of a pointer that implements a vector call handler.
Unfortunately, these two features don't work together. That is bad news for anyone who wants to extend an opaque type (e.g. PyTypeObject) and add the ability to dispatch vector calls. I ran into this issue while looking for temporary workarounds for #100554.
This extension creates a metaclass Meta that declares tp_call and vector call, along with a type Class created using this metaclass. It specifies the __vectorcalloffset__ using one of two different ways:
Compiling this extension with #define TRIGGER_BUG 1 and instantiating Class shows that the tp_call path is used.
Python 3.12.5 (main, Aug 6 2024, 19:08:49) [Clang 15.0.0 (clang-1500.1.0.2.5)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> from vectorcall_issue import Class
>>> Class()
Constructing using tp_call
<vectorcall_issue.Class object at 0x102faca10>
>>>
If I switch over from a relative to an absolute byte offset (change #define TRIGGER_BUG 1 to #define TRIGGER_BUG 0 at the top), the vector call is used. But that is not portable.
Python 3.12.5 (main, Aug 6 2024, 19:08:49) [Clang 15.0.0 (clang-1500.1.0.2.5)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> from vectorcall_issue import Class
>>> Class()
Constructing using vector call
<vectorcall_issue.Class object at 0x102fb8a10>
changed the title [-]C API: `PyType_FromSpec()`: `__vectorcalloffset__` does not support `Py_RELATIVE_OFFSET`[/-][+]C API: `PyType_FromSpec()`: `__vectorcalloffset__` (and other special offset members) does not support `Py_RELATIVE_OFFSET`[/+]on Aug 29, 2024
Activity
wjakob commentedon Aug 29, 2024
cc @encukou
[-]C API: `PyType_FromSpec()`: `__vectorcalloffset__` does not support `Py_RELATIVE_OFFSET`[/-][+]C API: `PyType_FromSpec()`: `__vectorcalloffset__` (and other special offset members) does not support `Py_RELATIVE_OFFSET`[/+]pythongh-123465: Allow Py_RELATIVE_OFFSET for __*offset__ members
encukou commentedon Sep 3, 2024
@wjakob Do you want to check if #123474 fixes the issue?
wjakob commentedon Sep 3, 2024
It does, thank you!
gh-123465: Allow Py_RELATIVE_OFFSET for __*offset__ members (GH-123474)
gh-123465: Ensure PyType_FromMetaclass avoids extra strcmp (GH-125460)
pythongh-123465: Ensure PyType_FromMetaclass avoids extra strcmp (pyt…
pythongh-123465: Ensure PyType_FromMetaclass avoids extra strcmp (pyt…