netgen-mesher 6.2.2506.post35.dev0__cp314-cp314-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/NgOCC.py +7 -0
- netgen/__init__.py +114 -0
- netgen/__init__.pyi +22 -0
- netgen/__main__.py +53 -0
- netgen/cmake/NetgenConfig.cmake +79 -0
- netgen/cmake/netgen-targets-release.cmake +69 -0
- netgen/cmake/netgen-targets.cmake +146 -0
- netgen/config/__init__.py +1 -0
- netgen/config/__init__.pyi +52 -0
- netgen/config/__main__.py +4 -0
- netgen/config/config.py +68 -0
- netgen/config/config.pyi +54 -0
- netgen/csg.py +25 -0
- netgen/geom2d.py +178 -0
- netgen/gui.py +82 -0
- netgen/include/core/archive.hpp +1256 -0
- netgen/include/core/array.hpp +1760 -0
- netgen/include/core/autodiff.hpp +1131 -0
- netgen/include/core/autodiffdiff.hpp +733 -0
- netgen/include/core/bitarray.hpp +240 -0
- netgen/include/core/concurrentqueue.h +3619 -0
- netgen/include/core/exception.hpp +145 -0
- netgen/include/core/flags.hpp +199 -0
- netgen/include/core/hashtable.hpp +1281 -0
- netgen/include/core/localheap.hpp +318 -0
- netgen/include/core/logging.hpp +117 -0
- netgen/include/core/memtracer.hpp +221 -0
- netgen/include/core/mpi4py_pycapi.h +245 -0
- netgen/include/core/mpi_wrapper.hpp +643 -0
- netgen/include/core/ng_mpi.hpp +94 -0
- netgen/include/core/ng_mpi_generated_declarations.hpp +155 -0
- netgen/include/core/ng_mpi_native.hpp +25 -0
- netgen/include/core/ngcore.hpp +32 -0
- netgen/include/core/ngcore_api.hpp +152 -0
- netgen/include/core/ngstream.hpp +115 -0
- netgen/include/core/paje_trace.hpp +279 -0
- netgen/include/core/profiler.hpp +382 -0
- netgen/include/core/python_ngcore.hpp +457 -0
- netgen/include/core/ranges.hpp +109 -0
- netgen/include/core/register_archive.hpp +100 -0
- netgen/include/core/signal.hpp +82 -0
- netgen/include/core/simd.hpp +160 -0
- netgen/include/core/simd_arm64.hpp +407 -0
- netgen/include/core/simd_avx.hpp +394 -0
- netgen/include/core/simd_avx512.hpp +285 -0
- netgen/include/core/simd_generic.hpp +1053 -0
- netgen/include/core/simd_math.hpp +178 -0
- netgen/include/core/simd_sse.hpp +289 -0
- netgen/include/core/statushandler.hpp +37 -0
- netgen/include/core/symboltable.hpp +153 -0
- netgen/include/core/table.hpp +810 -0
- netgen/include/core/taskmanager.hpp +1161 -0
- netgen/include/core/type_traits.hpp +65 -0
- netgen/include/core/utils.hpp +385 -0
- netgen/include/core/version.hpp +102 -0
- netgen/include/core/xbool.hpp +47 -0
- netgen/include/csg/algprim.hpp +563 -0
- netgen/include/csg/brick.hpp +150 -0
- netgen/include/csg/csg.hpp +43 -0
- netgen/include/csg/csgeom.hpp +389 -0
- netgen/include/csg/csgparser.hpp +101 -0
- netgen/include/csg/curve2d.hpp +67 -0
- netgen/include/csg/edgeflw.hpp +112 -0
- netgen/include/csg/explicitcurve2d.hpp +113 -0
- netgen/include/csg/extrusion.hpp +185 -0
- netgen/include/csg/gencyl.hpp +70 -0
- netgen/include/csg/geoml.hpp +16 -0
- netgen/include/csg/identify.hpp +213 -0
- netgen/include/csg/manifold.hpp +29 -0
- netgen/include/csg/meshsurf.hpp +46 -0
- netgen/include/csg/polyhedra.hpp +121 -0
- netgen/include/csg/revolution.hpp +180 -0
- netgen/include/csg/singularref.hpp +84 -0
- netgen/include/csg/solid.hpp +295 -0
- netgen/include/csg/specpoin.hpp +194 -0
- netgen/include/csg/spline3d.hpp +99 -0
- netgen/include/csg/splinesurface.hpp +85 -0
- netgen/include/csg/surface.hpp +394 -0
- netgen/include/csg/triapprox.hpp +63 -0
- netgen/include/csg/vscsg.hpp +34 -0
- netgen/include/general/autodiff.hpp +356 -0
- netgen/include/general/autoptr.hpp +39 -0
- netgen/include/general/gzstream.h +121 -0
- netgen/include/general/hashtabl.hpp +1692 -0
- netgen/include/general/myadt.hpp +48 -0
- netgen/include/general/mystring.hpp +226 -0
- netgen/include/general/netgenout.hpp +205 -0
- netgen/include/general/ngarray.hpp +797 -0
- netgen/include/general/ngbitarray.hpp +149 -0
- netgen/include/general/ngpython.hpp +74 -0
- netgen/include/general/optmem.hpp +44 -0
- netgen/include/general/parthreads.hpp +138 -0
- netgen/include/general/seti.hpp +50 -0
- netgen/include/general/sort.hpp +47 -0
- netgen/include/general/spbita2d.hpp +59 -0
- netgen/include/general/stack.hpp +114 -0
- netgen/include/general/table.hpp +280 -0
- netgen/include/general/template.hpp +509 -0
- netgen/include/geom2d/csg2d.hpp +750 -0
- netgen/include/geom2d/geometry2d.hpp +280 -0
- netgen/include/geom2d/spline2d.hpp +234 -0
- netgen/include/geom2d/vsgeom2d.hpp +28 -0
- netgen/include/gprim/adtree.hpp +1392 -0
- netgen/include/gprim/geom2d.hpp +858 -0
- netgen/include/gprim/geom3d.hpp +749 -0
- netgen/include/gprim/geomfuncs.hpp +212 -0
- netgen/include/gprim/geomobjects.hpp +544 -0
- netgen/include/gprim/geomops.hpp +404 -0
- netgen/include/gprim/geomtest3d.hpp +101 -0
- netgen/include/gprim/gprim.hpp +33 -0
- netgen/include/gprim/spline.hpp +778 -0
- netgen/include/gprim/splinegeometry.hpp +73 -0
- netgen/include/gprim/transform3d.hpp +216 -0
- netgen/include/include/acisgeom.hpp +3 -0
- netgen/include/include/csg.hpp +1 -0
- netgen/include/include/geometry2d.hpp +1 -0
- netgen/include/include/gprim.hpp +1 -0
- netgen/include/include/incopengl.hpp +62 -0
- netgen/include/include/inctcl.hpp +13 -0
- netgen/include/include/incvis.hpp +6 -0
- netgen/include/include/linalg.hpp +1 -0
- netgen/include/include/meshing.hpp +1 -0
- netgen/include/include/myadt.hpp +1 -0
- netgen/include/include/mydefs.hpp +70 -0
- netgen/include/include/mystdlib.h +59 -0
- netgen/include/include/netgen_config.hpp +27 -0
- netgen/include/include/netgen_version.hpp +9 -0
- netgen/include/include/nginterface_v2_impl.hpp +395 -0
- netgen/include/include/ngsimd.hpp +1 -0
- netgen/include/include/occgeom.hpp +1 -0
- netgen/include/include/opti.hpp +1 -0
- netgen/include/include/parallel.hpp +1 -0
- netgen/include/include/stlgeom.hpp +1 -0
- netgen/include/include/visual.hpp +1 -0
- netgen/include/interface/rw_medit.hpp +11 -0
- netgen/include/interface/writeuser.hpp +80 -0
- netgen/include/linalg/densemat.hpp +414 -0
- netgen/include/linalg/linalg.hpp +29 -0
- netgen/include/linalg/opti.hpp +142 -0
- netgen/include/linalg/polynomial.hpp +47 -0
- netgen/include/linalg/vector.hpp +217 -0
- netgen/include/meshing/adfront2.hpp +274 -0
- netgen/include/meshing/adfront3.hpp +332 -0
- netgen/include/meshing/basegeom.hpp +370 -0
- netgen/include/meshing/bcfunctions.hpp +53 -0
- netgen/include/meshing/bisect.hpp +72 -0
- netgen/include/meshing/boundarylayer.hpp +113 -0
- netgen/include/meshing/classifyhpel.hpp +1984 -0
- netgen/include/meshing/clusters.hpp +46 -0
- netgen/include/meshing/curvedelems.hpp +274 -0
- netgen/include/meshing/delaunay2d.hpp +73 -0
- netgen/include/meshing/fieldlines.hpp +103 -0
- netgen/include/meshing/findip.hpp +198 -0
- netgen/include/meshing/findip2.hpp +103 -0
- netgen/include/meshing/geomsearch.hpp +69 -0
- netgen/include/meshing/global.hpp +54 -0
- netgen/include/meshing/hpref_hex.hpp +330 -0
- netgen/include/meshing/hpref_prism.hpp +3405 -0
- netgen/include/meshing/hpref_pyramid.hpp +154 -0
- netgen/include/meshing/hpref_quad.hpp +2082 -0
- netgen/include/meshing/hpref_segm.hpp +122 -0
- netgen/include/meshing/hpref_tet.hpp +4230 -0
- netgen/include/meshing/hpref_trig.hpp +848 -0
- netgen/include/meshing/hprefinement.hpp +366 -0
- netgen/include/meshing/improve2.hpp +178 -0
- netgen/include/meshing/improve3.hpp +151 -0
- netgen/include/meshing/localh.hpp +223 -0
- netgen/include/meshing/meshclass.hpp +1076 -0
- netgen/include/meshing/meshfunc.hpp +47 -0
- netgen/include/meshing/meshing.hpp +63 -0
- netgen/include/meshing/meshing2.hpp +163 -0
- netgen/include/meshing/meshing3.hpp +123 -0
- netgen/include/meshing/meshtool.hpp +90 -0
- netgen/include/meshing/meshtype.hpp +1930 -0
- netgen/include/meshing/msghandler.hpp +62 -0
- netgen/include/meshing/paralleltop.hpp +172 -0
- netgen/include/meshing/python_mesh.hpp +206 -0
- netgen/include/meshing/ruler2.hpp +172 -0
- netgen/include/meshing/ruler3.hpp +211 -0
- netgen/include/meshing/soldata.hpp +141 -0
- netgen/include/meshing/specials.hpp +17 -0
- netgen/include/meshing/surfacegeom.hpp +73 -0
- netgen/include/meshing/topology.hpp +1003 -0
- netgen/include/meshing/validate.hpp +21 -0
- netgen/include/meshing/visual_interface.hpp +71 -0
- netgen/include/mydefs.hpp +70 -0
- netgen/include/nginterface.h +474 -0
- netgen/include/nginterface_v2.hpp +406 -0
- netgen/include/nglib.h +697 -0
- netgen/include/nglib_occ.h +50 -0
- netgen/include/occ/occ_edge.hpp +47 -0
- netgen/include/occ/occ_face.hpp +52 -0
- netgen/include/occ/occ_solid.hpp +23 -0
- netgen/include/occ/occ_utils.hpp +376 -0
- netgen/include/occ/occ_vertex.hpp +30 -0
- netgen/include/occ/occgeom.hpp +659 -0
- netgen/include/occ/occmeshsurf.hpp +168 -0
- netgen/include/occ/vsocc.hpp +33 -0
- netgen/include/pybind11/LICENSE +29 -0
- netgen/include/pybind11/attr.h +722 -0
- netgen/include/pybind11/buffer_info.h +208 -0
- netgen/include/pybind11/cast.h +2361 -0
- netgen/include/pybind11/chrono.h +228 -0
- netgen/include/pybind11/common.h +2 -0
- netgen/include/pybind11/complex.h +74 -0
- 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 +823 -0
- netgen/include/pybind11/detail/common.h +1348 -0
- netgen/include/pybind11/detail/cpp_conduit.h +75 -0
- netgen/include/pybind11/detail/descr.h +226 -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 +538 -0
- netgen/include/pybind11/detail/internals.h +799 -0
- 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 +1591 -0
- netgen/include/pybind11/detail/typeid.h +65 -0
- netgen/include/pybind11/detail/using_smart_holder.h +22 -0
- netgen/include/pybind11/detail/value_and_holder.h +90 -0
- netgen/include/pybind11/eigen/common.h +9 -0
- netgen/include/pybind11/eigen/matrix.h +723 -0
- netgen/include/pybind11/eigen/tensor.h +521 -0
- netgen/include/pybind11/eigen.h +12 -0
- netgen/include/pybind11/embed.h +320 -0
- netgen/include/pybind11/eval.h +161 -0
- netgen/include/pybind11/functional.h +147 -0
- netgen/include/pybind11/gil.h +199 -0
- netgen/include/pybind11/gil_safe_call_once.h +102 -0
- netgen/include/pybind11/gil_simple.h +37 -0
- netgen/include/pybind11/iostream.h +265 -0
- netgen/include/pybind11/native_enum.h +67 -0
- netgen/include/pybind11/numpy.h +2312 -0
- netgen/include/pybind11/operators.h +202 -0
- netgen/include/pybind11/options.h +92 -0
- netgen/include/pybind11/pybind11.h +3645 -0
- netgen/include/pybind11/pytypes.h +2680 -0
- netgen/include/pybind11/stl/filesystem.h +114 -0
- netgen/include/pybind11/stl.h +666 -0
- netgen/include/pybind11/stl_bind.h +858 -0
- netgen/include/pybind11/subinterpreter.h +299 -0
- netgen/include/pybind11/trampoline_self_life_support.h +65 -0
- netgen/include/pybind11/type_caster_pyobject_ptr.h +61 -0
- netgen/include/pybind11/typing.h +298 -0
- netgen/include/pybind11/warnings.h +75 -0
- netgen/include/stlgeom/meshstlsurface.hpp +67 -0
- netgen/include/stlgeom/stlgeom.hpp +491 -0
- netgen/include/stlgeom/stlline.hpp +193 -0
- netgen/include/stlgeom/stltool.hpp +331 -0
- netgen/include/stlgeom/stltopology.hpp +419 -0
- netgen/include/stlgeom/vsstl.hpp +58 -0
- netgen/include/visualization/meshdoc.hpp +42 -0
- netgen/include/visualization/mvdraw.hpp +325 -0
- netgen/include/visualization/vispar.hpp +128 -0
- netgen/include/visualization/visual.hpp +28 -0
- netgen/include/visualization/visual_api.hpp +10 -0
- netgen/include/visualization/vssolution.hpp +399 -0
- netgen/lib/libnggui.lib +0 -0
- netgen/lib/ngcore.lib +0 -0
- netgen/lib/nglib.lib +0 -0
- netgen/lib/togl.lib +0 -0
- netgen/libnggui.dll +0 -0
- netgen/libngguipy.lib +0 -0
- netgen/libngguipy.pyd +0 -0
- netgen/libngpy/_NgOCC.pyi +1545 -0
- netgen/libngpy/__init__.pyi +7 -0
- netgen/libngpy/_csg.pyi +259 -0
- netgen/libngpy/_geom2d.pyi +323 -0
- netgen/libngpy/_meshing.pyi +1111 -0
- netgen/libngpy/_stl.pyi +131 -0
- netgen/libngpy.lib +0 -0
- netgen/libngpy.pyd +0 -0
- netgen/meshing.py +65 -0
- netgen/ngcore.dll +0 -0
- netgen/nglib.dll +0 -0
- netgen/occ.py +52 -0
- netgen/read_gmsh.py +259 -0
- netgen/read_meshio.py +22 -0
- netgen/stl.py +2 -0
- netgen/togl.dll +0 -0
- netgen/version.py +2 -0
- netgen/webgui.py +529 -0
- netgen_mesher-6.2.2506.post35.dev0.data/data/share/netgen/boundarycondition.geo +16 -0
- netgen_mesher-6.2.2506.post35.dev0.data/data/share/netgen/boxcyl.geo +32 -0
- netgen_mesher-6.2.2506.post35.dev0.data/data/share/netgen/circle_on_cube.geo +27 -0
- netgen_mesher-6.2.2506.post35.dev0.data/data/share/netgen/cone.geo +13 -0
- netgen_mesher-6.2.2506.post35.dev0.data/data/share/netgen/cube.geo +16 -0
- netgen_mesher-6.2.2506.post35.dev0.data/data/share/netgen/cubeandring.geo +55 -0
- netgen_mesher-6.2.2506.post35.dev0.data/data/share/netgen/cubeandspheres.geo +21 -0
- netgen_mesher-6.2.2506.post35.dev0.data/data/share/netgen/cubemcyl.geo +18 -0
- netgen_mesher-6.2.2506.post35.dev0.data/data/share/netgen/cubemsphere.geo +19 -0
- netgen_mesher-6.2.2506.post35.dev0.data/data/share/netgen/cylinder.geo +12 -0
- netgen_mesher-6.2.2506.post35.dev0.data/data/share/netgen/cylsphere.geo +12 -0
- netgen_mesher-6.2.2506.post35.dev0.data/data/share/netgen/doc/ng4.pdf +0 -0
- netgen_mesher-6.2.2506.post35.dev0.data/data/share/netgen/ellipsoid.geo +8 -0
- netgen_mesher-6.2.2506.post35.dev0.data/data/share/netgen/ellipticcyl.geo +10 -0
- netgen_mesher-6.2.2506.post35.dev0.data/data/share/netgen/extrusion.geo +99 -0
- netgen_mesher-6.2.2506.post35.dev0.data/data/share/netgen/fichera.geo +24 -0
- netgen_mesher-6.2.2506.post35.dev0.data/data/share/netgen/frame.step +11683 -0
- netgen_mesher-6.2.2506.post35.dev0.data/data/share/netgen/hinge.stl +8486 -0
- netgen_mesher-6.2.2506.post35.dev0.data/data/share/netgen/lshape3d.geo +26 -0
- netgen_mesher-6.2.2506.post35.dev0.data/data/share/netgen/manyholes.geo +26 -0
- netgen_mesher-6.2.2506.post35.dev0.data/data/share/netgen/manyholes2.geo +26 -0
- netgen_mesher-6.2.2506.post35.dev0.data/data/share/netgen/matrix.geo +27 -0
- netgen_mesher-6.2.2506.post35.dev0.data/data/share/netgen/ortho.geo +11 -0
- netgen_mesher-6.2.2506.post35.dev0.data/data/share/netgen/part1.stl +2662 -0
- netgen_mesher-6.2.2506.post35.dev0.data/data/share/netgen/period.geo +33 -0
- netgen_mesher-6.2.2506.post35.dev0.data/data/share/netgen/py_tutorials/exportNeutral.py +26 -0
- netgen_mesher-6.2.2506.post35.dev0.data/data/share/netgen/py_tutorials/mesh.py +19 -0
- netgen_mesher-6.2.2506.post35.dev0.data/data/share/netgen/py_tutorials/shaft.geo +65 -0
- netgen_mesher-6.2.2506.post35.dev0.data/data/share/netgen/revolution.geo +18 -0
- netgen_mesher-6.2.2506.post35.dev0.data/data/share/netgen/screw.step +1694 -0
- netgen_mesher-6.2.2506.post35.dev0.data/data/share/netgen/sculpture.geo +13 -0
- netgen_mesher-6.2.2506.post35.dev0.data/data/share/netgen/shaft.geo +65 -0
- netgen_mesher-6.2.2506.post35.dev0.data/data/share/netgen/shell.geo +10 -0
- netgen_mesher-6.2.2506.post35.dev0.data/data/share/netgen/sphere.geo +8 -0
- netgen_mesher-6.2.2506.post35.dev0.data/data/share/netgen/sphereincube.geo +17 -0
- netgen_mesher-6.2.2506.post35.dev0.data/data/share/netgen/square.in2d +35 -0
- netgen_mesher-6.2.2506.post35.dev0.data/data/share/netgen/squarecircle.in2d +48 -0
- netgen_mesher-6.2.2506.post35.dev0.data/data/share/netgen/squarehole.in2d +47 -0
- netgen_mesher-6.2.2506.post35.dev0.data/data/share/netgen/torus.geo +8 -0
- netgen_mesher-6.2.2506.post35.dev0.data/data/share/netgen/trafo.geo +57 -0
- netgen_mesher-6.2.2506.post35.dev0.data/data/share/netgen/twobricks.geo +15 -0
- netgen_mesher-6.2.2506.post35.dev0.data/data/share/netgen/twocubes.geo +18 -0
- netgen_mesher-6.2.2506.post35.dev0.data/data/share/netgen/twocyl.geo +16 -0
- netgen_mesher-6.2.2506.post35.dev0.dist-info/METADATA +15 -0
- netgen_mesher-6.2.2506.post35.dev0.dist-info/RECORD +340 -0
- netgen_mesher-6.2.2506.post35.dev0.dist-info/WHEEL +5 -0
- netgen_mesher-6.2.2506.post35.dev0.dist-info/entry_points.txt +2 -0
- netgen_mesher-6.2.2506.post35.dev0.dist-info/licenses/AUTHORS +1 -0
- netgen_mesher-6.2.2506.post35.dev0.dist-info/licenses/LICENSE +504 -0
- netgen_mesher-6.2.2506.post35.dev0.dist-info/top_level.txt +2 -0
- pyngcore/__init__.py +1 -0
- pyngcore/pyngcore.cp314-win_amd64.pyd +0 -0
|
@@ -0,0 +1,799 @@
|
|
|
1
|
+
/*
|
|
2
|
+
pybind11/detail/internals.h: Internal data structure and related functions
|
|
3
|
+
|
|
4
|
+
Copyright (c) 2017 Wenzel Jakob <wenzel.jakob@epfl.ch>
|
|
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 <pybind11/conduit/pybind11_platform_abi_id.h>
|
|
13
|
+
#include <pybind11/gil_simple.h>
|
|
14
|
+
#include <pybind11/pytypes.h>
|
|
15
|
+
#include <pybind11/trampoline_self_life_support.h>
|
|
16
|
+
|
|
17
|
+
#include "common.h"
|
|
18
|
+
#include "struct_smart_holder.h"
|
|
19
|
+
|
|
20
|
+
#include <atomic>
|
|
21
|
+
#include <cstdint>
|
|
22
|
+
#include <exception>
|
|
23
|
+
#include <limits>
|
|
24
|
+
#include <mutex>
|
|
25
|
+
#include <thread>
|
|
26
|
+
|
|
27
|
+
/// Tracks the `internals` and `type_info` ABI version independent of the main library version.
|
|
28
|
+
///
|
|
29
|
+
/// Some portions of the code use an ABI that is conditional depending on this
|
|
30
|
+
/// version number. That allows ABI-breaking changes to be "pre-implemented".
|
|
31
|
+
/// Once the default version number is incremented, the conditional logic that
|
|
32
|
+
/// no longer applies can be removed. Additionally, users that need not
|
|
33
|
+
/// maintain ABI compatibility can increase the version number in order to take
|
|
34
|
+
/// advantage of any functionality/efficiency improvements that depend on the
|
|
35
|
+
/// newer ABI.
|
|
36
|
+
///
|
|
37
|
+
/// WARNING: If you choose to manually increase the ABI version, note that
|
|
38
|
+
/// pybind11 may not be tested as thoroughly with a non-default ABI version, and
|
|
39
|
+
/// further ABI-incompatible changes may be made before the ABI is officially
|
|
40
|
+
/// changed to the new version.
|
|
41
|
+
#ifndef PYBIND11_INTERNALS_VERSION
|
|
42
|
+
# define PYBIND11_INTERNALS_VERSION 11
|
|
43
|
+
#endif
|
|
44
|
+
|
|
45
|
+
#if PYBIND11_INTERNALS_VERSION < 11
|
|
46
|
+
# error "PYBIND11_INTERNALS_VERSION 11 is the minimum for all platforms for pybind11v3."
|
|
47
|
+
#endif
|
|
48
|
+
|
|
49
|
+
PYBIND11_NAMESPACE_BEGIN(PYBIND11_NAMESPACE)
|
|
50
|
+
|
|
51
|
+
using ExceptionTranslator = void (*)(std::exception_ptr);
|
|
52
|
+
|
|
53
|
+
// The old Python Thread Local Storage (TLS) API is deprecated in Python 3.7 in favor of the new
|
|
54
|
+
// Thread Specific Storage (TSS) API.
|
|
55
|
+
// Avoid unnecessary allocation of `Py_tss_t`, since we cannot use
|
|
56
|
+
// `Py_LIMITED_API` anyway.
|
|
57
|
+
#define PYBIND11_TLS_KEY_REF Py_tss_t &
|
|
58
|
+
#if defined(__clang__)
|
|
59
|
+
# define PYBIND11_TLS_KEY_INIT(var) \
|
|
60
|
+
_Pragma("clang diagnostic push") /**/ \
|
|
61
|
+
_Pragma("clang diagnostic ignored \"-Wmissing-field-initializers\"") /**/ \
|
|
62
|
+
Py_tss_t var \
|
|
63
|
+
= Py_tss_NEEDS_INIT; \
|
|
64
|
+
_Pragma("clang diagnostic pop")
|
|
65
|
+
#elif defined(__GNUC__) && !defined(__INTEL_COMPILER)
|
|
66
|
+
# define PYBIND11_TLS_KEY_INIT(var) \
|
|
67
|
+
_Pragma("GCC diagnostic push") /**/ \
|
|
68
|
+
_Pragma("GCC diagnostic ignored \"-Wmissing-field-initializers\"") /**/ \
|
|
69
|
+
Py_tss_t var \
|
|
70
|
+
= Py_tss_NEEDS_INIT; \
|
|
71
|
+
_Pragma("GCC diagnostic pop")
|
|
72
|
+
#else
|
|
73
|
+
# define PYBIND11_TLS_KEY_INIT(var) Py_tss_t var = Py_tss_NEEDS_INIT;
|
|
74
|
+
#endif
|
|
75
|
+
#define PYBIND11_TLS_KEY_CREATE(var) (PyThread_tss_create(&(var)) == 0)
|
|
76
|
+
#define PYBIND11_TLS_GET_VALUE(key) PyThread_tss_get(&(key))
|
|
77
|
+
#define PYBIND11_TLS_REPLACE_VALUE(key, value) PyThread_tss_set(&(key), (value))
|
|
78
|
+
#define PYBIND11_TLS_DELETE_VALUE(key) PyThread_tss_set(&(key), nullptr)
|
|
79
|
+
#define PYBIND11_TLS_FREE(key) PyThread_tss_delete(&(key))
|
|
80
|
+
|
|
81
|
+
/// A smart-pointer-like wrapper around a thread-specific value. get/set of the pointer applies to
|
|
82
|
+
/// the current thread only.
|
|
83
|
+
template <typename T>
|
|
84
|
+
class thread_specific_storage {
|
|
85
|
+
public:
|
|
86
|
+
thread_specific_storage() {
|
|
87
|
+
// NOLINTNEXTLINE(bugprone-assignment-in-if-condition)
|
|
88
|
+
if (!PYBIND11_TLS_KEY_CREATE(key_)) {
|
|
89
|
+
pybind11_fail(
|
|
90
|
+
"thread_specific_storage constructor: could not initialize the TSS key!");
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
~thread_specific_storage() {
|
|
95
|
+
// This destructor is often called *after* Py_Finalize(). That *SHOULD BE* fine on most
|
|
96
|
+
// platforms. The following details what happens when PyThread_tss_free is called in
|
|
97
|
+
// CPython. PYBIND11_TLS_FREE is PyThread_tss_free on python 3.7+. On older python, it does
|
|
98
|
+
// nothing. PyThread_tss_free calls PyThread_tss_delete and PyMem_RawFree.
|
|
99
|
+
// PyThread_tss_delete just calls TlsFree (on Windows) or pthread_key_delete (on *NIX).
|
|
100
|
+
// Neither of those have anything to do with CPython internals. PyMem_RawFree *requires*
|
|
101
|
+
// that the `key` be allocated with the CPython allocator (as it is by
|
|
102
|
+
// PyThread_tss_create).
|
|
103
|
+
// However, in GraalPy (as of v24.2 or older), TSS is implemented by Java and this call
|
|
104
|
+
// requires a living Python interpreter.
|
|
105
|
+
#ifdef GRAALVM_PYTHON
|
|
106
|
+
if (!Py_IsInitialized() || _Py_IsFinalizing()) {
|
|
107
|
+
return;
|
|
108
|
+
}
|
|
109
|
+
#endif
|
|
110
|
+
PYBIND11_TLS_FREE(key_);
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
thread_specific_storage(thread_specific_storage const &) = delete;
|
|
114
|
+
thread_specific_storage(thread_specific_storage &&) = delete;
|
|
115
|
+
thread_specific_storage &operator=(thread_specific_storage const &) = delete;
|
|
116
|
+
thread_specific_storage &operator=(thread_specific_storage &&) = delete;
|
|
117
|
+
|
|
118
|
+
T *get() const { return reinterpret_cast<T *>(PYBIND11_TLS_GET_VALUE(key_)); }
|
|
119
|
+
|
|
120
|
+
T &operator*() const { return *get(); }
|
|
121
|
+
explicit operator T *() const { return get(); }
|
|
122
|
+
explicit operator bool() const { return get() != nullptr; }
|
|
123
|
+
|
|
124
|
+
void set(T *val) { PYBIND11_TLS_REPLACE_VALUE(key_, reinterpret_cast<void *>(val)); }
|
|
125
|
+
void reset(T *p = nullptr) { set(p); }
|
|
126
|
+
thread_specific_storage &operator=(T *pval) {
|
|
127
|
+
set(pval);
|
|
128
|
+
return *this;
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
private:
|
|
132
|
+
PYBIND11_TLS_KEY_INIT(mutable key_)
|
|
133
|
+
};
|
|
134
|
+
|
|
135
|
+
PYBIND11_NAMESPACE_BEGIN(detail)
|
|
136
|
+
|
|
137
|
+
// This does NOT actually exist as a module.
|
|
138
|
+
#define PYBIND11_DUMMY_MODULE_NAME "pybind11_builtins"
|
|
139
|
+
|
|
140
|
+
// Forward declarations
|
|
141
|
+
inline PyTypeObject *make_static_property_type();
|
|
142
|
+
inline PyTypeObject *make_default_metaclass();
|
|
143
|
+
inline PyObject *make_object_base_type(PyTypeObject *metaclass);
|
|
144
|
+
inline void translate_exception(std::exception_ptr p);
|
|
145
|
+
|
|
146
|
+
// Python loads modules by default with dlopen with the RTLD_LOCAL flag; under libc++ and possibly
|
|
147
|
+
// other STLs, this means `typeid(A)` from one module won't equal `typeid(A)` from another module
|
|
148
|
+
// even when `A` is the same, non-hidden-visibility type (e.g. from a common include). Under
|
|
149
|
+
// libstdc++, this doesn't happen: equality and the type_index hash are based on the type name,
|
|
150
|
+
// which works. If not under a known-good stl, provide our own name-based hash and equality
|
|
151
|
+
// functions that use the type name.
|
|
152
|
+
#if !defined(_LIBCPP_VERSION)
|
|
153
|
+
inline bool same_type(const std::type_info &lhs, const std::type_info &rhs) { return lhs == rhs; }
|
|
154
|
+
using type_hash = std::hash<std::type_index>;
|
|
155
|
+
using type_equal_to = std::equal_to<std::type_index>;
|
|
156
|
+
#else
|
|
157
|
+
inline bool same_type(const std::type_info &lhs, const std::type_info &rhs) {
|
|
158
|
+
return lhs.name() == rhs.name() || std::strcmp(lhs.name(), rhs.name()) == 0;
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
struct type_hash {
|
|
162
|
+
size_t operator()(const std::type_index &t) const {
|
|
163
|
+
size_t hash = 5381;
|
|
164
|
+
const char *ptr = t.name();
|
|
165
|
+
while (auto c = static_cast<unsigned char>(*ptr++)) {
|
|
166
|
+
hash = (hash * 33) ^ c;
|
|
167
|
+
}
|
|
168
|
+
return hash;
|
|
169
|
+
}
|
|
170
|
+
};
|
|
171
|
+
|
|
172
|
+
struct type_equal_to {
|
|
173
|
+
bool operator()(const std::type_index &lhs, const std::type_index &rhs) const {
|
|
174
|
+
return lhs.name() == rhs.name() || std::strcmp(lhs.name(), rhs.name()) == 0;
|
|
175
|
+
}
|
|
176
|
+
};
|
|
177
|
+
#endif
|
|
178
|
+
|
|
179
|
+
template <typename value_type>
|
|
180
|
+
using type_map = std::unordered_map<std::type_index, value_type, type_hash, type_equal_to>;
|
|
181
|
+
|
|
182
|
+
struct override_hash {
|
|
183
|
+
inline size_t operator()(const std::pair<const PyObject *, const char *> &v) const {
|
|
184
|
+
size_t value = std::hash<const void *>()(v.first);
|
|
185
|
+
value ^= std::hash<const void *>()(v.second) + 0x9e3779b9 + (value << 6) + (value >> 2);
|
|
186
|
+
return value;
|
|
187
|
+
}
|
|
188
|
+
};
|
|
189
|
+
|
|
190
|
+
using instance_map = std::unordered_multimap<const void *, instance *>;
|
|
191
|
+
|
|
192
|
+
#ifdef Py_GIL_DISABLED
|
|
193
|
+
// Wrapper around PyMutex to provide BasicLockable semantics
|
|
194
|
+
class pymutex {
|
|
195
|
+
PyMutex mutex;
|
|
196
|
+
|
|
197
|
+
public:
|
|
198
|
+
pymutex() : mutex({}) {}
|
|
199
|
+
void lock() { PyMutex_Lock(&mutex); }
|
|
200
|
+
void unlock() { PyMutex_Unlock(&mutex); }
|
|
201
|
+
};
|
|
202
|
+
|
|
203
|
+
// Instance map shards are used to reduce mutex contention in free-threaded Python.
|
|
204
|
+
struct instance_map_shard {
|
|
205
|
+
instance_map registered_instances;
|
|
206
|
+
pymutex mutex;
|
|
207
|
+
// alignas(64) would be better, but causes compile errors in macOS before 10.14 (see #5200)
|
|
208
|
+
char padding[64 - (sizeof(instance_map) + sizeof(pymutex)) % 64];
|
|
209
|
+
};
|
|
210
|
+
|
|
211
|
+
static_assert(sizeof(instance_map_shard) % 64 == 0,
|
|
212
|
+
"instance_map_shard size is not a multiple of 64 bytes");
|
|
213
|
+
|
|
214
|
+
inline uint64_t round_up_to_next_pow2(uint64_t x) {
|
|
215
|
+
// Round-up to the next power of two.
|
|
216
|
+
// See https://graphics.stanford.edu/~seander/bithacks.html#RoundUpPowerOf2
|
|
217
|
+
x--;
|
|
218
|
+
x |= (x >> 1);
|
|
219
|
+
x |= (x >> 2);
|
|
220
|
+
x |= (x >> 4);
|
|
221
|
+
x |= (x >> 8);
|
|
222
|
+
x |= (x >> 16);
|
|
223
|
+
x |= (x >> 32);
|
|
224
|
+
x++;
|
|
225
|
+
return x;
|
|
226
|
+
}
|
|
227
|
+
#endif
|
|
228
|
+
|
|
229
|
+
class loader_life_support;
|
|
230
|
+
|
|
231
|
+
/// Internal data structure used to track registered instances and types.
|
|
232
|
+
/// Whenever binary incompatible changes are made to this structure,
|
|
233
|
+
/// `PYBIND11_INTERNALS_VERSION` must be incremented.
|
|
234
|
+
struct internals {
|
|
235
|
+
#ifdef Py_GIL_DISABLED
|
|
236
|
+
pymutex mutex;
|
|
237
|
+
pymutex exception_translator_mutex;
|
|
238
|
+
#endif
|
|
239
|
+
// std::type_index -> pybind11's type information
|
|
240
|
+
type_map<type_info *> registered_types_cpp;
|
|
241
|
+
// PyTypeObject* -> base type_info(s)
|
|
242
|
+
std::unordered_map<PyTypeObject *, std::vector<type_info *>> registered_types_py;
|
|
243
|
+
#ifdef Py_GIL_DISABLED
|
|
244
|
+
std::unique_ptr<instance_map_shard[]> instance_shards; // void * -> instance*
|
|
245
|
+
size_t instance_shards_mask = 0;
|
|
246
|
+
#else
|
|
247
|
+
instance_map registered_instances; // void * -> instance*
|
|
248
|
+
#endif
|
|
249
|
+
std::unordered_set<std::pair<const PyObject *, const char *>, override_hash>
|
|
250
|
+
inactive_override_cache;
|
|
251
|
+
type_map<std::vector<bool (*)(PyObject *, void *&)>> direct_conversions;
|
|
252
|
+
std::unordered_map<const PyObject *, std::vector<PyObject *>> patients;
|
|
253
|
+
std::forward_list<ExceptionTranslator> registered_exception_translators;
|
|
254
|
+
std::unordered_map<std::string, void *> shared_data; // Custom data to be shared across
|
|
255
|
+
// extensions
|
|
256
|
+
std::forward_list<std::string> static_strings; // Stores the std::strings backing
|
|
257
|
+
// detail::c_str()
|
|
258
|
+
PyTypeObject *static_property_type = nullptr;
|
|
259
|
+
PyTypeObject *default_metaclass = nullptr;
|
|
260
|
+
PyObject *instance_base = nullptr;
|
|
261
|
+
// Unused if PYBIND11_SIMPLE_GIL_MANAGEMENT is defined:
|
|
262
|
+
thread_specific_storage<PyThreadState> tstate;
|
|
263
|
+
thread_specific_storage<loader_life_support> loader_life_support_tls;
|
|
264
|
+
// Unused if PYBIND11_SIMPLE_GIL_MANAGEMENT is defined:
|
|
265
|
+
PyInterpreterState *istate = nullptr;
|
|
266
|
+
|
|
267
|
+
type_map<PyObject *> native_enum_type_map;
|
|
268
|
+
|
|
269
|
+
internals()
|
|
270
|
+
: static_property_type(make_static_property_type()),
|
|
271
|
+
default_metaclass(make_default_metaclass()) {
|
|
272
|
+
PyThreadState *cur_tstate = PyThreadState_Get();
|
|
273
|
+
tstate = cur_tstate;
|
|
274
|
+
|
|
275
|
+
istate = cur_tstate->interp;
|
|
276
|
+
registered_exception_translators.push_front(&translate_exception);
|
|
277
|
+
#ifdef Py_GIL_DISABLED
|
|
278
|
+
// Scale proportional to the number of cores. 2x is a heuristic to reduce contention.
|
|
279
|
+
// Make sure the number isn't unreasonable by limiting it to 16 bits (65K)
|
|
280
|
+
auto num_shards = static_cast<std::uint16_t>(
|
|
281
|
+
std::min<std::size_t>(round_up_to_next_pow2(2 * std::thread::hardware_concurrency()),
|
|
282
|
+
std::numeric_limits<std::uint16_t>::max()));
|
|
283
|
+
if (num_shards == 0) {
|
|
284
|
+
num_shards = 1;
|
|
285
|
+
}
|
|
286
|
+
instance_shards.reset(new instance_map_shard[num_shards]);
|
|
287
|
+
instance_shards_mask = num_shards - 1;
|
|
288
|
+
#endif
|
|
289
|
+
}
|
|
290
|
+
internals(const internals &other) = delete;
|
|
291
|
+
internals(internals &&other) = delete;
|
|
292
|
+
internals &operator=(const internals &other) = delete;
|
|
293
|
+
internals &operator=(internals &&other) = delete;
|
|
294
|
+
~internals() = default;
|
|
295
|
+
};
|
|
296
|
+
|
|
297
|
+
// the internals struct (above) is shared between all the modules. local_internals are only
|
|
298
|
+
// for a single module. Any changes made to internals may require an update to
|
|
299
|
+
// PYBIND11_INTERNALS_VERSION, breaking backwards compatibility. local_internals is, by design,
|
|
300
|
+
// restricted to a single module. Whether a module has local internals or not should not
|
|
301
|
+
// impact any other modules, because the only things accessing the local internals is the
|
|
302
|
+
// module that contains them.
|
|
303
|
+
struct local_internals {
|
|
304
|
+
type_map<type_info *> registered_types_cpp;
|
|
305
|
+
std::forward_list<ExceptionTranslator> registered_exception_translators;
|
|
306
|
+
PyTypeObject *function_record_py_type = nullptr;
|
|
307
|
+
};
|
|
308
|
+
|
|
309
|
+
enum class holder_enum_t : uint8_t {
|
|
310
|
+
undefined,
|
|
311
|
+
std_unique_ptr, // Default, lacking interop with std::shared_ptr.
|
|
312
|
+
std_shared_ptr, // Lacking interop with std::unique_ptr.
|
|
313
|
+
smart_holder, // Full std::unique_ptr / std::shared_ptr interop.
|
|
314
|
+
custom_holder,
|
|
315
|
+
};
|
|
316
|
+
|
|
317
|
+
/// Additional type information which does not fit into the PyTypeObject.
|
|
318
|
+
/// Changes to this struct also require bumping `PYBIND11_INTERNALS_VERSION`.
|
|
319
|
+
struct type_info {
|
|
320
|
+
PyTypeObject *type;
|
|
321
|
+
const std::type_info *cpptype;
|
|
322
|
+
size_t type_size, type_align, holder_size_in_ptrs;
|
|
323
|
+
void *(*operator_new)(size_t);
|
|
324
|
+
void (*init_instance)(instance *, const void *);
|
|
325
|
+
void (*dealloc)(value_and_holder &v_h);
|
|
326
|
+
|
|
327
|
+
// Cross-DSO-safe function pointers, to sidestep cross-DSO RTTI issues
|
|
328
|
+
// on platforms like macOS (see PR #5728 for details):
|
|
329
|
+
memory::get_guarded_delete_fn get_memory_guarded_delete = memory::get_guarded_delete;
|
|
330
|
+
get_trampoline_self_life_support_fn get_trampoline_self_life_support = nullptr;
|
|
331
|
+
|
|
332
|
+
std::vector<PyObject *(*) (PyObject *, PyTypeObject *)> implicit_conversions;
|
|
333
|
+
std::vector<std::pair<const std::type_info *, void *(*) (void *)>> implicit_casts;
|
|
334
|
+
std::vector<bool (*)(PyObject *, void *&)> *direct_conversions;
|
|
335
|
+
buffer_info *(*get_buffer)(PyObject *, void *) = nullptr;
|
|
336
|
+
void *get_buffer_data = nullptr;
|
|
337
|
+
void *(*module_local_load)(PyObject *, const type_info *) = nullptr;
|
|
338
|
+
holder_enum_t holder_enum_v = holder_enum_t::undefined;
|
|
339
|
+
/* A simple type never occurs as a (direct or indirect) parent
|
|
340
|
+
* of a class that makes use of multiple inheritance.
|
|
341
|
+
* A type can be simple even if it has non-simple ancestors as long as it has no descendants.
|
|
342
|
+
*/
|
|
343
|
+
bool simple_type : 1;
|
|
344
|
+
/* True if there is no multiple inheritance in this type's inheritance tree */
|
|
345
|
+
bool simple_ancestors : 1;
|
|
346
|
+
/* true if this is a type registered with py::module_local */
|
|
347
|
+
bool module_local : 1;
|
|
348
|
+
};
|
|
349
|
+
|
|
350
|
+
#define PYBIND11_INTERNALS_ID \
|
|
351
|
+
"__pybind11_internals_v" PYBIND11_TOSTRING(PYBIND11_INTERNALS_VERSION) \
|
|
352
|
+
PYBIND11_COMPILER_TYPE_LEADING_UNDERSCORE PYBIND11_PLATFORM_ABI_ID "__"
|
|
353
|
+
|
|
354
|
+
#define PYBIND11_MODULE_LOCAL_ID \
|
|
355
|
+
"__pybind11_module_local_v" PYBIND11_TOSTRING(PYBIND11_INTERNALS_VERSION) \
|
|
356
|
+
PYBIND11_COMPILER_TYPE_LEADING_UNDERSCORE PYBIND11_PLATFORM_ABI_ID "__"
|
|
357
|
+
|
|
358
|
+
inline PyThreadState *get_thread_state_unchecked() {
|
|
359
|
+
#if defined(PYPY_VERSION) || defined(GRAALVM_PYTHON)
|
|
360
|
+
return PyThreadState_GET();
|
|
361
|
+
#elif PY_VERSION_HEX < 0x030D0000
|
|
362
|
+
return _PyThreadState_UncheckedGet();
|
|
363
|
+
#else
|
|
364
|
+
return PyThreadState_GetUnchecked();
|
|
365
|
+
#endif
|
|
366
|
+
}
|
|
367
|
+
|
|
368
|
+
/// We use this counter to figure out if there are or have been multiple subinterpreters active at
|
|
369
|
+
/// any point. This must never decrease while any interpreter may be running in any thread!
|
|
370
|
+
inline std::atomic<int> &get_num_interpreters_seen() {
|
|
371
|
+
static std::atomic<int> counter(0);
|
|
372
|
+
return counter;
|
|
373
|
+
}
|
|
374
|
+
|
|
375
|
+
template <class T,
|
|
376
|
+
enable_if_t<std::is_same<std::nested_exception, remove_cvref_t<T>>::value, int> = 0>
|
|
377
|
+
bool handle_nested_exception(const T &exc, const std::exception_ptr &p) {
|
|
378
|
+
std::exception_ptr nested = exc.nested_ptr();
|
|
379
|
+
if (nested != nullptr && nested != p) {
|
|
380
|
+
translate_exception(nested);
|
|
381
|
+
return true;
|
|
382
|
+
}
|
|
383
|
+
return false;
|
|
384
|
+
}
|
|
385
|
+
|
|
386
|
+
template <class T,
|
|
387
|
+
enable_if_t<!std::is_same<std::nested_exception, remove_cvref_t<T>>::value, int> = 0>
|
|
388
|
+
bool handle_nested_exception(const T &exc, const std::exception_ptr &p) {
|
|
389
|
+
if (const auto *nep = dynamic_cast<const std::nested_exception *>(std::addressof(exc))) {
|
|
390
|
+
return handle_nested_exception(*nep, p);
|
|
391
|
+
}
|
|
392
|
+
return false;
|
|
393
|
+
}
|
|
394
|
+
|
|
395
|
+
inline bool raise_err(PyObject *exc_type, const char *msg) {
|
|
396
|
+
if (PyErr_Occurred()) {
|
|
397
|
+
raise_from(exc_type, msg);
|
|
398
|
+
return true;
|
|
399
|
+
}
|
|
400
|
+
set_error(exc_type, msg);
|
|
401
|
+
return false;
|
|
402
|
+
}
|
|
403
|
+
|
|
404
|
+
inline void translate_exception(std::exception_ptr p) {
|
|
405
|
+
if (!p) {
|
|
406
|
+
return;
|
|
407
|
+
}
|
|
408
|
+
try {
|
|
409
|
+
std::rethrow_exception(p);
|
|
410
|
+
} catch (error_already_set &e) {
|
|
411
|
+
handle_nested_exception(e, p);
|
|
412
|
+
e.restore();
|
|
413
|
+
return;
|
|
414
|
+
} catch (const builtin_exception &e) {
|
|
415
|
+
// Could not use template since it's an abstract class.
|
|
416
|
+
if (const auto *nep = dynamic_cast<const std::nested_exception *>(std::addressof(e))) {
|
|
417
|
+
handle_nested_exception(*nep, p);
|
|
418
|
+
}
|
|
419
|
+
e.set_error();
|
|
420
|
+
return;
|
|
421
|
+
} catch (const std::bad_alloc &e) {
|
|
422
|
+
handle_nested_exception(e, p);
|
|
423
|
+
raise_err(PyExc_MemoryError, e.what());
|
|
424
|
+
return;
|
|
425
|
+
} catch (const std::domain_error &e) {
|
|
426
|
+
handle_nested_exception(e, p);
|
|
427
|
+
raise_err(PyExc_ValueError, e.what());
|
|
428
|
+
return;
|
|
429
|
+
} catch (const std::invalid_argument &e) {
|
|
430
|
+
handle_nested_exception(e, p);
|
|
431
|
+
raise_err(PyExc_ValueError, e.what());
|
|
432
|
+
return;
|
|
433
|
+
} catch (const std::length_error &e) {
|
|
434
|
+
handle_nested_exception(e, p);
|
|
435
|
+
raise_err(PyExc_ValueError, e.what());
|
|
436
|
+
return;
|
|
437
|
+
} catch (const std::out_of_range &e) {
|
|
438
|
+
handle_nested_exception(e, p);
|
|
439
|
+
raise_err(PyExc_IndexError, e.what());
|
|
440
|
+
return;
|
|
441
|
+
} catch (const std::range_error &e) {
|
|
442
|
+
handle_nested_exception(e, p);
|
|
443
|
+
raise_err(PyExc_ValueError, e.what());
|
|
444
|
+
return;
|
|
445
|
+
} catch (const std::overflow_error &e) {
|
|
446
|
+
handle_nested_exception(e, p);
|
|
447
|
+
raise_err(PyExc_OverflowError, e.what());
|
|
448
|
+
return;
|
|
449
|
+
} catch (const std::exception &e) {
|
|
450
|
+
handle_nested_exception(e, p);
|
|
451
|
+
raise_err(PyExc_RuntimeError, e.what());
|
|
452
|
+
return;
|
|
453
|
+
} catch (const std::nested_exception &e) {
|
|
454
|
+
handle_nested_exception(e, p);
|
|
455
|
+
raise_err(PyExc_RuntimeError, "Caught an unknown nested exception!");
|
|
456
|
+
return;
|
|
457
|
+
} catch (...) {
|
|
458
|
+
raise_err(PyExc_RuntimeError, "Caught an unknown exception!");
|
|
459
|
+
return;
|
|
460
|
+
}
|
|
461
|
+
}
|
|
462
|
+
|
|
463
|
+
#if !defined(__GLIBCXX__)
|
|
464
|
+
inline void translate_local_exception(std::exception_ptr p) {
|
|
465
|
+
try {
|
|
466
|
+
if (p) {
|
|
467
|
+
std::rethrow_exception(p);
|
|
468
|
+
}
|
|
469
|
+
} catch (error_already_set &e) {
|
|
470
|
+
e.restore();
|
|
471
|
+
return;
|
|
472
|
+
} catch (const builtin_exception &e) {
|
|
473
|
+
e.set_error();
|
|
474
|
+
return;
|
|
475
|
+
}
|
|
476
|
+
}
|
|
477
|
+
#endif
|
|
478
|
+
|
|
479
|
+
inline object get_python_state_dict() {
|
|
480
|
+
object state_dict;
|
|
481
|
+
#if defined(PYPY_VERSION) || defined(GRAALVM_PYTHON)
|
|
482
|
+
state_dict = reinterpret_borrow<object>(PyEval_GetBuiltins());
|
|
483
|
+
#else
|
|
484
|
+
# if PY_VERSION_HEX < 0x03090000
|
|
485
|
+
PyInterpreterState *istate = _PyInterpreterState_Get();
|
|
486
|
+
# else
|
|
487
|
+
PyInterpreterState *istate = PyInterpreterState_Get();
|
|
488
|
+
# endif
|
|
489
|
+
if (istate) {
|
|
490
|
+
state_dict = reinterpret_borrow<object>(PyInterpreterState_GetDict(istate));
|
|
491
|
+
}
|
|
492
|
+
#endif
|
|
493
|
+
if (!state_dict) {
|
|
494
|
+
raise_from(PyExc_SystemError, "pybind11::detail::get_python_state_dict() FAILED");
|
|
495
|
+
throw error_already_set();
|
|
496
|
+
}
|
|
497
|
+
return state_dict;
|
|
498
|
+
}
|
|
499
|
+
|
|
500
|
+
template <typename InternalsType>
|
|
501
|
+
class internals_pp_manager {
|
|
502
|
+
public:
|
|
503
|
+
using on_fetch_function = void(InternalsType *);
|
|
504
|
+
internals_pp_manager(char const *id, on_fetch_function *on_fetch)
|
|
505
|
+
: holder_id_(id), on_fetch_(on_fetch) {}
|
|
506
|
+
|
|
507
|
+
/// Get the current pointer-to-pointer, allocating it if it does not already exist. May
|
|
508
|
+
/// acquire the GIL. Will never return nullptr.
|
|
509
|
+
std::unique_ptr<InternalsType> *get_pp() {
|
|
510
|
+
#ifdef PYBIND11_HAS_SUBINTERPRETER_SUPPORT
|
|
511
|
+
if (get_num_interpreters_seen() > 1) {
|
|
512
|
+
// Whenever the interpreter changes on the current thread we need to invalidate the
|
|
513
|
+
// internals_pp so that it can be pulled from the interpreter's state dict. That is
|
|
514
|
+
// slow, so we use the current PyThreadState to check if it is necessary.
|
|
515
|
+
auto *tstate = get_thread_state_unchecked();
|
|
516
|
+
if (!tstate || tstate->interp != last_istate_.get()) {
|
|
517
|
+
gil_scoped_acquire_simple gil;
|
|
518
|
+
if (!tstate) {
|
|
519
|
+
tstate = get_thread_state_unchecked();
|
|
520
|
+
}
|
|
521
|
+
last_istate_ = tstate->interp;
|
|
522
|
+
internals_tls_p_ = get_or_create_pp_in_state_dict();
|
|
523
|
+
}
|
|
524
|
+
return internals_tls_p_.get();
|
|
525
|
+
}
|
|
526
|
+
#endif
|
|
527
|
+
if (!internals_singleton_pp_) {
|
|
528
|
+
gil_scoped_acquire_simple gil;
|
|
529
|
+
internals_singleton_pp_ = get_or_create_pp_in_state_dict();
|
|
530
|
+
}
|
|
531
|
+
return internals_singleton_pp_;
|
|
532
|
+
}
|
|
533
|
+
|
|
534
|
+
/// Drop all the references we're currently holding.
|
|
535
|
+
void unref() {
|
|
536
|
+
#ifdef PYBIND11_HAS_SUBINTERPRETER_SUPPORT
|
|
537
|
+
if (get_num_interpreters_seen() > 1) {
|
|
538
|
+
last_istate_.reset();
|
|
539
|
+
internals_tls_p_.reset();
|
|
540
|
+
return;
|
|
541
|
+
}
|
|
542
|
+
#endif
|
|
543
|
+
internals_singleton_pp_ = nullptr;
|
|
544
|
+
}
|
|
545
|
+
|
|
546
|
+
void destroy() {
|
|
547
|
+
#ifdef PYBIND11_HAS_SUBINTERPRETER_SUPPORT
|
|
548
|
+
if (get_num_interpreters_seen() > 1) {
|
|
549
|
+
auto *tstate = get_thread_state_unchecked();
|
|
550
|
+
// this could be called without an active interpreter, just use what was cached
|
|
551
|
+
if (!tstate || tstate->interp == last_istate_.get()) {
|
|
552
|
+
auto tpp = internals_tls_p_.get();
|
|
553
|
+
if (tpp) {
|
|
554
|
+
delete tpp;
|
|
555
|
+
}
|
|
556
|
+
}
|
|
557
|
+
unref();
|
|
558
|
+
return;
|
|
559
|
+
}
|
|
560
|
+
#endif
|
|
561
|
+
delete internals_singleton_pp_;
|
|
562
|
+
unref();
|
|
563
|
+
}
|
|
564
|
+
|
|
565
|
+
private:
|
|
566
|
+
std::unique_ptr<InternalsType> *get_or_create_pp_in_state_dict() {
|
|
567
|
+
error_scope err_scope;
|
|
568
|
+
dict state_dict = get_python_state_dict();
|
|
569
|
+
auto internals_obj
|
|
570
|
+
= reinterpret_steal<object>(dict_getitemstringref(state_dict.ptr(), holder_id_));
|
|
571
|
+
std::unique_ptr<InternalsType> *pp = nullptr;
|
|
572
|
+
if (internals_obj) {
|
|
573
|
+
void *raw_ptr = PyCapsule_GetPointer(internals_obj.ptr(), /*name=*/nullptr);
|
|
574
|
+
if (!raw_ptr) {
|
|
575
|
+
raise_from(PyExc_SystemError,
|
|
576
|
+
"pybind11::detail::internals_pp_manager::get_pp_from_dict() FAILED");
|
|
577
|
+
throw error_already_set();
|
|
578
|
+
}
|
|
579
|
+
pp = reinterpret_cast<std::unique_ptr<InternalsType> *>(raw_ptr);
|
|
580
|
+
if (on_fetch_ && pp) {
|
|
581
|
+
on_fetch_(pp->get());
|
|
582
|
+
}
|
|
583
|
+
} else {
|
|
584
|
+
pp = new std::unique_ptr<InternalsType>;
|
|
585
|
+
// NOLINTNEXTLINE(bugprone-casting-through-void)
|
|
586
|
+
state_dict[holder_id_] = capsule(reinterpret_cast<void *>(pp));
|
|
587
|
+
}
|
|
588
|
+
return pp;
|
|
589
|
+
}
|
|
590
|
+
|
|
591
|
+
char const *holder_id_ = nullptr;
|
|
592
|
+
on_fetch_function *on_fetch_ = nullptr;
|
|
593
|
+
#ifdef PYBIND11_HAS_SUBINTERPRETER_SUPPORT
|
|
594
|
+
thread_specific_storage<PyInterpreterState> last_istate_;
|
|
595
|
+
thread_specific_storage<std::unique_ptr<InternalsType>> internals_tls_p_;
|
|
596
|
+
#endif
|
|
597
|
+
std::unique_ptr<InternalsType> *internals_singleton_pp_;
|
|
598
|
+
};
|
|
599
|
+
|
|
600
|
+
// If We loaded the internals through `state_dict`, our `error_already_set`
|
|
601
|
+
// and `builtin_exception` may be different local classes than the ones set up in the
|
|
602
|
+
// initial exception translator, below, so add another for our local exception classes.
|
|
603
|
+
//
|
|
604
|
+
// libstdc++ doesn't require this (types there are identified only by name)
|
|
605
|
+
// libc++ with CPython doesn't require this (types are explicitly exported)
|
|
606
|
+
// libc++ with PyPy still need it, awaiting further investigation
|
|
607
|
+
#if !defined(__GLIBCXX__)
|
|
608
|
+
inline void check_internals_local_exception_translator(internals *internals_ptr) {
|
|
609
|
+
if (internals_ptr) {
|
|
610
|
+
for (auto et : internals_ptr->registered_exception_translators) {
|
|
611
|
+
if (et == &translate_local_exception) {
|
|
612
|
+
return;
|
|
613
|
+
}
|
|
614
|
+
}
|
|
615
|
+
internals_ptr->registered_exception_translators.push_front(&translate_local_exception);
|
|
616
|
+
}
|
|
617
|
+
}
|
|
618
|
+
#endif
|
|
619
|
+
|
|
620
|
+
inline internals_pp_manager<internals> &get_internals_pp_manager() {
|
|
621
|
+
#if defined(__GLIBCXX__)
|
|
622
|
+
# define ON_FETCH_FN nullptr
|
|
623
|
+
#else
|
|
624
|
+
# define ON_FETCH_FN &check_internals_local_exception_translator
|
|
625
|
+
#endif
|
|
626
|
+
static internals_pp_manager<internals> internals_pp_manager(PYBIND11_INTERNALS_ID,
|
|
627
|
+
ON_FETCH_FN);
|
|
628
|
+
#undef ON_FETCH_FN
|
|
629
|
+
return internals_pp_manager;
|
|
630
|
+
}
|
|
631
|
+
|
|
632
|
+
/// Return a reference to the current `internals` data
|
|
633
|
+
PYBIND11_NOINLINE internals &get_internals() {
|
|
634
|
+
auto &ppmgr = get_internals_pp_manager();
|
|
635
|
+
auto &internals_ptr = *ppmgr.get_pp();
|
|
636
|
+
if (!internals_ptr) {
|
|
637
|
+
// Slow path, something needs fetched from the state dict or created
|
|
638
|
+
gil_scoped_acquire_simple gil;
|
|
639
|
+
error_scope err_scope;
|
|
640
|
+
internals_ptr.reset(new internals());
|
|
641
|
+
|
|
642
|
+
if (!internals_ptr->instance_base) {
|
|
643
|
+
// This calls get_internals, so cannot be called from within the internals constructor
|
|
644
|
+
// called above because internals_ptr must be set before get_internals is called again
|
|
645
|
+
internals_ptr->instance_base = make_object_base_type(internals_ptr->default_metaclass);
|
|
646
|
+
}
|
|
647
|
+
}
|
|
648
|
+
return *internals_ptr;
|
|
649
|
+
}
|
|
650
|
+
|
|
651
|
+
inline internals_pp_manager<local_internals> &get_local_internals_pp_manager() {
|
|
652
|
+
// Use the address of this static itself as part of the key, so that the value is uniquely tied
|
|
653
|
+
// to where the module is loaded in memory
|
|
654
|
+
static const std::string this_module_idstr
|
|
655
|
+
= PYBIND11_MODULE_LOCAL_ID
|
|
656
|
+
+ std::to_string(reinterpret_cast<uintptr_t>(&this_module_idstr));
|
|
657
|
+
static internals_pp_manager<local_internals> local_internals_pp_manager(
|
|
658
|
+
this_module_idstr.c_str(), nullptr);
|
|
659
|
+
return local_internals_pp_manager;
|
|
660
|
+
}
|
|
661
|
+
|
|
662
|
+
/// Works like `get_internals`, but for things which are locally registered.
|
|
663
|
+
inline local_internals &get_local_internals() {
|
|
664
|
+
auto &ppmgr = get_local_internals_pp_manager();
|
|
665
|
+
auto &internals_ptr = *ppmgr.get_pp();
|
|
666
|
+
if (!internals_ptr) {
|
|
667
|
+
internals_ptr.reset(new local_internals());
|
|
668
|
+
}
|
|
669
|
+
return *internals_ptr;
|
|
670
|
+
}
|
|
671
|
+
|
|
672
|
+
#ifdef Py_GIL_DISABLED
|
|
673
|
+
# define PYBIND11_LOCK_INTERNALS(internals) std::unique_lock<pymutex> lock((internals).mutex)
|
|
674
|
+
#else
|
|
675
|
+
# define PYBIND11_LOCK_INTERNALS(internals)
|
|
676
|
+
#endif
|
|
677
|
+
|
|
678
|
+
template <typename F>
|
|
679
|
+
inline auto with_internals(const F &cb) -> decltype(cb(get_internals())) {
|
|
680
|
+
auto &internals = get_internals();
|
|
681
|
+
PYBIND11_LOCK_INTERNALS(internals);
|
|
682
|
+
return cb(internals);
|
|
683
|
+
}
|
|
684
|
+
|
|
685
|
+
template <typename F>
|
|
686
|
+
inline auto with_exception_translators(const F &cb)
|
|
687
|
+
-> decltype(cb(get_internals().registered_exception_translators,
|
|
688
|
+
get_local_internals().registered_exception_translators)) {
|
|
689
|
+
auto &internals = get_internals();
|
|
690
|
+
#ifdef Py_GIL_DISABLED
|
|
691
|
+
std::unique_lock<pymutex> lock((internals).exception_translator_mutex);
|
|
692
|
+
#endif
|
|
693
|
+
auto &local_internals = get_local_internals();
|
|
694
|
+
return cb(internals.registered_exception_translators,
|
|
695
|
+
local_internals.registered_exception_translators);
|
|
696
|
+
}
|
|
697
|
+
|
|
698
|
+
inline std::uint64_t mix64(std::uint64_t z) {
|
|
699
|
+
// David Stafford's variant 13 of the MurmurHash3 finalizer popularized
|
|
700
|
+
// by the SplitMix PRNG.
|
|
701
|
+
// https://zimbry.blogspot.com/2011/09/better-bit-mixing-improving-on.html
|
|
702
|
+
z = (z ^ (z >> 30)) * 0xbf58476d1ce4e5b9;
|
|
703
|
+
z = (z ^ (z >> 27)) * 0x94d049bb133111eb;
|
|
704
|
+
return z ^ (z >> 31);
|
|
705
|
+
}
|
|
706
|
+
|
|
707
|
+
template <typename F>
|
|
708
|
+
inline auto with_instance_map(const void *ptr, const F &cb)
|
|
709
|
+
-> decltype(cb(std::declval<instance_map &>())) {
|
|
710
|
+
auto &internals = get_internals();
|
|
711
|
+
|
|
712
|
+
#ifdef Py_GIL_DISABLED
|
|
713
|
+
// Hash address to compute shard, but ignore low bits. We'd like allocations
|
|
714
|
+
// from the same thread/core to map to the same shard and allocations from
|
|
715
|
+
// other threads/cores to map to other shards. Using the high bits is a good
|
|
716
|
+
// heuristic because memory allocators often have a per-thread
|
|
717
|
+
// arena/superblock/segment from which smaller allocations are served.
|
|
718
|
+
auto addr = reinterpret_cast<std::uintptr_t>(ptr);
|
|
719
|
+
auto hash = mix64(static_cast<std::uint64_t>(addr >> 20));
|
|
720
|
+
auto idx = static_cast<size_t>(hash & internals.instance_shards_mask);
|
|
721
|
+
|
|
722
|
+
auto &shard = internals.instance_shards[idx];
|
|
723
|
+
std::unique_lock<pymutex> lock(shard.mutex);
|
|
724
|
+
return cb(shard.registered_instances);
|
|
725
|
+
#else
|
|
726
|
+
(void) ptr;
|
|
727
|
+
return cb(internals.registered_instances);
|
|
728
|
+
#endif
|
|
729
|
+
}
|
|
730
|
+
|
|
731
|
+
// Returns the number of registered instances for testing purposes. The result may not be
|
|
732
|
+
// consistent if other threads are registering or unregistering instances concurrently.
|
|
733
|
+
inline size_t num_registered_instances() {
|
|
734
|
+
auto &internals = get_internals();
|
|
735
|
+
#ifdef Py_GIL_DISABLED
|
|
736
|
+
size_t count = 0;
|
|
737
|
+
for (size_t i = 0; i <= internals.instance_shards_mask; ++i) {
|
|
738
|
+
auto &shard = internals.instance_shards[i];
|
|
739
|
+
std::unique_lock<pymutex> lock(shard.mutex);
|
|
740
|
+
count += shard.registered_instances.size();
|
|
741
|
+
}
|
|
742
|
+
return count;
|
|
743
|
+
#else
|
|
744
|
+
return internals.registered_instances.size();
|
|
745
|
+
#endif
|
|
746
|
+
}
|
|
747
|
+
|
|
748
|
+
/// Constructs a std::string with the given arguments, stores it in `internals`, and returns its
|
|
749
|
+
/// `c_str()`. Such strings objects have a long storage duration -- the internal strings are only
|
|
750
|
+
/// cleared when the program exits or after interpreter shutdown (when embedding), and so are
|
|
751
|
+
/// suitable for c-style strings needed by Python internals (such as PyTypeObject's tp_name).
|
|
752
|
+
template <typename... Args>
|
|
753
|
+
const char *c_str(Args &&...args) {
|
|
754
|
+
// GCC 4.8 doesn't like parameter unpack within lambda capture, so use
|
|
755
|
+
// PYBIND11_LOCK_INTERNALS.
|
|
756
|
+
auto &internals = get_internals();
|
|
757
|
+
PYBIND11_LOCK_INTERNALS(internals);
|
|
758
|
+
auto &strings = internals.static_strings;
|
|
759
|
+
strings.emplace_front(std::forward<Args>(args)...);
|
|
760
|
+
return strings.front().c_str();
|
|
761
|
+
}
|
|
762
|
+
|
|
763
|
+
PYBIND11_NAMESPACE_END(detail)
|
|
764
|
+
|
|
765
|
+
/// Returns a named pointer that is shared among all extension modules (using the same
|
|
766
|
+
/// pybind11 version) running in the current interpreter. Names starting with underscores
|
|
767
|
+
/// are reserved for internal usage. Returns `nullptr` if no matching entry was found.
|
|
768
|
+
PYBIND11_NOINLINE void *get_shared_data(const std::string &name) {
|
|
769
|
+
return detail::with_internals([&](detail::internals &internals) {
|
|
770
|
+
auto it = internals.shared_data.find(name);
|
|
771
|
+
return it != internals.shared_data.end() ? it->second : nullptr;
|
|
772
|
+
});
|
|
773
|
+
}
|
|
774
|
+
|
|
775
|
+
/// Set the shared data that can be later recovered by `get_shared_data()`.
|
|
776
|
+
PYBIND11_NOINLINE void *set_shared_data(const std::string &name, void *data) {
|
|
777
|
+
return detail::with_internals([&](detail::internals &internals) {
|
|
778
|
+
internals.shared_data[name] = data;
|
|
779
|
+
return data;
|
|
780
|
+
});
|
|
781
|
+
}
|
|
782
|
+
|
|
783
|
+
/// Returns a typed reference to a shared data entry (by using `get_shared_data()`) if
|
|
784
|
+
/// such entry exists. Otherwise, a new object of default-constructible type `T` is
|
|
785
|
+
/// added to the shared data under the given name and a reference to it is returned.
|
|
786
|
+
template <typename T>
|
|
787
|
+
T &get_or_create_shared_data(const std::string &name) {
|
|
788
|
+
return *detail::with_internals([&](detail::internals &internals) {
|
|
789
|
+
auto it = internals.shared_data.find(name);
|
|
790
|
+
T *ptr = (T *) (it != internals.shared_data.end() ? it->second : nullptr);
|
|
791
|
+
if (!ptr) {
|
|
792
|
+
ptr = new T();
|
|
793
|
+
internals.shared_data[name] = ptr;
|
|
794
|
+
}
|
|
795
|
+
return ptr;
|
|
796
|
+
});
|
|
797
|
+
}
|
|
798
|
+
|
|
799
|
+
PYBIND11_NAMESPACE_END(PYBIND11_NAMESPACE)
|