From fe40dfe67d2c7d31673ee8d41794897f839eb530 Mon Sep 17 00:00:00 2001 From: Wenzel Jakob Date: Mon, 7 Nov 2016 15:59:01 +0100 Subject: [PATCH] address number caster regression (fixes #484) --- include/pybind11/cast.h | 9 +++++++-- tests/test_issues.cpp | 10 ++++++---- tests/test_issues.py | 21 ++++++++++++++++++++- 3 files changed, 33 insertions(+), 7 deletions(-) diff --git a/include/pybind11/cast.h b/include/pybind11/cast.h index dd81d9a04..ddc1890c1 100644 --- a/include/pybind11/cast.h +++ b/include/pybind11/cast.h @@ -449,8 +449,13 @@ public: bool type_error = PyErr_ExceptionMatches(PyExc_TypeError); #endif PyErr_Clear(); - if (type_error && PyNumber_Check(src.ptr())) - return load(object(PyNumber_Long(src.ptr()), true), false); + if (type_error && PyNumber_Check(src.ptr())) { + object tmp(std::is_floating_point::value + ? PyNumber_Float(src.ptr()) + : PyNumber_Long(src.ptr()), true); + PyErr_Clear(); + return load(tmp, false); + } return false; } diff --git a/tests/test_issues.cpp b/tests/test_issues.cpp index 1374afeb7..084ea316d 100644 --- a/tests/test_issues.cpp +++ b/tests/test_issues.cpp @@ -11,7 +11,7 @@ #include "constructor_stats.h" #include #include - +#include #define TRACKERS(CLASS) CLASS() { print_default_created(this); } ~CLASS() { print_destroyed(this); } struct NestABase { int value = -2; TRACKERS(NestABase) }; @@ -346,10 +346,12 @@ void init_issues(py::module &m) { .def("child", &SpecialHolderObj::child, pybind11::return_value_policy::reference_internal) .def_readwrite("val", &SpecialHolderObj::val) .def_static("holder_cstats", &ConstructorStats::get>, - py::return_value_policy::reference) - ; -}; + py::return_value_policy::reference); + /// Issue #484: number conversion generates unhandled exceptions + m2.def("test_complex", [](float x) { py::print("{}"_s.format(x)); }); + m2.def("test_complex", [](std::complex x) { py::print("({}, {})"_s.format(x.real(), x.imag())); }); +} // MSVC workaround: trying to use a lambda here crashes MSCV test_initializer issues(&init_issues); diff --git a/tests/test_issues.py b/tests/test_issues.py index 6f84f777b..a2cf53082 100644 --- a/tests/test_issues.py +++ b/tests/test_issues.py @@ -60,7 +60,7 @@ def test_shared_ptr_gc(): assert i == v.value() -def test_no_id(capture, msg): +def test_no_id(msg): from pybind11_tests.issues import get_element, expect_float, expect_int with pytest.raises(TypeError) as excinfo: @@ -147,6 +147,7 @@ def test_move_fallback(): m1 = get_moveissue1(1) assert m1.value == 1 + def test_override_ref(): from pybind11_tests.issues import OverrideTest o = OverrideTest("asdf") @@ -162,6 +163,7 @@ def test_override_ref(): a.value = "bye" assert a.value == "bye" + def test_operators_notimplemented(capture): from pybind11_tests.issues import OpTest1, OpTest2 with capture: @@ -175,6 +177,7 @@ Add OpTest2 with OpTest2 Add OpTest2 with OpTest1 Add OpTest2 with OpTest1""" + def test_iterator_rvpolicy(): """ Issue 388: Can't make iterators via make_iterator() with different r/v policies """ from pybind11_tests.issues import make_iterator_1 @@ -184,6 +187,7 @@ def test_iterator_rvpolicy(): assert list(make_iterator_2()) == [1, 2, 3] assert(type(make_iterator_1()) != type(make_iterator_2())) + def test_dupe_assignment(): """ Issue 461: overwriting a class with a function """ from pybind11_tests.issues import dupe_exception_failures @@ -202,6 +206,7 @@ def test_enable_shared_from_this_with_reference_rvp(): del child, parent assert cstats.alive() == 0 + def test_non_destructed_holders(): """ Issue #478: unique ptrs constructed and freed without destruction """ from pybind11_tests import SpecialHolderObj @@ -218,3 +223,17 @@ def test_non_destructed_holders(): assert cstats.alive() == 1 del a assert cstats.alive() == 0 + + +def test_complex_cast(capture): + """ Issue #484: number conversion generates unhandled exceptions """ + from pybind11_tests.issues import test_complex + + with capture: + test_complex(1) + test_complex(2j) + + assert capture == """ +1.0 +(0.0, 2.0) +"""