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 9d107d2f75.

* Revert "Incomplete attempt to address regression introduced in #5381"

This reverts commit 8cf1cdbc96.

* 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 <gentlegiantJGC@users.noreply.github.com>
Co-authored-by: Ralf W. Grosse-Kunstleve <rgrossekunst@nvidia.com>
This commit is contained in:
Francesco Ballarin 2024-10-12 20:19:50 +02:00 committed by GitHub
parent 077e49fcd6
commit f7e14e985b
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 28 additions and 3 deletions

View File

@ -1564,15 +1564,24 @@ struct function_call {
handle init_self; handle init_self;
}; };
// See PR #5396 for the discussion that led to this
template <typename Base, typename Derived, typename = void>
struct is_same_or_base_of : std::is_same<Base, Derived> {};
// Only evaluate is_base_of if Derived is complete.
// is_base_of raises a compiler error if Derived is incomplete.
template <typename Base, typename Derived>
struct is_same_or_base_of<Base, Derived, decltype(void(sizeof(Derived)))>
: any_of<std::is_same<Base, Derived>, std::is_base_of<Base, Derived>> {};
/// Helper class which loads arguments for C++ functions called from Python /// Helper class which loads arguments for C++ functions called from Python
template <typename... Args> template <typename... Args>
class argument_loader { class argument_loader {
using indices = make_index_sequence<sizeof...(Args)>; using indices = make_index_sequence<sizeof...(Args)>;
template <typename Arg> template <typename Arg>
using argument_is_args = std::is_base_of<args, intrinsic_t<Arg>>; using argument_is_args = is_same_or_base_of<args, intrinsic_t<Arg>>;
template <typename Arg> template <typename Arg>
using argument_is_kwargs = std::is_base_of<kwargs, intrinsic_t<Arg>>; using argument_is_kwargs = is_same_or_base_of<kwargs, intrinsic_t<Arg>>;
// Get kwargs argument position, or -1 if not present: // Get kwargs argument position, or -1 if not present:
static constexpr auto kwargs_pos = constexpr_last<argument_is_kwargs, Args...>(); static constexpr auto kwargs_pos = constexpr_last<argument_is_kwargs, Args...>();

View File

@ -52,8 +52,24 @@ void bind_empty0(py::module_ &m) {
} }
} // namespace pr4220_tripped_over_this } // namespace pr4220_tripped_over_this
namespace pr5396_forward_declared_class {
class ForwardClass;
class Args : public py::args {};
} // namespace pr5396_forward_declared_class
} // namespace test_class } // namespace test_class
static_assert(py::detail::is_same_or_base_of<py::args, py::args>::value, "");
static_assert(
py::detail::is_same_or_base_of<py::args,
test_class::pr5396_forward_declared_class::Args>::value,
"");
static_assert(!py::detail::is_same_or_base_of<
py::args,
test_class::pr5396_forward_declared_class::ForwardClass>::value,
"");
TEST_SUBMODULE(class_, m) { TEST_SUBMODULE(class_, m) {
m.def("obj_class_name", [](py::handle obj) { return py::detail::obj_class_name(obj.ptr()); }); m.def("obj_class_name", [](py::handle obj) { return py::detail::obj_class_name(obj.ptr()); });