Skip to content

Add test_namespace_visibility (experiment, not for merging) #4044

New issue

Have a question about this project? # for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “#”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? # to your account

Closed
wants to merge 7 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 4 additions & 4 deletions include/pybind11/cast.h
Original file line number Diff line number Diff line change
Expand Up @@ -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 <typename type> \
struct always_construct_holder<holder_type> : always_construct_holder<void, ##__VA_ARGS__> { \
Expand All @@ -855,7 +855,7 @@ struct always_construct_holder {
class type_caster<holder_type, enable_if_t<!is_shared_ptr<holder_type>::value>> \
: public type_caster_holder<type, holder_type> {}; \
} \
}
PYBIND11_NAMESPACE_END(PYBIND11_NAMESPACE)

// PYBIND11_DECLARE_HOLDER_TYPE holder types:
template <typename base, typename holder>
Expand Down Expand Up @@ -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.:
Expand Down
2 changes: 1 addition & 1 deletion include/pybind11/detail/init.h
Original file line number Diff line number Diff line change
Expand Up @@ -425,4 +425,4 @@ struct pickle_factory<Get, Set, RetState(Self), NewInstance(ArgState)> {

PYBIND11_NAMESPACE_END(initimpl)
PYBIND11_NAMESPACE_END(detail)
PYBIND11_NAMESPACE_END(pybind11)
PYBIND11_NAMESPACE_END(PYBIND11_NAMESPACE)
4 changes: 2 additions & 2 deletions tests/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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)
Expand Down
5 changes: 5 additions & 0 deletions tests/conftest.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,11 @@
Adds docstring and exceptions message sanitizers.
"""

import sys

if sys.platform.startswith("linux"):
sys.setdlopenflags(0x100 | 0x2) # RTLD_GLOBAL | RTLD_NOW

import contextlib
import difflib
import gc
Expand Down
14 changes: 14 additions & 0 deletions tests/pybind11_cross_module_tests.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -16,9 +16,23 @@
#include <numeric>
#include <utility>

// 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

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
Expand Down
14 changes: 14 additions & 0 deletions tests/pybind11_tests.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,18 @@
#include <functional>
#include <list>

// 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

/*
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
Expand Down Expand Up @@ -73,6 +85,8 @@ PYBIND11_MODULE(pybind11_tests, m) {
m.attr("detailed_error_messages_enabled") = false;
#endif

PYBIND11_NS_VIS_DEFS

py::class_<UserType>(m, "UserType", "A `py::class_` type for testing")
.def(py::init<>())
.def(py::init<int>())
Expand Down
29 changes: 29 additions & 0 deletions tests/pybind11_tests.h
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@
#include <pybind11/eval.h>
#include <pybind11/pybind11.h>

#include <cstddef>

namespace py = pybind11;
using namespace pybind11::literals;

Expand Down Expand Up @@ -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<std::ptrdiff_t>(&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);
14 changes: 14 additions & 0 deletions tests/test_constants_and_functions.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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()"; }
Expand Down Expand Up @@ -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);

Expand Down
29 changes: 29 additions & 0 deletions tests/test_constants_and_functions.py
Original file line number Diff line number Diff line change
@@ -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

Expand Down
4 changes: 2 additions & 2 deletions tools/pybind11NewTools.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
4 changes: 2 additions & 2 deletions tools/pybind11Tools.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down