From 3cbaafdb8afb4a3053c25be926518585cc75d926 Mon Sep 17 00:00:00 2001 From: "Ralf W. Grosse-Kunstleve" Date: Tue, 17 Dec 2024 12:19:20 -0800 Subject: [PATCH] Test for `__cpp_inline_variables` and use `static_assert()` --- include/pybind11/cast.h | 7 +++++-- include/pybind11/pytypes.h | 3 +-- tests/test_pytypes.cpp | 6 +++--- tests/test_pytypes.py | 12 ++++++------ 4 files changed, 15 insertions(+), 13 deletions(-) diff --git a/include/pybind11/cast.h b/include/pybind11/cast.h index f67695519..4a10dcbbf 100644 --- a/include/pybind11/cast.h +++ b/include/pybind11/cast.h @@ -1366,16 +1366,19 @@ object object_or_cast(T &&o) { return pybind11::cast(std::forward(o)); } -#if defined(PYBIND11_CPP17) // Declared in pytypes.h: // Written here so make_caster can be used template template str_attr_accessor object_api::attr_with_type_hint(const char *key) const { +#if !defined(__cpp_inline_variables) + static_assert(false, + "C++17 feature __cpp_inline_variables not available: " + "https://en.cppreference.com/w/cpp/language/static#Static_data_members"); +#endif annotations()[key] = make_caster::name.text; return {derived(), key}; } -#endif // Placeholder type for the unneeded (and dead code) static variable in the // PYBIND11_OVERRIDE_OVERRIDE macro diff --git a/include/pybind11/pytypes.h b/include/pybind11/pytypes.h index 6ece5edbf..a30ecf4b8 100644 --- a/include/pybind11/pytypes.h +++ b/include/pybind11/pytypes.h @@ -113,11 +113,10 @@ public: /// See above (the only difference is that the key is provided as a string literal) str_attr_accessor attr(const char *key) const; -#if defined(PYBIND11_CPP17) // attr_with_type_hint is implemented in cast.h: template str_attr_accessor attr_with_type_hint(const char *key) const; -#endif + /** \rst Matches * unpacking in Python, e.g. to unpack arguments out of a ``tuple`` or ``list`` for a function call. Applying another * to the result yields diff --git a/tests/test_pytypes.cpp b/tests/test_pytypes.cpp index 792785baa..761d6cfaa 100644 --- a/tests/test_pytypes.cpp +++ b/tests/test_pytypes.cpp @@ -1038,7 +1038,7 @@ TEST_SUBMODULE(pytypes, m) { m.attr("defined_PYBIND11_TEST_PYTYPES_HAS_RANGES") = false; #endif -#if defined(PYBIND11_CPP17) +#if defined(__cpp_inline_variables) m.attr_with_type_hint>("list_int") = py::list(); m.attr_with_type_hint>("set_str") = py::set(); @@ -1059,9 +1059,9 @@ TEST_SUBMODULE(pytypes, m) { instance.attr_with_type_hint("y"); m.attr_with_type_hint>("CONST_INT") = 3; - m.attr("defined_PYBIND11_CPP17") = true; + m.attr("defined___cpp_inline_variables") = true; #else - m.attr("defined_PYBIND11_CPP17") = false; + m.attr("defined___cpp_inline_variables") = false; #endif m.def("half_of_number", [](const RealNumber &x) { return RealNumber{x.value / 2}; }); // std::vector diff --git a/tests/test_pytypes.py b/tests/test_pytypes.py index 554376ff9..24c5f2f0e 100644 --- a/tests/test_pytypes.py +++ b/tests/test_pytypes.py @@ -1111,8 +1111,8 @@ def get_annotations_helper(o): @pytest.mark.skipif( - not m.defined_PYBIND11_CPP17, - reason="C++17 Position Independent Code not available", + not m.defined___cpp_inline_variables, + reason="C++17 feature __cpp_inline_variables not available.", ) def test_module_attribute_types() -> None: module_annotations = get_annotations_helper(m) @@ -1122,8 +1122,8 @@ def test_module_attribute_types() -> None: @pytest.mark.skipif( - not m.defined_PYBIND11_CPP17, - reason="C++17 Position Independent Code not available", + not m.defined___cpp_inline_variables, + reason="C++17 feature __cpp_inline_variables not available.", ) def test_class_attribute_types() -> None: empty_annotations = get_annotations_helper(m.EmptyAnnotationClass) @@ -1154,8 +1154,8 @@ def test_class_attribute_types() -> None: @pytest.mark.skipif( - not m.defined_PYBIND11_CPP17, - reason="C++17 Position Independent Code not available", + not m.defined___cpp_inline_variables, + reason="C++17 feature __cpp_inline_variables not available.", ) def test_final_annotation() -> None: module_annotations = get_annotations_helper(m)