From a06949a9265014b3c581396c4f37c45ccc03dea6 Mon Sep 17 00:00:00 2001 From: "Ralf W. Grosse-Kunstleve" Date: Sun, 6 Nov 2022 15:05:15 -0800 Subject: [PATCH 01/24] Try using `std::hash`, `std::equal_to` everywhere. From PR #4316 we know that types in the unnamed namespace in different translation units do not compare equal, as desired. But do types in named namespaces compare equal, as desired? --- include/pybind11/detail/internals.h | 27 +-------------------------- 1 file changed, 1 insertion(+), 26 deletions(-) diff --git a/include/pybind11/detail/internals.h b/include/pybind11/detail/internals.h index 6fd61098c4..0064684212 100644 --- a/include/pybind11/detail/internals.h +++ b/include/pybind11/detail/internals.h @@ -114,35 +114,10 @@ inline void tls_replace_value(PYBIND11_TLS_KEY_REF key, void *value) { // libstdc++, this doesn't happen: equality and the type_index hash are based on the type name, // which works. If not under a known-good stl, provide our own name-based hash and equality // functions that use the type name. -#if defined(__GLIBCXX__) inline bool same_type(const std::type_info &lhs, const std::type_info &rhs) { return lhs == rhs; } -using type_hash = std::hash; -using type_equal_to = std::equal_to; -#else -inline bool same_type(const std::type_info &lhs, const std::type_info &rhs) { - return lhs.name() == rhs.name() || std::strcmp(lhs.name(), rhs.name()) == 0; -} - -struct type_hash { - size_t operator()(const std::type_index &t) const { - size_t hash = 5381; - const char *ptr = t.name(); - while (auto c = static_cast(*ptr++)) { - hash = (hash * 33) ^ c; - } - return hash; - } -}; - -struct type_equal_to { - bool operator()(const std::type_index &lhs, const std::type_index &rhs) const { - return lhs.name() == rhs.name() || std::strcmp(lhs.name(), rhs.name()) == 0; - } -}; -#endif template -using type_map = std::unordered_map; +using type_map = std::unordered_map; struct override_hash { inline size_t operator()(const std::pair &v) const { From 9d70eba39a0105eddf3830d0cd9f430ed34dd2de Mon Sep 17 00:00:00 2001 From: "Ralf W. Grosse-Kunstleve" Date: Sun, 6 Nov 2022 21:22:40 -0800 Subject: [PATCH 02/24] Revert "Try using `std::hash`, `std::equal_to` everywhere." This reverts commit a06949a9265014b3c581396c4f37c45ccc03dea6. --- include/pybind11/detail/internals.h | 27 ++++++++++++++++++++++++++- 1 file changed, 26 insertions(+), 1 deletion(-) diff --git a/include/pybind11/detail/internals.h b/include/pybind11/detail/internals.h index 0064684212..6fd61098c4 100644 --- a/include/pybind11/detail/internals.h +++ b/include/pybind11/detail/internals.h @@ -114,10 +114,35 @@ inline void tls_replace_value(PYBIND11_TLS_KEY_REF key, void *value) { // libstdc++, this doesn't happen: equality and the type_index hash are based on the type name, // which works. If not under a known-good stl, provide our own name-based hash and equality // functions that use the type name. +#if defined(__GLIBCXX__) inline bool same_type(const std::type_info &lhs, const std::type_info &rhs) { return lhs == rhs; } +using type_hash = std::hash; +using type_equal_to = std::equal_to; +#else +inline bool same_type(const std::type_info &lhs, const std::type_info &rhs) { + return lhs.name() == rhs.name() || std::strcmp(lhs.name(), rhs.name()) == 0; +} + +struct type_hash { + size_t operator()(const std::type_index &t) const { + size_t hash = 5381; + const char *ptr = t.name(); + while (auto c = static_cast(*ptr++)) { + hash = (hash * 33) ^ c; + } + return hash; + } +}; + +struct type_equal_to { + bool operator()(const std::type_index &lhs, const std::type_index &rhs) const { + return lhs.name() == rhs.name() || std::strcmp(lhs.name(), rhs.name()) == 0; + } +}; +#endif template -using type_map = std::unordered_map; +using type_map = std::unordered_map; struct override_hash { inline size_t operator()(const std::pair &v) const { From 9141519166efa03d36337eafa202bc82afacc575 Mon Sep 17 00:00:00 2001 From: "Ralf W. Grosse-Kunstleve" Date: Sun, 6 Nov 2022 21:27:29 -0800 Subject: [PATCH 03/24] Use "our own name-based hash and equality functions" for `std::type_index` only under macOS, based on results shown under https://github.com/pybind/pybind11/pull/4316#issuecomment-1305097879 --- include/pybind11/detail/internals.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/pybind11/detail/internals.h b/include/pybind11/detail/internals.h index 6fd61098c4..768a290fe2 100644 --- a/include/pybind11/detail/internals.h +++ b/include/pybind11/detail/internals.h @@ -114,7 +114,7 @@ inline void tls_replace_value(PYBIND11_TLS_KEY_REF key, void *value) { // libstdc++, this doesn't happen: equality and the type_index hash are based on the type name, // which works. If not under a known-good stl, provide our own name-based hash and equality // functions that use the type name. -#if defined(__GLIBCXX__) +#if !defined(__apple_build_version__) inline bool same_type(const std::type_info &lhs, const std::type_info &rhs) { return lhs == rhs; } using type_hash = std::hash; using type_equal_to = std::equal_to; From ba747dcfa4f525a47e70ac20695cc4f33f8b9f73 Mon Sep 17 00:00:00 2001 From: "Ralf W. Grosse-Kunstleve" Date: Mon, 7 Nov 2022 03:12:47 -0800 Subject: [PATCH 04/24] Patch in PR #4313: Minimal reproducer for clash when binding types defined in the unnamed namespace. --- tests/CMakeLists.txt | 2 ++ tests/test_unnamed_namespace_a.cpp | 9 +++++++++ tests/test_unnamed_namespace_a.py | 5 +++++ tests/test_unnamed_namespace_b.cpp | 9 +++++++++ tests/test_unnamed_namespace_b.py | 5 +++++ 5 files changed, 30 insertions(+) create mode 100644 tests/test_unnamed_namespace_a.cpp create mode 100644 tests/test_unnamed_namespace_a.py create mode 100644 tests/test_unnamed_namespace_b.cpp create mode 100644 tests/test_unnamed_namespace_b.py diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index 491f215cef..285f43b5b9 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -156,6 +156,8 @@ set(PYBIND11_TEST_FILES test_tagbased_polymorphic test_thread test_union + test_unnamed_namespace_a + test_unnamed_namespace_b test_virtual_functions) # Invoking cmake with something like: diff --git a/tests/test_unnamed_namespace_a.cpp b/tests/test_unnamed_namespace_a.cpp new file mode 100644 index 0000000000..4f6472c386 --- /dev/null +++ b/tests/test_unnamed_namespace_a.cpp @@ -0,0 +1,9 @@ +#include "pybind11_tests.h" + +namespace { +struct any_struct {}; +} // namespace + +TEST_SUBMODULE(unnamed_namespace_a, m) { + py::class_(m, "unnamed_namespace_a_any_struct"); +} diff --git a/tests/test_unnamed_namespace_a.py b/tests/test_unnamed_namespace_a.py new file mode 100644 index 0000000000..b823376a4b --- /dev/null +++ b/tests/test_unnamed_namespace_a.py @@ -0,0 +1,5 @@ +from pybind11_tests import unnamed_namespace_a as m + + +def test_have_type(): + assert hasattr(m, "unnamed_namespace_a_any_struct") diff --git a/tests/test_unnamed_namespace_b.cpp b/tests/test_unnamed_namespace_b.cpp new file mode 100644 index 0000000000..8c9b140098 --- /dev/null +++ b/tests/test_unnamed_namespace_b.cpp @@ -0,0 +1,9 @@ +#include "pybind11_tests.h" + +namespace { +struct any_struct {}; +} // namespace + +TEST_SUBMODULE(unnamed_namespace_b, m) { + py::class_(m, "unnamed_namespace_b_any_struct"); +} diff --git a/tests/test_unnamed_namespace_b.py b/tests/test_unnamed_namespace_b.py new file mode 100644 index 0000000000..0550bc4347 --- /dev/null +++ b/tests/test_unnamed_namespace_b.py @@ -0,0 +1,5 @@ +from pybind11_tests import unnamed_namespace_b as m + + +def test_have_type(): + assert hasattr(m, "unnamed_namespace_b_any_struct") From 191267055bb9904e2b948a60736225e87af342b2 Mon Sep 17 00:00:00 2001 From: "Ralf W. Grosse-Kunstleve" Date: Mon, 7 Nov 2022 04:13:28 -0800 Subject: [PATCH 05/24] test_unnamed_namespace_b xfail for clang --- tests/test_unnamed_namespace_a.py | 7 +++++-- tests/test_unnamed_namespace_b.cpp | 12 +++++++++++- tests/test_unnamed_namespace_b.py | 14 ++++++++++++-- 3 files changed, 28 insertions(+), 5 deletions(-) diff --git a/tests/test_unnamed_namespace_a.py b/tests/test_unnamed_namespace_a.py index b823376a4b..995c852e5f 100644 --- a/tests/test_unnamed_namespace_a.py +++ b/tests/test_unnamed_namespace_a.py @@ -1,5 +1,8 @@ +# NOTE: This test relies on pytest SORT ORDER: +# test_unnamed_namespace_a.py imported before test_unnamed_namespace_b.py + from pybind11_tests import unnamed_namespace_a as m -def test_have_type(): - assert hasattr(m, "unnamed_namespace_a_any_struct") +def test_have_class_any_struct(): + assert m.unnamed_namespace_a_any_struct is not None diff --git a/tests/test_unnamed_namespace_b.cpp b/tests/test_unnamed_namespace_b.cpp index 8c9b140098..87e5140950 100644 --- a/tests/test_unnamed_namespace_b.cpp +++ b/tests/test_unnamed_namespace_b.cpp @@ -5,5 +5,15 @@ struct any_struct {}; } // namespace TEST_SUBMODULE(unnamed_namespace_b, m) { - py::class_(m, "unnamed_namespace_b_any_struct"); + if (py::detail::get_type_info(typeid(any_struct)) == nullptr) { + py::class_(m, "unnamed_namespace_b_any_struct"); + } else { + m.attr("unnamed_namespace_b_any_struct") = py::none(); + } + m.attr("defined___clang__") = +#if defined(__clang__) + true; +#else + false; +#endif } diff --git a/tests/test_unnamed_namespace_b.py b/tests/test_unnamed_namespace_b.py index 0550bc4347..cb4c6f412a 100644 --- a/tests/test_unnamed_namespace_b.py +++ b/tests/test_unnamed_namespace_b.py @@ -1,5 +1,15 @@ +# NOTE: This test relies on pytest SORT ORDER: +# test_unnamed_namespace_a.py imported before test_unnamed_namespace_b.py + +import pytest + from pybind11_tests import unnamed_namespace_b as m -def test_have_type(): - assert hasattr(m, "unnamed_namespace_b_any_struct") +@pytest.mark.xfail( + "m.defined___clang__", + reason="Known issue with all clang versions: https://github.com/pybind/pybind11/pull/4316", + strict=True, +) +def test_have_class_any_struct(): + assert m.unnamed_namespace_b_any_struct is not None From d8b71181d9bfd9a144c4667840532adb627b1af8 Mon Sep 17 00:00:00 2001 From: "Ralf W. Grosse-Kunstleve" Date: Mon, 7 Nov 2022 04:30:28 -0800 Subject: [PATCH 06/24] `PYBIND11_INTERNALS_VERSION 5` --- include/pybind11/detail/internals.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/pybind11/detail/internals.h b/include/pybind11/detail/internals.h index 768a290fe2..6be57e7fd5 100644 --- a/include/pybind11/detail/internals.h +++ b/include/pybind11/detail/internals.h @@ -34,7 +34,7 @@ /// further ABI-incompatible changes may be made before the ABI is officially /// changed to the new version. #ifndef PYBIND11_INTERNALS_VERSION -# define PYBIND11_INTERNALS_VERSION 4 +# define PYBIND11_INTERNALS_VERSION 5 #endif PYBIND11_NAMESPACE_BEGIN(PYBIND11_NAMESPACE) From 780d3b2ed0ab01012e11d738a369c9f05a35538c Mon Sep 17 00:00:00 2001 From: "Ralf W. Grosse-Kunstleve" Date: Mon, 7 Nov 2022 04:55:22 -0800 Subject: [PATCH 07/24] Add a note to docs/classes.rst --- docs/classes.rst | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/docs/classes.rst b/docs/classes.rst index c0c53135b8..ca557936ed 100644 --- a/docs/classes.rst +++ b/docs/classes.rst @@ -58,6 +58,15 @@ interactive Python session demonstrating this example is shown below: Static member functions can be bound in the same way using :func:`class_::def_static`. +.. note:: + + Binding C++ types in unnamed namespaces (also known as anonymous namespaces) + works reliably only with GCC and MSVC, but not with CLANG. + See `#4316 `_ for background. + If portability is a concern, it is therefore not recommended to bind C++ + types in unnamed namespaces. It will be safest to manually pick unique + namespace names. + Keyword and default arguments ============================= It is possible to specify keyword and default arguments using the syntax From 3373b479b500ce39548da93103dbf5fe1f2c00ec Mon Sep 17 00:00:00 2001 From: "Ralf W. Grosse-Kunstleve" Date: Mon, 7 Nov 2022 10:14:27 -0800 Subject: [PATCH 08/24] For compatibility with Google-internal testing, test_unnamed_namespace_a & test_unnamed_namespace_b need to work when imported in any order. --- tests/test_unnamed_namespace_a.cpp | 12 +++++++++++- tests/test_unnamed_namespace_a.py | 28 ++++++++++++++++++++++++++-- tests/test_unnamed_namespace_b.py | 5 +---- 3 files changed, 38 insertions(+), 7 deletions(-) diff --git a/tests/test_unnamed_namespace_a.cpp b/tests/test_unnamed_namespace_a.cpp index 4f6472c386..7f7eb24aa1 100644 --- a/tests/test_unnamed_namespace_a.cpp +++ b/tests/test_unnamed_namespace_a.cpp @@ -5,5 +5,15 @@ struct any_struct {}; } // namespace TEST_SUBMODULE(unnamed_namespace_a, m) { - py::class_(m, "unnamed_namespace_a_any_struct"); + if (py::detail::get_type_info(typeid(any_struct)) == nullptr) { + py::class_(m, "unnamed_namespace_a_any_struct"); + } else { + m.attr("unnamed_namespace_a_any_struct") = py::none(); + } + m.attr("defined___clang__") = +#if defined(__clang__) + true; +#else + false; +#endif } diff --git a/tests/test_unnamed_namespace_a.py b/tests/test_unnamed_namespace_a.py index 995c852e5f..48ae562286 100644 --- a/tests/test_unnamed_namespace_a.py +++ b/tests/test_unnamed_namespace_a.py @@ -1,8 +1,32 @@ -# NOTE: This test relies on pytest SORT ORDER: -# test_unnamed_namespace_a.py imported before test_unnamed_namespace_b.py +import pytest from pybind11_tests import unnamed_namespace_a as m +from pybind11_tests import unnamed_namespace_b as mb +@pytest.mark.xfail( + "m.defined___clang__", + reason="Known issue with all clang versions: https://github.com/pybind/pybind11/pull/4316", + strict=False, +) def test_have_class_any_struct(): assert m.unnamed_namespace_a_any_struct is not None + + +def test_have_at_least_one_class_any_struct(): + assert ( + m.unnamed_namespace_a_any_struct is not None + or mb.unnamed_namespace_b_any_struct is not None + ) + + +@pytest.mark.xfail( + "m.defined___clang__", + reason="Known issue with all clang versions: https://github.com/pybind/pybind11/pull/4316", + strict=True, +) +def test_have_both_class_any_struct(): + assert ( + m.unnamed_namespace_a_any_struct is not None + and mb.unnamed_namespace_b_any_struct is not None + ) diff --git a/tests/test_unnamed_namespace_b.py b/tests/test_unnamed_namespace_b.py index cb4c6f412a..c6645e9c9b 100644 --- a/tests/test_unnamed_namespace_b.py +++ b/tests/test_unnamed_namespace_b.py @@ -1,6 +1,3 @@ -# NOTE: This test relies on pytest SORT ORDER: -# test_unnamed_namespace_a.py imported before test_unnamed_namespace_b.py - import pytest from pybind11_tests import unnamed_namespace_b as m @@ -9,7 +6,7 @@ @pytest.mark.xfail( "m.defined___clang__", reason="Known issue with all clang versions: https://github.com/pybind/pybind11/pull/4316", - strict=True, + strict=False, ) def test_have_class_any_struct(): assert m.unnamed_namespace_b_any_struct is not None From 8f0c28e86c3776ed35050c5f4aeafa0789e5e3a1 Mon Sep 17 00:00:00 2001 From: "Ralf W. Grosse-Kunstleve" Date: Mon, 7 Nov 2022 12:15:25 -0800 Subject: [PATCH 09/24] Trying "__GLIBCXX__ or Windows", based on observations from Google-internal testing. --- include/pybind11/detail/internals.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/pybind11/detail/internals.h b/include/pybind11/detail/internals.h index 6be57e7fd5..f0b5518c23 100644 --- a/include/pybind11/detail/internals.h +++ b/include/pybind11/detail/internals.h @@ -114,7 +114,7 @@ inline void tls_replace_value(PYBIND11_TLS_KEY_REF key, void *value) { // libstdc++, this doesn't happen: equality and the type_index hash are based on the type name, // which works. If not under a known-good stl, provide our own name-based hash and equality // functions that use the type name. -#if !defined(__apple_build_version__) +#if defined(__GLIBCXX__) || defined(WIN32) || defined(_WIN32) inline bool same_type(const std::type_info &lhs, const std::type_info &rhs) { return lhs == rhs; } using type_hash = std::hash; using type_equal_to = std::equal_to; From 883cadfd9b5ec752f39d5cafd422ba62b4dbcecc Mon Sep 17 00:00:00 2001 From: "Ralf W. Grosse-Kunstleve" Date: Mon, 7 Nov 2022 14:04:44 -0800 Subject: [PATCH 10/24] Try _LIBCPP_VERSION --- include/pybind11/detail/internals.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/pybind11/detail/internals.h b/include/pybind11/detail/internals.h index f0b5518c23..31e9287318 100644 --- a/include/pybind11/detail/internals.h +++ b/include/pybind11/detail/internals.h @@ -114,7 +114,7 @@ inline void tls_replace_value(PYBIND11_TLS_KEY_REF key, void *value) { // libstdc++, this doesn't happen: equality and the type_index hash are based on the type name, // which works. If not under a known-good stl, provide our own name-based hash and equality // functions that use the type name. -#if defined(__GLIBCXX__) || defined(WIN32) || defined(_WIN32) +#if !defined(_LIBCPP_VERSION) inline bool same_type(const std::type_info &lhs, const std::type_info &rhs) { return lhs == rhs; } using type_hash = std::hash; using type_equal_to = std::equal_to; From 72a88958504c94da406bd8c55e1b24db94883282 Mon Sep 17 00:00:00 2001 From: "Ralf W. Grosse-Kunstleve" Date: Mon, 7 Nov 2022 14:30:06 -0800 Subject: [PATCH 11/24] Account for libc++ behavior in tests and documentation. --- docs/classes.rst | 4 ++-- tests/test_unnamed_namespace_a.cpp | 6 ++++++ tests/test_unnamed_namespace_a.py | 8 ++++---- tests/test_unnamed_namespace_b.cpp | 6 ++++++ tests/test_unnamed_namespace_b.py | 4 ++-- 5 files changed, 20 insertions(+), 8 deletions(-) diff --git a/docs/classes.rst b/docs/classes.rst index ca557936ed..5fbe08870e 100644 --- a/docs/classes.rst +++ b/docs/classes.rst @@ -61,8 +61,8 @@ interactive Python session demonstrating this example is shown below: .. note:: Binding C++ types in unnamed namespaces (also known as anonymous namespaces) - works reliably only with GCC and MSVC, but not with CLANG. - See `#4316 `_ for background. + works reliably only with GCC and MSVC, but not with CLANG, or if libc++ is used. + See `#4319 `_ for background. If portability is a concern, it is therefore not recommended to bind C++ types in unnamed namespaces. It will be safest to manually pick unique namespace names. diff --git a/tests/test_unnamed_namespace_a.cpp b/tests/test_unnamed_namespace_a.cpp index 7f7eb24aa1..e538484aa4 100644 --- a/tests/test_unnamed_namespace_a.cpp +++ b/tests/test_unnamed_namespace_a.cpp @@ -15,5 +15,11 @@ TEST_SUBMODULE(unnamed_namespace_a, m) { true; #else false; +#endif + m.attr("defined__LIBCPP_VERSION") = +#if defined(_LIBCPP_VERSION) + true; +#else + false; #endif } diff --git a/tests/test_unnamed_namespace_a.py b/tests/test_unnamed_namespace_a.py index 48ae562286..1d3190ddfc 100644 --- a/tests/test_unnamed_namespace_a.py +++ b/tests/test_unnamed_namespace_a.py @@ -5,8 +5,8 @@ @pytest.mark.xfail( - "m.defined___clang__", - reason="Known issue with all clang versions: https://github.com/pybind/pybind11/pull/4316", + "m.defined___clang__ or m.defined__LIBCPP_VERSION", + reason="Known issues: https://github.com/pybind/pybind11/pull/4319", strict=False, ) def test_have_class_any_struct(): @@ -21,8 +21,8 @@ def test_have_at_least_one_class_any_struct(): @pytest.mark.xfail( - "m.defined___clang__", - reason="Known issue with all clang versions: https://github.com/pybind/pybind11/pull/4316", + "m.defined___clang__ or m.defined__LIBCPP_VERSION", + reason="Known issues: https://github.com/pybind/pybind11/pull/4319", strict=True, ) def test_have_both_class_any_struct(): diff --git a/tests/test_unnamed_namespace_b.cpp b/tests/test_unnamed_namespace_b.cpp index 87e5140950..84e3c29447 100644 --- a/tests/test_unnamed_namespace_b.cpp +++ b/tests/test_unnamed_namespace_b.cpp @@ -15,5 +15,11 @@ TEST_SUBMODULE(unnamed_namespace_b, m) { true; #else false; +#endif + m.attr("defined__LIBCPP_VERSION") = +#if defined(_LIBCPP_VERSION) + true; +#else + false; #endif } diff --git a/tests/test_unnamed_namespace_b.py b/tests/test_unnamed_namespace_b.py index c6645e9c9b..1e1efac62f 100644 --- a/tests/test_unnamed_namespace_b.py +++ b/tests/test_unnamed_namespace_b.py @@ -4,8 +4,8 @@ @pytest.mark.xfail( - "m.defined___clang__", - reason="Known issue with all clang versions: https://github.com/pybind/pybind11/pull/4316", + "m.defined___clang__ or m.defined__LIBCPP_VERSION", + reason="Known issues: https://github.com/pybind/pybind11/pull/4319", strict=False, ) def test_have_class_any_struct(): From 6f1ddb246f803f85fd26203656c811930c1ae97e Mon Sep 17 00:00:00 2001 From: "Ralf W. Grosse-Kunstleve" Date: Wed, 9 Nov 2022 20:50:49 -0800 Subject: [PATCH 12/24] Adjust expectations for Windows Clang (and make code less redundant). --- tests/test_unnamed_namespace_a.cpp | 6 ++++++ tests/test_unnamed_namespace_a.py | 20 +++++++++----------- tests/test_unnamed_namespace_b.cpp | 12 ------------ tests/test_unnamed_namespace_b.py | 11 ++--------- 4 files changed, 17 insertions(+), 32 deletions(-) diff --git a/tests/test_unnamed_namespace_a.cpp b/tests/test_unnamed_namespace_a.cpp index e538484aa4..e8704edca0 100644 --- a/tests/test_unnamed_namespace_a.cpp +++ b/tests/test_unnamed_namespace_a.cpp @@ -10,6 +10,12 @@ TEST_SUBMODULE(unnamed_namespace_a, m) { } else { m.attr("unnamed_namespace_a_any_struct") = py::none(); } + m.attr("defined_WIN32_or__WIN32") = +#if defined(WIN32) || defined(_WIN32) + true; +#else + false; +#endif m.attr("defined___clang__") = #if defined(__clang__) true; diff --git a/tests/test_unnamed_namespace_a.py b/tests/test_unnamed_namespace_a.py index 1d3190ddfc..be4f4bfe9b 100644 --- a/tests/test_unnamed_namespace_a.py +++ b/tests/test_unnamed_namespace_a.py @@ -3,14 +3,16 @@ from pybind11_tests import unnamed_namespace_a as m from pybind11_tests import unnamed_namespace_b as mb +XFAIL_CONDITION = "not m.defined_WIN32_or__WIN32 and (m.defined___clang__ or m.defined__LIBCPP_VERSION)" +XFAIL_REASON = "Known issues: https://github.com/pybind/pybind11/pull/4319" -@pytest.mark.xfail( - "m.defined___clang__ or m.defined__LIBCPP_VERSION", - reason="Known issues: https://github.com/pybind/pybind11/pull/4319", - strict=False, + +@pytest.mark.xfail(XFAIL_CONDITION, reason=XFAIL_REASON, strict=False) +@pytest.mark.parametrize( + "any_struct", (m.unnamed_namespace_a_any_struct, mb.unnamed_namespace_b_any_struct) ) -def test_have_class_any_struct(): - assert m.unnamed_namespace_a_any_struct is not None +def test_have_class_any_struct(any_struct): + assert any_struct is not None def test_have_at_least_one_class_any_struct(): @@ -20,11 +22,7 @@ def test_have_at_least_one_class_any_struct(): ) -@pytest.mark.xfail( - "m.defined___clang__ or m.defined__LIBCPP_VERSION", - reason="Known issues: https://github.com/pybind/pybind11/pull/4319", - strict=True, -) +@pytest.mark.xfail(XFAIL_CONDITION, reason=XFAIL_REASON, strict=True) def test_have_both_class_any_struct(): assert ( m.unnamed_namespace_a_any_struct is not None diff --git a/tests/test_unnamed_namespace_b.cpp b/tests/test_unnamed_namespace_b.cpp index 84e3c29447..f97757a7de 100644 --- a/tests/test_unnamed_namespace_b.cpp +++ b/tests/test_unnamed_namespace_b.cpp @@ -10,16 +10,4 @@ TEST_SUBMODULE(unnamed_namespace_b, m) { } else { m.attr("unnamed_namespace_b_any_struct") = py::none(); } - m.attr("defined___clang__") = -#if defined(__clang__) - true; -#else - false; -#endif - m.attr("defined__LIBCPP_VERSION") = -#if defined(_LIBCPP_VERSION) - true; -#else - false; -#endif } diff --git a/tests/test_unnamed_namespace_b.py b/tests/test_unnamed_namespace_b.py index 1e1efac62f..4bcaa7a6c5 100644 --- a/tests/test_unnamed_namespace_b.py +++ b/tests/test_unnamed_namespace_b.py @@ -1,12 +1,5 @@ -import pytest - from pybind11_tests import unnamed_namespace_b as m -@pytest.mark.xfail( - "m.defined___clang__ or m.defined__LIBCPP_VERSION", - reason="Known issues: https://github.com/pybind/pybind11/pull/4319", - strict=False, -) -def test_have_class_any_struct(): - assert m.unnamed_namespace_b_any_struct is not None +def test_have_attr_any_struct(): + assert hasattr(m, "unnamed_namespace_b_any_struct") From a1175edf90bff26449a27a6ad67b2c3f9ee0463e Mon Sep 17 00:00:00 2001 From: "Ralf W. Grosse-Kunstleve" Date: Wed, 9 Nov 2022 21:15:07 -0800 Subject: [PATCH 13/24] Add WindowsClang to ci.yml Added block transferred from PR #4321 --- .github/workflows/ci.yml | 65 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 65 insertions(+) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index a11cae1ab0..1c24f4f549 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -967,3 +967,68 @@ jobs: - name: Interface test C++17 run: PYTHONHOME=/${{matrix.sys}} PYTHONPATH=/${{matrix.sys}} cmake --build build3 --target test_cmake_build + + WindowsClang: + + strategy: + matrix: + os: [windows-latest] + python: ['3.10'] + + runs-on: "${{ matrix.os }}" + + name: "🐍 ${{ matrix.python }} • ${{ matrix.os }}" + + steps: + - name: Checkout + uses: actions/checkout@v3 + + - name: Set up Clang + uses: egor-tensin/setup-clang@v1 + + - name: Setup Python ${{ matrix.python }} + uses: actions/setup-python@v4 + with: + python-version: ${{ matrix.python }} + + - name: Update CMake + uses: jwlawson/actions-setup-cmake@v1.13 + + - name: Install ninja-build tool + uses: seanmiddleditch/gha-setup-ninja@v3 + + - name: Prepare env + run: python -m pip install -r tests/requirements.txt + + - name: Show Clang++ version + run: clang++ --version + + - name: Show CMake version + run: cmake --version + + # TODO: WERROR=ON + - name: Configure Clang + run: > + cmake -G Ninja -S . -B . + -DCMAKE_VERBOSE_MAKEFILE=ON + -DPYBIND11_WERROR=OFF + -DPYBIND11_SIMPLE_GIL_MANAGEMENT=OFF + -DDOWNLOAD_CATCH=ON + -DDOWNLOAD_EIGEN=ON + -DCMAKE_CXX_COMPILER=clang++ + -DCMAKE_CXX_STANDARD=17 + + - name: Build Clang + run: cmake --build . -j 2 + + - name: Python tests Clang + run: cmake --build . --target pytest -j 2 + + - name: C++ tests + run: cmake --build . --target cpptest -j 2 + + - name: Interface test Clang + run: cmake --build . --target test_cmake_build -j 2 + + - name: Clean directory + run: git clean -fdx From 5631d94e4ad33ac98bebe42255ec599fd9456344 Mon Sep 17 00:00:00 2001 From: "Ralf W. Grosse-Kunstleve" Date: Wed, 9 Nov 2022 23:23:27 -0800 Subject: [PATCH 14/24] Add clang-latest to name that appears in the GitHub Actions web view. --- .github/workflows/ci.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 1c24f4f549..d0c4c850f8 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -968,7 +968,7 @@ jobs: - name: Interface test C++17 run: PYTHONHOME=/${{matrix.sys}} PYTHONPATH=/${{matrix.sys}} cmake --build build3 --target test_cmake_build - WindowsClang: + windows_clang: strategy: matrix: @@ -977,7 +977,7 @@ jobs: runs-on: "${{ matrix.os }}" - name: "🐍 ${{ matrix.python }} • ${{ matrix.os }}" + name: "🐍 ${{ matrix.python }} • ${{ matrix.os }} • clang-latest" steps: - name: Checkout From 81a4e7ba8c562a10baeba84ec7a0651a0a6d2d7b Mon Sep 17 00:00:00 2001 From: "Ralf W. Grosse-Kunstleve" Date: Thu, 10 Nov 2022 07:04:28 -0800 Subject: [PATCH 15/24] Tweak the note in classes.rst again. --- docs/classes.rst | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/docs/classes.rst b/docs/classes.rst index 5fbe08870e..52cd52da3f 100644 --- a/docs/classes.rst +++ b/docs/classes.rst @@ -61,8 +61,9 @@ interactive Python session demonstrating this example is shown below: .. note:: Binding C++ types in unnamed namespaces (also known as anonymous namespaces) - works reliably only with GCC and MSVC, but not with CLANG, or if libc++ is used. - See `#4319 `_ for background. + works reliably on many platforms, but not all. The `XFAIL_CONDITION` in + tests/test_unnamed_namespace_a.py encodes the currently known conditions. + For background see `#4319 `_. If portability is a concern, it is therefore not recommended to bind C++ types in unnamed namespaces. It will be safest to manually pick unique namespace names. From 7075e00b7dc29ac2b789991542a0e2e4cdaea4e8 Mon Sep 17 00:00:00 2001 From: "Ralf W. Grosse-Kunstleve" Date: Thu, 10 Nov 2022 07:26:46 -0800 Subject: [PATCH 16/24] Add `pip install --upgrade pip`, Show env, cosmetic changes Already tested under PR #4321 --- .github/workflows/ci.yml | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index d0c4c850f8..adbbf626f1 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -980,6 +980,9 @@ jobs: name: "🐍 ${{ matrix.python }} • ${{ matrix.os }} • clang-latest" steps: + - name: Show env + run: env + - name: Checkout uses: actions/checkout@v3 @@ -997,8 +1000,10 @@ jobs: - name: Install ninja-build tool uses: seanmiddleditch/gha-setup-ninja@v3 - - name: Prepare env - run: python -m pip install -r tests/requirements.txt + - name: Run pip installs + run: | + python -m pip install --upgrade pip + python -m pip install -r tests/requirements.txt - name: Show Clang++ version run: clang++ --version @@ -1018,16 +1023,16 @@ jobs: -DCMAKE_CXX_COMPILER=clang++ -DCMAKE_CXX_STANDARD=17 - - name: Build Clang + - name: Build run: cmake --build . -j 2 - - name: Python tests Clang + - name: Python tests run: cmake --build . --target pytest -j 2 - name: C++ tests run: cmake --build . --target cpptest -j 2 - - name: Interface test Clang + - name: Interface test run: cmake --build . --target test_cmake_build -j 2 - name: Clean directory From b84a1630dace2ba82c865fdbbcc75d84a8c32327 Mon Sep 17 00:00:00 2001 From: "Ralf W. Grosse-Kunstleve" Date: Thu, 10 Nov 2022 07:29:07 -0800 Subject: [PATCH 17/24] Add macos_brew_install_llvm to ci.yml Added block transferred from PR #4324 --- .github/workflows/ci.yml | 65 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 65 insertions(+) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index adbbf626f1..c16b07423e 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -1037,3 +1037,68 @@ jobs: - name: Clean directory run: git clean -fdx + + macos_brew_install_llvm: + name: "macos-latest • brew install llvm" + runs-on: macos-latest + + env: + # https://apple.stackexchange.com/questions/227026/how-to-install-recent-clang-with-homebrew + LDFLAGS: '-L/usr/local/opt/llvm/lib -Wl,-rpath,/usr/local/opt/llvm/lib' + + steps: + - name: Update PATH + run: echo "/usr/local/opt/llvm/bin" >> $GITHUB_PATH + + - name: Show env + run: env + + - name: Checkout + uses: actions/checkout@v3 + + - name: Show Clang++ version before brew install llvm + run: clang++ --version + + - name: brew install llvm + run: brew install llvm + + - name: Show Clang++ version after brew install llvm + run: clang++ --version + + - name: Update CMake + uses: jwlawson/actions-setup-cmake@v1.13 + + - name: Run pip installs + run: | + python3 -m pip install --upgrade pip + python3 -m pip install -r tests/requirements.txt + + - name: Show CMake version + run: cmake --version + + - name: CMake Configure + run: > + cmake -S . -B . + -DCMAKE_VERBOSE_MAKEFILE=ON + -DPYBIND11_WERROR=ON + -DPYBIND11_SIMPLE_GIL_MANAGEMENT=OFF + -DDOWNLOAD_CATCH=ON + -DDOWNLOAD_EIGEN=ON + -DCMAKE_CXX_COMPILER=clang++ + -DCMAKE_CXX_STANDARD=17 + -DPYTHON_EXECUTABLE=$(python3 -c "import sys; print(sys.executable)") + + - name: Build + run: cmake --build . -j 2 + + - name: Python tests + run: cmake --build . --target pytest -j 2 + + - name: C++ tests + run: cmake --build . --target cpptest -j 2 + + - name: Interface test + run: cmake --build . --target test_cmake_build -j 2 + + - name: Clean directory + run: git clean -fdx From 4f06c061b6ea6bd8ffcb45c2cdf02c50f86017f4 Mon Sep 17 00:00:00 2001 From: "Ralf W. Grosse-Kunstleve" Date: Thu, 10 Nov 2022 06:29:12 -0800 Subject: [PATCH 18/24] `test_cross_module_exception_translator` xfail 'Homebrew Clang' --- tests/test_exceptions.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/tests/test_exceptions.py b/tests/test_exceptions.py index 7eb1a9d62c..0d2c808143 100644 --- a/tests/test_exceptions.py +++ b/tests/test_exceptions.py @@ -4,6 +4,7 @@ import env import pybind11_cross_module_tests as cm +import pybind11_tests # noqa: F401 from pybind11_tests import exceptions as m @@ -72,9 +73,9 @@ def test_cross_module_exceptions(msg): # TODO: FIXME @pytest.mark.xfail( - "env.PYPY and env.MACOS", + "env.MACOS and (env.PYPY or pybind11_tests.compiler_info.startswith('Homebrew Clang'))", raises=RuntimeError, - reason="Expected failure with PyPy and libc++ (Issue #2847 & PR #2999)", + reason="See Issue #2847, PR #2999, PR #4324", ) def test_cross_module_exception_translator(): with pytest.raises(KeyError): From 2180d04f9a6d91f75fb74d45709c154a75961591 Mon Sep 17 00:00:00 2001 From: "Ralf W. Grosse-Kunstleve" Date: Mon, 20 Mar 2023 13:46:19 -0700 Subject: [PATCH 19/24] Revert back to base version of .github/workflows/ci.yml (the ci.yml changes were merged under #4323 and #4326) --- .github/workflows/ci.yml | 135 --------------------------------------- 1 file changed, 135 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index c16b07423e..a11cae1ab0 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -967,138 +967,3 @@ jobs: - name: Interface test C++17 run: PYTHONHOME=/${{matrix.sys}} PYTHONPATH=/${{matrix.sys}} cmake --build build3 --target test_cmake_build - - windows_clang: - - strategy: - matrix: - os: [windows-latest] - python: ['3.10'] - - runs-on: "${{ matrix.os }}" - - name: "🐍 ${{ matrix.python }} • ${{ matrix.os }} • clang-latest" - - steps: - - name: Show env - run: env - - - name: Checkout - uses: actions/checkout@v3 - - - name: Set up Clang - uses: egor-tensin/setup-clang@v1 - - - name: Setup Python ${{ matrix.python }} - uses: actions/setup-python@v4 - with: - python-version: ${{ matrix.python }} - - - name: Update CMake - uses: jwlawson/actions-setup-cmake@v1.13 - - - name: Install ninja-build tool - uses: seanmiddleditch/gha-setup-ninja@v3 - - - name: Run pip installs - run: | - python -m pip install --upgrade pip - python -m pip install -r tests/requirements.txt - - - name: Show Clang++ version - run: clang++ --version - - - name: Show CMake version - run: cmake --version - - # TODO: WERROR=ON - - name: Configure Clang - run: > - cmake -G Ninja -S . -B . - -DCMAKE_VERBOSE_MAKEFILE=ON - -DPYBIND11_WERROR=OFF - -DPYBIND11_SIMPLE_GIL_MANAGEMENT=OFF - -DDOWNLOAD_CATCH=ON - -DDOWNLOAD_EIGEN=ON - -DCMAKE_CXX_COMPILER=clang++ - -DCMAKE_CXX_STANDARD=17 - - - name: Build - run: cmake --build . -j 2 - - - name: Python tests - run: cmake --build . --target pytest -j 2 - - - name: C++ tests - run: cmake --build . --target cpptest -j 2 - - - name: Interface test - run: cmake --build . --target test_cmake_build -j 2 - - - name: Clean directory - run: git clean -fdx - - macos_brew_install_llvm: - name: "macos-latest • brew install llvm" - runs-on: macos-latest - - env: - # https://apple.stackexchange.com/questions/227026/how-to-install-recent-clang-with-homebrew - LDFLAGS: '-L/usr/local/opt/llvm/lib -Wl,-rpath,/usr/local/opt/llvm/lib' - - steps: - - name: Update PATH - run: echo "/usr/local/opt/llvm/bin" >> $GITHUB_PATH - - - name: Show env - run: env - - - name: Checkout - uses: actions/checkout@v3 - - - name: Show Clang++ version before brew install llvm - run: clang++ --version - - - name: brew install llvm - run: brew install llvm - - - name: Show Clang++ version after brew install llvm - run: clang++ --version - - - name: Update CMake - uses: jwlawson/actions-setup-cmake@v1.13 - - - name: Run pip installs - run: | - python3 -m pip install --upgrade pip - python3 -m pip install -r tests/requirements.txt - - - name: Show CMake version - run: cmake --version - - - name: CMake Configure - run: > - cmake -S . -B . - -DCMAKE_VERBOSE_MAKEFILE=ON - -DPYBIND11_WERROR=ON - -DPYBIND11_SIMPLE_GIL_MANAGEMENT=OFF - -DDOWNLOAD_CATCH=ON - -DDOWNLOAD_EIGEN=ON - -DCMAKE_CXX_COMPILER=clang++ - -DCMAKE_CXX_STANDARD=17 - -DPYTHON_EXECUTABLE=$(python3 -c "import sys; print(sys.executable)") - - - name: Build - run: cmake --build . -j 2 - - - name: Python tests - run: cmake --build . --target pytest -j 2 - - - name: C++ tests - run: cmake --build . --target cpptest -j 2 - - - name: Interface test - run: cmake --build . --target test_cmake_build -j 2 - - - name: Clean directory - run: git clean -fdx From b882060643b10096ffabccf7cb9b63178cc3d92d Mon Sep 17 00:00:00 2001 From: "Ralf W. Grosse-Kunstleve" Date: Mon, 20 Mar 2023 13:49:44 -0700 Subject: [PATCH 20/24] Fixes for ruff --- tests/test_unnamed_namespace_a.py | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/tests/test_unnamed_namespace_a.py b/tests/test_unnamed_namespace_a.py index be4f4bfe9b..373693cd5c 100644 --- a/tests/test_unnamed_namespace_a.py +++ b/tests/test_unnamed_namespace_a.py @@ -9,7 +9,7 @@ @pytest.mark.xfail(XFAIL_CONDITION, reason=XFAIL_REASON, strict=False) @pytest.mark.parametrize( - "any_struct", (m.unnamed_namespace_a_any_struct, mb.unnamed_namespace_b_any_struct) + "any_struct", [m.unnamed_namespace_a_any_struct, mb.unnamed_namespace_b_any_struct] ) def test_have_class_any_struct(any_struct): assert any_struct is not None @@ -24,7 +24,5 @@ def test_have_at_least_one_class_any_struct(): @pytest.mark.xfail(XFAIL_CONDITION, reason=XFAIL_REASON, strict=True) def test_have_both_class_any_struct(): - assert ( - m.unnamed_namespace_a_any_struct is not None - and mb.unnamed_namespace_b_any_struct is not None - ) + assert m.unnamed_namespace_a_any_struct is not None + assert mb.unnamed_namespace_b_any_struct is not None From f1c3055a2decda121302343524db2277aa9ec9d9 Mon Sep 17 00:00:00 2001 From: "Ralf W. Grosse-Kunstleve" Date: Tue, 28 Mar 2023 16:17:37 -0700 Subject: [PATCH 21/24] Make updated condition in internals.h dependent on ABI version. --- include/pybind11/detail/internals.h | 3 ++- tests/test_unnamed_namespace_a.cpp | 7 +++++++ tests/test_unnamed_namespace_a.py | 8 +++++++- 3 files changed, 16 insertions(+), 2 deletions(-) diff --git a/include/pybind11/detail/internals.h b/include/pybind11/detail/internals.h index e42ea40305..aaa7f8686e 100644 --- a/include/pybind11/detail/internals.h +++ b/include/pybind11/detail/internals.h @@ -123,7 +123,8 @@ inline void tls_replace_value(PYBIND11_TLS_KEY_REF key, void *value) { // libstdc++, this doesn't happen: equality and the type_index hash are based on the type name, // which works. If not under a known-good stl, provide our own name-based hash and equality // functions that use the type name. -#if !defined(_LIBCPP_VERSION) +#if (PYBIND11_INTERNALS_VERSION <= 4 && defined(__GLIBCXX__)) \ + || (PYBIND11_INTERNALS_VERSION >= 5 && !defined(_LIBCPP_VERSION)) inline bool same_type(const std::type_info &lhs, const std::type_info &rhs) { return lhs == rhs; } using type_hash = std::hash; using type_equal_to = std::equal_to; diff --git a/tests/test_unnamed_namespace_a.cpp b/tests/test_unnamed_namespace_a.cpp index e8704edca0..2152e64bd7 100644 --- a/tests/test_unnamed_namespace_a.cpp +++ b/tests/test_unnamed_namespace_a.cpp @@ -10,6 +10,7 @@ TEST_SUBMODULE(unnamed_namespace_a, m) { } else { m.attr("unnamed_namespace_a_any_struct") = py::none(); } + m.attr("PYBIND11_INTERNALS_VERSION") = PYBIND11_INTERNALS_VERSION; m.attr("defined_WIN32_or__WIN32") = #if defined(WIN32) || defined(_WIN32) true; @@ -27,5 +28,11 @@ TEST_SUBMODULE(unnamed_namespace_a, m) { true; #else false; +#endif + m.attr("defined___GLIBCXX__") = +#if defined(__GLIBCXX__) + true; +#else + false; #endif } diff --git a/tests/test_unnamed_namespace_a.py b/tests/test_unnamed_namespace_a.py index 373693cd5c..9d9856c5a4 100644 --- a/tests/test_unnamed_namespace_a.py +++ b/tests/test_unnamed_namespace_a.py @@ -3,7 +3,13 @@ from pybind11_tests import unnamed_namespace_a as m from pybind11_tests import unnamed_namespace_b as mb -XFAIL_CONDITION = "not m.defined_WIN32_or__WIN32 and (m.defined___clang__ or m.defined__LIBCPP_VERSION)" +XFAIL_CONDITION = ( + "(m.PYBIND11_INTERNALS_VERSION <= 4 and (m.defined___clang__ or not m.defined___GLIBCXX__))" + " or " + "(m.PYBIND11_INTERNALS_VERSION >= 5 and not m.defined_WIN32_or__WIN32" + " and " + "(m.defined___clang__ or m.defined__LIBCPP_VERSION))" +) XFAIL_REASON = "Known issues: https://github.com/pybind/pybind11/pull/4319" From 0ff73a9831b8e7142dfbff626f5a006da2efcf79 Mon Sep 17 00:00:00 2001 From: "Ralf W. Grosse-Kunstleve" Date: Thu, 30 Mar 2023 08:59:13 -0700 Subject: [PATCH 22/24] Remove PYBIND11_TEST_OVERRIDE when testing with PYBIND11_INTERNALS_VERSION=10000000 --- .github/workflows/ci.yml | 1 - .github/workflows/upstream.yml | 1 - 2 files changed, 2 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 8befccdbc2..f63abbc2d4 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -164,7 +164,6 @@ jobs: -DDOWNLOAD_EIGEN=ON -DCMAKE_CXX_STANDARD=17 -DPYBIND11_INTERNALS_VERSION=10000000 - "-DPYBIND11_TEST_OVERRIDE=test_call_policies.cpp;test_gil_scoped.cpp;test_thread.cpp" ${{ matrix.args }} - name: Build (unstable ABI) diff --git a/.github/workflows/upstream.yml b/.github/workflows/upstream.yml index b7e14f72e8..10b017c518 100644 --- a/.github/workflows/upstream.yml +++ b/.github/workflows/upstream.yml @@ -95,7 +95,6 @@ jobs: -DDOWNLOAD_EIGEN=ON -DCMAKE_CXX_STANDARD=17 -DPYBIND11_INTERNALS_VERSION=10000000 - "-DPYBIND11_TEST_OVERRIDE=test_call_policies.cpp;test_gil_scoped.cpp;test_thread.cpp" - name: Build (unstable ABI) run: cmake --build build17max -j 2 From d0276c01cd9e0a24aafe74c698d666908a31a397 Mon Sep 17 00:00:00 2001 From: "Ralf W. Grosse-Kunstleve" Date: Thu, 20 Apr 2023 23:14:38 -0700 Subject: [PATCH 23/24] Selectively exercise cmake `-DPYBIND11_TEST_OVERRIDE`: ubuntu, macos, windows Extra work added to quick jobs, based on timings below, to not increase the GHA start-to-last-job-finished time. ``` Duration ^ Number of pytest runs ^ ^ Job identifier ^ ^ ^ 0:03:48.024227 1 1___3___Clang_3.6___C++11___x64.txt 0:03:58.992814 1 2___3___Clang_3.7___C++11___x64.txt 0:04:25.758942 1 1___3.7___Debian___x86____Install.txt 0:04:50.148276 1 4___3___Clang_7___C++11___x64.txt 0:04:55.784558 1 13___3___Clang_15___C++20___x64.txt 0:04:57.048754 1 6___3___Clang_dev___C++11___x64.txt 0:05:00.485181 1 7___3___Clang_5___C++14___x64.txt 0:05:03.744964 1 2___3___almalinux8___x64.txt 0:05:06.222752 1 5___3___Clang_9___C++11___x64.txt 0:05:11.767022 1 2___3___GCC_7___C++17__x64.txt 0:05:18.634930 1 2___3.11__deadsnakes____x64.txt 0:05:22.810995 1 1___3___GCC_7___C++11__x64.txt 0:05:25.275317 1 12___3___Clang_14___C++20___x64.txt 0:05:32.058174 1 5___3___GCC_10___C++17__x64.txt 0:05:39.381351 1 7___3___GCC_12___C++20__x64.txt 0:05:40.502252 1 8___3___Clang_10___C++17___x64.txt 0:05:59.344905 1 3___3___Clang_3.9___C++11___x64.txt 0:06:10.825147 1 6___3___GCC_11___C++20__x64.txt 0:06:20.655443 1 3___3___almalinux9___x64.txt 0:06:22.472061 1 3___3___GCC_8___C++14__x64.txt 0:06:42.647406 1 11___3___Clang_13___C++20___x64.txt 0:06:53.352720 1 1___3.10___CUDA_11.7___Ubuntu_22.04.txt 0:07:07.357801 1 2___3.7___MSVC_2019___x86_-DCMAKE_CXX_STANDARD=14.txt 0:07:09.057603 1 1___3___centos7___x64.txt 0:07:15.546282 1 1___3.8___MSVC_2019__Debug____x86_-DCMAKE_CXX_STANDARD=17.txt 0:07:22.566022 1 4___3___GCC_8___C++17__x64.txt 0:08:13.592674 1 2___3.9___MSVC_2019__Debug____x86_-DCMAKE_CXX_STANDARD=20.txt 0:08:16.422768 1 9___3___Clang_11___C++20___x64.txt 0:08:21.168457 1 3___3.8___MSVC_2019___x86_-DCMAKE_CXX_STANDARD=17.txt 0:08:27.129468 1 10___3___Clang_12___C++20___x64.txt 0:09:35.045470 1 1___3.10___windows-latest___clang-latest.txt 0:09:57.361843 1 1___3.9___MSVC_2022_C++20___x64.txt 0:10:35.187767 1 1___3.6___MSVC_2019___x86.txt 0:11:14.691200 4 2___3.9___ubuntu-20.04___x64.txt 0:11:37.701167 1 1_macos-latest___brew_install_llvm.txt 0:11:38.688299 4 4___3.11___ubuntu-20.04___x64.txt 0:11:52.720216 1 4___3.9___MSVC_2019___x86_-DCMAKE_CXX_STANDARD=20.txt 0:13:23.456591 4 6___pypy-3.8___ubuntu-20.04___x64_-DPYBIND11_FINDPYTHON=ON.txt 0:13:25.863592 2 1___3___ICC_latest___x64.txt 0:13:32.411758 3 9___3.9___windows-2022___x64.txt 0:13:45.473377 4 3___3.10___ubuntu-20.04___x64.txt 0:13:55.366447 4 5___pypy-3.7___ubuntu-20.04___x64.txt 0:13:57.969502 3 10___3.10___windows-2022___x64.txt 0:14:19.837475 3 11___3.11___windows-2022___x64.txt 0:14:33.316770 4 1___3.6___ubuntu-20.04___x64_-DPYBIND11_FINDPYTHON=ON_-DCMA.txt 0:15:34.449278 4 22___3.6___windows-2019___x64_-DPYBIND11_FINDPYTHON=ON.txt 0:16:25.189055 2 1___3.9-dbg__deadsnakes____Valgrind___x64.txt 0:17:20.956667 4 15___3.6___macos-latest___x64.txt 0:17:27.513891 4 23___3.9___windows-2019___x64.txt 0:17:58.783286 3 8___3.6___windows-2022___x64.txt 0:18:25.917828 4 7___pypy-3.9___ubuntu-20.04___x64.txt 0:19:17.399820 3 13___pypy-3.8___windows-2022___x64.txt 0:19:45.002122 3 12___pypy-3.7___windows-2022___x64.txt 0:20:03.201926 4 16___3.9___macos-latest___x64.txt 0:20:15.415178 4 17___3.10___macos-latest___x64.txt 0:20:20.263216 4 20___pypy-3.8___macos-latest___x64.txt 0:20:31.998226 3 1___3___windows-latest___mingw64.txt 0:20:40.812286 4 18___3.11___macos-latest___x64.txt 0:22:47.714749 4 19___pypy-3.7___macos-latest___x64.txt 0:23:04.435859 3 2___3___windows-latest___mingw32.txt 0:25:48.719597 3 14___pypy-3.9___windows-2022___x64.txt 0:26:01.211688 4 21___pypy-3.9___macos-latest___x64.txt 0:28:19.971015 1 1___3___CentOS7__PGI_22.9___x64.txt ``` --- .github/workflows/ci.yml | 51 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 51 insertions(+) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index f63abbc2d4..a2c2c310be 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -496,6 +496,24 @@ jobs: - name: Interface test run: cmake --build build --target test_cmake_build + - name: Configure - Exercise cmake -DPYBIND11_TEST_OVERRIDE + if: matrix.gcc == '12' + shell: bash + run: > + cmake -S . -B build_partial + -DPYBIND11_WERROR=ON + -DDOWNLOAD_CATCH=ON + -DCMAKE_CXX_STANDARD=${{ matrix.std }} + -DPYTHON_EXECUTABLE=$(python3 -c "import sys; print(sys.executable)") + "-DPYBIND11_TEST_OVERRIDE=test_call_policies.cpp;test_gil_scoped.cpp;test_thread.cpp" + + - name: Build - Exercise cmake -DPYBIND11_TEST_OVERRIDE + if: matrix.gcc == '12' + run: cmake --build build_partial -j 2 + + - name: Python tests - Exercise cmake -DPYBIND11_TEST_OVERRIDE + if: matrix.gcc == '12' + run: cmake --build build_partial --target pytest # Testing on ICC using the oneAPI apt repo icc: @@ -888,6 +906,21 @@ jobs: - name: Interface test C++20 run: cmake --build build --target test_cmake_build + - name: Configure C++20 - Exercise cmake -DPYBIND11_TEST_OVERRIDE + run: > + cmake -S . -B build_partial + -DPYBIND11_WERROR=ON + -DDOWNLOAD_CATCH=ON + -DDOWNLOAD_EIGEN=ON + -DCMAKE_CXX_STANDARD=20 + "-DPYBIND11_TEST_OVERRIDE=test_call_policies.cpp;test_gil_scoped.cpp;test_thread.cpp" + + - name: Build C++20 - Exercise cmake -DPYBIND11_TEST_OVERRIDE + run: cmake --build build_partial -j 2 + + - name: Python tests - Exercise cmake -DPYBIND11_TEST_OVERRIDE + run: cmake --build build_partial --target pytest + mingw: name: "🐍 3 • windows-latest • ${{ matrix.sys }}" runs-on: windows-latest @@ -1104,5 +1137,23 @@ jobs: - name: Interface test run: cmake --build . --target test_cmake_build -j 2 + - name: CMake Configure - Exercise cmake -DPYBIND11_TEST_OVERRIDE + run: > + cmake -S . -B build_partial + -DPYBIND11_WERROR=ON + -DPYBIND11_SIMPLE_GIL_MANAGEMENT=OFF + -DDOWNLOAD_CATCH=ON + -DDOWNLOAD_EIGEN=ON + -DCMAKE_CXX_COMPILER=clang++ + -DCMAKE_CXX_STANDARD=17 + -DPYTHON_EXECUTABLE=$(python3 -c "import sys; print(sys.executable)") + "-DPYBIND11_TEST_OVERRIDE=test_call_policies.cpp;test_gil_scoped.cpp;test_thread.cpp" + + - name: Build - Exercise cmake -DPYBIND11_TEST_OVERRIDE + run: cmake --build build_partial -j 2 + + - name: Python tests - Exercise cmake -DPYBIND11_TEST_OVERRIDE + run: cmake --build build_partial --target pytest -j 2 + - name: Clean directory run: git clean -fdx From 1b4a508d5e5d44d74664d8fa06c27cea568ff36a Mon Sep 17 00:00:00 2001 From: "Ralf W. Grosse-Kunstleve" Date: Tue, 25 Apr 2023 10:35:07 -0700 Subject: [PATCH 24/24] Update skipif for Python 3.12a7 (the WIP needs to be handled in a separate PR). --- tests/test_exceptions.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/test_exceptions.py b/tests/test_exceptions.py index 1b4c89add1..a92ab59a34 100644 --- a/tests/test_exceptions.py +++ b/tests/test_exceptions.py @@ -319,7 +319,7 @@ def test_error_already_set_what_with_happy_exceptions( @pytest.mark.skipif( # Intentionally very specific: - "sys.version_info == (3, 12, 0, 'alpha', 6)", + "sys.version_info == (3, 12, 0, 'alpha', 7)", reason="WIP: https://github.com/python/cpython/issues/102594", ) @pytest.mark.skipif("env.PYPY", reason="PyErr_NormalizeException Segmentation fault")