-
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
[FEAT] Rework casting #2646
Comments
Yes, we're aware. Hopefully, this could be some project for pybind11 3.0. Thanks for the summary, though! |
To clarify: fixing bugs and adding minor features seems definitely possible before, ofc. But a full redesign/rework will take some time be breaking changes. |
I've created a new "holders" label, for everything related to this type of thing. This should make it easier to find back issues and PRs (as you can search for everything with this label:
holders
Please apply it (or ping me or send me a message or ...), if you find anything related! EDIT: The distinction with the already existing "casters" label isn't always obvious. Let's be careful, but in case of doubt, better have the two labels than none? |
Boost.Python observations (also relevant to the issues reported under #2672):
|
One question: Would we consider slicing to be under this umbrella? As we discussed in VC, in an ideal world, this would be decoupled. However, the mechanisms for handling single and multiple inheritance are coupled due to how casting works in conjunction with object lifetime. EDIT (@YannickJadoul): another issue about "slicing" or however we're going to call this, to be mentioned in this item: #1941 |
My take: it's a very important use case. It will be great if we can capture this in the redesign, too. Let's try how far we get, and drop it only if we cannot find a reasonable way to handle it? "Slicing" is a very overloaded term. It could help the discussion if we had a more descriptive / less ambiguous term, especially to attract contributions or opinions from outsiders. |
Aye, gotcha, I assume in the context of |
@rwgk suggestion: port each Boost.Python test to PyBind11. That should flush out anything we took care to get right in Boost.Python but that isn't handled by PyBind11. |
Hi @EricCousineau-TRI , @rhaschke , @YannickJadoul I wrote proof-of-concept code & tests for a "smart holder" (under #2672). It's a different kind of holder compared to current pybind11 semantics, but the purpose is very similar. Please see the comment at the top of the header file. I hope the links below work permanently (beyond the next force push to my fork). EDIT 2021-01-14: WARNING: this version of smart_holder_poc.h has a serious bug: it is neither copyable nor movable, but those mechanism are not disabled. I'm working on a fix: include/pybind11/smart_holder_poc.h: tests/core/smart_holder_poc_test.cpp: I tested the code with this command:
The tests systematically cover all combinations of
|
Hi again @EricCousineau-TRI , @rhaschke , @YannickJadoul Under my experimental PR #2672 I added a "type_caster bare interface demo" (thanks a lot @laramiel for the tests/test_type_caster_bare_interface_demo.cpp: tests/test_type_caster_bare_interface_demo.py: Bigger picture:
|
Under my experimental PR #2672 I added a "test_classh_wip" (wip = work in progress) that combines test_type_caster_bare_interface_demo & smart_holder_poc. All tests/test_classh_wip.cpp: https://github.com/pybind/pybind11/pull/2672/files#diff-6e1ab7ea62c6e8b556380e2c3288f905bf4a06633238c37088ea6be0ad8c5a79 tests/test_classh_wip.py: https://github.com/pybind/pybind11/pull/2672/files#diff-9a69dff06135fd95cd59536a893fa3f9e9367517590f84fe249d047029189b4a Thus far, the required changes between |
|
|
Recently @rwgk revived the discussion on supporting movable custom types (and holders), see #2583, #2040, #1132.
I want to summarize the discussion so far and structure the problem into several subproblems, in the hope that we can focus our future discussion on the corresponding subproblems.
Fix segfaults due to mismatching holder types, i.e. fixing pybind11 wrapped method segfaults if a function returns
unique_ptr<T>
when holder isshared_ptr<T>
#1138 and C++ object is destructed before it can be used, when returned as ashared_ptr
and using default holder type #1215.pybind11 assumes that holder types are used consistently, i.e. once registered, a custom type needs to stick with its holder type, let it be the default
unique_ptr
or any custom smart ptr. However, this basic assumption is not validated (yet) and thus can cause severe segfaults if users don't obey this rule.I think Detect and fail if using mismatched holders #2644 addresses this issue in a clean and efficient manner (building on the great work Detect and fail if using mismatched holders #1161 from @jagerman) by validating holder compatibility at function/class definition time (runtime).
Support moving (rvalue-reference arguments) for custom types, allowing to (easily) wrap functions like this:
This doesn't work out of the box (yet), but is in principle possible already right now, employing a small wrapper function as pointed out by @YannickJadoul in [WIP] Towards a solution for custom-type rvalue arguments #2047 (comment).
My PR [WIP] Towards a solution for custom-type rvalue arguments #2047 is an initial attempt to enable this feature. However, I recently detected an open issue with this approach.
EDIT: In a rework, I hopefully fixed the move/copy semantics. See here for details.
Support moving of holder types, i.e. ownership transfer from python to C++, allowing to wrap functions like this:
There are two possible implementations for this: WIP: Support ownership transfer between C++ and Python with
shared_ptr<T>
andunique_ptr<T>
for pure C++ instances and single-inheritance instances #1146 (rather huge) and Towards a solution for rvalue holder arguments in wrapped functions #2046. However, to quote @wjakob:If implementing this, we need to ensure that all python object references of the moved holder are validated before
loading
. For an open issues on this, see Towards a solution for rvalue holder arguments in wrapped functions #2046 (comment).A feature related to both 1. and 3. is the (implicit) conversion between different holder types as requested e.g. in Detect and fail if using mismatched holders #1161 (comment) and proposed in Detect and fail if using mismatched holders #1161 (comment): Instead of complaining about incompatible holder types, pybind11 should "just" auto-magically convert between them - if possible. For example,
std::shared_ptr
can be implicitly move-constructed from astd::unique_ptr
, which indeed would make sense for function return values, i.e. auto-converting astd::unique_ptr
return value into astd::shared_ptr
holder.But, in my opinion, this is the only valid use case. If 3. is in place, argument conversion can be easily handled explicitly with corresponding wrapper functions.
Instead of a silently auto-converting between holders, maybe a new
return_value_policy
could be used that specifies the target holder type and then - at compile time - just adds another wrapping layer to convert the return value?As pointed out by @YannickJadoul in [WIP] Towards a solution for custom-type rvalue arguments #2047 (comment), there are some more open issues with casters, e.g. passing containers of char * (e.g. std::vector<char *>) does not work #2245/Fix casters of STL containers with
char*
#2303/[BUG] Keep pybind11 type casters alive recursively when needed #2527, or Casting from an unregistered type does not throw. #2336.EDIT(eric): pybind11 inheritance slicing; see [BUG] Problem when creating derived Python objects from C++ (inheritance slicing) #1333 for an example. Including it here due to current coupling to holder setup.
The text was updated successfully, but these errors were encountered: