Skip to content

Commit 9362b78

Browse files
Merge branch 'pybind:master' into master
2 parents cb0c69e + 7e418f4 commit 9362b78

File tree

3 files changed

+39
-2
lines changed

3 files changed

+39
-2
lines changed

include/pybind11/cast.h

+2-2
Original file line numberDiff line numberDiff line change
@@ -1570,9 +1570,9 @@ class argument_loader {
15701570
using indices = make_index_sequence<sizeof...(Args)>;
15711571

15721572
template <typename Arg>
1573-
using argument_is_args = std::is_same<intrinsic_t<Arg>, args>;
1573+
using argument_is_args = std::is_base_of<args, intrinsic_t<Arg>>;
15741574
template <typename Arg>
1575-
using argument_is_kwargs = std::is_same<intrinsic_t<Arg>, kwargs>;
1575+
using argument_is_kwargs = std::is_base_of<kwargs, intrinsic_t<Arg>>;
15761576
// Get kwargs argument position, or -1 if not present:
15771577
static constexpr auto kwargs_pos = constexpr_last<argument_is_kwargs, Args...>();
15781578

tests/test_kwargs_and_defaults.cpp

+26
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,26 @@
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+
1737
TEST_SUBMODULE(kwargs_and_defaults, m) {
1838
auto kw_func
1939
= [](int x, int y) { return "x=" + std::to_string(x) + ", y=" + std::to_string(y); };
@@ -322,4 +342,10 @@ TEST_SUBMODULE(kwargs_and_defaults, m) {
322342
py::pos_only{},
323343
py::arg("i"),
324344
py::arg("j"));
345+
346+
// Test support for args and kwargs subclasses
347+
m.def("args_kwargs_subclass_function",
348+
[](const ArgsSubclass &args, const KWArgsSubclass &kwargs) {
349+
return py::make_tuple(args, kwargs);
350+
});
325351
}

tests/test_kwargs_and_defaults.py

+11
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,10 @@ def test_function_signatures(doc):
1717
assert (
1818
doc(m.args_kwargs_function) == "args_kwargs_function(*args, **kwargs) -> tuple"
1919
)
20+
assert (
21+
doc(m.args_kwargs_subclass_function)
22+
== "args_kwargs_subclass_function(*Args, **KWArgs) -> tuple"
23+
)
2024
assert (
2125
doc(m.KWClass.foo0)
2226
== "foo0(self: m.kwargs_and_defaults.KWClass, arg0: int, arg1: float) -> None"
@@ -98,6 +102,7 @@ def test_arg_and_kwargs():
98102
args = "a1", "a2"
99103
kwargs = {"arg3": "a3", "arg4": 4}
100104
assert m.args_kwargs_function(*args, **kwargs) == (args, kwargs)
105+
assert m.args_kwargs_subclass_function(*args, **kwargs) == (args, kwargs)
101106

102107

103108
def test_mixed_args_and_kwargs(msg):
@@ -413,6 +418,12 @@ def test_args_refcount():
413418
)
414419
assert refcount(myval) == expected
415420

421+
assert m.args_kwargs_subclass_function(7, 8, myval, a=1, b=myval) == (
422+
(7, 8, myval),
423+
{"a": 1, "b": myval},
424+
)
425+
assert refcount(myval) == expected
426+
416427
exp3 = refcount(myval, myval, myval)
417428
assert m.args_refcount(myval, myval, myval) == (exp3, exp3, exp3)
418429
assert refcount(myval) == expected

0 commit comments

Comments
 (0)