Skip to content
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

Merged
merged 4 commits into from
May 12, 2023
Merged

Conversation

oremanj
Copy link
Contributor

@oremanj oremanj commented May 11, 2023

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 of std::shared_ptr<T> in non-enable_shared_from_this cases actually gets smaller; we were previously instantiating a deleter for PyObject* by mistake, and now we're not.

Copy link
Owner

@wjakob wjakob left a 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.

docs/ownership_adv.rst Outdated Show resolved Hide resolved
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
Copy link
Owner

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.

Copy link
Contributor Author

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
Copy link
Owner

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 👍

docs/ownership_adv.rst Outdated Show resolved Hide resolved
include/nanobind/nb_class.h Show resolved Hide resolved
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)),
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

new auto 🤯

@wjakob wjakob merged commit 936bfa5 into wjakob:master May 12, 2023
16 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

2 participants