Merge branch 'smart_holder' into odr_guard_sh

This commit is contained in:
Ralf W. Grosse-Kunstleve 2022-07-13 17:40:20 -07:00
commit 4dabffcbd5
8 changed files with 170 additions and 5 deletions

View File

@ -33,7 +33,7 @@ repos:
# Upgrade old Python syntax # Upgrade old Python syntax
- repo: https://github.com/asottile/pyupgrade - repo: https://github.com/asottile/pyupgrade
rev: "v2.34.0" rev: "v2.37.1"
hooks: hooks:
- id: pyupgrade - id: pyupgrade
args: [--py36-plus] args: [--py36-plus]
@ -73,7 +73,7 @@ repos:
# Autoremoves unused imports # Autoremoves unused imports
- repo: https://github.com/hadialqattan/pycln - repo: https://github.com/hadialqattan/pycln
rev: "v1.3.5" rev: "v2.0.1"
hooks: hooks:
- id: pycln - id: pycln
stages: [manual] stages: [manual]

View File

@ -1666,7 +1666,7 @@ unpacking_collector<policy> collect_arguments(Args &&...args) {
template <typename Derived> template <typename Derived>
template <return_value_policy policy, typename... Args> template <return_value_policy policy, typename... Args>
object object_api<Derived>::operator()(Args &&...args) const { object object_api<Derived>::operator()(Args &&...args) const {
#if defined(PYBIND11_DETAILED_ERROR_MESSAGES) #ifndef NDEBUG
if (!PyGILState_Check()) { if (!PyGILState_Check()) {
pybind11_fail("pybind11::object_api<>::operator() PyGILState_Check() failure."); pybind11_fail("pybind11::object_api<>::operator() PyGILState_Check() failure.");
} }

View File

@ -148,6 +148,7 @@ set(PYBIND11_TEST_FILES
test_eigen test_eigen
test_enum test_enum
test_eval test_eval
test_exc_namespace_visibility.py
test_exceptions test_exceptions
test_factory_constructors test_factory_constructors
test_gil_scoped test_gil_scoped
@ -238,6 +239,8 @@ tests_extra_targets("test_exceptions.py" "cross_module_interleaved_error_already
tests_extra_targets("test_gil_scoped.py" "cross_module_gil_utils") tests_extra_targets("test_gil_scoped.py" "cross_module_gil_utils")
tests_extra_targets("test_class_sh_module_local.py" tests_extra_targets("test_class_sh_module_local.py"
"class_sh_module_local_0;class_sh_module_local_1;class_sh_module_local_2") "class_sh_module_local_0;class_sh_module_local_1;class_sh_module_local_2")
tests_extra_targets("test_exc_namespace_visibility.py"
"namespace_visibility_1;namespace_visibility_2")
set(PYBIND11_EIGEN_REPO set(PYBIND11_EIGEN_REPO
"https://gitlab.com/libeigen/eigen.git" "https://gitlab.com/libeigen/eigen.git"
@ -428,8 +431,14 @@ if(PYBIND11_CUDA_TESTS)
endif() endif()
foreach(target ${test_targets}) foreach(target ${test_targets})
if("${target}" STREQUAL "pybind11_tests")
set(test_files ${PYBIND11_TEST_FILES}) set(test_files ${PYBIND11_TEST_FILES})
if(NOT "${target}" STREQUAL "pybind11_tests") elseif("${target}" STREQUAL "namespace_visibility_1")
set(test_files namespace_visibility_1s.cpp)
if(PYBIND11_CUDA_TESTS)
set_property(SOURCE namespace_visibility_1s.cpp PROPERTY LANGUAGE CUDA)
endif()
else()
set(test_files "") set(test_files "")
endif() endif()

View File

@ -0,0 +1,31 @@
// Copyright (c) 2022 The Pybind Development Team.
// All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
#pragma once
#include <cstddef>
#ifdef __GNUG__
# define PYBIND11_NS_VIS_U /* unspecified */
# 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() { \
static std::ptrdiff_t value = 0; \
return reinterpret_cast<std::ptrdiff_t>(&value); \
}
#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);

View File

@ -0,0 +1,24 @@
#include "pybind11/pybind11.h"
#include "namespace_visibility.inl"
// 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 }
// ^ ^
// bit used .............. here
// clang-format on
void namespace_visibility_1s(pybind11::module_ &m);
PYBIND11_MODULE(namespace_visibility_1, m) {
PYBIND11_NS_VIS_DEFS
auto sm = m.def_submodule("submodule");
namespace_visibility_1s(sm);
}

View File

@ -0,0 +1,17 @@
#include "pybind11/pybind11.h"
#include "namespace_visibility.inl"
// 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 }
// ^ ^
// bit used ............. here
// clang-format on
void namespace_visibility_1s(pybind11::module_ &m) { PYBIND11_NS_VIS_DEFS }

View File

@ -0,0 +1,17 @@
#include "pybind11/pybind11.h"
#include "namespace_visibility.inl"
// 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 }
// ^ ^
// bit used ............ here
// clang-format on
PYBIND11_MODULE(namespace_visibility_2, m) { PYBIND11_NS_VIS_DEFS }

View File

@ -0,0 +1,67 @@
# This is not really a unit test, but probing environment/toolchain/platform-specific
# behavior under the exact same conditions as normal tests.
# The results are useful to understanding the effects of, e.g., removing
# `-fvisibility=hidden` or `__attribute__((visibility("hidden")))`, or linking
# extensions statically with the core Python interpreter.
# NOTE
# ====
# The "exc_" in "test_exc_namespace_visibility.py" is a workaround, to avoid a
# test_cross_module_exception_translator (test_exceptions.py) failure. This
# test has to be imported (by pytest) before test_exceptions.py; pytest sorts
# lexically. See https://github.com/pybind/pybind11/pull/4054 for more information.
import itertools
import namespace_visibility_1
import namespace_visibility_2
import pytest
# Please take a quick look at namespace_visibility.h first, to see what is being probed.
#
# EXPECTED is for -fvisibility=hidden or equivalent, as recommended in the docs.
EXPECTED_ALL_UNIQUE_POINTERS_OBSERVED = "AAC:AAc:AaC:Aac:aAC:aAc:aaC:aac"
# ^^^
# namespace_visibility_1 pointer|||
# namespace_visibility_1.submodule pointer|| (identical letters means same pointer)
# namespace_visibility_2 pointer|
# Upper-case: namespace visibility unspecified
# Lower-case: namespace visibility hidden
# This test probes all 2**3 combinations of u/h ** number-of-sub/modules.
#
# Also observed:
# AAA:AAc:AaC:Aac:aAC:aAc:aaC:aac -fvisibility=default Linux
# AAA:AAc:AaA:Aac:aAC:aAc:aaC:aac -fvisibility=default macOS
# AAA:AAa:AaA:Aaa:aAA:aAa:aaA:aaa everything linked statically
def test_namespace_visibility():
modules = (
namespace_visibility_1,
namespace_visibility_1.submodule,
namespace_visibility_2,
)
unique_pointer_labels = "ABC"
unique_pointers_observed = []
# u = visibility unspecified
# h = visibility hidden
for visibility in itertools.product(*([("u", "h")] * len(modules))):
# See functions in namespace_visibility_*.cpp
func = "ns_vis_" + "".join(visibility) + "_func"
ptrs = []
uq_ptrs_obs = ""
for vis, m in zip(visibility, modules):
ptr = getattr(m, func)()
ptrs.append(ptr)
lbl = unique_pointer_labels[ptrs.index(ptr)]
if vis == "h":
# Encode u/h info as upper/lower case to make the final result
# as compact as possible.
lbl = lbl.lower()
uq_ptrs_obs += lbl
unique_pointers_observed.append(uq_ptrs_obs)
all_unique_pointers_observed = ":".join(unique_pointers_observed)
if all_unique_pointers_observed != EXPECTED_ALL_UNIQUE_POINTERS_OBSERVED:
pytest.skip(
f"UNUSUAL all_unique_pointers_observed: {all_unique_pointers_observed}"
)