diff --git a/docs/changelog.rst b/docs/changelog.rst index b5dee5f19..632f2be84 100644 --- a/docs/changelog.rst +++ b/docs/changelog.rst @@ -5,6 +5,8 @@ Changelog 1.8 (Not yet released) ---------------------- +* Prevent implicit conversion of floating point values to integral types in + function arguments * Transparent conversion of sparse and dense Eigen data types * Fixed incorrect default return value policy for functions returning a shared pointer diff --git a/example/issues.cpp b/example/issues.cpp index a4622149a..d1a1941b7 100644 --- a/example/issues.cpp +++ b/example/issues.cpp @@ -104,4 +104,8 @@ void init_issues(py::module &m) { // (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; }); + + // (no id): don't cast doubles to ints + m2.def("expect_float", [](float f) { return f; }); + m2.def("expect_int", [](int i) { return i; }); } diff --git a/example/issues.py b/example/issues.py index de417696f..d075e8340 100644 --- a/example/issues.py +++ b/example/issues.py @@ -8,6 +8,7 @@ from example.issues import DispatchIssue, dispatch_issue_go from example.issues import Placeholder, return_vec_of_reference_wrapper from example.issues import iterator_passthrough from example.issues import ElementList, ElementA, print_element +from example.issues import expect_float, expect_int import gc print_cchar("const char *") @@ -47,3 +48,10 @@ try: print_element(None) except Exception as e: print("Failed as expected: " + str(e)) + +try: + print(expect_int(5.2)) +except Exception as e: + print("Failed as expected: " + str(e)) + +print(expect_float(12)) diff --git a/example/issues.ref b/example/issues.ref index 2d34f4220..af61939c2 100644 --- a/example/issues.ref +++ b/example/issues.ref @@ -8,3 +8,7 @@ Yay.. Failed as expected: Incompatible function arguments. The following argument types are supported: 1. (example.issues.ElementA) -> NoneType +Failed as expected: Incompatible function arguments. The following argument types are supported: + 1. (int) -> int + +12.0 diff --git a/include/pybind11/cast.h b/include/pybind11/cast.h index add186f7c..31f5cb5a6 100644 --- a/include/pybind11/cast.h +++ b/include/pybind11/cast.h @@ -326,11 +326,15 @@ public: } if (std::is_floating_point::value) { py_value = (py_type) PyFloat_AsDouble(src.ptr()); } else if (sizeof(T) <= sizeof(long)) { + if (PyFloat_Check(src.ptr())) + return false; if (std::is_signed::value) py_value = (py_type) PyLong_AsLong(src.ptr()); else py_value = (py_type) PyLong_AsUnsignedLong(src.ptr()); } else { + if (PyFloat_Check(src.ptr())) + return false; if (std::is_signed::value) py_value = (py_type) PYBIND11_LONG_AS_LONGLONG(src.ptr()); else