Skip to content

Commit a86e7c4

Browse files
committed
Added noconvert support for arg/return type hints
1 parent d9f4e1b commit a86e7c4

File tree

3 files changed

+23
-2
lines changed

3 files changed

+23
-2
lines changed

include/pybind11/pybind11.h

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -497,8 +497,10 @@ class cpp_function : public function {
497497
} else if (c == '@') {
498498
// Handle types that differ depending on whether they appear
499499
// in an argument or a return value position
500+
// For named arguments (py::arg()) with noconvert set, use return value type
500501
++pc;
501-
if (!is_return_value) {
502+
if (!is_return_value
503+
&& !(arg_index < rec->args.size() && !rec->args[arg_index].convert)) {
502504
while (*pc && *pc != '@')
503505
signature += *pc++;
504506
if (*pc == '@')

tests/test_pytypes.cpp

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -161,7 +161,11 @@ struct type_caster<RealNumber> {
161161
return py::float_(number.value).release();
162162
}
163163

164-
bool load(handle src, bool) {
164+
bool load(handle src, bool convert) {
165+
// If we're in no-convert mode, only load if given a float
166+
if (!convert && !py::isinstance<py::float_>(src)) {
167+
return false;
168+
}
165169
if (!py::isinstance<py::float_>(src) && !py::isinstance<py::int_>(src)) {
166170
return false;
167171
}
@@ -1067,6 +1071,14 @@ TEST_SUBMODULE(pytypes, m) {
10671071
m.attr("defined___cpp_inline_variables") = false;
10681072
#endif
10691073
m.def("half_of_number", [](const RealNumber &x) { return RealNumber{x.value / 2}; });
1074+
m.def(
1075+
"half_of_number_convert",
1076+
[](const RealNumber &x) { return RealNumber{x.value / 2}; },
1077+
py::arg("x"));
1078+
m.def(
1079+
"half_of_number_noconvert",
1080+
[](const RealNumber &x) { return RealNumber{x.value / 2}; },
1081+
py::arg("x").noconvert());
10701082
// std::vector<T>
10711083
m.def("half_of_number_vector", [](const std::vector<RealNumber> &x) {
10721084
std::vector<RealNumber> result;

tests/test_pytypes.py

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1195,6 +1195,13 @@ def test_final_annotation() -> None:
11951195

11961196
def test_arg_return_type_hints(doc):
11971197
assert doc(m.half_of_number) == "half_of_number(arg0: Union[float, int]) -> float"
1198+
assert (
1199+
doc(m.half_of_number_convert)
1200+
== "half_of_number_convert(x: Union[float, int]) -> float"
1201+
)
1202+
assert (
1203+
doc(m.half_of_number_noconvert) == "half_of_number_noconvert(x: float) -> float"
1204+
)
11981205
assert m.half_of_number(2.0) == 1.0
11991206
assert m.half_of_number(2) == 1.0
12001207
assert m.half_of_number(0) == 0

0 commit comments

Comments
 (0)