mirror of
https://github.com/pybind/pybind11.git
synced 2026-04-19 22:39:09 +00:00
feat: rework of arg/return type hints to support .noconvert() (#5486)
* Added rework of arg/return typing * Changed `Path` to `pathlib.Path` for compatibility with pybind11-stubgen * Removed old arg/return type hint implementation * Added noconvert support for arg/return type hints * Added commented failing tests for Literals with special characters * Added return_descr/arg_descr for correct typing in typing::Callable * Fixed clang-tidy issues * Changed io_name to have explicit return type (for C++11 support) * style: pre-commit fixes * Added support for nested callables * Fixed missing include * Fixed is_return_value constructor call * Fixed clang-tidy issue * Uncommented test cases for special characters in literals * Moved literal tests to correct test case * Added escaping of special characters in typing::Literal * Readded mistakenly deleted bracket * Moved sanitize_string_literal to correct namespace * Added test for Literal with `!` and changed StringLiteral template param name * Added test for Literal with multiple and repeated special chars * Simplified string literal sanitization function * Added test for `->` in literal * Added test for `->` with io_name * Removed unused parameter name to prevent warning * Added escaping of `-` in literal to prevent processing of `->` * Fixed wrong computation of sanitized string literal length * Added cast to prevent error with MSVC * Simplified special character check --------- Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
This commit is contained in:
@@ -142,7 +142,6 @@ typedef py::typing::TypeVar<"V"> TypeVarV;
|
||||
// RealNumber:
|
||||
// * in arguments -> float | int
|
||||
// * in return -> float
|
||||
// * fallback -> complex
|
||||
// The choice of types is not really useful, but just made different for testing purposes.
|
||||
// According to `PEP 484 – Type Hints` annotating with `float` also allows `int`,
|
||||
// so using `float | int` could be replaced by just `float`.
|
||||
@@ -156,15 +155,17 @@ namespace detail {
|
||||
|
||||
template <>
|
||||
struct type_caster<RealNumber> {
|
||||
PYBIND11_TYPE_CASTER(RealNumber, const_name("complex"));
|
||||
static constexpr auto arg_name = const_name("Union[float, int]");
|
||||
static constexpr auto return_name = const_name("float");
|
||||
PYBIND11_TYPE_CASTER(RealNumber, io_name("Union[float, int]", "float"));
|
||||
|
||||
static handle cast(const RealNumber &number, return_value_policy, handle) {
|
||||
return py::float_(number.value).release();
|
||||
}
|
||||
|
||||
bool load(handle src, bool) {
|
||||
bool load(handle src, bool convert) {
|
||||
// If we're in no-convert mode, only load if given a float
|
||||
if (!convert && !py::isinstance<py::float_>(src)) {
|
||||
return false;
|
||||
}
|
||||
if (!py::isinstance<py::float_>(src) && !py::isinstance<py::int_>(src)) {
|
||||
return false;
|
||||
}
|
||||
@@ -970,6 +971,19 @@ TEST_SUBMODULE(pytypes, m) {
|
||||
.value("BLUE", literals::Color::BLUE);
|
||||
|
||||
m.def("annotate_literal", [](literals::LiteralFoo &o) -> py::object { return o; });
|
||||
// Literal with `@`, `%`, `{`, `}`, and `->`
|
||||
m.def("identity_literal_exclamation", [](const py::typing::Literal<"\"!\""> &x) { return x; });
|
||||
m.def("identity_literal_at", [](const py::typing::Literal<"\"@\""> &x) { return x; });
|
||||
m.def("identity_literal_percent", [](const py::typing::Literal<"\"%\""> &x) { return x; });
|
||||
m.def("identity_literal_curly_open", [](const py::typing::Literal<"\"{\""> &x) { return x; });
|
||||
m.def("identity_literal_curly_close", [](const py::typing::Literal<"\"}\""> &x) { return x; });
|
||||
m.def("identity_literal_arrow_with_io_name",
|
||||
[](const py::typing::Literal<"\"->\""> &x, const RealNumber &) { return x; });
|
||||
m.def("identity_literal_arrow_with_callable",
|
||||
[](const py::typing::Callable<RealNumber(const py::typing::Literal<"\"->\""> &,
|
||||
const RealNumber &)> &x) { return x; });
|
||||
m.def("identity_literal_all_special_chars",
|
||||
[](const py::typing::Literal<"\"!@!!->{%}\""> &x) { return x; });
|
||||
m.def("annotate_generic_containers",
|
||||
[](const py::typing::List<typevar::TypeVarT> &l) -> py::typing::List<typevar::TypeVarV> {
|
||||
return l;
|
||||
@@ -1070,6 +1084,14 @@ TEST_SUBMODULE(pytypes, m) {
|
||||
m.attr("defined___cpp_inline_variables") = false;
|
||||
#endif
|
||||
m.def("half_of_number", [](const RealNumber &x) { return RealNumber{x.value / 2}; });
|
||||
m.def(
|
||||
"half_of_number_convert",
|
||||
[](const RealNumber &x) { return RealNumber{x.value / 2}; },
|
||||
py::arg("x"));
|
||||
m.def(
|
||||
"half_of_number_noconvert",
|
||||
[](const RealNumber &x) { return RealNumber{x.value / 2}; },
|
||||
py::arg("x").noconvert());
|
||||
// std::vector<T>
|
||||
m.def("half_of_number_vector", [](const std::vector<RealNumber> &x) {
|
||||
std::vector<RealNumber> result;
|
||||
@@ -1130,6 +1152,16 @@ TEST_SUBMODULE(pytypes, m) {
|
||||
m.def("identity_iterable", [](const py::typing::Iterable<RealNumber> &x) { return x; });
|
||||
// Iterator<T>
|
||||
m.def("identity_iterator", [](const py::typing::Iterator<RealNumber> &x) { return x; });
|
||||
// Callable<R(A)> identity
|
||||
m.def("identity_callable",
|
||||
[](const py::typing::Callable<RealNumber(const RealNumber &)> &x) { return x; });
|
||||
// Callable<R(...)> identity
|
||||
m.def("identity_callable_ellipsis",
|
||||
[](const py::typing::Callable<RealNumber(py::ellipsis)> &x) { return x; });
|
||||
// Nested Callable<R(A)> identity
|
||||
m.def("identity_nested_callable",
|
||||
[](const py::typing::Callable<py::typing::Callable<RealNumber(const RealNumber &)>(
|
||||
py::typing::Callable<RealNumber(const RealNumber &)>)> &x) { return x; });
|
||||
// Callable<R(A)>
|
||||
m.def("apply_callable",
|
||||
[](const RealNumber &x, const py::typing::Callable<RealNumber(const RealNumber &)> &f) {
|
||||
|
||||
Reference in New Issue
Block a user