From 14cde218ef05d7568e2eac9672d1566093c1edf6 Mon Sep 17 00:00:00 2001 From: gentlegiantJGC Date: Fri, 20 Sep 2024 11:28:13 +0100 Subject: [PATCH 1/9] Allow subclasses of py::args and py::kwargs The current implementation does not allow subclasses of args or kwargs. This change allows subclasses to be used. --- include/pybind11/cast.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/include/pybind11/cast.h b/include/pybind11/cast.h index 0c862e4be..e3c8b9f65 100644 --- a/include/pybind11/cast.h +++ b/include/pybind11/cast.h @@ -1570,9 +1570,9 @@ class argument_loader { using indices = make_index_sequence; template - using argument_is_args = std::is_same, args>; + using argument_is_args = std::is_base_of>; template - using argument_is_kwargs = std::is_same, kwargs>; + using argument_is_kwargs = std::is_base_of>; // Get kwargs argument position, or -1 if not present: static constexpr auto kwargs_pos = constexpr_last(); From 82906b97c1a05e84e0c64a1df30c729afda5a32b Mon Sep 17 00:00:00 2001 From: gentlegiantJGC Date: Fri, 20 Sep 2024 18:57:50 +0100 Subject: [PATCH 2/9] Added test case --- tests/test_kwargs_and_defaults.cpp | 12 ++++++++++++ tests/test_kwargs_and_defaults.py | 5 +++++ 2 files changed, 17 insertions(+) diff --git a/tests/test_kwargs_and_defaults.cpp b/tests/test_kwargs_and_defaults.cpp index bc76ec7c2..f82db7543 100644 --- a/tests/test_kwargs_and_defaults.cpp +++ b/tests/test_kwargs_and_defaults.cpp @@ -322,4 +322,16 @@ TEST_SUBMODULE(kwargs_and_defaults, m) { py::pos_only{}, py::arg("i"), py::arg("j")); + + // Test support for args and kwargs subclasses + class ArgsSubclass: public py::args{ + using py::args::args; + } + class KWArgsSubclass: public py::kwargs{ + using py::kwargs::kwargs; + } + m.def("args_kwargs_subclass_function", [](const ArgsSubclass &args, const KWArgsSubclass &kwargs) { + return py::make_tuple(args, kwargs); + }); + } diff --git a/tests/test_kwargs_and_defaults.py b/tests/test_kwargs_and_defaults.py index b9b1a7ea8..8c9d46b04 100644 --- a/tests/test_kwargs_and_defaults.py +++ b/tests/test_kwargs_and_defaults.py @@ -426,3 +426,8 @@ def test_args_refcount(): assert m.mixed_args_refcount(myval, myval, myval) == (exp3_3, exp3_3, exp3_3) assert m.class_default_argument() == "" + + assert m.args_kwargs_subclass_function(7, 8, myval, a=1, b=myval) == ( + (7, 8, myval), + {"a": 1, "b": myval}, + ) From 82c99336cad32660b217f45de01e78859dc58d99 Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Fri, 20 Sep 2024 17:58:16 +0000 Subject: [PATCH 3/9] style: pre-commit fixes --- tests/test_kwargs_and_defaults.cpp | 16 +++++++--------- tests/test_kwargs_and_defaults.py | 2 +- 2 files changed, 8 insertions(+), 10 deletions(-) diff --git a/tests/test_kwargs_and_defaults.cpp b/tests/test_kwargs_and_defaults.cpp index f82db7543..5d9298749 100644 --- a/tests/test_kwargs_and_defaults.cpp +++ b/tests/test_kwargs_and_defaults.cpp @@ -322,16 +322,14 @@ TEST_SUBMODULE(kwargs_and_defaults, m) { py::pos_only{}, py::arg("i"), py::arg("j")); - + // Test support for args and kwargs subclasses - class ArgsSubclass: public py::args{ + class ArgsSubclass : public py::args { using py::args::args; - } - class KWArgsSubclass: public py::kwargs{ + } class KWArgsSubclass : public py::kwargs { using py::kwargs::kwargs; - } - m.def("args_kwargs_subclass_function", [](const ArgsSubclass &args, const KWArgsSubclass &kwargs) { - return py::make_tuple(args, kwargs); - }); - + } m.def("args_kwargs_subclass_function", + [](const ArgsSubclass &args, const KWArgsSubclass &kwargs) { + return py::make_tuple(args, kwargs); + }); } diff --git a/tests/test_kwargs_and_defaults.py b/tests/test_kwargs_and_defaults.py index 8c9d46b04..ac1f71a90 100644 --- a/tests/test_kwargs_and_defaults.py +++ b/tests/test_kwargs_and_defaults.py @@ -426,7 +426,7 @@ def test_args_refcount(): assert m.mixed_args_refcount(myval, myval, myval) == (exp3_3, exp3_3, exp3_3) assert m.class_default_argument() == "" - + assert m.args_kwargs_subclass_function(7, 8, myval, a=1, b=myval) == ( (7, 8, myval), {"a": 1, "b": myval}, From 4aaf8bb35fc405345cc8fc73967e70bc97ff3db4 Mon Sep 17 00:00:00 2001 From: gentlegiantJGC Date: Fri, 20 Sep 2024 19:24:38 +0100 Subject: [PATCH 4/9] Added missing semi-colons --- tests/test_kwargs_and_defaults.cpp | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/tests/test_kwargs_and_defaults.cpp b/tests/test_kwargs_and_defaults.cpp index 5d9298749..738e9e657 100644 --- a/tests/test_kwargs_and_defaults.cpp +++ b/tests/test_kwargs_and_defaults.cpp @@ -324,12 +324,13 @@ TEST_SUBMODULE(kwargs_and_defaults, m) { py::arg("j")); // Test support for args and kwargs subclasses - class ArgsSubclass : public py::args { + class ArgsSubclass: public py::args{ using py::args::args; - } class KWArgsSubclass : public py::kwargs { + }; + class KWArgsSubclass: public py::kwargs{ using py::kwargs::kwargs; - } m.def("args_kwargs_subclass_function", - [](const ArgsSubclass &args, const KWArgsSubclass &kwargs) { - return py::make_tuple(args, kwargs); - }); + }; + m.def("args_kwargs_subclass_function", [](const ArgsSubclass &args, const KWArgsSubclass &kwargs) { + return py::make_tuple(args, kwargs); + }); } From ce5e7be7f841f628a307f7d6097946c5517d495e Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Fri, 20 Sep 2024 18:25:09 +0000 Subject: [PATCH 5/9] style: pre-commit fixes --- tests/test_kwargs_and_defaults.cpp | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/tests/test_kwargs_and_defaults.cpp b/tests/test_kwargs_and_defaults.cpp index 738e9e657..31386f181 100644 --- a/tests/test_kwargs_and_defaults.cpp +++ b/tests/test_kwargs_and_defaults.cpp @@ -324,13 +324,14 @@ TEST_SUBMODULE(kwargs_and_defaults, m) { py::arg("j")); // Test support for args and kwargs subclasses - class ArgsSubclass: public py::args{ + class ArgsSubclass : public py::args { using py::args::args; }; - class KWArgsSubclass: public py::kwargs{ + class KWArgsSubclass : public py::kwargs { using py::kwargs::kwargs; }; - m.def("args_kwargs_subclass_function", [](const ArgsSubclass &args, const KWArgsSubclass &kwargs) { - return py::make_tuple(args, kwargs); - }); + m.def("args_kwargs_subclass_function", + [](const ArgsSubclass &args, const KWArgsSubclass &kwargs) { + return py::make_tuple(args, kwargs); + }); } From 4f54b374fbc51338175d619e893074e9572af494 Mon Sep 17 00:00:00 2001 From: gentlegiantJGC Date: Fri, 20 Sep 2024 20:10:49 +0100 Subject: [PATCH 6/9] Added handle_type_name --- tests/test_kwargs_and_defaults.cpp | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/tests/test_kwargs_and_defaults.cpp b/tests/test_kwargs_and_defaults.cpp index 31386f181..4586d98ab 100644 --- a/tests/test_kwargs_and_defaults.cpp +++ b/tests/test_kwargs_and_defaults.cpp @@ -330,6 +330,14 @@ TEST_SUBMODULE(kwargs_and_defaults, m) { class KWArgsSubclass : public py::kwargs { using py::kwargs::kwargs; }; + template <> + struct handle_type_name { + static constexpr auto name = const_name("*args"); + }; + template <> + struct handle_type_name { + static constexpr auto name = const_name("**kwargs"); + }; m.def("args_kwargs_subclass_function", [](const ArgsSubclass &args, const KWArgsSubclass &kwargs) { return py::make_tuple(args, kwargs); From 97c6798f72259f4b91989e506ea4d0be3f2a68a1 Mon Sep 17 00:00:00 2001 From: gentlegiantJGC Date: Fri, 20 Sep 2024 20:17:28 +0100 Subject: [PATCH 7/9] Moved classes outside of function --- tests/test_kwargs_and_defaults.cpp | 30 ++++++++++++++++-------------- 1 file changed, 16 insertions(+), 14 deletions(-) diff --git a/tests/test_kwargs_and_defaults.cpp b/tests/test_kwargs_and_defaults.cpp index 4586d98ab..30ecd9bd9 100644 --- a/tests/test_kwargs_and_defaults.cpp +++ b/tests/test_kwargs_and_defaults.cpp @@ -14,6 +14,22 @@ #include +// Classes needed for subclass test. +class ArgsSubclass : public py::args { + using py::args::args; +}; +class KWArgsSubclass : public py::kwargs { + using py::kwargs::kwargs; +}; +template <> +struct handle_type_name { + static constexpr auto name = const_name("*args"); +}; +template <> +struct handle_type_name { + static constexpr auto name = const_name("**kwargs"); +}; + TEST_SUBMODULE(kwargs_and_defaults, m) { auto kw_func = [](int x, int y) { return "x=" + std::to_string(x) + ", y=" + std::to_string(y); }; @@ -324,20 +340,6 @@ TEST_SUBMODULE(kwargs_and_defaults, m) { py::arg("j")); // Test support for args and kwargs subclasses - class ArgsSubclass : public py::args { - using py::args::args; - }; - class KWArgsSubclass : public py::kwargs { - using py::kwargs::kwargs; - }; - template <> - struct handle_type_name { - static constexpr auto name = const_name("*args"); - }; - template <> - struct handle_type_name { - static constexpr auto name = const_name("**kwargs"); - }; m.def("args_kwargs_subclass_function", [](const ArgsSubclass &args, const KWArgsSubclass &kwargs) { return py::make_tuple(args, kwargs); From 19503bfd31acc9a611a03deaec1912f7d2b6139e Mon Sep 17 00:00:00 2001 From: gentlegiantJGC Date: Fri, 20 Sep 2024 20:21:46 +0100 Subject: [PATCH 8/9] Added namespaces --- tests/test_kwargs_and_defaults.cpp | 21 +++++++++++++-------- 1 file changed, 13 insertions(+), 8 deletions(-) diff --git a/tests/test_kwargs_and_defaults.cpp b/tests/test_kwargs_and_defaults.cpp index 30ecd9bd9..03c121273 100644 --- a/tests/test_kwargs_and_defaults.cpp +++ b/tests/test_kwargs_and_defaults.cpp @@ -21,14 +21,19 @@ class ArgsSubclass : public py::args { class KWArgsSubclass : public py::kwargs { using py::kwargs::kwargs; }; -template <> -struct handle_type_name { - static constexpr auto name = const_name("*args"); -}; -template <> -struct handle_type_name { - static constexpr auto name = const_name("**kwargs"); -}; +namespace pybind11 { + namespace detail { + template <> + struct handle_type_name { + static constexpr auto name = const_name("*args"); + }; + template <> + struct handle_type_name { + static constexpr auto name = const_name("**kwargs"); + }; + } +} + TEST_SUBMODULE(kwargs_and_defaults, m) { auto kw_func From b74f295c9d9f7447192f105535f1aaec170cee99 Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Fri, 20 Sep 2024 19:22:07 +0000 Subject: [PATCH 9/9] style: pre-commit fixes --- tests/test_kwargs_and_defaults.cpp | 23 +++++++++++------------ 1 file changed, 11 insertions(+), 12 deletions(-) diff --git a/tests/test_kwargs_and_defaults.cpp b/tests/test_kwargs_and_defaults.cpp index 03c121273..afa9956c3 100644 --- a/tests/test_kwargs_and_defaults.cpp +++ b/tests/test_kwargs_and_defaults.cpp @@ -22,18 +22,17 @@ class KWArgsSubclass : public py::kwargs { using py::kwargs::kwargs; }; namespace pybind11 { - namespace detail { - template <> - struct handle_type_name { - static constexpr auto name = const_name("*args"); - }; - template <> - struct handle_type_name { - static constexpr auto name = const_name("**kwargs"); - }; - } -} - +namespace detail { +template <> +struct handle_type_name { + static constexpr auto name = const_name("*args"); +}; +template <> +struct handle_type_name { + static constexpr auto name = const_name("**kwargs"); +}; +} // namespace detail +} // namespace pybind11 TEST_SUBMODULE(kwargs_and_defaults, m) { auto kw_func