-
Notifications
You must be signed in to change notification settings - Fork 2.1k
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
casting c++-base class to py-derived class failes #1640
Comments
Hi!
you are comparing
You are assigning is this a typo? |
Hi, yes that was a typo, sorry for that. |
Howdy @TillLeiden! Since you want to have a Python class inherit from a C++ base class, there might be a few things:
|
The idea here is that one would like to "enhance" a C++ class in Python, then take produced C++ classes and cast them to the enhanced Python classes. So you want the assignment, not a check. For example, your c++ code produces an instance of CClass. You want to give a PClass to the user, without making a copy of the underlying class. I assume this is a clash related to |
@TillLeiden, you should get the same behavior if you remove all the Python inits and just put from cpp_module import CClass
# Python enhanced version
class PClass(CClass):
pass
c_class = CClass()
c_class.__class__ = PClass # this fails |
@henryiii Per convo on Gitter, it sounds like you also want to be able to extend it to multiple classes on-the-fly? But yeah, understanding this better, yes, it is a class with Since this the reassignment is done after construction time, there's now a discrepancy between the recorded type metadata (see Let me see if making it an actual trampoline resolves the error about deallocator mismatch (which looks like it's CPython, not pybind). |
Yeah, making the base class a trampoline does not work with the hot-swapping: So yeah, if you want something like this to really work with casting, these are the only three routes I can think of at the moment: Route 1 - Modify pybind source to fix the dealloc errorThis won't be fun, but may be fruitful if it doesn't mess up anything else? Route 2 - Explicitly Wrap / UnwrapUse something like If your types have a very specific trait, e.g. they inherit from something or whatevs that can be If your types do not have a specific trait, you will need to either shadow the specialization that calls into pybind11/include/pybind11/cast.h Line 936 in bd24155
Or (more suggested) explicitly wrap your types / casters. I had done so here: RobotLocomotion/drake#7793 (comment) Route 3 - Automagically Wrap / Unwrap by Modifying pybind sourceModify the
Then you can modify Routes 1 and 2 (if your classes have specific traits) sound somewhat feasible. Otherwise, seems less so... |
Issue description
Hello,
Consider a derived py-class (PClass) with a C++ class as base class (CClass).
If I want cast a CClass-Object to a PClass-Object, python gives me the following error:
TypeError: class assignment: 'PClass' deallocator differs from 'cpp_module.CClass'
I tested this with python3, clang-6.0, gcc 5.4, c++11 and c++17
Reproducible example code
working example with python
failing example with C++
output
The text was updated successfully, but these errors were encountered: