Made arithmetic and complex casters respect `convert`
Arithmetic and complex casters now only do a converting cast when
`convert=true`; previously they would convert always (e.g. when passing
an int to a float-accepting function, or a float to complex-accepting
function).
diff --git a/include/pybind11/cast.h b/include/pybind11/cast.h
index af85f9c..4dc3082 100644
--- a/include/pybind11/cast.h
+++ b/include/pybind11/cast.h
@@ -473,18 +473,22 @@
template <typename T>
struct type_caster<T, enable_if_t<std::is_arithmetic<T>::value>> {
- typedef typename std::conditional<sizeof(T) <= sizeof(long), long, long long>::type _py_type_0;
- typedef typename std::conditional<std::is_signed<T>::value, _py_type_0, typename std::make_unsigned<_py_type_0>::type>::type _py_type_1;
- typedef typename std::conditional<std::is_floating_point<T>::value, double, _py_type_1>::type py_type;
+ using _py_type_0 = conditional_t<sizeof(T) <= sizeof(long), long, long long>;
+ using _py_type_1 = conditional_t<std::is_signed<T>::value, _py_type_0, typename std::make_unsigned<_py_type_0>::type>;
+ using py_type = conditional_t<std::is_floating_point<T>::value, double, _py_type_1>;
public:
- bool load(handle src, bool) {
+ bool load(handle src, bool convert) {
py_type py_value;
- if (!src) {
+ if (!src)
return false;
- } if (std::is_floating_point<T>::value) {
- py_value = (py_type) PyFloat_AsDouble(src.ptr());
+
+ if (std::is_floating_point<T>::value) {
+ if (convert || PyFloat_Check(src.ptr()))
+ py_value = (py_type) PyFloat_AsDouble(src.ptr());
+ else
+ return false;
} else if (sizeof(T) <= sizeof(long)) {
if (PyFloat_Check(src.ptr()))
return false;
@@ -511,7 +515,7 @@
bool type_error = PyErr_ExceptionMatches(PyExc_TypeError);
#endif
PyErr_Clear();
- if (type_error && PyNumber_Check(src.ptr())) {
+ if (type_error && convert && PyNumber_Check(src.ptr())) {
auto tmp = reinterpret_borrow<object>(std::is_floating_point<T>::value
? PyNumber_Float(src.ptr())
: PyNumber_Long(src.ptr()));
diff --git a/include/pybind11/complex.h b/include/pybind11/complex.h
index a6b7b23..945ca07 100644
--- a/include/pybind11/complex.h
+++ b/include/pybind11/complex.h
@@ -28,9 +28,11 @@
template <typename T> class type_caster<std::complex<T>> {
public:
- bool load(handle src, bool) {
+ bool load(handle src, bool convert) {
if (!src)
return false;
+ if (!convert && !PyComplex_Check(src.ptr()))
+ return false;
Py_complex result = PyComplex_AsCComplex(src.ptr());
if (result.real == -1.0 && PyErr_Occurred()) {
PyErr_Clear();