Skip to content

Commit 2a7dda2

Browse files
committed
Added rework of arg/return typing
1 parent c5ed9d4 commit 2a7dda2

File tree

4 files changed

+33
-5
lines changed

4 files changed

+33
-5
lines changed

include/pybind11/detail/descr.h

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -99,6 +99,13 @@ constexpr descr<1, Type> const_name() {
9999
return {'%'};
100100
}
101101

102+
// Use a different name based on whether the parameter is used as input or output
103+
template <size_t N1, size_t N2>
104+
constexpr auto io_name(char const (&text1)[N1], char const (&text2)[N2]) {
105+
return const_name("@") + const_name(text1) + const_name("@") + const_name(text2)
106+
+ const_name("@");
107+
}
108+
102109
// If "_" is defined as a macro, py::detail::_ cannot be provided.
103110
// It is therefore best to use py::detail::const_name universally.
104111
// This block is for backward compatibility only.

include/pybind11/pybind11.h

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -440,6 +440,7 @@ class cpp_function : public function {
440440
std::string signature;
441441
size_t type_index = 0, arg_index = 0;
442442
bool is_starred = false;
443+
bool is_return_value = false;
443444
for (const auto *pc = text; *pc != '\0'; ++pc) {
444445
const auto c = *pc;
445446

@@ -493,7 +494,29 @@ class cpp_function : public function {
493494
} else {
494495
signature += detail::quote_cpp_type_name(detail::clean_type_id(t->name()));
495496
}
497+
} else if (c == '@') {
498+
// Handle types that differ depending on whether they appear
499+
// in an argument or a return value position
500+
++pc;
501+
if (!is_return_value) {
502+
while (*pc && *pc != '@')
503+
signature += *pc++;
504+
if (*pc == '@')
505+
++pc;
506+
while (*pc && *pc != '@')
507+
++pc;
508+
} else {
509+
while (*pc && *pc != '@')
510+
++pc;
511+
if (*pc == '@')
512+
++pc;
513+
while (*pc && *pc != '@')
514+
signature += *pc++;
515+
}
496516
} else {
517+
if (c == '-' && *(pc + 1) == '>') {
518+
is_return_value = true;
519+
}
497520
signature += c;
498521
}
499522
}

include/pybind11/stl/filesystem.h

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -106,9 +106,7 @@ struct path_caster {
106106
return true;
107107
}
108108

109-
PYBIND11_TYPE_CASTER(T, const_name("os.PathLike"));
110-
static constexpr auto arg_name = const_name("Union[os.PathLike, str, bytes]");
111-
static constexpr auto return_name = const_name("Path");
109+
PYBIND11_TYPE_CASTER(T, io_name("Union[os.PathLike, str, bytes]", "Path"));
112110
};
113111

114112
#endif // PYBIND11_HAS_FILESYSTEM || defined(PYBIND11_HAS_EXPERIMENTAL_FILESYSTEM)

tests/test_stl.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -267,11 +267,11 @@ def __fspath__(self):
267267
doc(m.parent_path)
268268
== "parent_path(arg0: Union[os.PathLike, str, bytes]) -> Path"
269269
)
270-
# std::vector should use name (for arg_name/return_name typing classes must be used)
270+
# std::vector
271271
assert m.parent_paths(["foo/bar", "foo/baz"]) == [Path("foo"), Path("foo")]
272272
assert (
273273
doc(m.parent_paths)
274-
== "parent_paths(arg0: list[os.PathLike]) -> list[os.PathLike]"
274+
== "parent_paths(arg0: list[Union[os.PathLike, str, bytes]]) -> list[Path]"
275275
)
276276
# py::typing::List
277277
assert m.parent_paths_list(["foo/bar", "foo/baz"]) == [Path("foo"), Path("foo")]

0 commit comments

Comments
 (0)