aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorYannick Jadoul <yannick.jadoul@belgacom.net>2021-01-01 17:37:28 +0100
committerGitHub <noreply@github.com>2021-01-01 17:37:28 +0100
commit98f1bbb8004f654ba9e26717bdf5912fb899b05a (patch)
tree5b6eb424707e74caf086bd8b1f7c74b478d14bec
parente57dd4717e3df2a9740addacdb4c1df67d772ef0 (diff)
downloadplatform_external_python_pybind11-98f1bbb8004f654ba9e26717bdf5912fb899b05a.tar.gz
platform_external_python_pybind11-98f1bbb8004f654ba9e26717bdf5912fb899b05a.tar.bz2
platform_external_python_pybind11-98f1bbb8004f654ba9e26717bdf5912fb899b05a.zip
Ignore deprecation warnings about old-style __init__/__setstate__ constructors in the tests (originally done in #2746) (#2759)
* Ignore old-style __init__ warnings * Simplify ignoreOldStyleInitWarnings with py::exec * Only wrap single class_::defs to ignore DeprecationWarnings about old-style __init__
-rw-r--r--tests/pybind11_tests.h13
-rw-r--r--tests/test_factory_constructors.cpp49
-rw-r--r--tests/test_pickling.cpp58
3 files changed, 76 insertions, 44 deletions
diff --git a/tests/pybind11_tests.h b/tests/pybind11_tests.h
index 4ff56c0..ccb0529 100644
--- a/tests/pybind11_tests.h
+++ b/tests/pybind11_tests.h
@@ -1,5 +1,6 @@
#pragma once
#include <pybind11/pybind11.h>
+#include <pybind11/eval.h>
#if defined(_MSC_VER) && _MSC_VER < 1910
// We get some really long type names here which causes MSVC 2015 to emit warnings
@@ -69,3 +70,15 @@ public:
};
PYBIND11_NAMESPACE_END(detail)
PYBIND11_NAMESPACE_END(pybind11)
+
+template <typename F>
+void ignoreOldStyleInitWarnings(F &&body) {
+ py::exec(R"(
+ message = "pybind11-bound class '.+' is using an old-style placement-new '(?:__init__|__setstate__)' which has been deprecated"
+
+ import warnings
+ with warnings.catch_warnings():
+ warnings.filterwarnings("ignore", message=message, category=FutureWarning)
+ body()
+ )", py::dict(py::arg("body") = py::cpp_function(body)));
+}
diff --git a/tests/test_factory_constructors.cpp b/tests/test_factory_constructors.cpp
index f42d1f2..7ff7e7b 100644
--- a/tests/test_factory_constructors.cpp
+++ b/tests/test_factory_constructors.cpp
@@ -183,11 +183,14 @@ TEST_SUBMODULE(factory_constructors, m) {
auto c4a = [c](pointer_tag, TF4_tag, int a) { (void) c; return new TestFactory4(a);};
// test_init_factory_basic, test_init_factory_casting
- py::class_<TestFactory3, std::shared_ptr<TestFactory3>>(m, "TestFactory3")
+ py::class_<TestFactory3, std::shared_ptr<TestFactory3>> pyTestFactory3(m, "TestFactory3");
+ pyTestFactory3
.def(py::init([](pointer_tag, int v) { return TestFactoryHelper::construct3(v); }))
- .def(py::init([](shared_ptr_tag) { return TestFactoryHelper::construct3(); }))
- .def("__init__", [](TestFactory3 &self, std::string v) { new (&self) TestFactory3(v); }) // placement-new ctor
-
+ .def(py::init([](shared_ptr_tag) { return TestFactoryHelper::construct3(); }));
+ ignoreOldStyleInitWarnings([&pyTestFactory3]() {
+ pyTestFactory3.def("__init__", [](TestFactory3 &self, std::string v) { new (&self) TestFactory3(v); }); // placement-new ctor
+ });
+ pyTestFactory3
// factories returning a derived type:
.def(py::init(c4a)) // derived ptr
.def(py::init([](pointer_tag, TF5_tag, int a) { return new TestFactory5(a); }))
@@ -304,24 +307,32 @@ TEST_SUBMODULE(factory_constructors, m) {
static void operator delete(void *p) { py::print("noisy delete"); ::operator delete(p); }
#endif
};
- py::class_<NoisyAlloc>(m, "NoisyAlloc")
+
+
+ py::class_<NoisyAlloc> pyNoisyAlloc(m, "NoisyAlloc");
// Since these overloads have the same number of arguments, the dispatcher will try each of
// them until the arguments convert. Thus we can get a pre-allocation here when passing a
// single non-integer:
- .def("__init__", [](NoisyAlloc *a, int i) { new (a) NoisyAlloc(i); }) // Regular constructor, runs first, requires preallocation
- .def(py::init([](double d) { return new NoisyAlloc(d); }))
-
- // The two-argument version: first the factory pointer overload.
- .def(py::init([](int i, int) { return new NoisyAlloc(i); }))
- // Return-by-value:
- .def(py::init([](double d, int) { return NoisyAlloc(d); }))
- // Old-style placement new init; requires preallocation
- .def("__init__", [](NoisyAlloc &a, double d, double) { new (&a) NoisyAlloc(d); })
- // Requires deallocation of previous overload preallocated value:
- .def(py::init([](int i, double) { return new NoisyAlloc(i); }))
- // Regular again: requires yet another preallocation
- .def("__init__", [](NoisyAlloc &a, int i, std::string) { new (&a) NoisyAlloc(i); })
- ;
+ ignoreOldStyleInitWarnings([&pyNoisyAlloc]() {
+ pyNoisyAlloc.def("__init__", [](NoisyAlloc *a, int i) { new (a) NoisyAlloc(i); }); // Regular constructor, runs first, requires preallocation
+ });
+
+ pyNoisyAlloc.def(py::init([](double d) { return new NoisyAlloc(d); }));
+
+ // The two-argument version: first the factory pointer overload.
+ pyNoisyAlloc.def(py::init([](int i, int) { return new NoisyAlloc(i); }));
+ // Return-by-value:
+ pyNoisyAlloc.def(py::init([](double d, int) { return NoisyAlloc(d); }));
+ // Old-style placement new init; requires preallocation
+ ignoreOldStyleInitWarnings([&pyNoisyAlloc]() {
+ pyNoisyAlloc.def("__init__", [](NoisyAlloc &a, double d, double) { new (&a) NoisyAlloc(d); });
+ });
+ // Requires deallocation of previous overload preallocated value:
+ pyNoisyAlloc.def(py::init([](int i, double) { return new NoisyAlloc(i); }));
+ // Regular again: requires yet another preallocation
+ ignoreOldStyleInitWarnings([&pyNoisyAlloc]() {
+ pyNoisyAlloc.def("__init__", [](NoisyAlloc &a, int i, std::string) { new (&a) NoisyAlloc(i); });
+ });
diff --git a/tests/test_pickling.cpp b/tests/test_pickling.cpp
index 9dc63bd..1a48595 100644
--- a/tests/test_pickling.cpp
+++ b/tests/test_pickling.cpp
@@ -31,7 +31,8 @@ TEST_SUBMODULE(pickling, m) {
using Pickleable::Pickleable;
};
- py::class_<Pickleable>(m, "Pickleable")
+ py::class_<Pickleable> pyPickleable(m, "Pickleable");
+ pyPickleable
.def(py::init<std::string>())
.def("value", &Pickleable::value)
.def("extra1", &Pickleable::extra1)
@@ -43,17 +44,20 @@ TEST_SUBMODULE(pickling, m) {
.def("__getstate__", [](const Pickleable &p) {
/* Return a tuple that fully encodes the state of the object */
return py::make_tuple(p.value(), p.extra1(), p.extra2());
- })
- .def("__setstate__", [](Pickleable &p, py::tuple t) {
- if (t.size() != 3)
- throw std::runtime_error("Invalid state!");
- /* Invoke the constructor (need to use in-place version) */
- new (&p) Pickleable(t[0].cast<std::string>());
-
- /* Assign any additional state */
- p.setExtra1(t[1].cast<int>());
- p.setExtra2(t[2].cast<int>());
});
+ ignoreOldStyleInitWarnings([&pyPickleable]() {
+ pyPickleable
+ .def("__setstate__", [](Pickleable &p, py::tuple t) {
+ if (t.size() != 3)
+ throw std::runtime_error("Invalid state!");
+ /* Invoke the constructor (need to use in-place version) */
+ new (&p) Pickleable(t[0].cast<std::string>());
+
+ /* Assign any additional state */
+ p.setExtra1(t[1].cast<int>());
+ p.setExtra2(t[2].cast<int>());
+ });
+ });
py::class_<PickleableNew, Pickleable>(m, "PickleableNew")
.def(py::init<std::string>())
@@ -87,27 +91,31 @@ TEST_SUBMODULE(pickling, m) {
using PickleableWithDict::PickleableWithDict;
};
- py::class_<PickleableWithDict>(m, "PickleableWithDict", py::dynamic_attr())
+ py::class_<PickleableWithDict> pyPickleableWithDict(m, "PickleableWithDict", py::dynamic_attr());
+ pyPickleableWithDict
.def(py::init<std::string>())
.def_readwrite("value", &PickleableWithDict::value)
.def_readwrite("extra", &PickleableWithDict::extra)
.def("__getstate__", [](py::object self) {
/* Also include __dict__ in state */
return py::make_tuple(self.attr("value"), self.attr("extra"), self.attr("__dict__"));
- })
- .def("__setstate__", [](py::object self, py::tuple t) {
- if (t.size() != 3)
- throw std::runtime_error("Invalid state!");
- /* Cast and construct */
- auto& p = self.cast<PickleableWithDict&>();
- new (&p) PickleableWithDict(t[0].cast<std::string>());
-
- /* Assign C++ state */
- p.extra = t[1].cast<int>();
-
- /* Assign Python state */
- self.attr("__dict__") = t[2];
});
+ ignoreOldStyleInitWarnings([&pyPickleableWithDict]() {
+ pyPickleableWithDict
+ .def("__setstate__", [](py::object self, py::tuple t) {
+ if (t.size() != 3)
+ throw std::runtime_error("Invalid state!");
+ /* Cast and construct */
+ auto& p = self.cast<PickleableWithDict&>();
+ new (&p) PickleableWithDict(t[0].cast<std::string>());
+
+ /* Assign C++ state */
+ p.extra = t[1].cast<int>();
+
+ /* Assign Python state */
+ self.attr("__dict__") = t[2];
+ });
+ });
py::class_<PickleableWithDictNew, PickleableWithDict>(m, "PickleableWithDictNew")
.def(py::init<std::string>())