-
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
Support keep_alive where nurse may be None #341
Conversation
Having a |
The nurse is checked against None before the patient reference count is incremented in keep_alive_impl, so I don't think there should be a problem with leaks. I'm wrapping a C++ class with a method that may return an object pointer or nullptr depending on other factors. I'd like the Python wrapper to return an instance or None, which currently doesn't work with keep_alive<0,1>. |
You changed the statement to |
The situation where patient is non-null and nurse is null is exactly the situation I am targeting, and self-deactivation is the desired behaviour. When nullptr is returned no keep_alive is required, but if a valid pointer is returned the keep_alive is activated. Note that this behaviour is consistent with the behaviour of return_value_policy reference_internal when None is returned. In the absense of this fix do you have any suggestions on how to wrap a function that may or may not return nullptr, and where the return value requires keep_alive<0,1>? |
I have to disagree that the situation is exceptional and indicates a problem - I have a valid use case wrapping a real-world C++ library where a method return value may sometimes be nullptr, but when it is not nullptr a keep_alive<0,1> is required. If it is acceptable for patient to be None, acting as a no-op with no error raised, then it makes sense to me that it would be acceptable for nurse to be None, also acting as a no-op with no error raised. Logically "Nurse, please keep nobody alive" and "Nobody, please keep patient alive" both result in no keep-alive. With this patch, having a None nurse becomes equivalent to having a valid nurse that is immediately garbage collected, in that the end result for both is a patient that is not kept alive by a nurse. To me, the following pseudo-code should have the same end-result, and I was surprised that they do not: nurse = Nurse() nurse = None |
That's not actually true (anymore) in current master since f2ecd89: Boost.Python also appears to support this (presumably for the same reasons @GlenWalker has given):
and so without this, we aren't quite equivalent to Boost.Python's On that note, if @wjakob decides to accept the change, it deserves an addition to |
That's a good point -- I forgot about the |
For example keep_alive<0,1>() should work where the return value may sometimes be None. At present a "Could not allocate weak reference!" exception is thrown. Update documentation to clarify behaviour of keep_alive when nurse is None or does not support weak references.
5b71d81
to
f45bb58
Compare
Commit now includes an update to advanced.rst to clarify the behaviour of keep_alive (based on boost::python documentation of with_custodian_and_ward) |
For example keep_alive<0,1>() should work where the return value may sometimes be None. At present a "Could not allocate weak reference!" exception is thrown.