-
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
bugfix: fixes a test suite bug in the __new__ example #4698
bugfix: fixes a test suite bug in the __new__ example #4698
Conversation
tests/test_class.cpp
Outdated
@@ -85,7 +85,7 @@ TEST_SUBMODULE(class_, m) { | |||
.def_static("new_instance", &NoConstructor::new_instance, "Return an instance"); | |||
|
|||
py::class_<NoConstructorNew>(m, "NoConstructorNew") | |||
.def(py::init([](const NoConstructorNew &self) { return self; })) // Need a NOOP __init__ | |||
.def(py::init<>()) // Need a NOOP __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.
This is the usual default ctor. Is this still the NOOP __init__
you wanted in #3265 (and is suggested by the NoConstructor...
name)?
I don't fully understand the mechanics behind __new__
and __init__
, so I resorted to limited trial and error. Long story short, this works:
.def(py::init([]() { return nullptr; }))
It passes with asan, msan, ubsan (Google toolchain).
FWIW
Before I settled on the above I tried:
.def("__init__", [](NoConstructorNew *) {}) // Need a NOOP __init__
This runs if NDEBUG
is defined, but not otherwise (using Python 3.10):
assert.h assertion failed at third_party/python_runtime/v3_10/Objects/typeobject.c:3823 in PyObject *_PyType_Lookup(PyTypeObject *, PyObject *): !PyErr_Occurred()
On Sep 20, 2021 @Skylion007 wrote:
I also wish there was a cleaner way to not have to implement init if new is defined, but I can't figure out how to hack to the metaclass not to complain.
I confirmed that we need one of the __init__
alternatives to avoid this error:
> instance = m.NoConstructorNew() # .__new__(m.NoConstructor.__class__)
E TypeError: pybind11_tests.class_.NoConstructorNew: No constructor defined!
I also confirmed that the existing code and the usual default ctor don't leak memory.
I'm really unsure TBH what's "right", strictly speaking, but the suggested code is the alternative that seems closest to an actual NOOP.
For completeness:
With the suggested code, this passes:
assert m.NoConstructorNew.__init__.__doc__.strip() == "__init__(self: pybind11_tests.class_.NoConstructorNew) -> None"
But l think it's best not to add this assert
. This is just to report what the new __doc__
is, because IIUC the existing __doc__
led @XuehaiPan to suspect there is a bug.
I went ahead and updated this PR, based on the work reported under #4698 (comment). |
@Skylion007 all tests pass. Could you please merge if this looks good to you? |
@rwgk Looks good to me. Let's merge |
Description
Fixes a test suite bug for new pointed out by @XuehaiPan in #4549