Skip to content

[Python] Avoid hack in setting __reduce__ attribute of CPPInstance #19222

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

Open
wants to merge 1 commit into
base: master
Choose a base branch
from

Conversation

guitargeek
Copy link
Contributor

The CPPIntance type is immutable, and new attributes can't be set:

import cppyy
>>> setattr(cppyy._backend.CPPInstance, "test", 10)
Traceback (most recent call last):
  File "<python-input-3>", line 1, in <module>
    setattr(cppyy._backend.CPPInstance, "test", 10)
    ~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
TypeError: cannot set 'test' attribute of immutable type 'cppyy.CPPInstance'
>>>

In our pythonizations, we still want to monkey-patch a __reduce__ method anyway, and to make Python not complain we to a hack by setting the attribute with the C Python API using PyObject_GenericSetAttr. This function doesn't normally do any safety checks, and our monkey patching works.

However, the Python debug build is not having any of that, thanks to a new assert that was added a year ago:

https://github.com/python/cpython/blame/c419af9e277bea7dd78f4defefc752fe93b0b8ec/Objects/object.c#L1921

To make the ROOT Python interface work with debug builds of the Python interpreter, we therefore have to implement adding the reduce method properly.

This commit suggests to achieve this by defining the __reduce__ method in the immutable CPPInstance type within CPyCppyy, but in such a way that its implementation can be routed to ROOT via a private API.

Copy link

github-actions bot commented Jun 28, 2025

Test Results

    19 files      19 suites   3d 4h 24m 37s ⏱️
 3 066 tests  3 066 ✅ 0 💤 0 ❌
56 717 runs  56 717 ✅ 0 💤 0 ❌

Results for commit b0cb54c.

♻️ This comment has been updated with latest results.

The CPPIntance type is immutable, and new attributes can't be set:
```txt
import cppyy
>>> setattr(cppyy._backend.CPPInstance, "test", 10)
Traceback (most recent call last):
  File "<python-input-3>", line 1, in <module>
    setattr(cppyy._backend.CPPInstance, "test", 10)
    ~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
TypeError: cannot set 'test' attribute of immutable type 'cppyy.CPPInstance'
>>>
```

In our pythonizations, we still want to monkey-patch a `__reduce__`
method anyway, and to make Python not complain we to a hack by setting
the attribute with the C Python API using `PyObject_GenericSetAttr`.
This function doesn't normally do any safety checks, and our monkey
patching works.

However, the Python debug build is not having any of that, thanks to a
new assert that was added a year ago:

https://github.com/python/cpython/blame/c419af9e277bea7dd78f4defefc752fe93b0b8ec/Objects/object.c#L1921

To make the ROOT Python interface work with debug builds of the Python
interpreter, we therefore have to implement adding the reduce method
properly.

This commit suggests to achieve this by defining the `__reduce__` method
in the immutable CPPInstance type within CPyCppyy, but in such a way
that its implementation can be routed to ROOT via a private API.
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.

1 participant