diff --git a/include/pybind11/typing.h b/include/pybind11/typing.h index b7b1a4e54a..0ee329d85a 100644 --- a/include/pybind11/typing.h +++ b/include/pybind11/typing.h @@ -79,6 +79,13 @@ struct handle_type_name> { static constexpr auto name = const_name("tuple[()]"); }; +template +struct handle_type_name> { + // PEP 484 specifies this syntax for a variable-length tuple + static constexpr auto name + = const_name("tuple[") + make_caster::name + const_name(", ...]"); +}; + template struct handle_type_name> { static constexpr auto name = const_name("dict[") + make_caster::name + const_name(", ") diff --git a/tests/test_pytypes.cpp b/tests/test_pytypes.cpp index 0cd480ebba..e840eb61f8 100644 --- a/tests/test_pytypes.cpp +++ b/tests/test_pytypes.cpp @@ -825,6 +825,8 @@ TEST_SUBMODULE(pytypes, m) { m.def("annotate_tuple_float_str", [](const py::typing::Tuple &) {}); m.def("annotate_tuple_empty", [](const py::typing::Tuple<> &) {}); + m.def("annotate_tuple_variable_length", + [](const py::typing::Tuple &) {}); 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 &) {}); diff --git a/tests/test_pytypes.py b/tests/test_pytypes.py index 2b2027316c..cfb144523a 100644 --- a/tests/test_pytypes.py +++ b/tests/test_pytypes.py @@ -911,6 +911,13 @@ def test_tuple_empty_annotations(doc): ) +def test_tuple_variable_length_annotations(doc): + assert ( + doc(m.annotate_tuple_variable_length) + == "annotate_tuple_variable_length(arg0: tuple[float, ...]) -> None" + ) + + def test_dict_annotations(doc): assert ( doc(m.annotate_dict_str_int)