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 @@ -798,11 +798,16 @@ PYBIND11_NAMESPACE_END(detail)
798
798
: Parent(check_(o) ? o.release().ptr() : ConvertFun(o.ptr()), stolen_t{}) \
799
799
{ if (!m_ptr) throw error_already_set (); }
800
800
801
+ #define PYBIND11_OBJECT_CHECK_FAILED (Name, o ) \
802
+ type_error (" Object of type '" + std::string(Py_TYPE(o.ptr())->tp_name) + "' is not an instance of '" #Name " '" )
803
+
801
804
#define PYBIND11_OBJECT (Name, Parent, CheckFun ) \
802
805
PYBIND11_OBJECT_COMMON (Name, Parent, CheckFun) \
803
806
/* This is deliberately not 'explicit' to allow implicit conversion from object: */ \
804
- Name(const object &o) : Parent(o) { } \
805
- Name (object &&o) : Parent(std::move(o)) { }
807
+ Name(const object &o) : Parent(o) \
808
+ { if (o && !check_ (o)) throw PYBIND11_OBJECT_CHECK_FAILED (Name, o); } \
809
+ Name (object &&o) : Parent(std::move(o)) \
810
+ { if (o && !check_ (o)) throw PYBIND11_OBJECT_CHECK_FAILED (Name, o); }
806
811
807
812
#define PYBIND11_OBJECT_DEFAULT (Name, Parent, CheckFun ) \
808
813
PYBIND11_OBJECT (Name, Parent, CheckFun) \
Original file line number Diff line number Diff line change @@ -240,6 +240,19 @@ TEST_SUBMODULE(pytypes, m) {
240
240
);
241
241
});
242
242
243
+ m.def (" nonconverting_constructor" , [](std::string type, py::object value) -> py::object {
244
+ if (type == " bytes" ) {
245
+ return py::bytes (value);
246
+ }
247
+ else if (type == " none" ) {
248
+ return py::none (value);
249
+ }
250
+ else if (type == " ellipsis" ) {
251
+ return py::ellipsis (value);
252
+ }
253
+ throw std::runtime_error (" Invalid type" );
254
+ });
255
+
243
256
m.def (" get_implicit_casting" , []() {
244
257
py::dict d;
245
258
d[" char*_i1" ] = " abc" ;
Original file line number Diff line number Diff line change @@ -225,6 +225,18 @@ def test_constructors():
225
225
for k in noconv2 :
226
226
assert noconv2 [k ] is expected [k ]
227
227
228
+ type_error_tests = [
229
+ ("bytes" , range (10 )),
230
+ ("none" , 42 ),
231
+ ("ellipsis" , 42 ),
232
+ ]
233
+ for t , v in type_error_tests :
234
+ with pytest .raises (TypeError ) as excinfo :
235
+ m .nonconverting_constructor (t , v )
236
+ expected_error = "Object of type '{}' is not an instance of '{}'" .format (
237
+ type (v ).__name__ , t )
238
+ assert str (excinfo .value ) == expected_error
239
+
228
240
229
241
def test_implicit_casting ():
230
242
"""Tests implicit casting when assigning or appending to dicts and lists."""
You can’t perform that action at this time.
0 commit comments