File tree Expand file tree Collapse file tree 8 files changed +49
-16
lines changed Expand file tree Collapse file tree 8 files changed +49
-16
lines changed Original file line number Diff line number Diff line change 39
39
PYBIND11_NAMESPACE_BEGIN (PYBIND11_NAMESPACE)
40
40
PYBIND11_NAMESPACE_BEGIN(detail)
41
41
42
- // Forward-declaration; see detail/class.h
43
- std::string get_fully_qualified_tp_name(PyTypeObject*);
44
-
45
42
// / A life support system for temporary objects created by `type_caster::load()`.
46
43
// / Adding a patient will keep it alive up until the enclosing function returns.
47
44
class loader_life_support {
Original file line number Diff line number Diff line change @@ -28,7 +28,11 @@ inline std::string get_fully_qualified_tp_name(PyTypeObject *type) {
28
28
#if !defined(PYPY_VERSION)
29
29
return type->tp_name ;
30
30
#else
31
- return handle ((PyObject *) type).attr (" __module__" ).cast <std::string>() + " ." + type->tp_name ;
31
+ auto module_name = handle ((PyObject *) type).attr (" __module__" ).cast <std::string>();
32
+ if (module_name == PYBIND11_BUILTINS_MODULE)
33
+ return type->tp_name ;
34
+ else
35
+ return std::move (module_name) + " ." + type->tp_name ;
32
36
#endif
33
37
}
34
38
Original file line number Diff line number Diff line change 182
182
#define PYBIND11_STR_TYPE ::pybind11::str
183
183
#define PYBIND11_BOOL_ATTR " __bool__"
184
184
#define PYBIND11_NB_BOOL (ptr ) ((ptr)->nb_bool)
185
+ #define PYBIND11_BUILTINS_MODULE " builtins"
185
186
// Providing a separate declaration to make Clang's -Wmissing-prototypes happy.
186
187
// See comment for PYBIND11_MODULE below for why this is marked "maybe unused".
187
188
#define PYBIND11_PLUGIN_IMPL (name ) \
209
210
#define PYBIND11_STR_TYPE ::pybind11::bytes
210
211
#define PYBIND11_BOOL_ATTR " __nonzero__"
211
212
#define PYBIND11_NB_BOOL (ptr ) ((ptr)->nb_nonzero)
213
+ #define PYBIND11_BUILTINS_MODULE " __builtin__"
212
214
// Providing a separate PyInit decl to make Clang's -Wmissing-prototypes happy.
213
215
// See comment for PYBIND11_MODULE below for why this is marked "maybe unused".
214
216
#define PYBIND11_PLUGIN_IMPL (name ) \
@@ -853,8 +855,8 @@ class any_container {
853
855
const std::vector<T> *operator ->() const { return &v; }
854
856
};
855
857
856
- PYBIND11_NAMESPACE_END (detail)
857
-
858
-
858
+ // Forward-declaration; see detail/class.h
859
+ std::string get_fully_qualified_tp_name (PyTypeObject*);
859
860
861
+ PYBIND11_NAMESPACE_END (detail)
860
862
PYBIND11_NAMESPACE_END (PYBIND11_NAMESPACE)
Original file line number Diff line number Diff line change @@ -812,11 +812,18 @@ PYBIND11_NAMESPACE_END(detail)
812
812
: Parent(check_(o) ? o.release().ptr() : ConvertFun(o.ptr()), stolen_t{}) \
813
813
{ if (!m_ptr) throw error_already_set (); }
814
814
815
+ #define PYBIND11_OBJECT_CHECK_FAILED (Name, o ) \
816
+ type_error (" Object of type '" + \
817
+ pybind11::detail::get_fully_qualified_tp_name (Py_TYPE(o.ptr())) + \
818
+ "' is not an instance of '" #Name " '" )
819
+
815
820
#define PYBIND11_OBJECT (Name, Parent, CheckFun ) \
816
821
PYBIND11_OBJECT_COMMON (Name, Parent, CheckFun) \
817
822
/* This is deliberately not 'explicit' to allow implicit conversion from object: */ \
818
- Name(const object &o) : Parent(o) { } \
819
- Name (object &&o) : Parent(std::move(o)) { }
823
+ Name(const object &o) : Parent(o) \
824
+ { if (o && !check_ (o)) throw PYBIND11_OBJECT_CHECK_FAILED (Name, o); } \
825
+ Name (object &&o) : Parent(std::move(o)) \
826
+ { if (o && !check_ (o)) throw PYBIND11_OBJECT_CHECK_FAILED (Name, o); }
820
827
821
828
#define PYBIND11_OBJECT_DEFAULT (Name, Parent, CheckFun ) \
822
829
PYBIND11_OBJECT (Name, Parent, CheckFun) \
Original file line number Diff line number Diff line change @@ -157,11 +157,7 @@ TEST_SUBMODULE(class_, m) {
157
157
});
158
158
159
159
m.def (" as_type" , [](py::object ob) {
160
- auto tp = py::type (ob);
161
- if (py::isinstance<py::type>(ob))
162
- return tp;
163
- else
164
- throw std::runtime_error (" Invalid type" );
160
+ return py::type (ob);
165
161
});
166
162
167
163
// test_mismatched_holder
Original file line number Diff line number Diff line change @@ -59,10 +59,10 @@ def test_type_of_py_nodelete():
59
59
def test_as_type_py ():
60
60
assert m .as_type (int ) == int
61
61
62
- with pytest .raises (RuntimeError ):
62
+ with pytest .raises (TypeError ):
63
63
assert m .as_type (1 ) == int
64
64
65
- with pytest .raises (RuntimeError ):
65
+ with pytest .raises (TypeError ):
66
66
assert m .as_type (m .DerivedClass1 ()) == m .DerivedClass1
67
67
68
68
Original file line number Diff line number Diff line change @@ -243,6 +243,19 @@ TEST_SUBMODULE(pytypes, m) {
243
243
244
244
m.def (" convert_to_pybind11_str" , [](py::object o) { return py::str (o); });
245
245
246
+ m.def (" nonconverting_constructor" , [](std::string type, py::object value) -> py::object {
247
+ if (type == " bytes" ) {
248
+ return py::bytes (value);
249
+ }
250
+ else if (type == " none" ) {
251
+ return py::none (value);
252
+ }
253
+ else if (type == " ellipsis" ) {
254
+ return py::ellipsis (value);
255
+ }
256
+ throw std::runtime_error (" Invalid type" );
257
+ });
258
+
246
259
m.def (" get_implicit_casting" , []() {
247
260
py::dict d;
248
261
d[" char*_i1" ] = " abc" ;
Original file line number Diff line number Diff line change @@ -245,6 +245,20 @@ def test_constructors():
245
245
assert noconv2 [k ] is expected [k ]
246
246
247
247
248
+ def test_non_converting_constructors ():
249
+ non_converting_test_cases = [
250
+ ("bytes" , range (10 )),
251
+ ("none" , 42 ),
252
+ ("ellipsis" , 42 ),
253
+ ]
254
+ for t , v in non_converting_test_cases :
255
+ with pytest .raises (TypeError ) as excinfo :
256
+ m .nonconverting_constructor (t , v )
257
+ expected_error = "Object of type '{}' is not an instance of '{}'" .format (
258
+ type (v ).__name__ , t )
259
+ assert str (excinfo .value ) == expected_error
260
+
261
+
248
262
def test_pybind11_str_raw_str ():
249
263
# specifically to exercise pybind11::str::raw_str
250
264
cvt = m .convert_to_pybind11_str
You can’t perform that action at this time.
0 commit comments