Compare commits

...

7 Commits

Author SHA1 Message Date
Megh Parikh 84d253503c
Merge 5f815052b0 into 1f8b4a7f1a 2024-09-20 23:42:16 -07:00
Hintay 1f8b4a7f1a
fix(cmake): `NO_EXTRAS` in `pybind11_add_module` function partially working (#5378) 2024-09-19 11:24:35 -04:00
dependabot[bot] ad9fd39e14
chore(deps): bump pypa/cibuildwheel in the actions group (#5376)
Bumps the actions group with 1 update: [pypa/cibuildwheel](https://github.com/pypa/cibuildwheel).


Updates `pypa/cibuildwheel` from 2.20 to 2.21
- [Release notes](https://github.com/pypa/cibuildwheel/releases)
- [Changelog](https://github.com/pypa/cibuildwheel/blob/main/docs/changelog.md)
- [Commits](https://github.com/pypa/cibuildwheel/compare/v2.20...v2.21)

---
updated-dependencies:
- dependency-name: pypa/cibuildwheel
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: actions
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-09-17 10:19:17 -07:00
vfdev 1d9483ff73
Added exception translator specific mutex used with try_translate_exceptions (#5362)
* Added exception translator specific mutex used with try_translate_exceptions
Fixes #5346

* - Replaced with_internals_for_exception_translator by with_exception_translators
- Incremented PYBIND11_INTERNALS_VERSION
- Added a test

* style: pre-commit fixes

* Fixed formatting and added explicit to ctors

* Addressed PR review comments

---------

Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
2024-09-17 09:47:20 -07:00
pre-commit-ci[bot] 5f815052b0 style: pre-commit fixes 2024-06-12 19:09:48 +00:00
Megh Parikh b8336a8bb7
Update cast.h 2024-06-12 15:09:21 -04:00
Megh Parikh 8869be19d8
Use argument-dependent-lookup for tuple_caster's get
Some libraries have custom container types and define their own `get`. They also extend the Pybind casters to bind their containers. This uses argument-dependent-lookup  for using the correct "get" function
2024-06-12 15:01:01 -04:00
9 changed files with 107 additions and 31 deletions

View File

@ -22,7 +22,7 @@ jobs:
submodules: true submodules: true
fetch-depth: 0 fetch-depth: 0
- uses: pypa/cibuildwheel@v2.20 - uses: pypa/cibuildwheel@v2.21
env: env:
PYODIDE_BUILD_EXPORTS: whole_archive PYODIDE_BUILD_EXPORTS: whole_archive
with: with:

View File

@ -685,23 +685,27 @@ public:
protected: protected:
template <size_t... Is> template <size_t... Is>
type implicit_cast(index_sequence<Is...>) & { type implicit_cast(index_sequence<Is...>) & {
return type(cast_op<Ts>(std::get<Is>(subcasters))...); using std::get;
return type(cast_op<Ts>(get<Is>(subcasters))...);
} }
template <size_t... Is> template <size_t... Is>
type implicit_cast(index_sequence<Is...>) && { type implicit_cast(index_sequence<Is...>) && {
return type(cast_op<Ts>(std::move(std::get<Is>(subcasters)))...); using std::get;
return type(cast_op<Ts>(std::move(get<Is>(subcasters)))...);
} }
static constexpr bool load_impl(const sequence &, bool, index_sequence<>) { return true; } static constexpr bool load_impl(const sequence &, bool, index_sequence<>) { return true; }
template <size_t... Is> template <size_t... Is>
bool load_impl(const sequence &seq, bool convert, index_sequence<Is...>) { bool load_impl(const sequence &seq, bool convert, index_sequence<Is...>) {
using std::get;
#ifdef __cpp_fold_expressions #ifdef __cpp_fold_expressions
if ((... || !std::get<Is>(subcasters).load(seq[Is], convert))) { if ((... || !get<Is>(subcasters).load(seq[Is], convert))) {
return false; return false;
} }
#else #else
for (bool r : {std::get<Is>(subcasters).load(seq[Is], convert)...}) { for (bool r : {get<Is>(subcasters).load(seq[Is], convert)...}) {
if (!r) { if (!r) {
return false; return false;
} }
@ -714,10 +718,11 @@ protected:
template <typename T, size_t... Is> template <typename T, size_t... Is>
static handle static handle
cast_impl(T &&src, return_value_policy policy, handle parent, index_sequence<Is...>) { cast_impl(T &&src, return_value_policy policy, handle parent, index_sequence<Is...>) {
using std::get;
PYBIND11_WORKAROUND_INCORRECT_MSVC_C4100(src, policy, parent); PYBIND11_WORKAROUND_INCORRECT_MSVC_C4100(src, policy, parent);
PYBIND11_WORKAROUND_INCORRECT_GCC_UNUSED_BUT_SET_PARAMETER(policy, parent); PYBIND11_WORKAROUND_INCORRECT_GCC_UNUSED_BUT_SET_PARAMETER(policy, parent);
std::array<object, size> entries{{reinterpret_steal<object>( std::array<object, size> entries{{reinterpret_steal<object>(
make_caster<Ts>::cast(std::get<Is>(std::forward<T>(src)), policy, parent))...}}; make_caster<Ts>::cast(get<Is>(std::forward<T>(src)), policy, parent))...}};
for (const auto &entry : entries) { for (const auto &entry : entries) {
if (!entry) { if (!entry) {
return handle(); return handle();

View File

@ -50,17 +50,17 @@ inline void try_translate_exceptions() {
- delegate translation to the next translator by throwing a new type of exception. - delegate translation to the next translator by throwing a new type of exception.
*/ */
bool handled = with_internals([&](internals &internals) { bool handled = with_exception_translators(
auto &local_exception_translators = get_local_internals().registered_exception_translators; [&](std::forward_list<ExceptionTranslator> &exception_translators,
if (detail::apply_exception_translators(local_exception_translators)) { std::forward_list<ExceptionTranslator> &local_exception_translators) {
return true; if (detail::apply_exception_translators(local_exception_translators)) {
} return true;
auto &exception_translators = internals.registered_exception_translators; }
if (detail::apply_exception_translators(exception_translators)) { if (detail::apply_exception_translators(exception_translators)) {
return true; return true;
} }
return false; return false;
}); });
if (!handled) { if (!handled) {
set_error(PyExc_SystemError, "Exception escaped from default exception translator!"); set_error(PyExc_SystemError, "Exception escaped from default exception translator!");

View File

@ -39,7 +39,11 @@
# if PY_VERSION_HEX >= 0x030C0000 || defined(_MSC_VER) # if PY_VERSION_HEX >= 0x030C0000 || defined(_MSC_VER)
// Version bump for Python 3.12+, before first 3.12 beta release. // Version bump for Python 3.12+, before first 3.12 beta release.
// Version bump for MSVC piggy-backed on PR #4779. See comments there. // Version bump for MSVC piggy-backed on PR #4779. See comments there.
# define PYBIND11_INTERNALS_VERSION 5 # ifdef Py_GIL_DISABLED
# define PYBIND11_INTERNALS_VERSION 6
# else
# define PYBIND11_INTERNALS_VERSION 5
# endif
# else # else
# define PYBIND11_INTERNALS_VERSION 4 # define PYBIND11_INTERNALS_VERSION 4
# endif # endif
@ -177,6 +181,7 @@ static_assert(sizeof(instance_map_shard) % 64 == 0,
struct internals { struct internals {
#ifdef Py_GIL_DISABLED #ifdef Py_GIL_DISABLED
pymutex mutex; pymutex mutex;
pymutex exception_translator_mutex;
#endif #endif
// std::type_index -> pybind11's type information // std::type_index -> pybind11's type information
type_map<type_info *> registered_types_cpp; type_map<type_info *> registered_types_cpp;
@ -643,6 +648,19 @@ inline auto with_internals(const F &cb) -> decltype(cb(get_internals())) {
return cb(internals); return cb(internals);
} }
template <typename F>
inline auto with_exception_translators(const F &cb)
-> decltype(cb(get_internals().registered_exception_translators,
get_local_internals().registered_exception_translators)) {
auto &internals = get_internals();
#ifdef Py_GIL_DISABLED
std::unique_lock<pymutex> lock((internals).exception_translator_mutex);
#endif
auto &local_internals = get_local_internals();
return cb(internals.registered_exception_translators,
local_internals.registered_exception_translators);
}
inline std::uint64_t mix64(std::uint64_t z) { inline std::uint64_t mix64(std::uint64_t z) {
// David Stafford's variant 13 of the MurmurHash3 finalizer popularized // David Stafford's variant 13 of the MurmurHash3 finalizer popularized
// by the SplitMix PRNG. // by the SplitMix PRNG.

View File

@ -2586,10 +2586,12 @@ void implicitly_convertible() {
} }
inline void register_exception_translator(ExceptionTranslator &&translator) { inline void register_exception_translator(ExceptionTranslator &&translator) {
detail::with_internals([&](detail::internals &internals) { detail::with_exception_translators(
internals.registered_exception_translators.push_front( [&](std::forward_list<ExceptionTranslator> &exception_translators,
std::forward<ExceptionTranslator>(translator)); std::forward_list<ExceptionTranslator> &local_exception_translators) {
}); (void) local_exception_translators;
exception_translators.push_front(std::forward<ExceptionTranslator>(translator));
});
} }
/** /**
@ -2599,11 +2601,12 @@ inline void register_exception_translator(ExceptionTranslator &&translator) {
* the exception. * the exception.
*/ */
inline void register_local_exception_translator(ExceptionTranslator &&translator) { inline void register_local_exception_translator(ExceptionTranslator &&translator) {
detail::with_internals([&](detail::internals &internals) { detail::with_exception_translators(
(void) internals; [&](std::forward_list<ExceptionTranslator> &exception_translators,
detail::get_local_internals().registered_exception_translators.push_front( std::forward_list<ExceptionTranslator> &local_exception_translators) {
std::forward<ExceptionTranslator>(translator)); (void) exception_translators;
}); local_exception_translators.push_front(std::forward<ExceptionTranslator>(translator));
});
} }
/** /**

View File

@ -0,0 +1,10 @@
from __future__ import annotations
class PythonMyException7(Exception):
def __init__(self, message):
self.message = message
super().__init__(message)
def __str__(self):
return "[PythonMyException7]: " + self.message.a

View File

@ -111,6 +111,16 @@ struct PythonAlreadySetInDestructor {
py::str s; py::str s;
}; };
struct CustomData {
explicit CustomData(const std::string &a) : a(a) {}
std::string a;
};
struct MyException7 {
explicit MyException7(const CustomData &message) : message(message) {}
CustomData message;
};
TEST_SUBMODULE(exceptions, m) { TEST_SUBMODULE(exceptions, m) {
m.def("throw_std_exception", m.def("throw_std_exception",
[]() { throw std::runtime_error("This exception was intentionally thrown."); }); []() { throw std::runtime_error("This exception was intentionally thrown."); });
@ -385,4 +395,33 @@ TEST_SUBMODULE(exceptions, m) {
// m.def("pass_exception_void", [](const py::exception<void>&) {}); // Does not compile. // m.def("pass_exception_void", [](const py::exception<void>&) {}); // Does not compile.
m.def("return_exception_void", []() { return py::exception<void>(); }); m.def("return_exception_void", []() { return py::exception<void>(); });
m.def("throws7", []() {
auto data = CustomData("abc");
throw MyException7(data);
});
py::class_<CustomData>(m, "CustomData", py::module_local())
.def(py::init<const std::string &>())
.def_readwrite("a", &CustomData::a);
PYBIND11_CONSTINIT static py::gil_safe_call_once_and_store<py::object>
PythonMyException7_storage;
PythonMyException7_storage.call_once_and_store_result([&]() {
auto mod = py::module_::import("custom_exceptions");
py::object obj = mod.attr("PythonMyException7");
return obj;
});
py::register_local_exception_translator([](std::exception_ptr p) {
try {
if (p) {
std::rethrow_exception(p);
}
} catch (const MyException7 &e) {
auto exc_type = PythonMyException7_storage.get_stored();
py::object exc_inst = exc_type(e.message);
PyErr_SetObject(PyExc_Exception, exc_inst.ptr());
}
});
} }

View File

@ -3,6 +3,7 @@ from __future__ import annotations
import sys import sys
import pytest import pytest
from custom_exceptions import PythonMyException7
import env import env
import pybind11_cross_module_tests as cm import pybind11_cross_module_tests as cm
@ -195,6 +196,10 @@ def test_custom(msg):
raise RuntimeError("Exception error: caught child from parent") from err raise RuntimeError("Exception error: caught child from parent") from err
assert msg(excinfo.value) == "this is a helper-defined translated exception" assert msg(excinfo.value) == "this is a helper-defined translated exception"
with pytest.raises(PythonMyException7) as excinfo:
m.throws7()
assert msg(excinfo.value) == "[PythonMyException7]: abc"
def test_nested_throws(capture): def test_nested_throws(capture):
"""Tests nested (e.g. C++ -> Python -> C++) exception handling""" """Tests nested (e.g. C++ -> Python -> C++) exception handling"""

View File

@ -274,10 +274,6 @@ function(pybind11_add_module target_name)
target_link_libraries(${target_name} PRIVATE pybind11::embed) target_link_libraries(${target_name} PRIVATE pybind11::embed)
endif() endif()
if(MSVC)
target_link_libraries(${target_name} PRIVATE pybind11::windows_extras)
endif()
# -fvisibility=hidden is required to allow multiple modules compiled against # -fvisibility=hidden is required to allow multiple modules compiled against
# different pybind versions to work properly, and for some features (e.g. # different pybind versions to work properly, and for some features (e.g.
# py::module_local). We force it on everything inside the `pybind11` # py::module_local). We force it on everything inside the `pybind11`