mirror of
https://github.com/pybind/pybind11.git
synced 2024-11-22 21:25:13 +00:00
don't try to cast 'None' into a C++ lvalue reference
This commit is contained in:
parent
bdd11030c2
commit
bd57eb484d
@ -21,7 +21,7 @@ void init_issues(py::module &m) {
|
|||||||
// #70 compilation issue if operator new is not public
|
// #70 compilation issue if operator new is not public
|
||||||
class NonConstructible { private: void *operator new(size_t bytes) throw(); };
|
class NonConstructible { private: void *operator new(size_t bytes) throw(); };
|
||||||
py::class_<NonConstructible>(m, "Foo");
|
py::class_<NonConstructible>(m, "Foo");
|
||||||
m.def("getstmt", []() -> NonConstructible * { return nullptr; },
|
m2.def("getstmt", []() -> NonConstructible * { return nullptr; },
|
||||||
py::return_value_policy::reference);
|
py::return_value_policy::reference);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@ -101,4 +101,7 @@ void init_issues(py::module &m) {
|
|||||||
list.append(py::cast(e));
|
list.append(py::cast(e));
|
||||||
return list;
|
return list;
|
||||||
});
|
});
|
||||||
};
|
|
||||||
|
// (no id): should not be able to pass 'None' to a reference argument
|
||||||
|
m2.def("print_element", [](ElementA &el) { std::cout << el.value() << std::endl; });
|
||||||
|
}
|
||||||
|
@ -7,7 +7,7 @@ from example.issues import print_cchar, print_char
|
|||||||
from example.issues import DispatchIssue, dispatch_issue_go
|
from example.issues import DispatchIssue, dispatch_issue_go
|
||||||
from example.issues import Placeholder, return_vec_of_reference_wrapper
|
from example.issues import Placeholder, return_vec_of_reference_wrapper
|
||||||
from example.issues import iterator_passthrough
|
from example.issues import iterator_passthrough
|
||||||
from example.issues import ElementList, ElementA
|
from example.issues import ElementList, ElementA, print_element
|
||||||
import gc
|
import gc
|
||||||
|
|
||||||
print_cchar("const char *")
|
print_cchar("const char *")
|
||||||
@ -42,3 +42,8 @@ gc.collect()
|
|||||||
for i, v in enumerate(el.get()):
|
for i, v in enumerate(el.get()):
|
||||||
print("%i==%i, " % (i, v.value()), end='')
|
print("%i==%i, " % (i, v.value()), end='')
|
||||||
print()
|
print()
|
||||||
|
|
||||||
|
try:
|
||||||
|
print_element(None)
|
||||||
|
except Exception as e:
|
||||||
|
print("Failed as expected: " + str(e))
|
||||||
|
@ -5,3 +5,6 @@ Yay..
|
|||||||
[Placeholder[1], Placeholder[2], Placeholder[3], Placeholder[4]]
|
[Placeholder[1], Placeholder[2], Placeholder[3], Placeholder[4]]
|
||||||
[3, 5, 7, 9, 11, 13, 15]
|
[3, 5, 7, 9, 11, 13, 15]
|
||||||
0==0, 1==1, 2==2, 3==3, 4==4, 5==5, 6==6, 7==7, 8==8, 9==9,
|
0==0, 1==1, 2==2, 3==3, 4==4, 5==5, 6==6, 7==7, 8==8, 9==9,
|
||||||
|
Failed as expected: Incompatible function arguments. The following argument types are supported:
|
||||||
|
1. (example.issues.ElementA) -> NoneType
|
||||||
|
|
||||||
|
@ -225,6 +225,8 @@ using cast_op_type = typename std::conditional<std::is_pointer<typename std::rem
|
|||||||
typename std::add_pointer<typename intrinsic_type<T>::type>::type,
|
typename std::add_pointer<typename intrinsic_type<T>::type>::type,
|
||||||
typename std::add_lvalue_reference<typename intrinsic_type<T>::type>::type>::type;
|
typename std::add_lvalue_reference<typename intrinsic_type<T>::type>::type>::type;
|
||||||
|
|
||||||
|
/// Thrown then trying to cast a null pointer into a reference argument
|
||||||
|
class invalid_reference_cast : public std::exception { };
|
||||||
|
|
||||||
/// Generic type caster for objects stored on the heap
|
/// Generic type caster for objects stored on the heap
|
||||||
template <typename type> class type_caster_base : public type_caster_generic {
|
template <typename type> class type_caster_base : public type_caster_generic {
|
||||||
@ -254,7 +256,7 @@ public:
|
|||||||
template <typename T> using cast_op_type = pybind11::detail::cast_op_type<T>;
|
template <typename T> using cast_op_type = pybind11::detail::cast_op_type<T>;
|
||||||
|
|
||||||
operator type*() { return (type *) value; }
|
operator type*() { return (type *) value; }
|
||||||
operator type&() { return *((type *) value); }
|
operator type&() { if (!value) throw invalid_reference_cast(); return *((type *) value); }
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
typedef void *(*Constructor)(const void *stream);
|
typedef void *(*Constructor)(const void *stream);
|
||||||
|
@ -409,8 +409,13 @@ protected:
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
if (kwargs_consumed == nkwargs)
|
if (kwargs_consumed == nkwargs)
|
||||||
result = it->impl(it, args_, parent);
|
result = it->impl(it, args_, parent);
|
||||||
|
} catch (detail::invalid_reference_cast &) {
|
||||||
|
result = PYBIND11_TRY_NEXT_OVERLOAD;
|
||||||
|
}
|
||||||
|
|
||||||
if (result.ptr() != PYBIND11_TRY_NEXT_OVERLOAD)
|
if (result.ptr() != PYBIND11_TRY_NEXT_OVERLOAD)
|
||||||
break;
|
break;
|
||||||
|
Loading…
Reference in New Issue
Block a user