Revert "[smart_holder] Add a new return value policy `return_as_bytes` (#3838)"

This reverts commit 7064d43bc9.

Conflicts resolved in:
    include/pybind11/eigen.h
    tests/test_builtin_casters.cpp
This commit is contained in:
Ralf W. Grosse-Kunstleve 2024-06-10 19:19:37 -07:00 committed by Ralf W. Grosse-Kunstleve
parent e16b9eaa42
commit 0de9906459
8 changed files with 4 additions and 104 deletions

View File

@ -476,15 +476,11 @@ struct string_caster {
return true;
}
static handle cast(const StringType &src, return_value_policy policy, handle /* parent */) {
static handle
cast(const StringType &src, return_value_policy /* policy */, handle /* parent */) {
const char *buffer = reinterpret_cast<const char *>(src.data());
auto nbytes = ssize_t(src.size() * sizeof(CharT));
handle s;
if (policy == return_value_policy::_return_as_bytes) {
s = PyBytes_FromStringAndSize(buffer, nbytes);
} else {
s = decode_utfN(buffer, nbytes);
}
handle s = decode_utfN(buffer, nbytes);
if (!s) {
throw error_already_set();
}

View File

@ -542,19 +542,7 @@ enum class return_value_policy : uint8_t {
collected while Python is still using the child. More advanced
variations of this scheme are also possible using combinations of
return_value_policy::reference and the keep_alive call policy */
reference_internal,
/** With this policy, C++ string types are converted to Python bytes,
instead of str. This is most useful when a C++ function returns a
container-like type with nested C++ string types, and `py::bytes` cannot
be applied easily. Dictionary like types might not work, for example,
`Dict[str, bytes]`, because this policy forces all string return values
to be converted to bytes. Note that this return_value_policy is not
concerned with lifetime/ownership semantics, like the other policies,
but the purpose of _return_as_bytes is certain to be orthogonal, because
C++ strings are always copied to Python `bytes` or `str`.
NOTE: This policy is NOT available on master. */
_return_as_bytes
reference_internal
};
#define PYBIND11_HAS_RETURN_VALUE_POLICY_RETURN_AS_BYTES

View File

@ -909,15 +909,12 @@ struct smart_holder_type_caster<std::shared_ptr<T>> : smart_holder_type_caster_l
break;
case return_value_policy::take_ownership:
throw cast_error("Invalid return_value_policy for shared_ptr (take_ownership).");
break;
case return_value_policy::copy:
case return_value_policy::move:
break;
case return_value_policy::reference:
throw cast_error("Invalid return_value_policy for shared_ptr (reference).");
break;
case return_value_policy::reference_internal:
case return_value_policy::_return_as_bytes:
break;
}
if (!src) {

View File

@ -625,10 +625,6 @@ public:
keep_alive_impl(inst, parent);
break;
case return_value_policy::_return_as_bytes:
pybind11_fail("return_value_policy::_return_as_bytes does not apply.");
break;
default:
throw cast_error("unhandled return_value_policy: should not happen!");
}

View File

@ -11,17 +11,10 @@
#include "pybind11_tests.h"
#include <utility>
struct ConstRefCasted {
int tag;
};
struct StringAttr {
explicit StringAttr(std::string v) : value(std::move(v)) {}
std::string value;
};
PYBIND11_NAMESPACE_BEGIN(pybind11)
PYBIND11_NAMESPACE_BEGIN(detail)
template <>
@ -390,29 +383,5 @@ TEST_SUBMODULE(builtin_casters, m) {
m.def("takes_const_ref_wrap",
[](std::reference_wrapper<const ConstRefCasted> x) { return x.get().tag; });
// test return_value_policy::_return_as_bytes
m.def(
"invalid_utf8_string_as_bytes",
[]() { return std::string("\xba\xd0\xba\xd0"); },
py::return_value_policy::_return_as_bytes);
m.def("invalid_utf8_string_as_str", []() { return std::string("\xba\xd0\xba\xd0"); });
m.def(
"invalid_utf8_char_array_as_bytes",
[]() { return "\xba\xd0\xba\xd0"; },
py::return_value_policy::_return_as_bytes);
py::class_<StringAttr>(m, "StringAttr")
.def(py::init<std::string>())
.def_property(
"value",
py::cpp_function([](StringAttr &self) { return self.value; },
py::return_value_policy::_return_as_bytes),
py::cpp_function([](StringAttr &self, std::string v) { self.value = std::move(v); }));
#ifdef PYBIND11_HAS_STRING_VIEW
m.def(
"invalid_utf8_string_view_as_bytes",
[]() { return std::string_view("\xba\xd0\xba\xd0"); },
py::return_value_policy::_return_as_bytes);
#endif
PYBIND11_WARNING_POP
}

View File

@ -526,17 +526,3 @@ def test_const_ref_caster():
assert m.takes_const_ptr(x) == 5
assert m.takes_const_ref(x) == 4
assert m.takes_const_ref_wrap(x) == 4
def test_return_as_bytes_policy():
expected_return_value = b"\xba\xd0\xba\xd0"
assert m.invalid_utf8_string_as_bytes() == expected_return_value
with pytest.raises(UnicodeDecodeError):
m.invalid_utf8_string_as_str()
assert m.invalid_utf8_char_array_as_bytes() == expected_return_value
obj = m.StringAttr(expected_return_value)
assert obj.value == expected_return_value
obj.value = "123"
assert obj.value == b"123"
if hasattr(m, "has_string_view"):
assert m.invalid_utf8_string_view_as_bytes() == expected_return_value

View File

@ -546,25 +546,4 @@ TEST_SUBMODULE(stl, m) {
[]() { return new std::vector<bool>(4513); },
// Without explicitly specifying `take_ownership`, this function leaks.
py::return_value_policy::take_ownership);
// test return_value_policy::_return_as_bytes
m.def(
"invalid_utf8_string_array_as_bytes",
[]() { return std::array<std::string, 1>{{"\xba\xd0\xba\xd0"}}; },
py::return_value_policy::_return_as_bytes);
m.def("invalid_utf8_string_array_as_str",
[]() { return std::array<std::string, 1>{{"\xba\xd0\xba\xd0"}}; });
#ifdef PYBIND11_HAS_OPTIONAL
m.def(
"invalid_utf8_optional_string_as_bytes",
[]() { return std::optional<std::string>{"\xba\xd0\xba\xd0"}; },
py::return_value_policy::_return_as_bytes);
#endif
#ifdef PYBIND11_TEST_VARIANT
m.def(
"invalid_utf8_variant_string_as_bytes",
[]() { return variant<std::string, int>{"\xba\xd0\xba\xd0"}; },
py::return_value_policy::_return_as_bytes);
#endif
}

View File

@ -379,14 +379,3 @@ def test_return_vector_bool_raw_ptr():
v = m.return_vector_bool_raw_ptr()
assert isinstance(v, list)
assert len(v) == 4513
def test_return_as_bytes_policy():
expected_return_value = b"\xba\xd0\xba\xd0"
assert m.invalid_utf8_string_array_as_bytes() == [expected_return_value]
with pytest.raises(UnicodeDecodeError):
m.invalid_utf8_string_array_as_str()
if hasattr(m, "has_optional"):
assert m.invalid_utf8_optional_string_as_bytes() == expected_return_value
if hasattr(m, "load_variant"):
assert m.invalid_utf8_variant_string_as_bytes() == expected_return_value