mirror of
https://github.com/pybind/pybind11.git
synced 2026-03-14 20:27:47 +00:00
Override deduced Base class when defining Derived methods
When defining method from a member function pointer (e.g. `.def("f",
&Derived::f)`) we run into a problem if `&Derived::f` is actually
implemented in some base class `Base` when `Base` isn't
pybind-registered.
This happens because the class type is deduced from the member function
pointer, which then becomes a lambda with first argument this deduced
type. For a base class implementation, the deduced type is `Base`, not
`Derived`, and so we generate and registered an overload which takes a
`Base *` as first argument. Trying to call this fails if `Base` isn't
registered (e.g. because it's an implementation detail class that isn't
intended to be exposed to Python) because the type caster for an
unregistered type always fails.
This commit adds a `method_adaptor` function that rebinds a member
function to a derived type member function and otherwise (i.e. regular
functions/lambda) leaves the argument as-is. This is now used for class
definitions so that they are bound with type being registered rather
than a potential base type.
A closely related fix in this commit is to similarly update the lambdas
used for `def_readwrite` (and related) to bind to the class type being
registered rather than the deduced type so that registering a property
that resolves to a base class member similarly generates a usable
function.
Fixes #854, #910.
Co-Authored-By: Dean Moldovan <dean0x7d@gmail.com>
This commit is contained in:
@@ -457,3 +457,23 @@ def test_str_issue(msg):
|
||||
|
||||
Invoked with: 'no', 'such', 'constructor'
|
||||
"""
|
||||
|
||||
|
||||
def test_unregistered_base_implementations():
|
||||
from pybind11_tests import RegisteredDerived
|
||||
|
||||
a = RegisteredDerived()
|
||||
a.do_nothing()
|
||||
assert a.rw_value == 42
|
||||
assert a.ro_value == 1.25
|
||||
a.rw_value += 5
|
||||
assert a.sum() == 48.25
|
||||
a.increase_value()
|
||||
assert a.rw_value == 48
|
||||
assert a.ro_value == 1.5
|
||||
assert a.sum() == 49.5
|
||||
assert a.rw_value_prop == 48
|
||||
a.rw_value_prop += 1
|
||||
assert a.rw_value_prop == 49
|
||||
a.increase_value()
|
||||
assert a.ro_value_prop == 1.75
|
||||
|
||||
Reference in New Issue
Block a user