Commit 99773fc5 by Yannick Jadoul Committed by GitHub

fix: throw error_already_set in py::len on failing PyObject_Length (#2575)

* Throw error_already_set in py::len on failing PyObject_Length

* Fix tests to mach error message on PyPy
parent 2f746eee
......@@ -1530,13 +1530,17 @@ inline memoryview memoryview::from_buffer(
/// \addtogroup python_builtins
/// @{
/// Get the length of a Python object.
inline size_t len(handle h) {
ssize_t result = PyObject_Length(h.ptr());
if (result < 0)
pybind11_fail("Unable to compute length of object");
throw error_already_set();
return (size_t) result;
}
/// Get the length hint of a Python object.
/// Returns 0 when this cannot be determined.
inline size_t len_hint(handle h) {
#if PY_VERSION_HEX >= 0x03040000
ssize_t result = PyObject_LengthHint(h.ptr(), 0);
......
......@@ -407,4 +407,7 @@ TEST_SUBMODULE(pytypes, m) {
buf, static_cast<ssize_t>(strlen(buf)));
});
#endif
// test_builtin_functions
m.def("get_len", [](py::handle h) { return py::len(h); });
}
......@@ -424,3 +424,11 @@ def test_memoryview_from_memory():
assert isinstance(view, memoryview)
assert view.format == 'B'
assert bytes(view) == b'\xff\xe1\xab\x37'
def test_builtin_functions():
assert m.get_len([i for i in range(42)]) == 42
with pytest.raises(TypeError) as exc_info:
m.get_len(i for i in range(42))
assert str(exc_info.value) in ["object of type 'generator' has no len()",
"'generator' has no length"] # PyPy
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment