-
Notifications
You must be signed in to change notification settings - Fork 42
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
Regression in passing buffers through void *
with Python 3.13
#272
Comments
The `IsCTypesArrayOrPointer` gives false positives in Python 3.13, resulting the void pointer converter to take the wrong code path and crash. See: wlav/cppyy#272 This code path is used for implicit conversion from other `ctypes` pointer types to `void*`, which is not strictly required. One can always do an explicit cast: `ctypes.cast(my_ptr, ctypes.c_void_p )`. Given that this a niche feature that broke Python 3.13 support for functions taking `void*`, which is quite common, it can be argued that it's better to remove this implicit conversion. This commit fixes the following tests under Python 3.13: ``` roottest-python-basic-datatype roottest-python-cpp-cpp ``` This reverts the following commit from upstream: wlav/CPyCppyy@80a0205
The `IsCTypesArrayOrPointer` gives false positives in Python 3.13, resulting the void pointer converter to take the wrong code path and crash. See: wlav/cppyy#272 This code path is used for implicit conversion from other `ctypes` pointer types to `void*`, which is not strictly required. One can always do an explicit cast: `ctypes.cast(my_ptr, ctypes.c_void_p )`. Given that this a niche feature that broke Python 3.13 support for functions taking `void*`, which is quite common, it can be argued that it's better to remove this implicit conversion. This commit fixes the following tests under Python 3.13: ``` roottest-python-basic-datatype roottest-python-cpp-cpp ``` This reverts the following commit from upstream: wlav/CPyCppyy@80a0205
The `IsCTypesArrayOrPointer` gives false positives in Python 3.13, resulting the void pointer converter to take the wrong code path and crash. See: wlav/cppyy#272 This code path is used for implicit conversion from other `ctypes` pointer types to `void*`, which is not strictly required. One can always do an explicit cast: `ctypes.cast(my_ptr, ctypes.c_void_p )`. Given that this a niche feature that broke Python 3.13 support for functions taking `void*`, which is quite common, it can be argued that it's better to remove this implicit conversion. This commit fixes the following tests under Python 3.13: ``` roottest-python-basic-datatype roottest-python-cpp-cpp ``` This reverts the following commit from upstream: wlav/CPyCppyy@80a0205
The `IsCTypesArrayOrPointer` gives false positives in Python 3.13, resulting the void pointer converter to take the wrong code path and crash. See: wlav/cppyy#272 This code path is used for implicit conversion from other `ctypes` pointer types to `void*`, which is not strictly required. One can always do an explicit cast: `ctypes.cast(my_ptr, ctypes.c_void_p )`. Given that this a niche feature that broke Python 3.13 support for functions taking `void*`, which is quite common, it can be argued that it's better to remove this implicit conversion. This commit fixes the following tests under Python 3.13: ``` roottest-python-basic-datatype roottest-python-cpp-cpp ``` This reverts the following commit from upstream: wlav/CPyCppyy@80a0205
The `IsCTypesArrayOrPointer` gives false positives in Python 3.13, resulting the void pointer converter to take the wrong code path and crash. See: wlav/cppyy#272 This code path is used for implicit conversion from other `ctypes` pointer types to `void*`, which is not strictly required. One can always do an explicit cast: `ctypes.cast(my_ptr, ctypes.c_void_p )`. Given that this a niche feature that broke Python 3.13 support for functions taking `void*`, which is quite common, it can be argued that it's better to remove this implicit conversion. This commit fixes the following tests under Python 3.13: ``` roottest-python-basic-datatype roottest-python-cpp-cpp ``` This reverts the following commit from upstream: wlav/CPyCppyy@80a0205
The `IsCTypesArrayOrPointer` gives false positives in Python 3.13, resulting the void pointer converter to take the wrong code path and crash. See: wlav/cppyy#272 This code path is used for implicit conversion from other `ctypes` pointer types to `void*`, which is not strictly required. One can always do an explicit cast: `ctypes.cast(my_ptr, ctypes.c_void_p )`. Given that this a niche feature that broke Python 3.13 support for functions taking `void*`, which is quite common, it can be argued that it's better to remove this implicit conversion. This commit fixes the following tests under Python 3.13: ``` roottest-python-basic-datatype roottest-python-cpp-cpp ``` This reverts the following commit from upstream: wlav/CPyCppyy@80a0205
The reason why it worked was that ctypes' types have had a custom dictionary type ( From the py3.13 code, the proper way of checking would now be a |
Ah ok I suspected something like that! Great that you found the |
It's not in the docs (I'm sure; haven't actually looked) b/c |
It's actually not used as a type base class, but as a meta type and their doesn't seem to be any hierarchy of meta types. Ie., a simple test w/o needing to copy/expose any functions from |
Looks like there was more to it than just convenience: the dict-checking trick also covered pointer types which are created at runtime and which are not part (as such) of |
void *
with Python 3.13void *
with Python 3.13
Should work now. I found no better way than to copy the state definition. I'd rather pick the metatype from one of the existing types (as that would not involve code copying), but the modules (and types) associated with pointers are those where and from what they are created at run-time, making that unreliable. (Note that even for getting the state, the relevant module is |
Credit goes to Wim Lavrijsen (@wlav). See also: wlav/cppyy#272.
Thank you so much for you updates! With my previous hotfixes, we could already add Fedora 41 with Python 3.13 in the CI. I'm checking now if everything works with your solution: |
I'm down to 2 leak checks failing on py3.13 that don't under other pythons; then 4 more tests that are failing b/c of Clang 16 (3 related to not keeping |
Good to hear! On our side, I don't see any regressions anymore due to Python 3.13 for whatever test coverage we have :) So we're shifting the effort again towards general PyROOT improvements. Especially for the memory regulator, that regular comes to bite us (see root-project/root#16837). We also discussed with Vassil at the last Tuesday meeting that we have to do a general revamp of how ROOT is initialized, since it's too implicit. |
Credit goes to Wim Lavrijsen (@wlav). See also: wlav/cppyy#272.
Credit goes to Wim Lavrijsen (@wlav). See also: wlav/cppyy#272.
Credit goes to Wim Lavrijsen (@wlav). See also: wlav/cppyy#272.
Reproducer:
I investigated the problem a bit, and it turns out the
IsCTypesArrayOrPointer()
is giving a false positive, resulting in the wrong code path being taken:https://github.com/wlav/CPyCppyy/blob/master/src/Converters.cxx#L1510
@wlav, do you have any idea on how to improve this function? I don't understand its implementation, unfortunately. How does relate comparing the type of the extended dictionary (
Py_TYPE(pytype->tp_dict)
) into figuring out whether it's a ctype or not? Is thePyTYPE
of a dictionary not always a dictionary anyway, therefore resulting in the false positive?The text was updated successfully, but these errors were encountered: