Skip to content

Commit 08e234d

Browse files
committed
Merge branch 'master' into sh_merge_master
2 parents c6c9a9e + 6d4805c commit 08e234d

File tree

17 files changed

+185
-70
lines changed

17 files changed

+185
-70
lines changed

.github/workflows/emscripten.yaml

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
name: WASM
2+
3+
on:
4+
workflow_dispatch:
5+
pull_request:
6+
branches:
7+
- master
8+
9+
concurrency:
10+
group: ${{ github.workflow }}-${{ github.ref }}
11+
cancel-in-progress: true
12+
13+
jobs:
14+
build-wasm-emscripten:
15+
name: Pyodide wheel
16+
runs-on: ubuntu-22.04
17+
steps:
18+
- uses: actions/checkout@v4
19+
with:
20+
submodules: true
21+
fetch-depth: 0
22+
23+
- uses: pypa/[email protected]
24+
env:
25+
PYODIDE_BUILD_EXPORTS: whole_archive
26+
CFLAGS: -fexceptions
27+
LDFLAGS: -fexceptions
28+
with:
29+
package-dir: tests
30+
only: cp312-pyodide_wasm32

CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -159,6 +159,7 @@ set(PYBIND11_HEADERS
159159
include/pybind11/detail/type_caster_base.h
160160
include/pybind11/detail/type_caster_odr_guard.h
161161
include/pybind11/detail/typeid.h
162+
include/pybind11/detail/value_and_holder.h
162163
include/pybind11/attr.h
163164
include/pybind11/buffer_info.h
164165
include/pybind11/cast.h

include/pybind11/cast.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -824,11 +824,11 @@ struct copyable_holder_caster : public type_caster_base<type> {
824824
}
825825
}
826826

827-
bool load_value(value_and_holder &&v_h) {
827+
void load_value(value_and_holder &&v_h) {
828828
if (v_h.holder_constructed()) {
829829
value = v_h.value_ptr();
830830
holder = v_h.template holder<holder_type>();
831-
return true;
831+
return;
832832
}
833833
throw cast_error("Unable to cast from non-held to held instance (T& to Holder<T>) "
834834
#if !defined(PYBIND11_DETAILED_ERROR_MESSAGES)

include/pybind11/detail/common.h

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -462,6 +462,22 @@ PYBIND11_WARNING_POP
462462
return "Hello, World!";
463463
});
464464
}
465+
466+
The third macro argument is optional (available since 2.13.0), and can be used to
467+
mark the extension module as safe to run without the GIL under a free-threaded CPython
468+
interpreter. Passing this argument has no effect on other interpreters.
469+
470+
.. code-block:: cpp
471+
472+
PYBIND11_MODULE(example, m, py::mod_gil_not_used()) {
473+
m.doc() = "pybind11 example module safe to run without the GIL";
474+
475+
// Add bindings here
476+
m.def("foo", []() {
477+
return "Hello, Free-threaded World!";
478+
});
479+
}
480+
465481
\endrst */
466482
#define PYBIND11_MODULE(name, variable, ...) \
467483
static ::pybind11::module_::module_def PYBIND11_CONCAT(pybind11_module_def_, name) \

include/pybind11/detail/init.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -129,7 +129,7 @@ void construct(value_and_holder &v_h, Cpp<Class> *ptr, bool need_alias) {
129129
// the holder and destruction happens when we leave the C++ scope, and the holder
130130
// class gets to handle the destruction however it likes.
131131
v_h.value_ptr() = ptr;
132-
v_h.set_instance_registered(true); // SHORTCUT To prevent init_instance from registering it
132+
v_h.set_instance_registered(true); // Trick to prevent init_instance from registering it
133133
// DANGER ZONE BEGIN: exceptions will leave v_h in an invalid state.
134134
v_h.type->init_instance(v_h.inst, nullptr); // Set up the holder
135135
Holder<Class> temp_holder(std::move(v_h.holder<Holder<Class>>())); // Steal the holder

include/pybind11/detail/type_caster_base.h

Lines changed: 1 addition & 61 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
#include "descr.h"
1515
#include "internals.h"
1616
#include "typeid.h"
17+
#include "value_and_holder.h"
1718

1819
#include <cstdint>
1920
#include <iterator>
@@ -259,67 +260,6 @@ PYBIND11_NOINLINE handle find_registered_python_instance(void *src,
259260
});
260261
}
261262

262-
struct value_and_holder {
263-
instance *inst = nullptr;
264-
size_t index = 0u;
265-
const detail::type_info *type = nullptr;
266-
void **vh = nullptr;
267-
268-
// Main constructor for a found value/holder:
269-
value_and_holder(instance *i, const detail::type_info *type, size_t vpos, size_t index)
270-
: inst{i}, index{index}, type{type},
271-
vh{inst->simple_layout ? inst->simple_value_holder
272-
: &inst->nonsimple.values_and_holders[vpos]} {}
273-
274-
// Default constructor (used to signal a value-and-holder not found by get_value_and_holder())
275-
value_and_holder() = default;
276-
277-
// Used for past-the-end iterator
278-
explicit value_and_holder(size_t index) : index{index} {}
279-
280-
template <typename V = void>
281-
V *&value_ptr() const {
282-
return reinterpret_cast<V *&>(vh[0]);
283-
}
284-
// True if this `value_and_holder` has a non-null value pointer
285-
explicit operator bool() const { return value_ptr() != nullptr; }
286-
287-
template <typename H>
288-
H &holder() const {
289-
return reinterpret_cast<H &>(vh[1]);
290-
}
291-
bool holder_constructed() const {
292-
return inst->simple_layout
293-
? inst->simple_holder_constructed
294-
: (inst->nonsimple.status[index] & instance::status_holder_constructed) != 0u;
295-
}
296-
// NOLINTNEXTLINE(readability-make-member-function-const)
297-
void set_holder_constructed(bool v = true) {
298-
if (inst->simple_layout) {
299-
inst->simple_holder_constructed = v;
300-
} else if (v) {
301-
inst->nonsimple.status[index] |= instance::status_holder_constructed;
302-
} else {
303-
inst->nonsimple.status[index] &= (std::uint8_t) ~instance::status_holder_constructed;
304-
}
305-
}
306-
bool instance_registered() const {
307-
return inst->simple_layout
308-
? inst->simple_instance_registered
309-
: ((inst->nonsimple.status[index] & instance::status_instance_registered) != 0);
310-
}
311-
// NOLINTNEXTLINE(readability-make-member-function-const)
312-
void set_instance_registered(bool v = true) {
313-
if (inst->simple_layout) {
314-
inst->simple_instance_registered = v;
315-
} else if (v) {
316-
inst->nonsimple.status[index] |= instance::status_instance_registered;
317-
} else {
318-
inst->nonsimple.status[index] &= (std::uint8_t) ~instance::status_instance_registered;
319-
}
320-
}
321-
};
322-
323263
// Container for accessing and iterating over an instance's values/holders
324264
struct values_and_holders {
325265
private:
Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,77 @@
1+
// Copyright (c) 2016-2024 The Pybind Development Team.
2+
// All rights reserved. Use of this source code is governed by a
3+
// BSD-style license that can be found in the LICENSE file.
4+
5+
#pragma once
6+
7+
#include "common.h"
8+
9+
#include <cstddef>
10+
#include <typeinfo>
11+
12+
PYBIND11_NAMESPACE_BEGIN(PYBIND11_NAMESPACE)
13+
PYBIND11_NAMESPACE_BEGIN(detail)
14+
15+
struct value_and_holder {
16+
instance *inst = nullptr;
17+
size_t index = 0u;
18+
const detail::type_info *type = nullptr;
19+
void **vh = nullptr;
20+
21+
// Main constructor for a found value/holder:
22+
value_and_holder(instance *i, const detail::type_info *type, size_t vpos, size_t index)
23+
: inst{i}, index{index}, type{type},
24+
vh{inst->simple_layout ? inst->simple_value_holder
25+
: &inst->nonsimple.values_and_holders[vpos]} {}
26+
27+
// Default constructor (used to signal a value-and-holder not found by get_value_and_holder())
28+
value_and_holder() = default;
29+
30+
// Used for past-the-end iterator
31+
explicit value_and_holder(size_t index) : index{index} {}
32+
33+
template <typename V = void>
34+
V *&value_ptr() const {
35+
return reinterpret_cast<V *&>(vh[0]);
36+
}
37+
// True if this `value_and_holder` has a non-null value pointer
38+
explicit operator bool() const { return value_ptr() != nullptr; }
39+
40+
template <typename H>
41+
H &holder() const {
42+
return reinterpret_cast<H &>(vh[1]);
43+
}
44+
bool holder_constructed() const {
45+
return inst->simple_layout
46+
? inst->simple_holder_constructed
47+
: (inst->nonsimple.status[index] & instance::status_holder_constructed) != 0u;
48+
}
49+
// NOLINTNEXTLINE(readability-make-member-function-const)
50+
void set_holder_constructed(bool v = true) {
51+
if (inst->simple_layout) {
52+
inst->simple_holder_constructed = v;
53+
} else if (v) {
54+
inst->nonsimple.status[index] |= instance::status_holder_constructed;
55+
} else {
56+
inst->nonsimple.status[index] &= (std::uint8_t) ~instance::status_holder_constructed;
57+
}
58+
}
59+
bool instance_registered() const {
60+
return inst->simple_layout
61+
? inst->simple_instance_registered
62+
: ((inst->nonsimple.status[index] & instance::status_instance_registered) != 0);
63+
}
64+
// NOLINTNEXTLINE(readability-make-member-function-const)
65+
void set_instance_registered(bool v = true) {
66+
if (inst->simple_layout) {
67+
inst->simple_instance_registered = v;
68+
} else if (v) {
69+
inst->nonsimple.status[index] |= instance::status_instance_registered;
70+
} else {
71+
inst->nonsimple.status[index] &= (std::uint8_t) ~instance::status_instance_registered;
72+
}
73+
}
74+
};
75+
76+
PYBIND11_NAMESPACE_END(detail)
77+
PYBIND11_NAMESPACE_END(PYBIND11_NAMESPACE)

tests/CMakeLists.txt

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -88,7 +88,12 @@ set(PYBIND11_TEST_FILTER
8888
if(CMAKE_CURRENT_SOURCE_DIR STREQUAL CMAKE_SOURCE_DIR)
8989
# We're being loaded directly, i.e. not via add_subdirectory, so make this
9090
# work as its own project and load the pybind11Config to get the tools we need
91-
find_package(pybind11 REQUIRED CONFIG)
91+
92+
if(SKBUILD)
93+
add_subdirectory(.. pybind11_src)
94+
else()
95+
find_package(pybind11 REQUIRED CONFIG)
96+
endif()
9297
endif()
9398

9499
if(NOT CMAKE_BUILD_TYPE AND NOT DEFINED CMAKE_CONFIGURATION_TYPES)
@@ -524,6 +529,9 @@ foreach(target ${test_targets})
524529
endforeach()
525530
endif()
526531
endif()
532+
if(SKBUILD)
533+
install(TARGETS ${target} LIBRARY DESTINATION .)
534+
endif()
527535
endforeach()
528536

529537
# Provide nice organisation in IDEs

tests/extra_python_package/test_files.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,7 @@
6565
"include/pybind11/detail/type_caster_base.h",
6666
"include/pybind11/detail/type_caster_odr_guard.h",
6767
"include/pybind11/detail/typeid.h",
68+
"include/pybind11/detail/value_and_holder.h",
6869
}
6970

7071
eigen_headers = {

tests/pyproject.toml

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
# Warning: this is currently used for pyodide, and is not a general out-of-tree
2+
# builder for the tests (yet). Specifically, wheels can't be built from SDists.
3+
4+
[build-system]
5+
requires = ["scikit-build-core"]
6+
build-backend = "scikit_build_core.build"
7+
8+
[project]
9+
name = "pybind11_tests"
10+
version = "0.0.1"
11+
dependencies = ["pytest", "pytest-timeout", "numpy", "scipy"]
12+
13+
[tool.scikit-build.cmake.define]
14+
PYBIND11_FINDPYTHON = true
15+
16+
[tool.cibuildwheel]
17+
test-command = "pytest -o timeout=0 -p no:cacheprovider {project}/tests/test_*.py"

0 commit comments

Comments
 (0)