Skip to content

Commit f7e14e9

Browse files
francesco-ballarinpre-commit-ci[bot]gentlegiantJGCrwgk
authored
Address regression introduced in #5381 (#5396)
* Incomplete attempt to address regression introduced in #5381 * style: pre-commit fixes * Revert "style: pre-commit fixes" This reverts commit 9d107d2. * Revert "Incomplete attempt to address regression introduced in #5381" This reverts commit 8cf1cdb. * Simpler fix for the regression introduced in #5381 * style: pre-commit fixes * Added if constexpr workaround This can probably be done better but at least this is a start. * style: pre-commit fixes * Replace if constexpr with template struct if constexpr was not added until C++ 17. I think this should do the same thing as before. * style: pre-commit fixes * Made comment clearer * Added test cases * style: pre-commit fixes * Fixed is_same_or_base_of reference * style: pre-commit fixes * Added static assert messages * style: pre-commit fixes * Replaced typedef with using * style: pre-commit fixes * Back out `ForwardClassPtr` (to be discussed separately). Tested locally with clang-tidy. * Shuffle new `static_assert()` and leave error messages blank (they are more distracting than helpful here). --------- Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com> Co-authored-by: gentlegiantJGC <[email protected]> Co-authored-by: Ralf W. Grosse-Kunstleve <[email protected]>
1 parent 077e49f commit f7e14e9

File tree

2 files changed

+28
-3
lines changed

2 files changed

+28
-3
lines changed

include/pybind11/cast.h

+12-3
Original file line numberDiff line numberDiff line change
@@ -1564,15 +1564,24 @@ struct function_call {
15641564
handle init_self;
15651565
};
15661566

1567+
// See PR #5396 for the discussion that led to this
1568+
template <typename Base, typename Derived, typename = void>
1569+
struct is_same_or_base_of : std::is_same<Base, Derived> {};
1570+
1571+
// Only evaluate is_base_of if Derived is complete.
1572+
// is_base_of raises a compiler error if Derived is incomplete.
1573+
template <typename Base, typename Derived>
1574+
struct is_same_or_base_of<Base, Derived, decltype(void(sizeof(Derived)))>
1575+
: any_of<std::is_same<Base, Derived>, std::is_base_of<Base, Derived>> {};
1576+
15671577
/// Helper class which loads arguments for C++ functions called from Python
15681578
template <typename... Args>
15691579
class argument_loader {
15701580
using indices = make_index_sequence<sizeof...(Args)>;
1571-
15721581
template <typename Arg>
1573-
using argument_is_args = std::is_base_of<args, intrinsic_t<Arg>>;
1582+
using argument_is_args = is_same_or_base_of<args, intrinsic_t<Arg>>;
15741583
template <typename Arg>
1575-
using argument_is_kwargs = std::is_base_of<kwargs, intrinsic_t<Arg>>;
1584+
using argument_is_kwargs = is_same_or_base_of<kwargs, intrinsic_t<Arg>>;
15761585
// Get kwargs argument position, or -1 if not present:
15771586
static constexpr auto kwargs_pos = constexpr_last<argument_is_kwargs, Args...>();
15781587

tests/test_class.cpp

+16
Original file line numberDiff line numberDiff line change
@@ -52,8 +52,24 @@ void bind_empty0(py::module_ &m) {
5252
}
5353

5454
} // namespace pr4220_tripped_over_this
55+
56+
namespace pr5396_forward_declared_class {
57+
class ForwardClass;
58+
class Args : public py::args {};
59+
} // namespace pr5396_forward_declared_class
60+
5561
} // namespace test_class
5662

63+
static_assert(py::detail::is_same_or_base_of<py::args, py::args>::value, "");
64+
static_assert(
65+
py::detail::is_same_or_base_of<py::args,
66+
test_class::pr5396_forward_declared_class::Args>::value,
67+
"");
68+
static_assert(!py::detail::is_same_or_base_of<
69+
py::args,
70+
test_class::pr5396_forward_declared_class::ForwardClass>::value,
71+
"");
72+
5773
TEST_SUBMODULE(class_, m) {
5874
m.def("obj_class_name", [](py::handle obj) { return py::detail::obj_class_name(obj.ptr()); });
5975

0 commit comments

Comments
 (0)