Skip to content

Commit df15e13

Browse files
committed
Make string conversion stricter
The string conversion logic added in PR pybind#624 for all std::basic_strings was derived from the old std::wstring logic, but that was underused and turns out to have had a bug in accepting almost anything convertible to unicode, while the previous std::string logic was much stricter. This restores the previous std::string logic by only allowing actual unicode or string types. Fixes pybind#685.
1 parent dd01665 commit df15e13

File tree

3 files changed

+15
-0
lines changed

3 files changed

+15
-0
lines changed

include/pybind11/cast.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -657,6 +657,8 @@ struct type_caster<std::basic_string<CharT, Traits, Allocator>, enable_if_t<is_s
657657
return false;
658658
// The below is a guaranteed failure in Python 3 when PyUnicode_Check returns false
659659
#else
660+
if (!PYBIND11_BYTES_CHECK(load_src.ptr()))
661+
return false;
660662
temp = reinterpret_steal<object>(PyUnicode_FromObject(load_src.ptr()));
661663
if (!temp) { PyErr_Clear(); return false; }
662664
load_src = temp;

tests/test_numpy_array.cpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -150,4 +150,9 @@ test_initializer numpy_array([](py::module &m) {
150150
"array_t<double>"_a=py::array_t<double>(o)
151151
);
152152
});
153+
154+
// Issue 685: ndarray shouldn't go to std::string overload
155+
sm.def("issue685", [](std::string) { return "string"; });
156+
sm.def("issue685", [](py::array) { return "array"; });
157+
sm.def("issue685", [](py::object) { return "other"; });
153158
});

tests/test_numpy_array.py

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -272,3 +272,11 @@ def test_constructors():
272272
assert results["array"].dtype == np.int_
273273
assert results["array_t<int32>"].dtype == np.int32
274274
assert results["array_t<double>"].dtype == np.float64
275+
276+
277+
def test_greedy_string_overload(): # issue 685
278+
from pybind11_tests.array import issue685
279+
280+
assert issue685("abc") == "string"
281+
assert issue685(np.array([97, 98, 99], dtype='b')) == "array"
282+
assert issue685(123) == "other"

0 commit comments

Comments
 (0)