netgen-mesher 6.2.2504.post11.dev0__cp313-cp313-win_amd64.whl → 6.2.2506.post48.dev0__cp313-cp313-win_amd64.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- netgen/__init__.pyi +3 -3
- netgen/cmake/NetgenConfig.cmake +10 -9
- netgen/config/__init__.pyi +8 -8
- netgen/config/config.py +7 -7
- netgen/config/config.pyi +8 -8
- netgen/include/core/archive.hpp +18 -3
- netgen/include/core/array.hpp +20 -4
- netgen/include/core/autodiff.hpp +9 -11
- netgen/include/core/autodiffdiff.hpp +0 -2
- netgen/include/core/bitarray.hpp +1 -1
- netgen/include/core/flags.hpp +1 -1
- netgen/include/core/hashtable.hpp +1 -1
- netgen/include/core/memtracer.hpp +7 -7
- netgen/include/core/ngcore.hpp +5 -0
- netgen/include/core/ngcore_api.hpp +11 -0
- netgen/include/core/paje_trace.hpp +9 -8
- netgen/include/core/profiler.hpp +5 -5
- netgen/include/core/register_archive.hpp +8 -0
- netgen/include/core/simd.hpp +69 -1
- netgen/include/core/simd_arm64.hpp +205 -1
- netgen/include/core/simd_avx.hpp +72 -4
- netgen/include/core/simd_avx512.hpp +9 -0
- netgen/include/core/simd_generic.hpp +274 -8
- netgen/include/core/simd_math.hpp +178 -0
- netgen/include/core/simd_sse.hpp +11 -1
- netgen/include/core/statushandler.hpp +37 -0
- netgen/include/core/table.hpp +3 -2
- netgen/include/core/taskmanager.hpp +34 -1
- netgen/include/core/utils.hpp +3 -8
- netgen/include/include/netgen_version.hpp +4 -4
- netgen/include/meshing/basegeom.hpp +1 -4
- netgen/include/meshing/global.hpp +0 -17
- netgen/include/meshing/hpref_tet.hpp +41 -0
- netgen/include/meshing/hprefinement.hpp +2 -0
- netgen/include/meshing/meshtype.hpp +2 -1
- netgen/include/meshing/msghandler.hpp +9 -6
- netgen/include/meshing/topology.hpp +2 -2
- netgen/include/nginterface.h +3 -2
- netgen/include/occ/occ_utils.hpp +26 -0
- netgen/include/occ/occgeom.hpp +8 -0
- netgen/include/pybind11/attr.h +40 -8
- netgen/include/pybind11/buffer_info.h +14 -14
- netgen/include/pybind11/cast.h +553 -29
- netgen/include/pybind11/chrono.h +4 -1
- netgen/include/pybind11/conduit/README.txt +15 -0
- netgen/include/pybind11/conduit/pybind11_conduit_v1.h +116 -0
- netgen/include/pybind11/conduit/pybind11_platform_abi_id.h +87 -0
- netgen/include/pybind11/conduit/wrap_include_python_h.h +72 -0
- netgen/include/pybind11/critical_section.h +56 -0
- netgen/include/pybind11/detail/class.h +172 -97
- netgen/include/pybind11/detail/common.h +270 -189
- netgen/include/pybind11/detail/cpp_conduit.h +75 -0
- netgen/include/pybind11/detail/descr.h +55 -0
- netgen/include/pybind11/detail/dynamic_raw_ptr_cast_if_possible.h +39 -0
- netgen/include/pybind11/detail/exception_translation.h +71 -0
- netgen/include/pybind11/detail/function_record_pyobject.h +191 -0
- netgen/include/pybind11/detail/init.h +113 -9
- netgen/include/pybind11/detail/internals.h +479 -344
- netgen/include/pybind11/detail/native_enum_data.h +209 -0
- netgen/include/pybind11/detail/pybind11_namespace_macros.h +82 -0
- netgen/include/pybind11/detail/struct_smart_holder.h +378 -0
- netgen/include/pybind11/detail/type_caster_base.h +506 -133
- netgen/include/pybind11/detail/using_smart_holder.h +22 -0
- netgen/include/pybind11/detail/value_and_holder.h +90 -0
- netgen/include/pybind11/eigen/matrix.h +19 -10
- netgen/include/pybind11/eigen/tensor.h +15 -11
- netgen/include/pybind11/embed.h +50 -46
- netgen/include/pybind11/eval.h +11 -6
- netgen/include/pybind11/functional.h +58 -49
- netgen/include/pybind11/gil.h +34 -82
- netgen/include/pybind11/gil_safe_call_once.h +12 -1
- netgen/include/pybind11/gil_simple.h +37 -0
- netgen/include/pybind11/native_enum.h +67 -0
- netgen/include/pybind11/numpy.h +272 -93
- netgen/include/pybind11/pybind11.h +947 -265
- netgen/include/pybind11/pytypes.h +127 -21
- netgen/include/pybind11/stl/filesystem.h +23 -25
- netgen/include/pybind11/stl.h +277 -59
- netgen/include/pybind11/stl_bind.h +42 -7
- netgen/include/pybind11/subinterpreter.h +299 -0
- netgen/include/pybind11/trampoline_self_life_support.h +65 -0
- netgen/include/pybind11/typing.h +177 -4
- netgen/include/pybind11/warnings.h +75 -0
- netgen/include/visualization/mvdraw.hpp +48 -12
- netgen/include/visualization/vssolution.hpp +3 -1
- netgen/lib/libnggui.lib +0 -0
- netgen/lib/ngcore.lib +0 -0
- netgen/lib/nglib.lib +0 -0
- netgen/libnggui.dll +0 -0
- netgen/libngguipy.pyd +0 -0
- netgen/libngpy/_NgOCC.pyi +224 -139
- netgen/libngpy/_csg.pyi +26 -26
- netgen/libngpy/_geom2d.pyi +34 -25
- netgen/libngpy/_meshing.pyi +262 -111
- netgen/libngpy/_stl.pyi +3 -4
- netgen/libngpy.pyd +0 -0
- netgen/ngcore.dll +0 -0
- netgen/nglib.dll +0 -0
- netgen/read_gmsh.py +41 -0
- netgen/togl.dll +0 -0
- netgen/version.py +1 -1
- netgen/webgui.py +38 -2
- {netgen_mesher-6.2.2504.post11.dev0.dist-info → netgen_mesher-6.2.2506.post48.dev0.dist-info}/METADATA +2 -1
- {netgen_mesher-6.2.2504.post11.dev0.dist-info → netgen_mesher-6.2.2506.post48.dev0.dist-info}/RECORD +153 -132
- pyngcore/pyngcore.cp313-win_amd64.pyd +0 -0
- {netgen_mesher-6.2.2504.post11.dev0.data → netgen_mesher-6.2.2506.post48.dev0.data}/data/share/netgen/boundarycondition.geo +0 -0
- {netgen_mesher-6.2.2504.post11.dev0.data → netgen_mesher-6.2.2506.post48.dev0.data}/data/share/netgen/boxcyl.geo +0 -0
- {netgen_mesher-6.2.2504.post11.dev0.data → netgen_mesher-6.2.2506.post48.dev0.data}/data/share/netgen/circle_on_cube.geo +0 -0
- {netgen_mesher-6.2.2504.post11.dev0.data → netgen_mesher-6.2.2506.post48.dev0.data}/data/share/netgen/cone.geo +0 -0
- {netgen_mesher-6.2.2504.post11.dev0.data → netgen_mesher-6.2.2506.post48.dev0.data}/data/share/netgen/cube.geo +0 -0
- {netgen_mesher-6.2.2504.post11.dev0.data → netgen_mesher-6.2.2506.post48.dev0.data}/data/share/netgen/cubeandring.geo +0 -0
- {netgen_mesher-6.2.2504.post11.dev0.data → netgen_mesher-6.2.2506.post48.dev0.data}/data/share/netgen/cubeandspheres.geo +0 -0
- {netgen_mesher-6.2.2504.post11.dev0.data → netgen_mesher-6.2.2506.post48.dev0.data}/data/share/netgen/cubemcyl.geo +0 -0
- {netgen_mesher-6.2.2504.post11.dev0.data → netgen_mesher-6.2.2506.post48.dev0.data}/data/share/netgen/cubemsphere.geo +0 -0
- {netgen_mesher-6.2.2504.post11.dev0.data → netgen_mesher-6.2.2506.post48.dev0.data}/data/share/netgen/cylinder.geo +0 -0
- {netgen_mesher-6.2.2504.post11.dev0.data → netgen_mesher-6.2.2506.post48.dev0.data}/data/share/netgen/cylsphere.geo +0 -0
- {netgen_mesher-6.2.2504.post11.dev0.data → netgen_mesher-6.2.2506.post48.dev0.data}/data/share/netgen/doc/ng4.pdf +0 -0
- {netgen_mesher-6.2.2504.post11.dev0.data → netgen_mesher-6.2.2506.post48.dev0.data}/data/share/netgen/ellipsoid.geo +0 -0
- {netgen_mesher-6.2.2504.post11.dev0.data → netgen_mesher-6.2.2506.post48.dev0.data}/data/share/netgen/ellipticcyl.geo +0 -0
- {netgen_mesher-6.2.2504.post11.dev0.data → netgen_mesher-6.2.2506.post48.dev0.data}/data/share/netgen/extrusion.geo +0 -0
- {netgen_mesher-6.2.2504.post11.dev0.data → netgen_mesher-6.2.2506.post48.dev0.data}/data/share/netgen/fichera.geo +0 -0
- {netgen_mesher-6.2.2504.post11.dev0.data → netgen_mesher-6.2.2506.post48.dev0.data}/data/share/netgen/frame.step +0 -0
- {netgen_mesher-6.2.2504.post11.dev0.data → netgen_mesher-6.2.2506.post48.dev0.data}/data/share/netgen/hinge.stl +0 -0
- {netgen_mesher-6.2.2504.post11.dev0.data → netgen_mesher-6.2.2506.post48.dev0.data}/data/share/netgen/lshape3d.geo +0 -0
- {netgen_mesher-6.2.2504.post11.dev0.data → netgen_mesher-6.2.2506.post48.dev0.data}/data/share/netgen/manyholes.geo +0 -0
- {netgen_mesher-6.2.2504.post11.dev0.data → netgen_mesher-6.2.2506.post48.dev0.data}/data/share/netgen/manyholes2.geo +0 -0
- {netgen_mesher-6.2.2504.post11.dev0.data → netgen_mesher-6.2.2506.post48.dev0.data}/data/share/netgen/matrix.geo +0 -0
- {netgen_mesher-6.2.2504.post11.dev0.data → netgen_mesher-6.2.2506.post48.dev0.data}/data/share/netgen/ortho.geo +0 -0
- {netgen_mesher-6.2.2504.post11.dev0.data → netgen_mesher-6.2.2506.post48.dev0.data}/data/share/netgen/part1.stl +0 -0
- {netgen_mesher-6.2.2504.post11.dev0.data → netgen_mesher-6.2.2506.post48.dev0.data}/data/share/netgen/period.geo +0 -0
- {netgen_mesher-6.2.2504.post11.dev0.data → netgen_mesher-6.2.2506.post48.dev0.data}/data/share/netgen/py_tutorials/exportNeutral.py +0 -0
- {netgen_mesher-6.2.2504.post11.dev0.data → netgen_mesher-6.2.2506.post48.dev0.data}/data/share/netgen/py_tutorials/mesh.py +0 -0
- {netgen_mesher-6.2.2504.post11.dev0.data → netgen_mesher-6.2.2506.post48.dev0.data}/data/share/netgen/py_tutorials/shaft.geo +0 -0
- {netgen_mesher-6.2.2504.post11.dev0.data → netgen_mesher-6.2.2506.post48.dev0.data}/data/share/netgen/revolution.geo +0 -0
- {netgen_mesher-6.2.2504.post11.dev0.data → netgen_mesher-6.2.2506.post48.dev0.data}/data/share/netgen/screw.step +0 -0
- {netgen_mesher-6.2.2504.post11.dev0.data → netgen_mesher-6.2.2506.post48.dev0.data}/data/share/netgen/sculpture.geo +0 -0
- {netgen_mesher-6.2.2504.post11.dev0.data → netgen_mesher-6.2.2506.post48.dev0.data}/data/share/netgen/shaft.geo +0 -0
- {netgen_mesher-6.2.2504.post11.dev0.data → netgen_mesher-6.2.2506.post48.dev0.data}/data/share/netgen/shell.geo +0 -0
- {netgen_mesher-6.2.2504.post11.dev0.data → netgen_mesher-6.2.2506.post48.dev0.data}/data/share/netgen/sphere.geo +0 -0
- {netgen_mesher-6.2.2504.post11.dev0.data → netgen_mesher-6.2.2506.post48.dev0.data}/data/share/netgen/sphereincube.geo +0 -0
- {netgen_mesher-6.2.2504.post11.dev0.data → netgen_mesher-6.2.2506.post48.dev0.data}/data/share/netgen/square.in2d +0 -0
- {netgen_mesher-6.2.2504.post11.dev0.data → netgen_mesher-6.2.2506.post48.dev0.data}/data/share/netgen/squarecircle.in2d +0 -0
- {netgen_mesher-6.2.2504.post11.dev0.data → netgen_mesher-6.2.2506.post48.dev0.data}/data/share/netgen/squarehole.in2d +0 -0
- {netgen_mesher-6.2.2504.post11.dev0.data → netgen_mesher-6.2.2506.post48.dev0.data}/data/share/netgen/torus.geo +0 -0
- {netgen_mesher-6.2.2504.post11.dev0.data → netgen_mesher-6.2.2506.post48.dev0.data}/data/share/netgen/trafo.geo +0 -0
- {netgen_mesher-6.2.2504.post11.dev0.data → netgen_mesher-6.2.2506.post48.dev0.data}/data/share/netgen/twobricks.geo +0 -0
- {netgen_mesher-6.2.2504.post11.dev0.data → netgen_mesher-6.2.2506.post48.dev0.data}/data/share/netgen/twocubes.geo +0 -0
- {netgen_mesher-6.2.2504.post11.dev0.data → netgen_mesher-6.2.2506.post48.dev0.data}/data/share/netgen/twocyl.geo +0 -0
- {netgen_mesher-6.2.2504.post11.dev0.dist-info → netgen_mesher-6.2.2506.post48.dev0.dist-info}/AUTHORS +0 -0
- {netgen_mesher-6.2.2504.post11.dev0.dist-info → netgen_mesher-6.2.2506.post48.dev0.dist-info}/LICENSE +0 -0
- {netgen_mesher-6.2.2504.post11.dev0.dist-info → netgen_mesher-6.2.2506.post48.dev0.dist-info}/WHEEL +0 -0
- {netgen_mesher-6.2.2504.post11.dev0.dist-info → netgen_mesher-6.2.2506.post48.dev0.dist-info}/entry_points.txt +0 -0
- {netgen_mesher-6.2.2504.post11.dev0.dist-info → netgen_mesher-6.2.2506.post48.dev0.dist-info}/top_level.txt +0 -0
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
// Copyright (c) 2024 The pybind Community.
|
|
2
|
+
|
|
3
|
+
#pragma once
|
|
4
|
+
|
|
5
|
+
#include <pybind11/pytypes.h>
|
|
6
|
+
|
|
7
|
+
#include "common.h"
|
|
8
|
+
#include "internals.h"
|
|
9
|
+
|
|
10
|
+
#include <typeinfo>
|
|
11
|
+
|
|
12
|
+
PYBIND11_NAMESPACE_BEGIN(PYBIND11_NAMESPACE)
|
|
13
|
+
PYBIND11_NAMESPACE_BEGIN(detail)
|
|
14
|
+
|
|
15
|
+
// Forward declaration needed here: Refactoring opportunity.
|
|
16
|
+
extern "C" inline PyObject *pybind11_object_new(PyTypeObject *type, PyObject *, PyObject *);
|
|
17
|
+
|
|
18
|
+
inline bool type_is_managed_by_our_internals(PyTypeObject *type_obj) {
|
|
19
|
+
#if defined(PYPY_VERSION)
|
|
20
|
+
auto &internals = get_internals();
|
|
21
|
+
return bool(internals.registered_types_py.find(type_obj)
|
|
22
|
+
!= internals.registered_types_py.end());
|
|
23
|
+
#else
|
|
24
|
+
return bool(type_obj->tp_new == pybind11_object_new);
|
|
25
|
+
#endif
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
inline bool is_instance_method_of_type(PyTypeObject *type_obj, PyObject *attr_name) {
|
|
29
|
+
PyObject *descr = _PyType_Lookup(type_obj, attr_name);
|
|
30
|
+
return bool((descr != nullptr) && PyInstanceMethod_Check(descr));
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
inline object try_get_cpp_conduit_method(PyObject *obj) {
|
|
34
|
+
if (PyType_Check(obj)) {
|
|
35
|
+
return object();
|
|
36
|
+
}
|
|
37
|
+
PyTypeObject *type_obj = Py_TYPE(obj);
|
|
38
|
+
str attr_name("_pybind11_conduit_v1_");
|
|
39
|
+
bool assumed_to_be_callable = false;
|
|
40
|
+
if (type_is_managed_by_our_internals(type_obj)) {
|
|
41
|
+
if (!is_instance_method_of_type(type_obj, attr_name.ptr())) {
|
|
42
|
+
return object();
|
|
43
|
+
}
|
|
44
|
+
assumed_to_be_callable = true;
|
|
45
|
+
}
|
|
46
|
+
PyObject *method = PyObject_GetAttr(obj, attr_name.ptr());
|
|
47
|
+
if (method == nullptr) {
|
|
48
|
+
PyErr_Clear();
|
|
49
|
+
return object();
|
|
50
|
+
}
|
|
51
|
+
if (!assumed_to_be_callable && PyCallable_Check(method) == 0) {
|
|
52
|
+
Py_DECREF(method);
|
|
53
|
+
return object();
|
|
54
|
+
}
|
|
55
|
+
return reinterpret_steal<object>(method);
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
inline void *try_raw_pointer_ephemeral_from_cpp_conduit(handle src,
|
|
59
|
+
const std::type_info *cpp_type_info) {
|
|
60
|
+
object method = try_get_cpp_conduit_method(src.ptr());
|
|
61
|
+
if (method) {
|
|
62
|
+
capsule cpp_type_info_capsule(const_cast<void *>(static_cast<const void *>(cpp_type_info)),
|
|
63
|
+
typeid(std::type_info).name());
|
|
64
|
+
object cpp_conduit = method(bytes(PYBIND11_PLATFORM_ABI_ID),
|
|
65
|
+
cpp_type_info_capsule,
|
|
66
|
+
bytes("raw_pointer_ephemeral"));
|
|
67
|
+
if (isinstance<capsule>(cpp_conduit)) {
|
|
68
|
+
return reinterpret_borrow<capsule>(cpp_conduit).get_pointer();
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
return nullptr;
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
PYBIND11_NAMESPACE_END(detail)
|
|
75
|
+
PYBIND11_NAMESPACE_END(PYBIND11_NAMESPACE)
|
|
@@ -99,6 +99,26 @@ constexpr descr<1, Type> const_name() {
|
|
|
99
99
|
return {'%'};
|
|
100
100
|
}
|
|
101
101
|
|
|
102
|
+
// Use a different name based on whether the parameter is used as input or output
|
|
103
|
+
template <size_t N1, size_t N2>
|
|
104
|
+
constexpr descr<N1 + N2 + 1> io_name(char const (&text1)[N1], char const (&text2)[N2]) {
|
|
105
|
+
return const_name("@") + const_name(text1) + const_name("@") + const_name(text2)
|
|
106
|
+
+ const_name("@");
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
// Ternary description for io_name (like the numeric type_caster)
|
|
110
|
+
template <bool B, size_t N1, size_t N2, size_t N3, size_t N4>
|
|
111
|
+
constexpr enable_if_t<B, descr<N1 + N2 + 1>>
|
|
112
|
+
io_name(char const (&text1)[N1], char const (&text2)[N2], char const (&)[N3], char const (&)[N4]) {
|
|
113
|
+
return io_name(text1, text2);
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
template <bool B, size_t N1, size_t N2, size_t N3, size_t N4>
|
|
117
|
+
constexpr enable_if_t<!B, descr<N3 + N4 + 1>>
|
|
118
|
+
io_name(char const (&)[N1], char const (&)[N2], char const (&text3)[N3], char const (&text4)[N4]) {
|
|
119
|
+
return io_name(text3, text4);
|
|
120
|
+
}
|
|
121
|
+
|
|
102
122
|
// If "_" is defined as a macro, py::detail::_ cannot be provided.
|
|
103
123
|
// It is therefore best to use py::detail::const_name universally.
|
|
104
124
|
// This block is for backward compatibility only.
|
|
@@ -137,12 +157,24 @@ constexpr descr<1, Type> _() {
|
|
|
137
157
|
#endif // #ifndef _
|
|
138
158
|
|
|
139
159
|
constexpr descr<0> concat() { return {}; }
|
|
160
|
+
constexpr descr<0> union_concat() { return {}; }
|
|
140
161
|
|
|
141
162
|
template <size_t N, typename... Ts>
|
|
142
163
|
constexpr descr<N, Ts...> concat(const descr<N, Ts...> &descr) {
|
|
143
164
|
return descr;
|
|
144
165
|
}
|
|
145
166
|
|
|
167
|
+
template <size_t N, typename... Ts>
|
|
168
|
+
constexpr descr<N, Ts...> union_concat(const descr<N, Ts...> &descr) {
|
|
169
|
+
return descr;
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
template <size_t N1, size_t N2, typename... Ts1, typename... Ts2>
|
|
173
|
+
constexpr descr<N1 + N2 + 3, Ts1..., Ts2...> operator|(const descr<N1, Ts1...> &a,
|
|
174
|
+
const descr<N2, Ts2...> &b) {
|
|
175
|
+
return a + const_name(" | ") + b;
|
|
176
|
+
}
|
|
177
|
+
|
|
146
178
|
#ifdef __cpp_fold_expressions
|
|
147
179
|
template <size_t N1, size_t N2, typename... Ts1, typename... Ts2>
|
|
148
180
|
constexpr descr<N1 + N2 + 2, Ts1..., Ts2...> operator,(const descr<N1, Ts1...> &a,
|
|
@@ -154,12 +186,25 @@ template <size_t N, typename... Ts, typename... Args>
|
|
|
154
186
|
constexpr auto concat(const descr<N, Ts...> &d, const Args &...args) {
|
|
155
187
|
return (d, ..., args);
|
|
156
188
|
}
|
|
189
|
+
|
|
190
|
+
template <size_t N, typename... Ts, typename... Args>
|
|
191
|
+
constexpr auto union_concat(const descr<N, Ts...> &d, const Args &...args) {
|
|
192
|
+
return (d | ... | args);
|
|
193
|
+
}
|
|
194
|
+
|
|
157
195
|
#else
|
|
158
196
|
template <size_t N, typename... Ts, typename... Args>
|
|
159
197
|
constexpr auto concat(const descr<N, Ts...> &d, const Args &...args)
|
|
160
198
|
-> decltype(std::declval<descr<N + 2, Ts...>>() + concat(args...)) {
|
|
161
199
|
return d + const_name(", ") + concat(args...);
|
|
162
200
|
}
|
|
201
|
+
|
|
202
|
+
template <size_t N, typename... Ts, typename... Args>
|
|
203
|
+
constexpr auto union_concat(const descr<N, Ts...> &d, const Args &...args)
|
|
204
|
+
-> decltype(std::declval<descr<N + 3, Ts...>>() + union_concat(args...)) {
|
|
205
|
+
return d + const_name(" | ") + union_concat(args...);
|
|
206
|
+
}
|
|
207
|
+
|
|
163
208
|
#endif
|
|
164
209
|
|
|
165
210
|
template <size_t N, typename... Ts>
|
|
@@ -167,5 +212,15 @@ constexpr descr<N + 2, Ts...> type_descr(const descr<N, Ts...> &descr) {
|
|
|
167
212
|
return const_name("{") + descr + const_name("}");
|
|
168
213
|
}
|
|
169
214
|
|
|
215
|
+
template <size_t N, typename... Ts>
|
|
216
|
+
constexpr descr<N + 4, Ts...> arg_descr(const descr<N, Ts...> &descr) {
|
|
217
|
+
return const_name("@^") + descr + const_name("@!");
|
|
218
|
+
}
|
|
219
|
+
|
|
220
|
+
template <size_t N, typename... Ts>
|
|
221
|
+
constexpr descr<N + 4, Ts...> return_descr(const descr<N, Ts...> &descr) {
|
|
222
|
+
return const_name("@$") + descr + const_name("@!");
|
|
223
|
+
}
|
|
224
|
+
|
|
170
225
|
PYBIND11_NAMESPACE_END(detail)
|
|
171
226
|
PYBIND11_NAMESPACE_END(PYBIND11_NAMESPACE)
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
// Copyright (c) 2021 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 <type_traits>
|
|
10
|
+
|
|
11
|
+
PYBIND11_NAMESPACE_BEGIN(PYBIND11_NAMESPACE)
|
|
12
|
+
PYBIND11_NAMESPACE_BEGIN(detail)
|
|
13
|
+
|
|
14
|
+
template <typename To, typename From, typename SFINAE = void>
|
|
15
|
+
struct dynamic_raw_ptr_cast_is_possible : std::false_type {};
|
|
16
|
+
|
|
17
|
+
template <typename To, typename From>
|
|
18
|
+
struct dynamic_raw_ptr_cast_is_possible<
|
|
19
|
+
To,
|
|
20
|
+
From,
|
|
21
|
+
detail::enable_if_t<!std::is_same<To, void>::value && std::is_polymorphic<From>::value>>
|
|
22
|
+
: std::true_type {};
|
|
23
|
+
|
|
24
|
+
template <typename To,
|
|
25
|
+
typename From,
|
|
26
|
+
detail::enable_if_t<!dynamic_raw_ptr_cast_is_possible<To, From>::value, int> = 0>
|
|
27
|
+
To *dynamic_raw_ptr_cast_if_possible(From * /*ptr*/) {
|
|
28
|
+
return nullptr;
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
template <typename To,
|
|
32
|
+
typename From,
|
|
33
|
+
detail::enable_if_t<dynamic_raw_ptr_cast_is_possible<To, From>::value, int> = 0>
|
|
34
|
+
To *dynamic_raw_ptr_cast_if_possible(From *ptr) {
|
|
35
|
+
return dynamic_cast<To *>(ptr);
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
PYBIND11_NAMESPACE_END(detail)
|
|
39
|
+
PYBIND11_NAMESPACE_END(PYBIND11_NAMESPACE)
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
/*
|
|
2
|
+
pybind11/detail/exception_translation.h: means to translate C++ exceptions to Python exceptions
|
|
3
|
+
|
|
4
|
+
Copyright (c) 2024 The Pybind Development Team.
|
|
5
|
+
|
|
6
|
+
All rights reserved. Use of this source code is governed by a
|
|
7
|
+
BSD-style license that can be found in the LICENSE file.
|
|
8
|
+
*/
|
|
9
|
+
|
|
10
|
+
#pragma once
|
|
11
|
+
|
|
12
|
+
#include "common.h"
|
|
13
|
+
#include "internals.h"
|
|
14
|
+
|
|
15
|
+
PYBIND11_NAMESPACE_BEGIN(PYBIND11_NAMESPACE)
|
|
16
|
+
PYBIND11_NAMESPACE_BEGIN(detail)
|
|
17
|
+
|
|
18
|
+
// Apply all the extensions translators from a list
|
|
19
|
+
// Return true if one of the translators completed without raising an exception
|
|
20
|
+
// itself. Return of false indicates that if there are other translators
|
|
21
|
+
// available, they should be tried.
|
|
22
|
+
inline bool apply_exception_translators(std::forward_list<ExceptionTranslator> &translators) {
|
|
23
|
+
auto last_exception = std::current_exception();
|
|
24
|
+
|
|
25
|
+
for (auto &translator : translators) {
|
|
26
|
+
try {
|
|
27
|
+
translator(last_exception);
|
|
28
|
+
return true;
|
|
29
|
+
} catch (...) {
|
|
30
|
+
last_exception = std::current_exception();
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
return false;
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
inline void try_translate_exceptions() {
|
|
37
|
+
/* When an exception is caught, give each registered exception
|
|
38
|
+
translator a chance to translate it to a Python exception. First
|
|
39
|
+
all module-local translators will be tried in reverse order of
|
|
40
|
+
registration. If none of the module-locale translators handle
|
|
41
|
+
the exception (or there are no module-locale translators) then
|
|
42
|
+
the global translators will be tried, also in reverse order of
|
|
43
|
+
registration.
|
|
44
|
+
|
|
45
|
+
A translator may choose to do one of the following:
|
|
46
|
+
|
|
47
|
+
- catch the exception and call py::set_error()
|
|
48
|
+
to set a standard (or custom) Python exception, or
|
|
49
|
+
- do nothing and let the exception fall through to the next translator, or
|
|
50
|
+
- delegate translation to the next translator by throwing a new type of exception.
|
|
51
|
+
*/
|
|
52
|
+
|
|
53
|
+
bool handled = with_exception_translators(
|
|
54
|
+
[&](std::forward_list<ExceptionTranslator> &exception_translators,
|
|
55
|
+
std::forward_list<ExceptionTranslator> &local_exception_translators) {
|
|
56
|
+
if (detail::apply_exception_translators(local_exception_translators)) {
|
|
57
|
+
return true;
|
|
58
|
+
}
|
|
59
|
+
if (detail::apply_exception_translators(exception_translators)) {
|
|
60
|
+
return true;
|
|
61
|
+
}
|
|
62
|
+
return false;
|
|
63
|
+
});
|
|
64
|
+
|
|
65
|
+
if (!handled) {
|
|
66
|
+
set_error(PyExc_SystemError, "Exception escaped from default exception translator!");
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
PYBIND11_NAMESPACE_END(detail)
|
|
71
|
+
PYBIND11_NAMESPACE_END(PYBIND11_NAMESPACE)
|
|
@@ -0,0 +1,191 @@
|
|
|
1
|
+
// Copyright (c) 2024-2025 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
|
+
// For background see the description of PR google/pybind11clif#30099.
|
|
6
|
+
|
|
7
|
+
#pragma once
|
|
8
|
+
|
|
9
|
+
#include <pybind11/attr.h>
|
|
10
|
+
#include <pybind11/conduit/pybind11_platform_abi_id.h>
|
|
11
|
+
#include <pybind11/pytypes.h>
|
|
12
|
+
|
|
13
|
+
#include "common.h"
|
|
14
|
+
|
|
15
|
+
#include <cstring>
|
|
16
|
+
#include <utility>
|
|
17
|
+
|
|
18
|
+
PYBIND11_NAMESPACE_BEGIN(PYBIND11_NAMESPACE)
|
|
19
|
+
PYBIND11_NAMESPACE_BEGIN(detail)
|
|
20
|
+
|
|
21
|
+
struct function_record_PyObject {
|
|
22
|
+
PyObject_HEAD
|
|
23
|
+
function_record *cpp_func_rec;
|
|
24
|
+
};
|
|
25
|
+
|
|
26
|
+
PYBIND11_NAMESPACE_BEGIN(function_record_PyTypeObject_methods)
|
|
27
|
+
|
|
28
|
+
PyObject *tp_new_impl(PyTypeObject *type, PyObject *args, PyObject *kwds);
|
|
29
|
+
PyObject *tp_alloc_impl(PyTypeObject *type, Py_ssize_t nitems);
|
|
30
|
+
int tp_init_impl(PyObject *self, PyObject *args, PyObject *kwds);
|
|
31
|
+
void tp_dealloc_impl(PyObject *self);
|
|
32
|
+
void tp_free_impl(void *self);
|
|
33
|
+
|
|
34
|
+
static PyObject *reduce_ex_impl(PyObject *self, PyObject *, PyObject *);
|
|
35
|
+
|
|
36
|
+
static PyMethodDef tp_methods_impl[]
|
|
37
|
+
= {{"__reduce_ex__",
|
|
38
|
+
// reduce_ex_impl is a PyCFunctionWithKeywords, but PyMethodDef
|
|
39
|
+
// requires a PyCFunction. The cast through void* is safe and
|
|
40
|
+
// idiomatic with METH_KEYWORDS, and it successfully sidesteps
|
|
41
|
+
// unhelpful compiler warnings.
|
|
42
|
+
// NOLINTNEXTLINE(bugprone-casting-through-void)
|
|
43
|
+
reinterpret_cast<PyCFunction>(reinterpret_cast<void *>(reduce_ex_impl)),
|
|
44
|
+
METH_VARARGS | METH_KEYWORDS,
|
|
45
|
+
nullptr},
|
|
46
|
+
{nullptr, nullptr, 0, nullptr}};
|
|
47
|
+
|
|
48
|
+
// Python 3.12+ emits a DeprecationWarning for heap types whose tp_name does
|
|
49
|
+
// not contain a dot ('.') and that lack a __module__ attribute. For pybind11's
|
|
50
|
+
// internal function_record type, we do not have an actual module object to
|
|
51
|
+
// attach, so we cannot use PyType_FromModuleAndSpec (introduced in Python 3.9)
|
|
52
|
+
// to set __module__ automatically.
|
|
53
|
+
//
|
|
54
|
+
// As a workaround, we define a "qualified" type name that includes a dummy
|
|
55
|
+
// module name (PYBIND11_DUMMY_MODULE_NAME). This is non‑idiomatic but avoids
|
|
56
|
+
// the deprecation warning, and results in reprs like
|
|
57
|
+
//
|
|
58
|
+
// <class 'pybind11_builtins.pybind11_detail_function_record_...'>
|
|
59
|
+
//
|
|
60
|
+
// even though no real pybind11_builtins module exists. If pybind11 gains an
|
|
61
|
+
// actual module object in the future, this code should switch to
|
|
62
|
+
// PyType_FromModuleAndSpec for Python 3.9+ and drop the dummy module
|
|
63
|
+
// workaround.
|
|
64
|
+
//
|
|
65
|
+
// Note that this name is versioned.
|
|
66
|
+
#define PYBIND11_DETAIL_FUNCTION_RECORD_TP_PLAINNAME \
|
|
67
|
+
"pybind11_detail_function_record_" PYBIND11_DETAIL_FUNCTION_RECORD_ABI_ID \
|
|
68
|
+
"_" PYBIND11_PLATFORM_ABI_ID
|
|
69
|
+
constexpr char tp_plainname_impl[] = PYBIND11_DETAIL_FUNCTION_RECORD_TP_PLAINNAME;
|
|
70
|
+
constexpr char tp_qualname_impl[]
|
|
71
|
+
= PYBIND11_DUMMY_MODULE_NAME "." PYBIND11_DETAIL_FUNCTION_RECORD_TP_PLAINNAME;
|
|
72
|
+
|
|
73
|
+
PYBIND11_NAMESPACE_END(function_record_PyTypeObject_methods)
|
|
74
|
+
|
|
75
|
+
static PyType_Slot function_record_PyType_Slots[] = {
|
|
76
|
+
{Py_tp_dealloc,
|
|
77
|
+
reinterpret_cast<void *>(function_record_PyTypeObject_methods::tp_dealloc_impl)},
|
|
78
|
+
{Py_tp_methods,
|
|
79
|
+
reinterpret_cast<void *>(function_record_PyTypeObject_methods::tp_methods_impl)},
|
|
80
|
+
{Py_tp_init, reinterpret_cast<void *>(function_record_PyTypeObject_methods::tp_init_impl)},
|
|
81
|
+
{Py_tp_alloc, reinterpret_cast<void *>(function_record_PyTypeObject_methods::tp_alloc_impl)},
|
|
82
|
+
{Py_tp_new, reinterpret_cast<void *>(function_record_PyTypeObject_methods::tp_new_impl)},
|
|
83
|
+
{Py_tp_free, reinterpret_cast<void *>(function_record_PyTypeObject_methods::tp_free_impl)},
|
|
84
|
+
{0, nullptr}};
|
|
85
|
+
|
|
86
|
+
static PyType_Spec function_record_PyType_Spec
|
|
87
|
+
= {function_record_PyTypeObject_methods::tp_qualname_impl,
|
|
88
|
+
sizeof(function_record_PyObject),
|
|
89
|
+
0,
|
|
90
|
+
Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HEAPTYPE,
|
|
91
|
+
function_record_PyType_Slots};
|
|
92
|
+
|
|
93
|
+
inline PyTypeObject *get_function_record_PyTypeObject() {
|
|
94
|
+
PyTypeObject *&py_type_obj = detail::get_local_internals().function_record_py_type;
|
|
95
|
+
if (!py_type_obj) {
|
|
96
|
+
PyObject *py_obj = PyType_FromSpec(&function_record_PyType_Spec);
|
|
97
|
+
if (py_obj == nullptr) {
|
|
98
|
+
throw error_already_set();
|
|
99
|
+
}
|
|
100
|
+
py_type_obj = reinterpret_cast<PyTypeObject *>(py_obj);
|
|
101
|
+
}
|
|
102
|
+
return py_type_obj;
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
inline bool is_function_record_PyObject(PyObject *obj) {
|
|
106
|
+
if (PyType_Check(obj) != 0) {
|
|
107
|
+
return false;
|
|
108
|
+
}
|
|
109
|
+
PyTypeObject *obj_type = Py_TYPE(obj);
|
|
110
|
+
|
|
111
|
+
PyTypeObject *frtype = get_function_record_PyTypeObject();
|
|
112
|
+
|
|
113
|
+
// Fast path (pointer comparison).
|
|
114
|
+
if (obj_type == frtype) {
|
|
115
|
+
return true;
|
|
116
|
+
}
|
|
117
|
+
// This works across extension modules. Note that tp_name is versioned.
|
|
118
|
+
if (strcmp(obj_type->tp_name, function_record_PyTypeObject_methods::tp_qualname_impl) == 0
|
|
119
|
+
|| strcmp(obj_type->tp_name, function_record_PyTypeObject_methods::tp_plainname_impl)
|
|
120
|
+
== 0) {
|
|
121
|
+
return true;
|
|
122
|
+
}
|
|
123
|
+
return false;
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
inline function_record *function_record_ptr_from_PyObject(PyObject *obj) {
|
|
127
|
+
if (is_function_record_PyObject(obj)) {
|
|
128
|
+
return ((detail::function_record_PyObject *) obj)->cpp_func_rec;
|
|
129
|
+
}
|
|
130
|
+
return nullptr;
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
inline object function_record_PyObject_New() {
|
|
134
|
+
auto *py_func_rec = PyObject_New(function_record_PyObject, get_function_record_PyTypeObject());
|
|
135
|
+
if (py_func_rec == nullptr) {
|
|
136
|
+
throw error_already_set();
|
|
137
|
+
}
|
|
138
|
+
py_func_rec->cpp_func_rec = nullptr; // For clarity/purity. Redundant in practice.
|
|
139
|
+
return reinterpret_steal<object>((PyObject *) py_func_rec);
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
PYBIND11_NAMESPACE_BEGIN(function_record_PyTypeObject_methods)
|
|
143
|
+
|
|
144
|
+
// Guard against accidents & oversights, in particular when porting to future Python versions.
|
|
145
|
+
inline PyObject *tp_new_impl(PyTypeObject *, PyObject *, PyObject *) {
|
|
146
|
+
pybind11_fail("UNEXPECTED CALL OF function_record_PyTypeObject_methods::tp_new_impl");
|
|
147
|
+
// return nullptr; // Unreachable.
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
inline PyObject *tp_alloc_impl(PyTypeObject *, Py_ssize_t) {
|
|
151
|
+
pybind11_fail("UNEXPECTED CALL OF function_record_PyTypeObject_methods::tp_alloc_impl");
|
|
152
|
+
// return nullptr; // Unreachable.
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
inline int tp_init_impl(PyObject *, PyObject *, PyObject *) {
|
|
156
|
+
pybind11_fail("UNEXPECTED CALL OF function_record_PyTypeObject_methods::tp_init_impl");
|
|
157
|
+
// return -1; // Unreachable.
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
inline void tp_free_impl(void *) {
|
|
161
|
+
pybind11_fail("UNEXPECTED CALL OF function_record_PyTypeObject_methods::tp_free_impl");
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
inline PyObject *reduce_ex_impl(PyObject *self, PyObject *, PyObject *) {
|
|
165
|
+
// Deliberately ignoring the arguments for simplicity (expected is `protocol: int`).
|
|
166
|
+
const function_record *rec = function_record_ptr_from_PyObject(self);
|
|
167
|
+
if (rec == nullptr) {
|
|
168
|
+
pybind11_fail(
|
|
169
|
+
"FATAL: function_record_PyTypeObject reduce_ex_impl(): cannot obtain cpp_func_rec.");
|
|
170
|
+
}
|
|
171
|
+
if (rec->name != nullptr && rec->name[0] != '\0' && rec->scope
|
|
172
|
+
&& PyModule_Check(rec->scope.ptr()) != 0) {
|
|
173
|
+
object scope_module = get_scope_module(rec->scope);
|
|
174
|
+
if (scope_module) {
|
|
175
|
+
auto builtins = reinterpret_borrow<dict>(PyEval_GetBuiltins());
|
|
176
|
+
auto builtins_eval = builtins["eval"];
|
|
177
|
+
auto reconstruct_args = make_tuple(str("__import__('importlib').import_module('")
|
|
178
|
+
+ scope_module + str("')"));
|
|
179
|
+
return make_tuple(std::move(builtins_eval), std::move(reconstruct_args))
|
|
180
|
+
.release()
|
|
181
|
+
.ptr();
|
|
182
|
+
}
|
|
183
|
+
}
|
|
184
|
+
set_error(PyExc_RuntimeError, repr(self) + str(" is not pickleable."));
|
|
185
|
+
return nullptr;
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
PYBIND11_NAMESPACE_END(function_record_PyTypeObject_methods)
|
|
189
|
+
|
|
190
|
+
PYBIND11_NAMESPACE_END(detail)
|
|
191
|
+
PYBIND11_NAMESPACE_END(PYBIND11_NAMESPACE)
|
|
@@ -10,6 +10,7 @@
|
|
|
10
10
|
#pragma once
|
|
11
11
|
|
|
12
12
|
#include "class.h"
|
|
13
|
+
#include "using_smart_holder.h"
|
|
13
14
|
|
|
14
15
|
PYBIND11_NAMESPACE_BEGIN(PYBIND11_NAMESPACE)
|
|
15
16
|
|
|
@@ -36,7 +37,7 @@ private:
|
|
|
36
37
|
|
|
37
38
|
PYBIND11_NAMESPACE_BEGIN(initimpl)
|
|
38
39
|
|
|
39
|
-
inline void no_nullptr(void *ptr) {
|
|
40
|
+
inline void no_nullptr(const void *ptr) {
|
|
40
41
|
if (!ptr) {
|
|
41
42
|
throw type_error("pybind11::init(): factory function returned nullptr");
|
|
42
43
|
}
|
|
@@ -60,7 +61,7 @@ bool is_alias(Cpp<Class> *ptr) {
|
|
|
60
61
|
}
|
|
61
62
|
// Failing fallback version of the above for a no-alias class (always returns false)
|
|
62
63
|
template <typename /*Class*/>
|
|
63
|
-
constexpr bool is_alias(void *) {
|
|
64
|
+
constexpr bool is_alias(const void *) {
|
|
64
65
|
return false;
|
|
65
66
|
}
|
|
66
67
|
|
|
@@ -128,11 +129,13 @@ void construct(value_and_holder &v_h, Cpp<Class> *ptr, bool need_alias) {
|
|
|
128
129
|
// the holder and destruction happens when we leave the C++ scope, and the holder
|
|
129
130
|
// class gets to handle the destruction however it likes.
|
|
130
131
|
v_h.value_ptr() = ptr;
|
|
131
|
-
v_h.set_instance_registered(true);
|
|
132
|
-
|
|
132
|
+
v_h.set_instance_registered(true); // Trick to prevent init_instance from registering it
|
|
133
|
+
// DANGER ZONE BEGIN: exceptions will leave v_h in an invalid state.
|
|
134
|
+
v_h.type->init_instance(v_h.inst, nullptr); // Set up the holder
|
|
133
135
|
Holder<Class> temp_holder(std::move(v_h.holder<Holder<Class>>())); // Steal the holder
|
|
134
136
|
v_h.type->dealloc(v_h); // Destroys the moved-out holder remains, resets value ptr to null
|
|
135
137
|
v_h.set_instance_registered(false);
|
|
138
|
+
// DANGER ZONE END.
|
|
136
139
|
|
|
137
140
|
construct_alias_from_cpp<Class>(is_alias_constructible<Class>{}, v_h, std::move(*ptr));
|
|
138
141
|
} else {
|
|
@@ -153,7 +156,7 @@ void construct(value_and_holder &v_h, Alias<Class> *alias_ptr, bool) {
|
|
|
153
156
|
// holder. This also handles types like std::shared_ptr<T> and std::unique_ptr<T> where T is a
|
|
154
157
|
// derived type (through those holder's implicit conversion from derived class holder
|
|
155
158
|
// constructors).
|
|
156
|
-
template <typename Class>
|
|
159
|
+
template <typename Class, detail::enable_if_t<!is_smart_holder<Holder<Class>>::value, int> = 0>
|
|
157
160
|
void construct(value_and_holder &v_h, Holder<Class> holder, bool need_alias) {
|
|
158
161
|
PYBIND11_WORKAROUND_INCORRECT_MSVC_C4100(need_alias);
|
|
159
162
|
auto *ptr = holder_helper<Holder<Class>>::get(holder);
|
|
@@ -164,7 +167,12 @@ void construct(value_and_holder &v_h, Holder<Class> holder, bool need_alias) {
|
|
|
164
167
|
"is not an alias instance");
|
|
165
168
|
}
|
|
166
169
|
|
|
167
|
-
|
|
170
|
+
// Cast away constness to store in void* storage.
|
|
171
|
+
// The value_and_holder storage is fundamentally untyped (void**), so we lose
|
|
172
|
+
// const-correctness here by design. The const qualifier will be restored
|
|
173
|
+
// when the pointer is later retrieved and cast back to the original type.
|
|
174
|
+
// This explicit const_cast makes the const-removal clearly visible.
|
|
175
|
+
v_h.value_ptr() = const_cast<void *>(static_cast<const void *>(ptr));
|
|
168
176
|
v_h.type->init_instance(v_h.inst, &holder);
|
|
169
177
|
}
|
|
170
178
|
|
|
@@ -195,6 +203,92 @@ void construct(value_and_holder &v_h, Alias<Class> &&result, bool) {
|
|
|
195
203
|
v_h.value_ptr() = new Alias<Class>(std::move(result));
|
|
196
204
|
}
|
|
197
205
|
|
|
206
|
+
template <typename T, typename D>
|
|
207
|
+
smart_holder init_smart_holder_from_unique_ptr(std::unique_ptr<T, D> &&unq_ptr,
|
|
208
|
+
bool void_cast_raw_ptr) {
|
|
209
|
+
void *void_ptr = void_cast_raw_ptr ? static_cast<void *>(unq_ptr.get()) : nullptr;
|
|
210
|
+
return smart_holder::from_unique_ptr(std::move(unq_ptr), void_ptr);
|
|
211
|
+
}
|
|
212
|
+
|
|
213
|
+
template <typename Class,
|
|
214
|
+
typename D = std::default_delete<Cpp<Class>>,
|
|
215
|
+
detail::enable_if_t<is_smart_holder<Holder<Class>>::value, int> = 0>
|
|
216
|
+
void construct(value_and_holder &v_h, std::unique_ptr<Cpp<Class>, D> &&unq_ptr, bool need_alias) {
|
|
217
|
+
PYBIND11_WORKAROUND_INCORRECT_MSVC_C4100(need_alias);
|
|
218
|
+
auto *ptr = unq_ptr.get();
|
|
219
|
+
no_nullptr(ptr);
|
|
220
|
+
if (Class::has_alias && need_alias && !is_alias<Class>(ptr)) {
|
|
221
|
+
throw type_error("pybind11::init(): construction failed: returned std::unique_ptr pointee "
|
|
222
|
+
"is not an alias instance");
|
|
223
|
+
}
|
|
224
|
+
// Here and below: if the new object is a trampoline, the shared_from_this mechanism needs
|
|
225
|
+
// to be prevented from accessing the smart_holder vptr, because it does not keep the
|
|
226
|
+
// trampoline Python object alive. For types that don't inherit from enable_shared_from_this
|
|
227
|
+
// it does not matter if void_cast_raw_ptr is true or false, therefore it's not necessary
|
|
228
|
+
// to also inspect the type.
|
|
229
|
+
auto smhldr = init_smart_holder_from_unique_ptr(
|
|
230
|
+
std::move(unq_ptr), /*void_cast_raw_ptr*/ Class::has_alias && is_alias<Class>(ptr));
|
|
231
|
+
v_h.value_ptr() = ptr;
|
|
232
|
+
v_h.type->init_instance(v_h.inst, &smhldr);
|
|
233
|
+
}
|
|
234
|
+
|
|
235
|
+
template <typename Class,
|
|
236
|
+
typename D = std::default_delete<Alias<Class>>,
|
|
237
|
+
detail::enable_if_t<is_smart_holder<Holder<Class>>::value, int> = 0>
|
|
238
|
+
void construct(value_and_holder &v_h,
|
|
239
|
+
std::unique_ptr<Alias<Class>, D> &&unq_ptr,
|
|
240
|
+
bool /*need_alias*/) {
|
|
241
|
+
auto *ptr = unq_ptr.get();
|
|
242
|
+
no_nullptr(ptr);
|
|
243
|
+
auto smhldr
|
|
244
|
+
= init_smart_holder_from_unique_ptr(std::move(unq_ptr), /*void_cast_raw_ptr*/ true);
|
|
245
|
+
v_h.value_ptr() = ptr;
|
|
246
|
+
v_h.type->init_instance(v_h.inst, &smhldr);
|
|
247
|
+
}
|
|
248
|
+
|
|
249
|
+
template <typename PtrType, typename Class>
|
|
250
|
+
void construct_from_shared_ptr(value_and_holder &v_h,
|
|
251
|
+
std::shared_ptr<PtrType> &&shd_ptr,
|
|
252
|
+
bool need_alias) {
|
|
253
|
+
static_assert(std::is_same<PtrType, Cpp<Class>>::value
|
|
254
|
+
|| std::is_same<PtrType, const Cpp<Class>>::value,
|
|
255
|
+
"Expected (const) Cpp<Class> as shared_ptr pointee");
|
|
256
|
+
auto *ptr = shd_ptr.get();
|
|
257
|
+
no_nullptr(ptr);
|
|
258
|
+
if (Class::has_alias && need_alias && !is_alias<Class>(ptr)) {
|
|
259
|
+
throw type_error("pybind11::init(): construction failed: returned std::shared_ptr pointee "
|
|
260
|
+
"is not an alias instance");
|
|
261
|
+
}
|
|
262
|
+
// Cast to non-const if needed, consistent with internal design
|
|
263
|
+
auto smhldr
|
|
264
|
+
= smart_holder::from_shared_ptr(std::const_pointer_cast<Cpp<Class>>(std::move(shd_ptr)));
|
|
265
|
+
v_h.value_ptr() = const_cast<Cpp<Class> *>(ptr);
|
|
266
|
+
v_h.type->init_instance(v_h.inst, &smhldr);
|
|
267
|
+
}
|
|
268
|
+
|
|
269
|
+
template <typename Class, detail::enable_if_t<is_smart_holder<Holder<Class>>::value, int> = 0>
|
|
270
|
+
void construct(value_and_holder &v_h, std::shared_ptr<Cpp<Class>> &&shd_ptr, bool need_alias) {
|
|
271
|
+
construct_from_shared_ptr<Cpp<Class>, Class>(v_h, std::move(shd_ptr), need_alias);
|
|
272
|
+
}
|
|
273
|
+
|
|
274
|
+
template <typename Class, detail::enable_if_t<is_smart_holder<Holder<Class>>::value, int> = 0>
|
|
275
|
+
void construct(value_and_holder &v_h,
|
|
276
|
+
std::shared_ptr<const Cpp<Class>> &&shd_ptr,
|
|
277
|
+
bool need_alias) {
|
|
278
|
+
construct_from_shared_ptr<const Cpp<Class>, Class>(v_h, std::move(shd_ptr), need_alias);
|
|
279
|
+
}
|
|
280
|
+
|
|
281
|
+
template <typename Class, detail::enable_if_t<is_smart_holder<Holder<Class>>::value, int> = 0>
|
|
282
|
+
void construct(value_and_holder &v_h,
|
|
283
|
+
std::shared_ptr<Alias<Class>> &&shd_ptr,
|
|
284
|
+
bool /*need_alias*/) {
|
|
285
|
+
auto *ptr = shd_ptr.get();
|
|
286
|
+
no_nullptr(ptr);
|
|
287
|
+
auto smhldr = smart_holder::from_shared_ptr(shd_ptr);
|
|
288
|
+
v_h.value_ptr() = ptr;
|
|
289
|
+
v_h.type->init_instance(v_h.inst, &smhldr);
|
|
290
|
+
}
|
|
291
|
+
|
|
198
292
|
// Implementing class for py::init<...>()
|
|
199
293
|
template <typename... Args>
|
|
200
294
|
struct constructor {
|
|
@@ -202,7 +296,8 @@ struct constructor {
|
|
|
202
296
|
static void execute(Class &cl, const Extra &...extra) {
|
|
203
297
|
cl.def(
|
|
204
298
|
"__init__",
|
|
205
|
-
[](value_and_holder &v_h,
|
|
299
|
+
[](value_and_holder &v_h,
|
|
300
|
+
Args... args) { // NOLINT(performance-unnecessary-value-param)
|
|
206
301
|
v_h.value_ptr() = construct_or_initialize<Cpp<Class>>(std::forward<Args>(args)...);
|
|
207
302
|
},
|
|
208
303
|
is_new_style_constructor(),
|
|
@@ -380,7 +475,16 @@ void setstate(value_and_holder &v_h, std::pair<T, O> &&result, bool need_alias)
|
|
|
380
475
|
// See PR #2972 for details.
|
|
381
476
|
return;
|
|
382
477
|
}
|
|
383
|
-
|
|
478
|
+
// Our tests never run into an unset dict, but being careful here for now (see #5658)
|
|
479
|
+
auto dict = getattr((PyObject *) v_h.inst, "__dict__", none());
|
|
480
|
+
if (dict.is_none()) {
|
|
481
|
+
setattr((PyObject *) v_h.inst, "__dict__", d);
|
|
482
|
+
} else {
|
|
483
|
+
// Keep the original object dict and just update it
|
|
484
|
+
if (PyDict_Update(dict.ptr(), d.ptr()) < 0) {
|
|
485
|
+
throw error_already_set();
|
|
486
|
+
}
|
|
487
|
+
}
|
|
384
488
|
}
|
|
385
489
|
|
|
386
490
|
/// Implementation for py::pickle(GetState, SetState)
|
|
@@ -408,7 +512,7 @@ struct pickle_factory<Get, Set, RetState(Self), NewInstance(ArgState)> {
|
|
|
408
512
|
|
|
409
513
|
template <typename Class, typename... Extra>
|
|
410
514
|
void execute(Class &cl, const Extra &...extra) && {
|
|
411
|
-
cl.def("__getstate__", std::move(get));
|
|
515
|
+
cl.def("__getstate__", std::move(get), pos_only());
|
|
412
516
|
|
|
413
517
|
#if defined(PYBIND11_CPP14)
|
|
414
518
|
cl.def(
|