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

Add support for custom call policies #767

Open
wants to merge 1 commit into
base: master
Choose a base branch
from

Conversation

oremanj
Copy link
Contributor

@oremanj oremanj commented Oct 24, 2024

This PR adds a new function annotation, nb::call_policy<Policy>(), which causes static methods of the user-provided Policy to be invoked before and after the bound C++ function. Unlike call_guard, the call policy methods operate on the Python object level and have access to the function arguments (precall can even modify them) and return value. This allows various esoteric user customizations that might be desirable in certain circumstances, with a minimal impact on the footprint of nanobind itself.

Motivating use case: a number of the types of interest in my application support a lightweight callback mechanism. The callback type we use is trivially copyable, so it can't manage ownership of a Python object directly. A custom call policy allows us to automatically take out a reference to the underlying Python callable when a new callback is subscribed, and drop the reference when it's unsubscribed. Allowing precall() to modify the argument list permits normalization (letting equal-but-distinct Python callables map to identical C++ callback objects, so that the C++ unsubscribe logic can find the callback that was originally subscribed).

While working on this I noticed that a function annotated with nb::keep_alive will leak a reference to its return value if the keep_alive can't be set up. I worked around the analogous issue for call policies, but didn't change the implementation of keep_alive in case this is a deliberate performance tradeoff.

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.

1 participant