Skip to content

Commit 6d98d4d

Browse files
Add type hints for args and kwargs (#5357)
* Allow subclasses of args and kwargs The current implementation disallows subclasses of args and kwargs * Added object type hint to args and kwargs * Added type hinted args and kwargs classes * Changed default type hint to typing.Any * Removed args and kwargs type hint * Updated tests Modified the tests from #5381 to use the real Args and KWArgs classes * Added comment
1 parent a90e2af commit 6d98d4d

File tree

4 files changed

+22
-22
lines changed

4 files changed

+22
-22
lines changed

include/pybind11/cast.h

+8
Original file line numberDiff line numberDiff line change
@@ -1012,10 +1012,18 @@ template <>
10121012
struct handle_type_name<args> {
10131013
static constexpr auto name = const_name("*args");
10141014
};
1015+
template <typename T>
1016+
struct handle_type_name<Args<T>> {
1017+
static constexpr auto name = const_name("*args: ") + make_caster<T>::name;
1018+
};
10151019
template <>
10161020
struct handle_type_name<kwargs> {
10171021
static constexpr auto name = const_name("**kwargs");
10181022
};
1023+
template <typename T>
1024+
struct handle_type_name<KWArgs<T>> {
1025+
static constexpr auto name = const_name("**kwargs: ") + make_caster<T>::name;
1026+
};
10191027
template <>
10201028
struct handle_type_name<obj_attr_accessor> {
10211029
static constexpr auto name = const_name<obj_attr_accessor>();

include/pybind11/pytypes.h

+12
Original file line numberDiff line numberDiff line change
@@ -2226,6 +2226,18 @@ class kwargs : public dict {
22262226
PYBIND11_OBJECT_DEFAULT(kwargs, dict, PyDict_Check)
22272227
};
22282228

2229+
// Subclasses of args and kwargs to support type hinting
2230+
// as defined in PEP 484. See #5357 for more info.
2231+
template <typename T>
2232+
class Args : public args {
2233+
using args::args;
2234+
};
2235+
2236+
template <typename T>
2237+
class KWArgs : public kwargs {
2238+
using kwargs::kwargs;
2239+
};
2240+
22292241
class anyset : public object {
22302242
public:
22312243
PYBIND11_OBJECT(anyset, object, PyAnySet_Check)

tests/test_kwargs_and_defaults.cpp

+1-21
Original file line numberDiff line numberDiff line change
@@ -14,26 +14,6 @@
1414

1515
#include <utility>
1616

17-
// Classes needed for subclass test.
18-
class ArgsSubclass : public py::args {
19-
using py::args::args;
20-
};
21-
class KWArgsSubclass : public py::kwargs {
22-
using py::kwargs::kwargs;
23-
};
24-
namespace pybind11 {
25-
namespace detail {
26-
template <>
27-
struct handle_type_name<ArgsSubclass> {
28-
static constexpr auto name = const_name("*Args");
29-
};
30-
template <>
31-
struct handle_type_name<KWArgsSubclass> {
32-
static constexpr auto name = const_name("**KWArgs");
33-
};
34-
} // namespace detail
35-
} // namespace pybind11
36-
3717
TEST_SUBMODULE(kwargs_and_defaults, m) {
3818
auto kw_func
3919
= [](int x, int y) { return "x=" + std::to_string(x) + ", y=" + std::to_string(y); };
@@ -345,7 +325,7 @@ TEST_SUBMODULE(kwargs_and_defaults, m) {
345325

346326
// Test support for args and kwargs subclasses
347327
m.def("args_kwargs_subclass_function",
348-
[](const ArgsSubclass &args, const KWArgsSubclass &kwargs) {
328+
[](const py::Args<std::string> &args, const py::KWArgs<std::string> &kwargs) {
349329
return py::make_tuple(args, kwargs);
350330
});
351331
}

tests/test_kwargs_and_defaults.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ def test_function_signatures(doc):
2020
)
2121
assert (
2222
doc(m.args_kwargs_subclass_function)
23-
== "args_kwargs_subclass_function(*Args, **KWArgs) -> tuple"
23+
== "args_kwargs_subclass_function(*args: str, **kwargs: str) -> tuple"
2424
)
2525
assert (
2626
doc(m.KWClass.foo0)

0 commit comments

Comments
 (0)