fix(types): add typing and collections.abc module prefix (#5663)

* Fix Python 3.8 type hints and add module prefix

These type hints are invalid in Python 3.8.
Add `typing.` prefix to remove ambiguity.

* style: pre-commit fixes

* Add module prefix to Union

* Rename macros

* Improve comment

* Comment out 3.8 type hint macros

Fixing this issue in Python 3.8 will require updating lots of tests. This can be added in a further pull request.

* Add Iterable module prefix

* Add module prefix to Iterator

* Add module prefix to Callable

* Re-add accidentally deleted brackets

* Add module prefix to Optional

* Add module prefix to Final

* Add module prefix to ClassVar

* Add module prefix to TypeGuard

* Add module prefix to TypeIs

* Add module prefix to NoReturn

* Add module prefix to Never

* Add module prefix to Literal

* Add module prefix to Callable

* Add module prefix to Sequence

* Add module prefix to Iterator

* style: pre-commit fixes

* Remove type hint macros

* style: pre-commit fixes

---------

Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
This commit is contained in:
gentlegiantJGC
2025-05-19 16:54:31 +01:00
committed by GitHub
parent 4587d33cf9
commit 67424358f4
13 changed files with 126 additions and 94 deletions

View File

@@ -1359,7 +1359,7 @@ struct handle_type_name<dict> {
};
template <>
struct handle_type_name<anyset> {
static constexpr auto name = const_name("Union[set, frozenset]");
static constexpr auto name = const_name("typing.Union[set, frozenset]");
};
template <>
struct handle_type_name<set> {
@@ -1395,11 +1395,11 @@ struct handle_type_name<int_> {
};
template <>
struct handle_type_name<iterable> {
static constexpr auto name = const_name("Iterable");
static constexpr auto name = const_name("collections.abc.Iterable");
};
template <>
struct handle_type_name<iterator> {
static constexpr auto name = const_name("Iterator");
static constexpr auto name = const_name("collections.abc.Iterator");
};
template <>
struct handle_type_name<float_> {
@@ -1407,7 +1407,7 @@ struct handle_type_name<float_> {
};
template <>
struct handle_type_name<function> {
static constexpr auto name = const_name("Callable");
static constexpr auto name = const_name("collections.abc.Callable");
};
template <>
struct handle_type_name<handle> {
@@ -1419,7 +1419,7 @@ struct handle_type_name<none> {
};
template <>
struct handle_type_name<sequence> {
static constexpr auto name = const_name("Sequence");
static constexpr auto name = const_name("collections.abc.Sequence");
};
template <>
struct handle_type_name<bytearray> {

View File

@@ -137,7 +137,7 @@ public:
PYBIND11_TYPE_CASTER(
type,
const_name("Callable[[")
const_name("collections.abc.Callable[[")
+ ::pybind11::detail::concat(::pybind11::detail::arg_descr(make_caster<Args>::name)...)
+ const_name("], ") + ::pybind11::detail::return_descr(make_caster<retval_type>::name)
+ const_name("]"));

View File

@@ -1252,7 +1252,7 @@ PYBIND11_NAMESPACE_END(function_record_PyTypeObject_methods)
template <>
struct handle_type_name<cpp_function> {
static constexpr auto name = const_name("Callable");
static constexpr auto name = const_name("collections.abc.Callable");
};
PYBIND11_NAMESPACE_END(detail)

View File

@@ -557,7 +557,8 @@ struct optional_caster {
return true;
}
PYBIND11_TYPE_CASTER(Type, const_name("Optional[") + value_conv::name + const_name("]"));
PYBIND11_TYPE_CASTER(Type,
const_name("typing.Optional[") + value_conv::name + const_name("]"));
};
#if defined(PYBIND11_HAS_OPTIONAL)
@@ -642,7 +643,7 @@ struct variant_caster<V<Ts...>> {
using Type = V<Ts...>;
PYBIND11_TYPE_CASTER(Type,
const_name("Union[")
const_name("typing.Union[")
+ ::pybind11::detail::concat(make_caster<Ts>::name...)
+ const_name("]"));
};

View File

@@ -96,7 +96,7 @@ public:
return true;
}
PYBIND11_TYPE_CASTER(T, io_name("Union[os.PathLike, str, bytes]", "pathlib.Path"));
PYBIND11_TYPE_CASTER(T, io_name("typing.Union[os.PathLike, str, bytes]", "pathlib.Path"));
};
#endif // PYBIND11_HAS_FILESYSTEM || defined(PYBIND11_HAS_EXPERIMENTAL_FILESYSTEM)

View File

@@ -182,19 +182,21 @@ struct handle_type_name<typing::Set<T>> {
template <typename T>
struct handle_type_name<typing::Iterable<T>> {
static constexpr auto name = const_name("Iterable[") + make_caster<T>::name + const_name("]");
static constexpr auto name
= const_name("collections.abc.Iterable[") + make_caster<T>::name + const_name("]");
};
template <typename T>
struct handle_type_name<typing::Iterator<T>> {
static constexpr auto name = const_name("Iterator[") + make_caster<T>::name + const_name("]");
static constexpr auto name
= const_name("collections.abc.Iterator[") + make_caster<T>::name + const_name("]");
};
template <typename Return, typename... Args>
struct handle_type_name<typing::Callable<Return(Args...)>> {
using retval_type = conditional_t<std::is_same<Return, void>::value, void_type, Return>;
static constexpr auto name
= const_name("Callable[[")
= const_name("collections.abc.Callable[[")
+ ::pybind11::detail::concat(::pybind11::detail::arg_descr(make_caster<Args>::name)...)
+ const_name("], ") + ::pybind11::detail::return_descr(make_caster<retval_type>::name)
+ const_name("]");
@@ -204,7 +206,7 @@ template <typename Return>
struct handle_type_name<typing::Callable<Return(ellipsis)>> {
// PEP 484 specifies this syntax for defining only return types of callables
using retval_type = conditional_t<std::is_same<Return, void>::value, void_type, Return>;
static constexpr auto name = const_name("Callable[..., ")
static constexpr auto name = const_name("collections.abc.Callable[..., ")
+ ::pybind11::detail::return_descr(make_caster<retval_type>::name)
+ const_name("]");
};
@@ -216,46 +218,50 @@ struct handle_type_name<typing::Type<T>> {
template <typename... Types>
struct handle_type_name<typing::Union<Types...>> {
static constexpr auto name = const_name("Union[")
static constexpr auto name = const_name("typing.Union[")
+ ::pybind11::detail::concat(make_caster<Types>::name...)
+ const_name("]");
};
template <typename T>
struct handle_type_name<typing::Optional<T>> {
static constexpr auto name = const_name("Optional[") + make_caster<T>::name + const_name("]");
static constexpr auto name
= const_name("typing.Optional[") + make_caster<T>::name + const_name("]");
};
template <typename T>
struct handle_type_name<typing::Final<T>> {
static constexpr auto name = const_name("Final[")
static constexpr auto name = const_name("typing.Final[")
+ ::pybind11::detail::return_descr(make_caster<T>::name)
+ const_name("]");
};
template <typename T>
struct handle_type_name<typing::ClassVar<T>> {
static constexpr auto name = const_name("ClassVar[") + make_caster<T>::name + const_name("]");
static constexpr auto name
= const_name("typing.ClassVar[") + make_caster<T>::name + const_name("]");
};
template <typename T>
struct handle_type_name<typing::TypeGuard<T>> {
static constexpr auto name = const_name("TypeGuard[") + make_caster<T>::name + const_name("]");
static constexpr auto name
= const_name("typing.TypeGuard[") + make_caster<T>::name + const_name("]");
};
template <typename T>
struct handle_type_name<typing::TypeIs<T>> {
static constexpr auto name = const_name("TypeIs[") + make_caster<T>::name + const_name("]");
static constexpr auto name
= const_name("typing.TypeIs[") + make_caster<T>::name + const_name("]");
};
template <>
struct handle_type_name<typing::NoReturn> {
static constexpr auto name = const_name("NoReturn");
static constexpr auto name = const_name("typing.NoReturn");
};
template <>
struct handle_type_name<typing::Never> {
static constexpr auto name = const_name("Never");
static constexpr auto name = const_name("typing.Never");
};
#if defined(PYBIND11_TYPING_H_HAS_STRING_LITERAL)
@@ -281,7 +287,7 @@ consteval auto sanitize_string_literal() {
template <typing::StringLiteral... Literals>
struct handle_type_name<typing::Literal<Literals...>> {
static constexpr auto name
= const_name("Literal[")
= const_name("typing.Literal[")
+ pybind11::detail::concat(const_name(sanitize_string_literal<Literals>().name)...)
+ const_name("]");
};

View File

@@ -140,11 +140,11 @@ def test_cpp_function_roundtrip():
def test_function_signatures(doc):
assert (
doc(m.test_callback3)
== "test_callback3(arg0: Callable[[typing.SupportsInt], int]) -> str"
== "test_callback3(arg0: collections.abc.Callable[[typing.SupportsInt], int]) -> str"
)
assert (
doc(m.test_callback4)
== "test_callback4() -> Callable[[typing.SupportsInt], int]"
== "test_callback4() -> collections.abc.Callable[[typing.SupportsInt], int]"
)
@@ -231,7 +231,7 @@ def test_custom_func2():
def test_callback_docstring():
assert (
m.test_tuple_unpacking.__doc__.strip()
== "test_tuple_unpacking(arg0: Callable) -> object"
== "test_tuple_unpacking(arg0: collections.abc.Callable) -> object"
)

View File

@@ -23,8 +23,9 @@ struct type_caster<user_space::Point2D> {
// This macro inserts a lot of boilerplate code and sets the type hint.
// `io_name` is used to specify different type hints for arguments and return values.
// The signature of our negate function would then look like:
// `negate(Sequence[float]) -> tuple[float, float]`
PYBIND11_TYPE_CASTER(user_space::Point2D, io_name("Sequence[float]", "tuple[float, float]"));
// `negate(collections.abc.Sequence[float]) -> tuple[float, float]`
PYBIND11_TYPE_CASTER(user_space::Point2D,
io_name("collections.abc.Sequence[float]", "tuple[float, float]"));
// C++ -> Python: convert `Point2D` to `tuple[float, float]`. The second and third arguments
// are used to indicate the return value policy and parent object (for

View File

@@ -21,7 +21,10 @@ def assert_negate_function(
def test_negate(doc: SanitizedString) -> None:
assert doc(m.negate) == "negate(arg0: Sequence[float]) -> tuple[float, float]"
assert (
doc(m.negate)
== "negate(arg0: collections.abc.Sequence[float]) -> tuple[float, float]"
)
assert_negate_function([1.0, -1.0], (-1.0, 1.0))
assert_negate_function((1.0, -1.0), (-1.0, 1.0))
assert_negate_function([1, -1], (-1.0, 1.0))

View File

@@ -155,7 +155,7 @@ namespace detail {
template <>
struct type_caster<RealNumber> {
PYBIND11_TYPE_CASTER(RealNumber, io_name("Union[float, int]", "float"));
PYBIND11_TYPE_CASTER(RealNumber, io_name("typing.Union[float, int]", "float"));
static handle cast(const RealNumber &number, return_value_policy, handle) {
return py::float_(number.value).release();

View File

@@ -31,7 +31,7 @@ def test_int(doc):
def test_iterator(doc):
assert doc(m.get_iterator) == "get_iterator() -> Iterator"
assert doc(m.get_iterator) == "get_iterator() -> collections.abc.Iterator"
@pytest.mark.parametrize(
@@ -51,7 +51,7 @@ def test_from_iterable(pytype, from_iter_func):
def test_iterable(doc):
assert doc(m.get_iterable) == "get_iterable() -> Iterable"
assert doc(m.get_iterable) == "get_iterable() -> collections.abc.Iterable"
lst = [1, 2, 3]
i = m.get_first_item_from_iterable(lst)
assert i == 1
@@ -130,7 +130,10 @@ def test_set(capture, doc):
assert m.anyset_contains({"foo"}, "foo")
assert doc(m.get_set) == "get_set() -> set"
assert doc(m.print_anyset) == "print_anyset(arg0: Union[set, frozenset]) -> None"
assert (
doc(m.print_anyset)
== "print_anyset(arg0: typing.Union[set, frozenset]) -> None"
)
def test_frozenset(capture, doc):
@@ -955,28 +958,28 @@ def test_set_annotations(doc):
def test_iterable_annotations(doc):
assert (
doc(m.annotate_iterable_str)
== "annotate_iterable_str(arg0: Iterable[str]) -> None"
== "annotate_iterable_str(arg0: collections.abc.Iterable[str]) -> None"
)
def test_iterator_annotations(doc):
assert (
doc(m.annotate_iterator_int)
== "annotate_iterator_int(arg0: Iterator[typing.SupportsInt]) -> None"
== "annotate_iterator_int(arg0: collections.abc.Iterator[typing.SupportsInt]) -> None"
)
def test_fn_annotations(doc):
assert (
doc(m.annotate_fn)
== "annotate_fn(arg0: Callable[[list[str], str], int]) -> None"
== "annotate_fn(arg0: collections.abc.Callable[[list[str], str], int]) -> None"
)
def test_fn_return_only(doc):
assert (
doc(m.annotate_fn_only_return)
== "annotate_fn_only_return(arg0: Callable[..., int]) -> None"
== "annotate_fn_only_return(arg0: collections.abc.Callable[..., int]) -> None"
)
@@ -989,54 +992,57 @@ def test_type_annotation(doc):
def test_union_annotations(doc):
assert (
doc(m.annotate_union)
== "annotate_union(arg0: list[Union[str, typing.SupportsInt, object]], arg1: str, arg2: typing.SupportsInt, arg3: object) -> list[Union[str, int, object]]"
== "annotate_union(arg0: list[typing.Union[str, typing.SupportsInt, object]], arg1: str, arg2: typing.SupportsInt, arg3: object) -> list[typing.Union[str, int, object]]"
)
def test_union_typing_only(doc):
assert (
doc(m.union_typing_only)
== "union_typing_only(arg0: list[Union[str]]) -> list[Union[int]]"
== "union_typing_only(arg0: list[typing.Union[str]]) -> list[typing.Union[int]]"
)
def test_union_object_annotations(doc):
assert (
doc(m.annotate_union_to_object)
== "annotate_union_to_object(arg0: Union[typing.SupportsInt, str]) -> object"
== "annotate_union_to_object(arg0: typing.Union[typing.SupportsInt, str]) -> object"
)
def test_optional_annotations(doc):
assert (
doc(m.annotate_optional)
== "annotate_optional(arg0: list) -> list[Optional[str]]"
== "annotate_optional(arg0: list) -> list[typing.Optional[str]]"
)
def test_type_guard_annotations(doc):
assert (
doc(m.annotate_type_guard)
== "annotate_type_guard(arg0: object) -> TypeGuard[str]"
== "annotate_type_guard(arg0: object) -> typing.TypeGuard[str]"
)
def test_type_is_annotations(doc):
assert doc(m.annotate_type_is) == "annotate_type_is(arg0: object) -> TypeIs[str]"
assert (
doc(m.annotate_type_is)
== "annotate_type_is(arg0: object) -> typing.TypeIs[str]"
)
def test_no_return_annotation(doc):
assert doc(m.annotate_no_return) == "annotate_no_return() -> NoReturn"
assert doc(m.annotate_no_return) == "annotate_no_return() -> typing.NoReturn"
def test_never_annotation(doc):
assert doc(m.annotate_never) == "annotate_never() -> Never"
assert doc(m.annotate_never) == "annotate_never() -> typing.Never"
def test_optional_object_annotations(doc):
assert (
doc(m.annotate_optional_to_object)
== "annotate_optional_to_object(arg0: Optional[typing.SupportsInt]) -> object"
== "annotate_optional_to_object(arg0: typing.Optional[typing.SupportsInt]) -> object"
)
@@ -1047,40 +1053,40 @@ def test_optional_object_annotations(doc):
def test_literal(doc):
assert (
doc(m.annotate_literal)
== 'annotate_literal(arg0: Literal[26, 0x1A, "hello world", b"hello world", u"hello world", True, Color.RED, None]) -> object'
== 'annotate_literal(arg0: typing.Literal[26, 0x1A, "hello world", b"hello world", u"hello world", True, Color.RED, None]) -> object'
)
# The characters !, @, %, {, } and -> are used in the signature parser as special characters, but Literal should escape those for the parser to work.
assert (
doc(m.identity_literal_exclamation)
== 'identity_literal_exclamation(arg0: Literal["!"]) -> Literal["!"]'
== 'identity_literal_exclamation(arg0: typing.Literal["!"]) -> typing.Literal["!"]'
)
assert (
doc(m.identity_literal_at)
== 'identity_literal_at(arg0: Literal["@"]) -> Literal["@"]'
== 'identity_literal_at(arg0: typing.Literal["@"]) -> typing.Literal["@"]'
)
assert (
doc(m.identity_literal_percent)
== 'identity_literal_percent(arg0: Literal["%"]) -> Literal["%"]'
== 'identity_literal_percent(arg0: typing.Literal["%"]) -> typing.Literal["%"]'
)
assert (
doc(m.identity_literal_curly_open)
== 'identity_literal_curly_open(arg0: Literal["{"]) -> Literal["{"]'
== 'identity_literal_curly_open(arg0: typing.Literal["{"]) -> typing.Literal["{"]'
)
assert (
doc(m.identity_literal_curly_close)
== 'identity_literal_curly_close(arg0: Literal["}"]) -> Literal["}"]'
== 'identity_literal_curly_close(arg0: typing.Literal["}"]) -> typing.Literal["}"]'
)
assert (
doc(m.identity_literal_arrow_with_io_name)
== 'identity_literal_arrow_with_io_name(arg0: Literal["->"], arg1: Union[float, int]) -> Literal["->"]'
== 'identity_literal_arrow_with_io_name(arg0: typing.Literal["->"], arg1: typing.Union[float, int]) -> typing.Literal["->"]'
)
assert (
doc(m.identity_literal_arrow_with_callable)
== 'identity_literal_arrow_with_callable(arg0: Callable[[Literal["->"], Union[float, int]], float]) -> Callable[[Literal["->"], Union[float, int]], float]'
== 'identity_literal_arrow_with_callable(arg0: collections.abc.Callable[[typing.Literal["->"], typing.Union[float, int]], float]) -> collections.abc.Callable[[typing.Literal["->"], typing.Union[float, int]], float]'
)
assert (
doc(m.identity_literal_all_special_chars)
== 'identity_literal_all_special_chars(arg0: Literal["!@!!->{%}"]) -> Literal["!@!!->{%}"]'
== 'identity_literal_all_special_chars(arg0: typing.Literal["!@!!->{%}"]) -> typing.Literal["!@!!->{%}"]'
)
@@ -1164,7 +1170,7 @@ def test_module_attribute_types() -> None:
assert module_annotations["foo"] == "pybind11_tests.pytypes.foo"
assert (
module_annotations["foo_union"]
== "Union[pybind11_tests.pytypes.foo, pybind11_tests.pytypes.foo2, pybind11_tests.pytypes.foo3]"
== "typing.Union[pybind11_tests.pytypes.foo, pybind11_tests.pytypes.foo2, pybind11_tests.pytypes.foo3]"
)
@@ -1195,9 +1201,10 @@ def test_class_attribute_types() -> None:
instance_annotations = get_annotations_helper(m.Instance)
assert empty_annotations is None
assert static_annotations["x"] == "ClassVar[typing.SupportsFloat]"
assert static_annotations["x"] == "typing.ClassVar[typing.SupportsFloat]"
assert (
static_annotations["dict_str_int"] == "ClassVar[dict[str, typing.SupportsInt]]"
static_annotations["dict_str_int"]
== "typing.ClassVar[dict[str, typing.SupportsInt]]"
)
assert m.Static.x == 1.0
@@ -1239,14 +1246,17 @@ def test_redeclaration_attr_with_type_hint() -> None:
)
def test_final_annotation() -> None:
module_annotations = get_annotations_helper(m)
assert module_annotations["CONST_INT"] == "Final[int]"
assert module_annotations["CONST_INT"] == "typing.Final[int]"
def test_arg_return_type_hints(doc):
assert doc(m.half_of_number) == "half_of_number(arg0: Union[float, int]) -> float"
assert (
doc(m.half_of_number)
== "half_of_number(arg0: typing.Union[float, int]) -> float"
)
assert (
doc(m.half_of_number_convert)
== "half_of_number_convert(x: Union[float, int]) -> float"
== "half_of_number_convert(x: typing.Union[float, int]) -> float"
)
assert (
doc(m.half_of_number_noconvert) == "half_of_number_noconvert(x: float) -> float"
@@ -1259,87 +1269,87 @@ def test_arg_return_type_hints(doc):
# std::vector<T>
assert (
doc(m.half_of_number_vector)
== "half_of_number_vector(arg0: collections.abc.Sequence[Union[float, int]]) -> list[float]"
== "half_of_number_vector(arg0: collections.abc.Sequence[typing.Union[float, int]]) -> list[float]"
)
# Tuple<T, T>
assert (
doc(m.half_of_number_tuple)
== "half_of_number_tuple(arg0: tuple[Union[float, int], Union[float, int]]) -> tuple[float, float]"
== "half_of_number_tuple(arg0: tuple[typing.Union[float, int], typing.Union[float, int]]) -> tuple[float, float]"
)
# Tuple<T, ...>
assert (
doc(m.half_of_number_tuple_ellipsis)
== "half_of_number_tuple_ellipsis(arg0: tuple[Union[float, int], ...]) -> tuple[float, ...]"
== "half_of_number_tuple_ellipsis(arg0: tuple[typing.Union[float, int], ...]) -> tuple[float, ...]"
)
# Dict<K, V>
assert (
doc(m.half_of_number_dict)
== "half_of_number_dict(arg0: dict[str, Union[float, int]]) -> dict[str, float]"
== "half_of_number_dict(arg0: dict[str, typing.Union[float, int]]) -> dict[str, float]"
)
# List<T>
assert (
doc(m.half_of_number_list)
== "half_of_number_list(arg0: list[Union[float, int]]) -> list[float]"
== "half_of_number_list(arg0: list[typing.Union[float, int]]) -> list[float]"
)
# List<List<T>>
assert (
doc(m.half_of_number_nested_list)
== "half_of_number_nested_list(arg0: list[list[Union[float, int]]]) -> list[list[float]]"
== "half_of_number_nested_list(arg0: list[list[typing.Union[float, int]]]) -> list[list[float]]"
)
# Set<T>
assert (
doc(m.identity_set)
== "identity_set(arg0: set[Union[float, int]]) -> set[float]"
== "identity_set(arg0: set[typing.Union[float, int]]) -> set[float]"
)
# Iterable<T>
assert (
doc(m.identity_iterable)
== "identity_iterable(arg0: Iterable[Union[float, int]]) -> Iterable[float]"
== "identity_iterable(arg0: collections.abc.Iterable[typing.Union[float, int]]) -> collections.abc.Iterable[float]"
)
# Iterator<T>
assert (
doc(m.identity_iterator)
== "identity_iterator(arg0: Iterator[Union[float, int]]) -> Iterator[float]"
== "identity_iterator(arg0: collections.abc.Iterator[typing.Union[float, int]]) -> collections.abc.Iterator[float]"
)
# Callable<R(A)> identity
assert (
doc(m.identity_callable)
== "identity_callable(arg0: Callable[[Union[float, int]], float]) -> Callable[[Union[float, int]], float]"
== "identity_callable(arg0: collections.abc.Callable[[typing.Union[float, int]], float]) -> collections.abc.Callable[[typing.Union[float, int]], float]"
)
# Callable<R(...)> identity
assert (
doc(m.identity_callable_ellipsis)
== "identity_callable_ellipsis(arg0: Callable[..., float]) -> Callable[..., float]"
== "identity_callable_ellipsis(arg0: collections.abc.Callable[..., float]) -> collections.abc.Callable[..., float]"
)
# Nested Callable<R(A)> identity
assert (
doc(m.identity_nested_callable)
== "identity_nested_callable(arg0: Callable[[Callable[[Union[float, int]], float]], Callable[[Union[float, int]], float]]) -> Callable[[Callable[[Union[float, int]], float]], Callable[[Union[float, int]], float]]"
== "identity_nested_callable(arg0: collections.abc.Callable[[collections.abc.Callable[[typing.Union[float, int]], float]], collections.abc.Callable[[typing.Union[float, int]], float]]) -> collections.abc.Callable[[collections.abc.Callable[[typing.Union[float, int]], float]], collections.abc.Callable[[typing.Union[float, int]], float]]"
)
# Callable<R(A)>
assert (
doc(m.apply_callable)
== "apply_callable(arg0: Union[float, int], arg1: Callable[[Union[float, int]], float]) -> float"
== "apply_callable(arg0: typing.Union[float, int], arg1: collections.abc.Callable[[typing.Union[float, int]], float]) -> float"
)
# Callable<R(...)>
assert (
doc(m.apply_callable_ellipsis)
== "apply_callable_ellipsis(arg0: Union[float, int], arg1: Callable[..., float]) -> float"
== "apply_callable_ellipsis(arg0: typing.Union[float, int], arg1: collections.abc.Callable[..., float]) -> float"
)
# Union<T1, T2>
assert (
doc(m.identity_union)
== "identity_union(arg0: Union[Union[float, int], str]) -> Union[float, str]"
== "identity_union(arg0: typing.Union[typing.Union[float, int], str]) -> typing.Union[float, str]"
)
# Optional<T>
assert (
doc(m.identity_optional)
== "identity_optional(arg0: Optional[Union[float, int]]) -> Optional[float]"
== "identity_optional(arg0: typing.Optional[typing.Union[float, int]]) -> typing.Optional[float]"
)
# TypeGuard<T>
assert (
doc(m.check_type_guard)
== "check_type_guard(arg0: list[object]) -> TypeGuard[list[float]]"
== "check_type_guard(arg0: list[object]) -> typing.TypeGuard[list[float]]"
)
# TypeIs<T>
assert doc(m.check_type_is) == "check_type_is(arg0: object) -> TypeIs[float]"
assert doc(m.check_type_is) == "check_type_is(arg0: object) -> typing.TypeIs[float]"

View File

@@ -64,12 +64,20 @@ def test_generalized_iterators_simple():
def test_iterator_doc_annotations():
assert m.IntPairs.nonref.__doc__.endswith("-> Iterator[tuple[int, int]]\n")
assert m.IntPairs.nonref_keys.__doc__.endswith("-> Iterator[int]\n")
assert m.IntPairs.nonref_values.__doc__.endswith("-> Iterator[int]\n")
assert m.IntPairs.simple_iterator.__doc__.endswith("-> Iterator[tuple[int, int]]\n")
assert m.IntPairs.simple_keys.__doc__.endswith("-> Iterator[int]\n")
assert m.IntPairs.simple_values.__doc__.endswith("-> Iterator[int]\n")
assert m.IntPairs.nonref.__doc__.endswith(
"-> collections.abc.Iterator[tuple[int, int]]\n"
)
assert m.IntPairs.nonref_keys.__doc__.endswith("-> collections.abc.Iterator[int]\n")
assert m.IntPairs.nonref_values.__doc__.endswith(
"-> collections.abc.Iterator[int]\n"
)
assert m.IntPairs.simple_iterator.__doc__.endswith(
"-> collections.abc.Iterator[tuple[int, int]]\n"
)
assert m.IntPairs.simple_keys.__doc__.endswith("-> collections.abc.Iterator[int]\n")
assert m.IntPairs.simple_values.__doc__.endswith(
"-> collections.abc.Iterator[int]\n"
)
def test_iterator_referencing():
@@ -194,7 +202,10 @@ def test_sequence_length():
def test_sequence_doc():
assert m.sequence_length.__doc__.strip() == "sequence_length(arg0: Sequence) -> int"
assert (
m.sequence_length.__doc__.strip()
== "sequence_length(arg0: collections.abc.Sequence) -> int"
)
def test_map_iterator():

View File

@@ -276,19 +276,19 @@ def test_fs_path(doc):
assert m.parent_path(PseudoBytesPath()) == Path("foo")
assert (
doc(m.parent_path)
== "parent_path(arg0: Union[os.PathLike, str, bytes]) -> pathlib.Path"
== "parent_path(arg0: typing.Union[os.PathLike, str, bytes]) -> pathlib.Path"
)
# std::vector
assert m.parent_paths(["foo/bar", "foo/baz"]) == [Path("foo"), Path("foo")]
assert (
doc(m.parent_paths)
== "parent_paths(arg0: collections.abc.Sequence[Union[os.PathLike, str, bytes]]) -> list[pathlib.Path]"
== "parent_paths(arg0: collections.abc.Sequence[typing.Union[os.PathLike, str, bytes]]) -> list[pathlib.Path]"
)
# py::typing::List
assert m.parent_paths_list(["foo/bar", "foo/baz"]) == [Path("foo"), Path("foo")]
assert (
doc(m.parent_paths_list)
== "parent_paths_list(arg0: list[Union[os.PathLike, str, bytes]]) -> list[pathlib.Path]"
== "parent_paths_list(arg0: list[typing.Union[os.PathLike, str, bytes]]) -> list[pathlib.Path]"
)
# Nested py::typing::List
assert m.parent_paths_nested_list([["foo/bar"], ["foo/baz", "foo/buzz"]]) == [
@@ -297,13 +297,13 @@ def test_fs_path(doc):
]
assert (
doc(m.parent_paths_nested_list)
== "parent_paths_nested_list(arg0: list[list[Union[os.PathLike, str, bytes]]]) -> list[list[pathlib.Path]]"
== "parent_paths_nested_list(arg0: list[list[typing.Union[os.PathLike, str, bytes]]]) -> list[list[pathlib.Path]]"
)
# py::typing::Tuple
assert m.parent_paths_tuple(("foo/bar", "foo/baz")) == (Path("foo"), Path("foo"))
assert (
doc(m.parent_paths_tuple)
== "parent_paths_tuple(arg0: tuple[Union[os.PathLike, str, bytes], Union[os.PathLike, str, bytes]]) -> tuple[pathlib.Path, pathlib.Path]"
== "parent_paths_tuple(arg0: tuple[typing.Union[os.PathLike, str, bytes], typing.Union[os.PathLike, str, bytes]]) -> tuple[pathlib.Path, pathlib.Path]"
)
# py::typing::Dict
assert m.parent_paths_dict(
@@ -319,7 +319,7 @@ def test_fs_path(doc):
}
assert (
doc(m.parent_paths_dict)
== "parent_paths_dict(arg0: dict[str, Union[os.PathLike, str, bytes]]) -> dict[str, pathlib.Path]"
== "parent_paths_dict(arg0: dict[str, typing.Union[os.PathLike, str, bytes]]) -> dict[str, pathlib.Path]"
)
@@ -337,7 +337,7 @@ def test_variant(doc):
assert (
doc(m.load_variant)
== "load_variant(arg0: Union[typing.SupportsInt, str, typing.SupportsFloat, None]) -> str"
== "load_variant(arg0: typing.Union[typing.SupportsInt, str, typing.SupportsFloat, None]) -> str"
)
@@ -353,7 +353,7 @@ def test_variant_monostate(doc):
assert (
doc(m.load_monostate_variant)
== "load_monostate_variant(arg0: Union[None, typing.SupportsInt, str]) -> str"
== "load_monostate_variant(arg0: typing.Union[None, typing.SupportsInt, str]) -> str"
)