Skip to content

Commit fe40dfe

Browse files
committed
address number caster regression (fixes #484)
1 parent c07ec31 commit fe40dfe

File tree

3 files changed

+33
-7
lines changed

3 files changed

+33
-7
lines changed

include/pybind11/cast.h

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -449,8 +449,13 @@ struct type_caster<T, enable_if_t<std::is_arithmetic<T>::value>> {
449449
bool type_error = PyErr_ExceptionMatches(PyExc_TypeError);
450450
#endif
451451
PyErr_Clear();
452-
if (type_error && PyNumber_Check(src.ptr()))
453-
return load(object(PyNumber_Long(src.ptr()), true), false);
452+
if (type_error && PyNumber_Check(src.ptr())) {
453+
object tmp(std::is_floating_point<T>::value
454+
? PyNumber_Float(src.ptr())
455+
: PyNumber_Long(src.ptr()), true);
456+
PyErr_Clear();
457+
return load(tmp, false);
458+
}
454459
return false;
455460
}
456461

tests/test_issues.cpp

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111
#include "constructor_stats.h"
1212
#include <pybind11/stl.h>
1313
#include <pybind11/operators.h>
14-
14+
#include <pybind11/complex.h>
1515

1616
#define TRACKERS(CLASS) CLASS() { print_default_created(this); } ~CLASS() { print_destroyed(this); }
1717
struct NestABase { int value = -2; TRACKERS(NestABase) };
@@ -346,10 +346,12 @@ void init_issues(py::module &m) {
346346
.def("child", &SpecialHolderObj::child, pybind11::return_value_policy::reference_internal)
347347
.def_readwrite("val", &SpecialHolderObj::val)
348348
.def_static("holder_cstats", &ConstructorStats::get<custom_unique_ptr<SpecialHolderObj>>,
349-
py::return_value_policy::reference)
350-
;
351-
};
349+
py::return_value_policy::reference);
352350

351+
/// Issue #484: number conversion generates unhandled exceptions
352+
m2.def("test_complex", [](float x) { py::print("{}"_s.format(x)); });
353+
m2.def("test_complex", [](std::complex<float> x) { py::print("({}, {})"_s.format(x.real(), x.imag())); });
354+
}
353355

354356
// MSVC workaround: trying to use a lambda here crashes MSCV
355357
test_initializer issues(&init_issues);

tests/test_issues.py

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,7 @@ def test_shared_ptr_gc():
6060
assert i == v.value()
6161

6262

63-
def test_no_id(capture, msg):
63+
def test_no_id(msg):
6464
from pybind11_tests.issues import get_element, expect_float, expect_int
6565

6666
with pytest.raises(TypeError) as excinfo:
@@ -147,6 +147,7 @@ def test_move_fallback():
147147
m1 = get_moveissue1(1)
148148
assert m1.value == 1
149149

150+
150151
def test_override_ref():
151152
from pybind11_tests.issues import OverrideTest
152153
o = OverrideTest("asdf")
@@ -162,6 +163,7 @@ def test_override_ref():
162163
a.value = "bye"
163164
assert a.value == "bye"
164165

166+
165167
def test_operators_notimplemented(capture):
166168
from pybind11_tests.issues import OpTest1, OpTest2
167169
with capture:
@@ -175,6 +177,7 @@ def test_operators_notimplemented(capture):
175177
Add OpTest2 with OpTest1
176178
Add OpTest2 with OpTest1"""
177179

180+
178181
def test_iterator_rvpolicy():
179182
""" Issue 388: Can't make iterators via make_iterator() with different r/v policies """
180183
from pybind11_tests.issues import make_iterator_1
@@ -184,6 +187,7 @@ def test_iterator_rvpolicy():
184187
assert list(make_iterator_2()) == [1, 2, 3]
185188
assert(type(make_iterator_1()) != type(make_iterator_2()))
186189

190+
187191
def test_dupe_assignment():
188192
""" Issue 461: overwriting a class with a function """
189193
from pybind11_tests.issues import dupe_exception_failures
@@ -202,6 +206,7 @@ def test_enable_shared_from_this_with_reference_rvp():
202206
del child, parent
203207
assert cstats.alive() == 0
204208

209+
205210
def test_non_destructed_holders():
206211
""" Issue #478: unique ptrs constructed and freed without destruction """
207212
from pybind11_tests import SpecialHolderObj
@@ -218,3 +223,17 @@ def test_non_destructed_holders():
218223
assert cstats.alive() == 1
219224
del a
220225
assert cstats.alive() == 0
226+
227+
228+
def test_complex_cast(capture):
229+
""" Issue #484: number conversion generates unhandled exceptions """
230+
from pybind11_tests.issues import test_complex
231+
232+
with capture:
233+
test_complex(1)
234+
test_complex(2j)
235+
236+
assert capture == """
237+
1.0
238+
(0.0, 2.0)
239+
"""

0 commit comments

Comments
 (0)