File tree Expand file tree Collapse file tree 3 files changed +32
-2
lines changed Expand file tree Collapse file tree 3 files changed +32
-2
lines changed Original file line number Diff line number Diff line change @@ -794,11 +794,16 @@ PYBIND11_NAMESPACE_END(detail)
794
794
: Parent(check_(o) ? o.release().ptr() : ConvertFun(o.ptr()), stolen_t{}) \
795
795
{ if (!m_ptr) throw error_already_set (); }
796
796
797
+ #define PYBIND11_OBJECT_CHECK_FAILED (Name, o ) \
798
+ type_error (" Object of type '" + std::string(Py_TYPE(o.ptr())->tp_name) + "' is not an instance of '" #Name " '" )
799
+
797
800
#define PYBIND11_OBJECT (Name, Parent, CheckFun ) \
798
801
PYBIND11_OBJECT_COMMON (Name, Parent, CheckFun) \
799
802
/* This is deliberately not 'explicit' to allow implicit conversion from object: */ \
800
- Name(const object &o) : Parent(o) { } \
801
- Name (object &&o) : Parent(std::move(o)) { }
803
+ Name(const object &o) : Parent(o) \
804
+ { if (o && !check_ (o)) throw PYBIND11_OBJECT_CHECK_FAILED (Name, o); } \
805
+ Name (object &&o) : Parent(std::move(o)) \
806
+ { if (o && !check_ (o)) throw PYBIND11_OBJECT_CHECK_FAILED (Name, o); }
802
807
803
808
#define PYBIND11_OBJECT_DEFAULT (Name, Parent, CheckFun ) \
804
809
PYBIND11_OBJECT (Name, Parent, CheckFun) \
Original file line number Diff line number Diff line change @@ -242,6 +242,19 @@ TEST_SUBMODULE(pytypes, m) {
242
242
243
243
m.def (" convert_to_pybind11_str" , [](py::object o) { return py::str (o); });
244
244
245
+ m.def (" nonconverting_constructor" , [](std::string type, py::object value) -> py::object {
246
+ if (type == " bytes" ) {
247
+ return py::bytes (value);
248
+ }
249
+ else if (type == " none" ) {
250
+ return py::none (value);
251
+ }
252
+ else if (type == " ellipsis" ) {
253
+ return py::ellipsis (value);
254
+ }
255
+ throw std::runtime_error (" Invalid type" );
256
+ });
257
+
245
258
m.def (" get_implicit_casting" , []() {
246
259
py::dict d;
247
260
d[" char*_i1" ] = " abc" ;
Original file line number Diff line number Diff line change @@ -230,6 +230,18 @@ def test_constructors():
230
230
for k in noconv2 :
231
231
assert noconv2 [k ] is expected [k ]
232
232
233
+ type_error_tests = [
234
+ ("bytes" , range (10 )),
235
+ ("none" , 42 ),
236
+ ("ellipsis" , 42 ),
237
+ ]
238
+ for t , v in type_error_tests :
239
+ with pytest .raises (TypeError ) as excinfo :
240
+ m .nonconverting_constructor (t , v )
241
+ expected_error = "Object of type '{}' is not an instance of '{}'" .format (
242
+ type (v ).__name__ , t )
243
+ assert str (excinfo .value ) == expected_error
244
+
233
245
234
246
def test_pybind11_str_raw_str ():
235
247
# specifically to exercise pybind11::str::raw_str
You can’t perform that action at this time.
0 commit comments