From feeadbcb7a6b5212eb5dcce30987d25cbc117eec Mon Sep 17 00:00:00 2001 From: "Ralf W. Grosse-Kunstleve" Date: Tue, 5 Jul 2022 15:34:55 -0700 Subject: [PATCH 1/7] Add `test_namespace_visibility` (experiment, not for merging) To answer the question: Is there a difference in behavior if some `__attribute__((visibility("hidden")))` are missing? --- tests/conftest.py | 5 +++++ tests/pybind11_cross_module_tests.cpp | 14 +++++++++++++ tests/pybind11_tests.cpp | 14 +++++++++++++ tests/pybind11_tests.h | 29 ++++++++++++++++++++++++++ tests/test_constants_and_functions.cpp | 14 +++++++++++++ tests/test_constants_and_functions.py | 29 ++++++++++++++++++++++++++ 6 files changed, 105 insertions(+) diff --git a/tests/conftest.py b/tests/conftest.py index e72ec0ef81..ad6f38bff0 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -4,6 +4,11 @@ Adds docstring and exceptions message sanitizers. """ +import sys + +if sys.platform.startswith("OFFlinux"): + sys.setdlopenflags(0x100 | 0x2) # RTLD_GLOBAL | RTLD_NOW + import contextlib import difflib import gc diff --git a/tests/pybind11_cross_module_tests.cpp b/tests/pybind11_cross_module_tests.cpp index 9379f3f259..441ff6ae0e 100644 --- a/tests/pybind11_cross_module_tests.cpp +++ b/tests/pybind11_cross_module_tests.cpp @@ -16,9 +16,23 @@ #include #include +// clang-format off +namespace pybind11_ns_vis_uuu PYBIND11_NS_VIS_U { PYBIND11_NS_VIS_FUNC } +namespace pybind11_ns_vis_uuh PYBIND11_NS_VIS_U { PYBIND11_NS_VIS_FUNC } +namespace pybind11_ns_vis_uhu PYBIND11_NS_VIS_U { PYBIND11_NS_VIS_FUNC } +namespace pybind11_ns_vis_uhh PYBIND11_NS_VIS_U { PYBIND11_NS_VIS_FUNC } +namespace pybind11_ns_vis_huu PYBIND11_NS_VIS_H { PYBIND11_NS_VIS_FUNC } +namespace pybind11_ns_vis_huh PYBIND11_NS_VIS_H { PYBIND11_NS_VIS_FUNC } +namespace pybind11_ns_vis_hhu PYBIND11_NS_VIS_H { PYBIND11_NS_VIS_FUNC } +namespace pybind11_ns_vis_hhh PYBIND11_NS_VIS_H { PYBIND11_NS_VIS_FUNC } +// ^ +// clang-format on + PYBIND11_MODULE(pybind11_cross_module_tests, m) { m.doc() = "pybind11 cross-module test module"; + PYBIND11_NS_VIS_DEFS + // test_local_bindings.py tests: // // Definitions here are tested by importing both this module and the diff --git a/tests/pybind11_tests.cpp b/tests/pybind11_tests.cpp index 3c04699157..ba17470b65 100644 --- a/tests/pybind11_tests.cpp +++ b/tests/pybind11_tests.cpp @@ -14,6 +14,18 @@ #include #include +// clang-format off +namespace pybind11_ns_vis_uuu PYBIND11_NS_VIS_U { PYBIND11_NS_VIS_FUNC } +namespace pybind11_ns_vis_uuh PYBIND11_NS_VIS_H { PYBIND11_NS_VIS_FUNC } +namespace pybind11_ns_vis_uhu PYBIND11_NS_VIS_U { PYBIND11_NS_VIS_FUNC } +namespace pybind11_ns_vis_uhh PYBIND11_NS_VIS_H { PYBIND11_NS_VIS_FUNC } +namespace pybind11_ns_vis_huu PYBIND11_NS_VIS_U { PYBIND11_NS_VIS_FUNC } +namespace pybind11_ns_vis_huh PYBIND11_NS_VIS_H { PYBIND11_NS_VIS_FUNC } +namespace pybind11_ns_vis_hhu PYBIND11_NS_VIS_U { PYBIND11_NS_VIS_FUNC } +namespace pybind11_ns_vis_hhh PYBIND11_NS_VIS_H { PYBIND11_NS_VIS_FUNC } +// ^ +// clang-format on + /* For testing purposes, we define a static global variable here in a function that each individual test .cpp calls with its initialization lambda. It's convenient here because we can just not @@ -73,6 +85,8 @@ PYBIND11_MODULE(pybind11_tests, m) { m.attr("detailed_error_messages_enabled") = false; #endif + PYBIND11_NS_VIS_DEFS + py::class_(m, "UserType", "A `py::class_` type for testing") .def(py::init<>()) .def(py::init()) diff --git a/tests/pybind11_tests.h b/tests/pybind11_tests.h index a7c00c2f9b..9a882834dd 100644 --- a/tests/pybind11_tests.h +++ b/tests/pybind11_tests.h @@ -3,6 +3,8 @@ #include #include +#include + namespace py = pybind11; using namespace pybind11::literals; @@ -83,3 +85,30 @@ void ignoreOldStyleInitWarnings(F &&body) { )", py::dict(py::arg("body") = py::cpp_function(body))); } + +#ifdef __GNUG__ +# define PYBIND11_NS_VIS_U +# define PYBIND11_NS_VIS_H __attribute__((visibility("hidden"))) +#else +# define PYBIND11_NS_VIS_U +# define PYBIND11_NS_VIS_H +#endif + +#define PYBIND11_NS_VIS_FUNC \ + inline std::ptrdiff_t func(bool get_address) { \ + static std::ptrdiff_t counter = 0; \ + if (get_address) { \ + return reinterpret_cast(&counter); \ + } \ + return counter++; \ + } + +#define PYBIND11_NS_VIS_DEFS \ + m.def("ns_vis_uuu_func", pybind11_ns_vis_uuu::func); \ + m.def("ns_vis_uuh_func", pybind11_ns_vis_uuh::func); \ + m.def("ns_vis_uhu_func", pybind11_ns_vis_uhu::func); \ + m.def("ns_vis_uhh_func", pybind11_ns_vis_uhh::func); \ + m.def("ns_vis_huu_func", pybind11_ns_vis_huu::func); \ + m.def("ns_vis_huh_func", pybind11_ns_vis_huh::func); \ + m.def("ns_vis_hhu_func", pybind11_ns_vis_hhu::func); \ + m.def("ns_vis_hhh_func", pybind11_ns_vis_hhh::func); diff --git a/tests/test_constants_and_functions.cpp b/tests/test_constants_and_functions.cpp index 1918a429c8..c1017abcb3 100644 --- a/tests/test_constants_and_functions.cpp +++ b/tests/test_constants_and_functions.cpp @@ -10,6 +10,18 @@ #include "pybind11_tests.h" +// clang-format off +namespace pybind11_ns_vis_uuu PYBIND11_NS_VIS_U { PYBIND11_NS_VIS_FUNC } +namespace pybind11_ns_vis_uuh PYBIND11_NS_VIS_U { PYBIND11_NS_VIS_FUNC } +namespace pybind11_ns_vis_uhu PYBIND11_NS_VIS_H { PYBIND11_NS_VIS_FUNC } +namespace pybind11_ns_vis_uhh PYBIND11_NS_VIS_H { PYBIND11_NS_VIS_FUNC } +namespace pybind11_ns_vis_huu PYBIND11_NS_VIS_U { PYBIND11_NS_VIS_FUNC } +namespace pybind11_ns_vis_huh PYBIND11_NS_VIS_U { PYBIND11_NS_VIS_FUNC } +namespace pybind11_ns_vis_hhu PYBIND11_NS_VIS_H { PYBIND11_NS_VIS_FUNC } +namespace pybind11_ns_vis_hhh PYBIND11_NS_VIS_H { PYBIND11_NS_VIS_FUNC } +// ^ +// clang-format on + enum MyEnum { EFirstEntry = 1, ESecondEntry }; std::string test_function1() { return "test_function()"; } @@ -83,6 +95,8 @@ struct C { } // namespace test_exc_sp TEST_SUBMODULE(constants_and_functions, m) { + PYBIND11_NS_VIS_DEFS + // test_constants m.attr("some_constant") = py::int_(14); diff --git a/tests/test_constants_and_functions.py b/tests/test_constants_and_functions.py index 5da0b84b8e..c6e90886b4 100644 --- a/tests/test_constants_and_functions.py +++ b/tests/test_constants_and_functions.py @@ -1,8 +1,37 @@ +import itertools + import pytest +import pybind11_cross_module_tests +import pybind11_tests + m = pytest.importorskip("pybind11_tests.constants_and_functions") +def test_namespace_visibility(): + mdls = ( + pybind11_tests, + pybind11_tests.constants_and_functions, + pybind11_cross_module_tests, + ) + codes = [] + for vis in itertools.product(*([("u", "h")] * len(mdls))): + func = "ns_vis_" + "".join(vis) + "_func" + addrs = [] + code = "" + for v, mdl in zip(vis, mdls): + addr = getattr(mdl, func)(True) + addrs.append(addr) + c = "ABC"[addrs.index(addr)] + if v == "h": + c = c.lower() + code += c + codes.append(code) + code_line = ":".join(codes) + if code_line != "AAC:AAc:AaC:Aac:aAC:aAc:aaC:aac": + pytest.skip(f"UNEXPECTED code_line: {code_line}") + + def test_constants(): assert m.some_constant == 14 From 00500fd318cfaff09046893de725a943c8f1068d Mon Sep 17 00:00:00 2001 From: "Ralf W. Grosse-Kunstleve" Date: Tue, 5 Jul 2022 18:56:52 -0700 Subject: [PATCH 2/7] Use `RTLD_GLOBAL | RTLD_NOW` under Linux --- tests/conftest.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/conftest.py b/tests/conftest.py index ad6f38bff0..c03f38ccdb 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -6,7 +6,7 @@ import sys -if sys.platform.startswith("OFFlinux"): +if sys.platform.startswith("linux"): sys.setdlopenflags(0x100 | 0x2) # RTLD_GLOBAL | RTLD_NOW import contextlib From c0ef15a1771380f68126c74b58f62d8c57b51e01 Mon Sep 17 00:00:00 2001 From: "Ralf W. Grosse-Kunstleve" Date: Tue, 5 Jul 2022 19:45:50 -0700 Subject: [PATCH 3/7] Force CXX_VISIBILITY_PRESET, CUDA_VISIBILITY_PRESET default --- tools/pybind11NewTools.cmake | 4 ++-- tools/pybind11Tools.cmake | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/tools/pybind11NewTools.cmake b/tools/pybind11NewTools.cmake index abba0fe0e2..508b2e3edb 100644 --- a/tools/pybind11NewTools.cmake +++ b/tools/pybind11NewTools.cmake @@ -209,11 +209,11 @@ function(pybind11_add_module target_name) # namespace; also turning it on for a pybind module compilation here avoids # potential warnings or issues from having mixed hidden/non-hidden types. if(NOT DEFINED CMAKE_CXX_VISIBILITY_PRESET) - set_target_properties(${target_name} PROPERTIES CXX_VISIBILITY_PRESET "hidden") + set_target_properties(${target_name} PROPERTIES CXX_VISIBILITY_PRESET "default") endif() if(NOT DEFINED CMAKE_CUDA_VISIBILITY_PRESET) - set_target_properties(${target_name} PROPERTIES CUDA_VISIBILITY_PRESET "hidden") + set_target_properties(${target_name} PROPERTIES CUDA_VISIBILITY_PRESET "default") endif() # If we don't pass a WITH_SOABI or WITHOUT_SOABI, use our own default handling of extensions diff --git a/tools/pybind11Tools.cmake b/tools/pybind11Tools.cmake index 5535e872f3..240e96cca3 100644 --- a/tools/pybind11Tools.cmake +++ b/tools/pybind11Tools.cmake @@ -189,11 +189,11 @@ function(pybind11_add_module target_name) # namespace; also turning it on for a pybind module compilation here avoids # potential warnings or issues from having mixed hidden/non-hidden types. if(NOT DEFINED CMAKE_CXX_VISIBILITY_PRESET) - set_target_properties(${target_name} PROPERTIES CXX_VISIBILITY_PRESET "hidden") + set_target_properties(${target_name} PROPERTIES CXX_VISIBILITY_PRESET "default") endif() if(NOT DEFINED CMAKE_CUDA_VISIBILITY_PRESET) - set_target_properties(${target_name} PROPERTIES CUDA_VISIBILITY_PRESET "hidden") + set_target_properties(${target_name} PROPERTIES CUDA_VISIBILITY_PRESET "default") endif() if(ARG_NO_EXTRAS) From e38caecb08bacae847ccf3951e006c14ac957d18 Mon Sep 17 00:00:00 2001 From: "Ralf W. Grosse-Kunstleve" Date: Wed, 6 Jul 2022 04:23:51 -0700 Subject: [PATCH 4/7] Force `PYBIND11_WERROR` off --- tests/CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index 7296cd1b81..184f4c4d6f 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -365,7 +365,7 @@ function(pybind11_enable_warnings target_name) -Wnon-virtual-dtor) endif() - if(PYBIND11_WERROR) + if(PYBIND11_WERROR AND NOT PYBIND11_WERROR) # ******** FORCE OFF ******** if(MSVC) target_compile_options(${target_name} PRIVATE /WX) elseif(PYBIND11_CUDA_TESTS) From e9569b51441fc6d2df523b3640724dcfe8376be1 Mon Sep 17 00:00:00 2001 From: "Ralf W. Grosse-Kunstleve" Date: Wed, 6 Jul 2022 04:58:16 -0700 Subject: [PATCH 5/7] Flip uuu...hhh bits, to be in the same order as the ABC address labels (purely to be more intuitive, it does not change anything substantial). --- tests/pybind11_cross_module_tests.cpp | 10 +++++----- tests/pybind11_tests.cpp | 10 +++++----- 2 files changed, 10 insertions(+), 10 deletions(-) diff --git a/tests/pybind11_cross_module_tests.cpp b/tests/pybind11_cross_module_tests.cpp index 441ff6ae0e..96a6fe7635 100644 --- a/tests/pybind11_cross_module_tests.cpp +++ b/tests/pybind11_cross_module_tests.cpp @@ -18,14 +18,14 @@ // clang-format off namespace pybind11_ns_vis_uuu PYBIND11_NS_VIS_U { PYBIND11_NS_VIS_FUNC } -namespace pybind11_ns_vis_uuh PYBIND11_NS_VIS_U { PYBIND11_NS_VIS_FUNC } +namespace pybind11_ns_vis_uuh PYBIND11_NS_VIS_H { PYBIND11_NS_VIS_FUNC } namespace pybind11_ns_vis_uhu PYBIND11_NS_VIS_U { PYBIND11_NS_VIS_FUNC } -namespace pybind11_ns_vis_uhh PYBIND11_NS_VIS_U { PYBIND11_NS_VIS_FUNC } -namespace pybind11_ns_vis_huu PYBIND11_NS_VIS_H { PYBIND11_NS_VIS_FUNC } +namespace pybind11_ns_vis_uhh PYBIND11_NS_VIS_H { PYBIND11_NS_VIS_FUNC } +namespace pybind11_ns_vis_huu PYBIND11_NS_VIS_U { PYBIND11_NS_VIS_FUNC } namespace pybind11_ns_vis_huh PYBIND11_NS_VIS_H { PYBIND11_NS_VIS_FUNC } -namespace pybind11_ns_vis_hhu PYBIND11_NS_VIS_H { PYBIND11_NS_VIS_FUNC } +namespace pybind11_ns_vis_hhu PYBIND11_NS_VIS_U { PYBIND11_NS_VIS_FUNC } namespace pybind11_ns_vis_hhh PYBIND11_NS_VIS_H { PYBIND11_NS_VIS_FUNC } -// ^ +// ^ // clang-format on PYBIND11_MODULE(pybind11_cross_module_tests, m) { diff --git a/tests/pybind11_tests.cpp b/tests/pybind11_tests.cpp index ba17470b65..d30e9a0cf3 100644 --- a/tests/pybind11_tests.cpp +++ b/tests/pybind11_tests.cpp @@ -16,14 +16,14 @@ // clang-format off namespace pybind11_ns_vis_uuu PYBIND11_NS_VIS_U { PYBIND11_NS_VIS_FUNC } -namespace pybind11_ns_vis_uuh PYBIND11_NS_VIS_H { PYBIND11_NS_VIS_FUNC } +namespace pybind11_ns_vis_uuh PYBIND11_NS_VIS_U { PYBIND11_NS_VIS_FUNC } namespace pybind11_ns_vis_uhu PYBIND11_NS_VIS_U { PYBIND11_NS_VIS_FUNC } -namespace pybind11_ns_vis_uhh PYBIND11_NS_VIS_H { PYBIND11_NS_VIS_FUNC } -namespace pybind11_ns_vis_huu PYBIND11_NS_VIS_U { PYBIND11_NS_VIS_FUNC } +namespace pybind11_ns_vis_uhh PYBIND11_NS_VIS_U { PYBIND11_NS_VIS_FUNC } +namespace pybind11_ns_vis_huu PYBIND11_NS_VIS_H { PYBIND11_NS_VIS_FUNC } namespace pybind11_ns_vis_huh PYBIND11_NS_VIS_H { PYBIND11_NS_VIS_FUNC } -namespace pybind11_ns_vis_hhu PYBIND11_NS_VIS_U { PYBIND11_NS_VIS_FUNC } +namespace pybind11_ns_vis_hhu PYBIND11_NS_VIS_H { PYBIND11_NS_VIS_FUNC } namespace pybind11_ns_vis_hhh PYBIND11_NS_VIS_H { PYBIND11_NS_VIS_FUNC } -// ^ +// ^ // clang-format on /* From 6a518f663408234cce64d61031e32509a5abb387 Mon Sep 17 00:00:00 2001 From: "Ralf W. Grosse-Kunstleve" Date: Wed, 6 Jul 2022 05:07:38 -0700 Subject: [PATCH 6/7] Disable test_iostream TO AVOID SEGFAULT: Python 3 - CentOS7 / PGI 22.3 - x64 --- tests/CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index 184f4c4d6f..6c4682ebaa 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -134,7 +134,7 @@ set(PYBIND11_TEST_FILES test_exceptions test_factory_constructors test_gil_scoped - test_iostream + # test_iostream TO AVOID SEGFAULT: Python 3 - CentOS7 / PGI 22.3 - x64 test_kwargs_and_defaults test_local_bindings test_methods_and_attributes From 3f01275cbe041711c6872e85628eb18a7fcbb794 Mon Sep 17 00:00:00 2001 From: "Ralf W. Grosse-Kunstleve" Date: Sat, 18 Jun 2022 22:06:52 -0700 Subject: [PATCH 7/7] PYBIND11_NAMESPACE consistency fixes. --- include/pybind11/cast.h | 8 ++++---- include/pybind11/detail/init.h | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/include/pybind11/cast.h b/include/pybind11/cast.h index 9a971704e4..782fb20d46 100644 --- a/include/pybind11/cast.h +++ b/include/pybind11/cast.h @@ -846,7 +846,7 @@ struct always_construct_holder { /// Create a specialization for custom holder types (silently ignores std::shared_ptr) #define PYBIND11_DECLARE_HOLDER_TYPE(type, holder_type, ...) \ - namespace pybind11 { \ + PYBIND11_NAMESPACE_BEGIN(PYBIND11_NAMESPACE) \ namespace detail { \ template \ struct always_construct_holder : always_construct_holder { \ @@ -855,7 +855,7 @@ struct always_construct_holder { class type_caster::value>> \ : public type_caster_holder {}; \ } \ - } + PYBIND11_NAMESPACE_END(PYBIND11_NAMESPACE) // PYBIND11_DECLARE_HOLDER_TYPE holder types: template @@ -1650,12 +1650,12 @@ handle type::handle_of() { } #define PYBIND11_MAKE_OPAQUE(...) \ - namespace pybind11 { \ + PYBIND11_NAMESPACE_BEGIN(PYBIND11_NAMESPACE) \ namespace detail { \ template <> \ class type_caster<__VA_ARGS__> : public type_caster_base<__VA_ARGS__> {}; \ } \ - } + PYBIND11_NAMESPACE_END(PYBIND11_NAMESPACE) /// Lets you pass a type containing a `,` through a macro parameter without needing a separate /// typedef, e.g.: diff --git a/include/pybind11/detail/init.h b/include/pybind11/detail/init.h index e1e665a69b..05f4fe54aa 100644 --- a/include/pybind11/detail/init.h +++ b/include/pybind11/detail/init.h @@ -425,4 +425,4 @@ struct pickle_factory { PYBIND11_NAMESPACE_END(initimpl) PYBIND11_NAMESPACE_END(detail) -PYBIND11_NAMESPACE_END(pybind11) +PYBIND11_NAMESPACE_END(PYBIND11_NAMESPACE)