-
Notifications
You must be signed in to change notification settings - Fork 7
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
Change implementation of the __init__() must be called when overriding __init__
safety feature to work for any metaclass.
#30095
Merged
Merged
Changes from all commits
Commits
Show all changes
16 commits
Select commit
Hold shift + click to select a range
a911a18
Also wrap with `py::metaclass((PyObject *) &PyType_Type)`
9c3799c
Transfer additional tests from PyCLIF python_multiple_inheritance_tes…
b9aeb34
Expand tests to fully cover wrapping with alternative metaclasses.
7b66ebe
* Factor out `ensure_base_init_functions_were_called()`.
a87e484
Bug fix (maybe actually two bugs?): simplify condition to `type->tp_i…
8a58d6b
Removing `Py_DECREF(self)` that leads to MSAN failure (Google toolcha…
1f155c3
IncludeCleaner fixes (Google toolchain).
d1ab242
Restore `type->tp_call = pybind11_meta_call;` for PyPy only.
38ac8d9
pytest.skip("ensure_base_init_functions_were_called() does not work w…
bf9d647
Merge branch 'google_pywrapcc_main' into tp_init_intercepted_pywrapcc
9cc3de1
Do not intercept our own `tp_init` function (`pybind11_object_init`).
a9922b4
Add `derived_tp_init_registry` weakref-based cleanup.
5c558e6
Replace `assert()` with `if` to resolve erroneous `lambda capture 'ty…
2f917e5
Add `derived_tp_init_registry()->count(type) == 0` condition.
766b97f
Changes based on feedback from @rainwoodman
fd47cc6
Use PYBIND11_INIT_SAFETY_CHECKS_VIA_* macros, based on suggestion fro…
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -1207,6 +1207,33 @@ class cpp_function : public function { | |
} | ||
}; | ||
|
||
PYBIND11_NAMESPACE_BEGIN(detail) | ||
|
||
/// Instance creation function for all pybind11 types. It only allocates space for the | ||
/// C++ object, but doesn't call the constructor -- an `__init__` function must do that. | ||
extern "C" inline PyObject *pybind11_object_new(PyTypeObject *type, PyObject *, PyObject *) { | ||
#if defined(PYBIND11_INIT_SAFETY_CHECKS_VIA_INTERCEPTING_TP_INIT) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. maybe the ifdef for pybind11_meta_call should also be in the body like here? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Decided on chat: leaving as is. |
||
if (type->tp_init != pybind11_object_init && type->tp_init != tp_init_with_safety_checks | ||
&& derived_tp_init_registry()->count(type) == 0) { | ||
weakref((PyObject *) type, cpp_function([type](handle wr) { | ||
auto num_erased = derived_tp_init_registry()->erase(type); | ||
if (num_erased != 1) { | ||
pybind11_fail("FATAL: Internal consistency check failed at " __FILE__ | ||
":" PYBIND11_TOSTRING(__LINE__) ": num_erased=" | ||
+ std::to_string(num_erased)); | ||
} | ||
wr.dec_ref(); | ||
})) | ||
.release(); | ||
(*derived_tp_init_registry())[type] = type->tp_init; | ||
type->tp_init = tp_init_with_safety_checks; | ||
} | ||
#endif // PYBIND11_INIT_SAFETY_CHECKS_VIA_INTERCEPTING_TP_INIT | ||
return make_new_instance(type); | ||
} | ||
|
||
PYBIND11_NAMESPACE_END(detail) | ||
|
||
/// Wrapper for Python extension modules | ||
class module_ : public object { | ||
public: | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
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.
How is this condition guaranteed? Looks like we don't ensure it when intercepting tp_init, based on my initial read of the pybind11object_new method.
PS: if it was not for consisitency with pyclif naming, I would recommend calling this safe_tp_init.
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.
It's not. I put the
assert()
here only to be sure my code isn't doing something unexpected. This PR is already TGP tested, which makes me believe it is very unlikely that theassert()
will ever fire, but if it does, I'll have a concrete situation to fix (as opposed to anticipating/guessing).Name changed to
tp_init_with_safety_checks
.(After this PR is merged I'll go back and change the PyCLIF code accordingly. I also want to backport the weakref-based cleanup.)