Skip to content

Commit 468513d

Browse files
committed
adding @jagerman's isinstance<str> specialization for Python 3 only
1 parent dda9bc8 commit 468513d

File tree

3 files changed

+26
-1
lines changed

3 files changed

+26
-1
lines changed

include/pybind11/pytypes.h

+4
Original file line numberDiff line numberDiff line change
@@ -943,6 +943,10 @@ class str : public object {
943943
};
944944
/// @} pytypes
945945

946+
#if PY_MAJOR_VERSION >= 3
947+
template <> inline bool isinstance<str>(handle obj) { return PyUnicode_Check(obj.ptr()); }
948+
#endif
949+
946950
inline namespace literals {
947951
/** \rst
948952
String literal version of `str`

tests/test_pytypes.cpp

+3
Original file line numberDiff line numberDiff line change
@@ -370,4 +370,7 @@ TEST_SUBMODULE(pytypes, m) {
370370

371371
m.def("isinstance_str", [](py::object o) { return py::isinstance<py::str>(o); });
372372
m.def("isinstance_bytes", [](py::object o) { return py::isinstance<py::bytes>(o); });
373+
374+
m.def("pass_to_std_string", [](std::string s) { return s.size(); });
375+
m.def("pass_to_py_str", [](py::str s) { return py::len(s); });
373376
}

tests/test_pytypes.py

+19-1
Original file line numberDiff line numberDiff line change
@@ -362,5 +362,23 @@ def test_isinstance_string_types():
362362
else:
363363
assert not isinstance(actual_bytes, str)
364364
assert isinstance(actual_unicode, str)
365-
assert m.isinstance_str(actual_bytes) # REALLY BAD for Python 3?
365+
assert not m.isinstance_str(actual_bytes)
366366
assert m.isinstance_str(actual_unicode)
367+
368+
369+
def test_pass_str_or_bytes_to_std_string():
370+
actual_bytes = b"bytes"
371+
actual_unicode = u"str"
372+
assert m.pass_to_std_string(actual_unicode) == 3
373+
assert m.pass_to_std_string(actual_bytes) == 5
374+
assert m.pass_to_py_str(actual_unicode) == 3
375+
if str is bytes: # Python 2
376+
m.pass_to_py_str(actual_bytes) == 5
377+
else:
378+
with pytest.raises(TypeError) as excinfo:
379+
m.pass_to_py_str(actual_bytes)
380+
assert str(excinfo.value) == """\
381+
pass_to_py_str(): incompatible function arguments. The following argument types are supported:
382+
1. (arg0: str) -> int
383+
384+
Invoked with: b'bytes'"""

0 commit comments

Comments
 (0)