From c9149d995c801831632b654e0e8e65f2f2f31e2b Mon Sep 17 00:00:00 2001 From: Sergei Izmailov Date: Wed, 13 Sep 2023 04:46:58 +0900 Subject: [PATCH 1/3] fix: Use lowercase builtin collection names (#4833) --- include/pybind11/cast.h | 2 +- include/pybind11/stl.h | 8 ++++---- tests/test_builtin_casters.py | 4 ++-- tests/test_kwargs_and_defaults.py | 2 +- tests/test_stl.py | 24 ++++++++++++------------ 5 files changed, 20 insertions(+), 20 deletions(-) diff --git a/include/pybind11/cast.h b/include/pybind11/cast.h index 8a4e2e647..99bf4fac3 100644 --- a/include/pybind11/cast.h +++ b/include/pybind11/cast.h @@ -661,7 +661,7 @@ public: } static constexpr auto name - = const_name("Tuple[") + concat(make_caster::name...) + const_name("]"); + = const_name("tuple[") + concat(make_caster::name...) + const_name("]"); template using cast_op_type = type; diff --git a/include/pybind11/stl.h b/include/pybind11/stl.h index f39f44f7c..6eb485991 100644 --- a/include/pybind11/stl.h +++ b/include/pybind11/stl.h @@ -100,7 +100,7 @@ public: return s.release(); } - PYBIND11_TYPE_CASTER(type, const_name("Set[") + key_conv::name + const_name("]")); + PYBIND11_TYPE_CASTER(type, const_name("set[") + key_conv::name + const_name("]")); }; template @@ -157,7 +157,7 @@ public: } PYBIND11_TYPE_CASTER(Type, - const_name("Dict[") + key_conv::name + const_name(", ") + value_conv::name + const_name("dict[") + key_conv::name + const_name(", ") + value_conv::name + const_name("]")); }; @@ -208,7 +208,7 @@ public: return l.release(); } - PYBIND11_TYPE_CASTER(Type, const_name("List[") + value_conv::name + const_name("]")); + PYBIND11_TYPE_CASTER(Type, const_name("list[") + value_conv::name + const_name("]")); }; template @@ -274,7 +274,7 @@ public: PYBIND11_TYPE_CASTER(ArrayType, const_name(const_name(""), const_name("Annotated[")) - + const_name("List[") + value_conv::name + const_name("]") + + const_name("list[") + value_conv::name + const_name("]") + const_name(const_name(""), const_name(", FixedSize(") + const_name() + const_name(")]"))); diff --git a/tests/test_builtin_casters.py b/tests/test_builtin_casters.py index b1f57bdd9..dbac1cbc2 100644 --- a/tests/test_builtin_casters.py +++ b/tests/test_builtin_casters.py @@ -352,7 +352,7 @@ def test_tuple(doc): assert ( doc(m.pair_passthrough) == """ - pair_passthrough(arg0: Tuple[bool, str]) -> Tuple[str, bool] + pair_passthrough(arg0: tuple[bool, str]) -> tuple[str, bool] Return a pair in reversed order """ @@ -360,7 +360,7 @@ def test_tuple(doc): assert ( doc(m.tuple_passthrough) == """ - tuple_passthrough(arg0: Tuple[bool, str, int]) -> Tuple[int, str, bool] + tuple_passthrough(arg0: tuple[bool, str, int]) -> tuple[int, str, bool] Return a triple in reversed order """ diff --git a/tests/test_kwargs_and_defaults.py b/tests/test_kwargs_and_defaults.py index b57700197..9d9738de7 100644 --- a/tests/test_kwargs_and_defaults.py +++ b/tests/test_kwargs_and_defaults.py @@ -8,7 +8,7 @@ def test_function_signatures(doc): assert doc(m.kw_func1) == "kw_func1(x: int, y: int) -> str" assert doc(m.kw_func2) == "kw_func2(x: int = 100, y: int = 200) -> str" assert doc(m.kw_func3) == "kw_func3(data: str = 'Hello world!') -> None" - assert doc(m.kw_func4) == "kw_func4(myList: List[int] = [13, 17]) -> str" + assert doc(m.kw_func4) == "kw_func4(myList: list[int] = [13, 17]) -> str" assert doc(m.kw_func_udl) == "kw_func_udl(x: int, y: int = 300) -> str" assert doc(m.kw_func_udl_z) == "kw_func_udl_z(x: int, y: int = 0) -> str" assert doc(m.args_function) == "args_function(*args) -> tuple" diff --git a/tests/test_stl.py b/tests/test_stl.py index 8a614f8b8..b08bd4680 100644 --- a/tests/test_stl.py +++ b/tests/test_stl.py @@ -16,8 +16,8 @@ def test_vector(doc): assert m.load_bool_vector([True, False]) assert m.load_bool_vector((True, False)) - assert doc(m.cast_vector) == "cast_vector() -> List[int]" - assert doc(m.load_vector) == "load_vector(arg0: List[int]) -> bool" + assert doc(m.cast_vector) == "cast_vector() -> list[int]" + assert doc(m.load_vector) == "load_vector(arg0: list[int]) -> bool" # Test regression caused by 936: pointers to stl containers weren't castable assert m.cast_ptr_vector() == ["lvalue", "lvalue"] @@ -39,10 +39,10 @@ def test_array(doc): assert m.load_array(lst) assert m.load_array(tuple(lst)) - assert doc(m.cast_array) == "cast_array() -> Annotated[List[int], FixedSize(2)]" + assert doc(m.cast_array) == "cast_array() -> Annotated[list[int], FixedSize(2)]" assert ( doc(m.load_array) - == "load_array(arg0: Annotated[List[int], FixedSize(2)]) -> bool" + == "load_array(arg0: Annotated[list[int], FixedSize(2)]) -> bool" ) @@ -53,8 +53,8 @@ def test_valarray(doc): assert m.load_valarray(lst) assert m.load_valarray(tuple(lst)) - assert doc(m.cast_valarray) == "cast_valarray() -> List[int]" - assert doc(m.load_valarray) == "load_valarray(arg0: List[int]) -> bool" + assert doc(m.cast_valarray) == "cast_valarray() -> list[int]" + assert doc(m.load_valarray) == "load_valarray(arg0: list[int]) -> bool" def test_map(doc): @@ -66,8 +66,8 @@ def test_map(doc): assert "key2" in d assert m.load_map(d) - assert doc(m.cast_map) == "cast_map() -> Dict[str, str]" - assert doc(m.load_map) == "load_map(arg0: Dict[str, str]) -> bool" + assert doc(m.cast_map) == "cast_map() -> dict[str, str]" + assert doc(m.load_map) == "load_map(arg0: dict[str, str]) -> bool" def test_set(doc): @@ -78,8 +78,8 @@ def test_set(doc): assert m.load_set(s) assert m.load_set(frozenset(s)) - assert doc(m.cast_set) == "cast_set() -> Set[str]" - assert doc(m.load_set) == "load_set(arg0: Set[str]) -> bool" + assert doc(m.cast_set) == "cast_set() -> set[str]" + assert doc(m.load_set) == "load_set(arg0: set[str]) -> bool" def test_recursive_casting(): @@ -303,7 +303,7 @@ def test_stl_pass_by_pointer(msg): msg(excinfo.value) == """ stl_pass_by_pointer(): incompatible function arguments. The following argument types are supported: - 1. (v: List[int] = None) -> List[int] + 1. (v: list[int] = None) -> list[int] Invoked with: """ @@ -315,7 +315,7 @@ def test_stl_pass_by_pointer(msg): msg(excinfo.value) == """ stl_pass_by_pointer(): incompatible function arguments. The following argument types are supported: - 1. (v: List[int] = None) -> List[int] + 1. (v: list[int] = None) -> list[int] Invoked with: None """ From b4573674bc65a7842b49be45d63b582f4c15d1b4 Mon Sep 17 00:00:00 2001 From: Sergei Izmailov Date: Wed, 13 Sep 2023 04:47:39 +0900 Subject: [PATCH 2/3] Update render for buffer sequence and handle (#4831) * fix: Add capitalize render name of `py::buffer` and `py::sequence` * fix: Render `py::handle` same way as `py::object` * tests: Fix tests `handle` -> `object` * tests: Test capitaliation of `py::sequence` and `py::buffer` * style: pre-commit fixes * fix: Render `py::object` as `Any` * Revert "fix: Render `py::object` as `Any`" This reverts commit 7861dcfabb78ac210b4c67c35a0d47fb67525a96. --------- Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com> Co-authored-by: Ralf W. Grosse-Kunstleve --- include/pybind11/cast.h | 12 ++++++++++++ tests/test_buffers.py | 7 +++++++ tests/test_factory_constructors.py | 4 ++-- tests/test_sequences_and_iterators.py | 4 ++++ 4 files changed, 25 insertions(+), 2 deletions(-) diff --git a/include/pybind11/cast.h b/include/pybind11/cast.h index 99bf4fac3..3c9b7c927 100644 --- a/include/pybind11/cast.h +++ b/include/pybind11/cast.h @@ -882,6 +882,10 @@ struct handle_type_name { static constexpr auto name = const_name(PYBIND11_BYTES_NAME); }; template <> +struct handle_type_name { + static constexpr auto name = const_name("Buffer"); +}; +template <> struct handle_type_name { static constexpr auto name = const_name("int"); }; @@ -902,10 +906,18 @@ struct handle_type_name { static constexpr auto name = const_name("Callable"); }; template <> +struct handle_type_name { + static constexpr auto name = handle_type_name::name; +}; +template <> struct handle_type_name { static constexpr auto name = const_name("None"); }; template <> +struct handle_type_name { + static constexpr auto name = const_name("Sequence"); +}; +template <> struct handle_type_name { static constexpr auto name = const_name("*args"); }; diff --git a/tests/test_buffers.py b/tests/test_buffers.py index 63d9d869f..5d33625ba 100644 --- a/tests/test_buffers.py +++ b/tests/test_buffers.py @@ -219,3 +219,10 @@ def test_ctypes_from_buffer(): assert cinfo.shape == pyinfo.shape assert cinfo.strides == pyinfo.strides assert not cinfo.readonly + + +def test_buffer_docstring(): + assert ( + m.get_buffer_info.__doc__.strip() + == "get_buffer_info(arg0: Buffer) -> pybind11_tests.buffers.buffer_info" + ) diff --git a/tests/test_factory_constructors.py b/tests/test_factory_constructors.py index 04df80260..a9004cbf6 100644 --- a/tests/test_factory_constructors.py +++ b/tests/test_factory_constructors.py @@ -77,7 +77,7 @@ def test_init_factory_signature(msg): 1. m.factory_constructors.TestFactory1(arg0: m.factory_constructors.tag.unique_ptr_tag, arg1: int) 2. m.factory_constructors.TestFactory1(arg0: str) 3. m.factory_constructors.TestFactory1(arg0: m.factory_constructors.tag.pointer_tag) - 4. m.factory_constructors.TestFactory1(arg0: handle, arg1: int, arg2: handle) + 4. m.factory_constructors.TestFactory1(arg0: object, arg1: int, arg2: object) Invoked with: 'invalid', 'constructor', 'arguments' """ @@ -95,7 +95,7 @@ def test_init_factory_signature(msg): 3. __init__(self: m.factory_constructors.TestFactory1, arg0: m.factory_constructors.tag.pointer_tag) -> None - 4. __init__(self: m.factory_constructors.TestFactory1, arg0: handle, arg1: int, arg2: handle) -> None + 4. __init__(self: m.factory_constructors.TestFactory1, arg0: object, arg1: int, arg2: object) -> None """ ) diff --git a/tests/test_sequences_and_iterators.py b/tests/test_sequences_and_iterators.py index dc129f2bf..acbe9d898 100644 --- a/tests/test_sequences_and_iterators.py +++ b/tests/test_sequences_and_iterators.py @@ -171,6 +171,10 @@ def test_sequence_length(): assert m.sequence_length("hello") == 5 +def test_sequence_doc(): + assert m.sequence_length.__doc__.strip() == "sequence_length(arg0: Sequence) -> int" + + def test_map_iterator(): sm = m.StringMap({"hi": "bye", "black": "white"}) assert sm["hi"] == "bye" From 8c7b8dd0ae74b36b7d42f77b0dd4096ebb7f4ab1 Mon Sep 17 00:00:00 2001 From: Sergei Izmailov Date: Wed, 13 Sep 2023 04:48:27 +0900 Subject: [PATCH 3/3] fix: Missing typed variants of `iterator` and `iterable` (#4832) --- include/pybind11/typing.h | 20 ++++++++++++++++++++ tests/test_pytypes.cpp | 2 ++ tests/test_pytypes.py | 14 ++++++++++++++ 3 files changed, 36 insertions(+) diff --git a/include/pybind11/typing.h b/include/pybind11/typing.h index 74fd82eac..b7b1a4e54 100644 --- a/include/pybind11/typing.h +++ b/include/pybind11/typing.h @@ -45,6 +45,16 @@ class Set : public set { using set::set; }; +template +class Iterable : public iterable { + using iterable::iterable; +}; + +template +class Iterator : public iterator { + using iterator::iterator; +}; + template class Callable; @@ -85,6 +95,16 @@ struct handle_type_name> { static constexpr auto name = const_name("set[") + make_caster::name + const_name("]"); }; +template +struct handle_type_name> { + static constexpr auto name = const_name("Iterable[") + make_caster::name + const_name("]"); +}; + +template +struct handle_type_name> { + static constexpr auto name = const_name("Iterator[") + make_caster::name + const_name("]"); +}; + template struct handle_type_name> { using retval_type = conditional_t::value, void_type, Return>; diff --git a/tests/test_pytypes.cpp b/tests/test_pytypes.cpp index b03f5624e..0a587680f 100644 --- a/tests/test_pytypes.cpp +++ b/tests/test_pytypes.cpp @@ -828,6 +828,8 @@ TEST_SUBMODULE(pytypes, m) { m.def("annotate_dict_str_int", [](const py::typing::Dict &) {}); m.def("annotate_list_int", [](const py::typing::List &) {}); m.def("annotate_set_str", [](const py::typing::Set &) {}); + m.def("annotate_iterable_str", [](const py::typing::Iterable &) {}); + m.def("annotate_iterator_int", [](const py::typing::Iterator &) {}); m.def("annotate_fn", [](const py::typing::Callable, py::str)> &) {}); } diff --git a/tests/test_pytypes.py b/tests/test_pytypes.py index e88a9328f..2b2027316 100644 --- a/tests/test_pytypes.py +++ b/tests/test_pytypes.py @@ -926,6 +926,20 @@ def test_set_annotations(doc): assert doc(m.annotate_set_str) == "annotate_set_str(arg0: set[str]) -> None" +def test_iterable_annotations(doc): + assert ( + doc(m.annotate_iterable_str) + == "annotate_iterable_str(arg0: Iterable[str]) -> None" + ) + + +def test_iterator_annotations(doc): + assert ( + doc(m.annotate_iterator_int) + == "annotate_iterator_int(arg0: Iterator[int]) -> None" + ) + + def test_fn_annotations(doc): assert ( doc(m.annotate_fn)