Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Adding tests specifically to exercise pybind11::str::raw_str. #2366

Merged
merged 1 commit into from
Aug 11, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions tests/test_pytypes.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -237,6 +237,8 @@ TEST_SUBMODULE(pytypes, m) {
);
});

m.def("convert_to_pybind11_str", [](py::object o) { return py::str(o); });

m.def("get_implicit_casting", []() {
py::dict d;
d["char*_i1"] = "abc";
Expand Down
32 changes: 32 additions & 0 deletions tests/test_pytypes.py
Original file line number Diff line number Diff line change
Expand Up @@ -220,6 +220,38 @@ def test_constructors():
assert noconv2[k] is expected[k]


def test_pybind11_str_raw_str():
# specifically to exercise pybind11::str::raw_str
cvt = m.convert_to_pybind11_str
assert cvt(u"Str") == u"Str"
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This could also be:

pybind11_str = unicode if sys.version_info.major < 3 else str
for test in [u"Str",
             None,
             False,
             True,
             ...]:
    assert cvt(test) == pybind11_str(test)

Or do we need to be explicit here, line by line?

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I actually prefer it being explicit, just to make it as clear as possible, and permit specific branching.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Also fine. Let's leave it up to @rwgk, then :-)

assert cvt(b'Bytes') == u"Bytes" if str is bytes else "b'Bytes'"
assert cvt(None) == u"None"
assert cvt(False) == u"False"
assert cvt(True) == u"True"
assert cvt(42) == u"42"
assert cvt(2**65) == u"36893488147419103232"
assert cvt(-1.50) == u"-1.5"
assert cvt(()) == u"()"
assert cvt((18,)) == u"(18,)"
assert cvt([]) == u"[]"
assert cvt([28]) == u"[28]"
assert cvt({}) == u"{}"
assert cvt({3: 4}) == u"{3: 4}"
assert cvt(set()) == u"set([])" if str is bytes else "set()"
assert cvt({3, 3}) == u"set([3])" if str is bytes else "{3}"
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Another one, sorry. There're no funky unicode characters/string/weirdly encoded strings as bytes here!

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

And while you're add it, I don't know how much work it is, but some checks on types with custom __str__/__unicode__ methods might be interesting?


valid_orig = u"DZ"
valid_utf8 = valid_orig.encode("utf-8")
valid_cvt = cvt(valid_utf8)
assert type(valid_cvt) == bytes # Probably surprising.
assert valid_cvt == b'\xc7\xb1'

malformed_utf8 = b'\x80'
malformed_cvt = cvt(malformed_utf8)
assert type(malformed_cvt) == bytes # Probably surprising.
assert malformed_cvt == b'\x80'


def test_implicit_casting():
"""Tests implicit casting when assigning or appending to dicts and lists."""
z = m.get_implicit_casting()
Expand Down