-
Notifications
You must be signed in to change notification settings - Fork 170
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
Support enable_shared_from_this #212
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is beautiful work, thank you a lot! Just a few tiny comments/requests, then this can go in.
slightly larger than bindings for a class that doesn't, as nanobind | ||
must produce type-specific code to implement the above behaviors. | ||
|
||
.. warning:: The ``shared_from_this()`` method will only work when there |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Doesn't the body (The [..]
) need to start on the line following the warning::
block? Maybe I just misremember.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I've always written them this way, and the docs look correct when built. I think the only requirement is that continuation lines line up with the 'w' in warning::
.
|
||
Replacing shared pointers with :ref:`intrusive reference counting | ||
<intrusive>` fixes this limitations. | ||
enable_shared_from_this |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Awesome, this is really clear documentation of the nuances of this feature 👍
d.flags |= (uint32_t) detail::type_flags::has_shared_from_this; | ||
d.keep_shared_from_this_alive = [](PyObject *self) noexcept { | ||
if (auto sp = inst_ptr<T>(self)->weak_from_this().lock()) { | ||
detail::keep_alive(self, new auto(std::move(sp)), |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
new auto
🤯
Per discussion in #183, this is not actually dangerous, although it does have some caveats (which I think I've thoroughly documented).
This turned out better than I thought it would: it is unexpectedly possible to support the feature where returning a raw pointer whose
enable_shared_from_this
subobject knows about a shared_ptr creates a Python object that shares ownership with that shared_ptr, without requiring#include <memory>
anywhere in nanobind that doesn't already have it.Size impact:
nb_type.cpp.o
increases by 148 bytes. Use ofstd::shared_ptr<T>
in non-enable_shared_from_this
cases actually gets smaller; we were previously instantiating a deleter forPyObject*
by mistake, and now we're not.