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.
Files changed (340) hide show
  1. netgen/NgOCC.py +7 -0
  2. netgen/__init__.py +114 -0
  3. netgen/__init__.pyi +22 -0
  4. netgen/__main__.py +53 -0
  5. netgen/cmake/NetgenConfig.cmake +79 -0
  6. netgen/cmake/netgen-targets-release.cmake +69 -0
  7. netgen/cmake/netgen-targets.cmake +146 -0
  8. netgen/config/__init__.py +1 -0
  9. netgen/config/__init__.pyi +52 -0
  10. netgen/config/__main__.py +4 -0
  11. netgen/config/config.py +68 -0
  12. netgen/config/config.pyi +54 -0
  13. netgen/csg.py +25 -0
  14. netgen/geom2d.py +178 -0
  15. netgen/gui.py +82 -0
  16. netgen/include/core/archive.hpp +1256 -0
  17. netgen/include/core/array.hpp +1760 -0
  18. netgen/include/core/autodiff.hpp +1131 -0
  19. netgen/include/core/autodiffdiff.hpp +733 -0
  20. netgen/include/core/bitarray.hpp +240 -0
  21. netgen/include/core/concurrentqueue.h +3619 -0
  22. netgen/include/core/exception.hpp +145 -0
  23. netgen/include/core/flags.hpp +199 -0
  24. netgen/include/core/hashtable.hpp +1281 -0
  25. netgen/include/core/localheap.hpp +318 -0
  26. netgen/include/core/logging.hpp +117 -0
  27. netgen/include/core/memtracer.hpp +221 -0
  28. netgen/include/core/mpi4py_pycapi.h +245 -0
  29. netgen/include/core/mpi_wrapper.hpp +643 -0
  30. netgen/include/core/ng_mpi.hpp +94 -0
  31. netgen/include/core/ng_mpi_generated_declarations.hpp +155 -0
  32. netgen/include/core/ng_mpi_native.hpp +25 -0
  33. netgen/include/core/ngcore.hpp +32 -0
  34. netgen/include/core/ngcore_api.hpp +152 -0
  35. netgen/include/core/ngstream.hpp +115 -0
  36. netgen/include/core/paje_trace.hpp +279 -0
  37. netgen/include/core/profiler.hpp +382 -0
  38. netgen/include/core/python_ngcore.hpp +457 -0
  39. netgen/include/core/ranges.hpp +109 -0
  40. netgen/include/core/register_archive.hpp +100 -0
  41. netgen/include/core/signal.hpp +82 -0
  42. netgen/include/core/simd.hpp +160 -0
  43. netgen/include/core/simd_arm64.hpp +407 -0
  44. netgen/include/core/simd_avx.hpp +394 -0
  45. netgen/include/core/simd_avx512.hpp +285 -0
  46. netgen/include/core/simd_generic.hpp +1053 -0
  47. netgen/include/core/simd_math.hpp +178 -0
  48. netgen/include/core/simd_sse.hpp +289 -0
  49. netgen/include/core/statushandler.hpp +37 -0
  50. netgen/include/core/symboltable.hpp +153 -0
  51. netgen/include/core/table.hpp +810 -0
  52. netgen/include/core/taskmanager.hpp +1161 -0
  53. netgen/include/core/type_traits.hpp +65 -0
  54. netgen/include/core/utils.hpp +385 -0
  55. netgen/include/core/version.hpp +102 -0
  56. netgen/include/core/xbool.hpp +47 -0
  57. netgen/include/csg/algprim.hpp +563 -0
  58. netgen/include/csg/brick.hpp +150 -0
  59. netgen/include/csg/csg.hpp +43 -0
  60. netgen/include/csg/csgeom.hpp +389 -0
  61. netgen/include/csg/csgparser.hpp +101 -0
  62. netgen/include/csg/curve2d.hpp +67 -0
  63. netgen/include/csg/edgeflw.hpp +112 -0
  64. netgen/include/csg/explicitcurve2d.hpp +113 -0
  65. netgen/include/csg/extrusion.hpp +185 -0
  66. netgen/include/csg/gencyl.hpp +70 -0
  67. netgen/include/csg/geoml.hpp +16 -0
  68. netgen/include/csg/identify.hpp +213 -0
  69. netgen/include/csg/manifold.hpp +29 -0
  70. netgen/include/csg/meshsurf.hpp +46 -0
  71. netgen/include/csg/polyhedra.hpp +121 -0
  72. netgen/include/csg/revolution.hpp +180 -0
  73. netgen/include/csg/singularref.hpp +84 -0
  74. netgen/include/csg/solid.hpp +295 -0
  75. netgen/include/csg/specpoin.hpp +194 -0
  76. netgen/include/csg/spline3d.hpp +99 -0
  77. netgen/include/csg/splinesurface.hpp +85 -0
  78. netgen/include/csg/surface.hpp +394 -0
  79. netgen/include/csg/triapprox.hpp +63 -0
  80. netgen/include/csg/vscsg.hpp +34 -0
  81. netgen/include/general/autodiff.hpp +356 -0
  82. netgen/include/general/autoptr.hpp +39 -0
  83. netgen/include/general/gzstream.h +121 -0
  84. netgen/include/general/hashtabl.hpp +1692 -0
  85. netgen/include/general/myadt.hpp +48 -0
  86. netgen/include/general/mystring.hpp +226 -0
  87. netgen/include/general/netgenout.hpp +205 -0
  88. netgen/include/general/ngarray.hpp +797 -0
  89. netgen/include/general/ngbitarray.hpp +149 -0
  90. netgen/include/general/ngpython.hpp +74 -0
  91. netgen/include/general/optmem.hpp +44 -0
  92. netgen/include/general/parthreads.hpp +138 -0
  93. netgen/include/general/seti.hpp +50 -0
  94. netgen/include/general/sort.hpp +47 -0
  95. netgen/include/general/spbita2d.hpp +59 -0
  96. netgen/include/general/stack.hpp +114 -0
  97. netgen/include/general/table.hpp +280 -0
  98. netgen/include/general/template.hpp +509 -0
  99. netgen/include/geom2d/csg2d.hpp +750 -0
  100. netgen/include/geom2d/geometry2d.hpp +280 -0
  101. netgen/include/geom2d/spline2d.hpp +234 -0
  102. netgen/include/geom2d/vsgeom2d.hpp +28 -0
  103. netgen/include/gprim/adtree.hpp +1392 -0
  104. netgen/include/gprim/geom2d.hpp +858 -0
  105. netgen/include/gprim/geom3d.hpp +749 -0
  106. netgen/include/gprim/geomfuncs.hpp +212 -0
  107. netgen/include/gprim/geomobjects.hpp +544 -0
  108. netgen/include/gprim/geomops.hpp +404 -0
  109. netgen/include/gprim/geomtest3d.hpp +101 -0
  110. netgen/include/gprim/gprim.hpp +33 -0
  111. netgen/include/gprim/spline.hpp +778 -0
  112. netgen/include/gprim/splinegeometry.hpp +73 -0
  113. netgen/include/gprim/transform3d.hpp +216 -0
  114. netgen/include/include/acisgeom.hpp +3 -0
  115. netgen/include/include/csg.hpp +1 -0
  116. netgen/include/include/geometry2d.hpp +1 -0
  117. netgen/include/include/gprim.hpp +1 -0
  118. netgen/include/include/incopengl.hpp +62 -0
  119. netgen/include/include/inctcl.hpp +13 -0
  120. netgen/include/include/incvis.hpp +6 -0
  121. netgen/include/include/linalg.hpp +1 -0
  122. netgen/include/include/meshing.hpp +1 -0
  123. netgen/include/include/myadt.hpp +1 -0
  124. netgen/include/include/mydefs.hpp +70 -0
  125. netgen/include/include/mystdlib.h +59 -0
  126. netgen/include/include/netgen_config.hpp +27 -0
  127. netgen/include/include/netgen_version.hpp +9 -0
  128. netgen/include/include/nginterface_v2_impl.hpp +395 -0
  129. netgen/include/include/ngsimd.hpp +1 -0
  130. netgen/include/include/occgeom.hpp +1 -0
  131. netgen/include/include/opti.hpp +1 -0
  132. netgen/include/include/parallel.hpp +1 -0
  133. netgen/include/include/stlgeom.hpp +1 -0
  134. netgen/include/include/visual.hpp +1 -0
  135. netgen/include/interface/rw_medit.hpp +11 -0
  136. netgen/include/interface/writeuser.hpp +80 -0
  137. netgen/include/linalg/densemat.hpp +414 -0
  138. netgen/include/linalg/linalg.hpp +29 -0
  139. netgen/include/linalg/opti.hpp +142 -0
  140. netgen/include/linalg/polynomial.hpp +47 -0
  141. netgen/include/linalg/vector.hpp +217 -0
  142. netgen/include/meshing/adfront2.hpp +274 -0
  143. netgen/include/meshing/adfront3.hpp +332 -0
  144. netgen/include/meshing/basegeom.hpp +370 -0
  145. netgen/include/meshing/bcfunctions.hpp +53 -0
  146. netgen/include/meshing/bisect.hpp +72 -0
  147. netgen/include/meshing/boundarylayer.hpp +113 -0
  148. netgen/include/meshing/classifyhpel.hpp +1984 -0
  149. netgen/include/meshing/clusters.hpp +46 -0
  150. netgen/include/meshing/curvedelems.hpp +274 -0
  151. netgen/include/meshing/delaunay2d.hpp +73 -0
  152. netgen/include/meshing/fieldlines.hpp +103 -0
  153. netgen/include/meshing/findip.hpp +198 -0
  154. netgen/include/meshing/findip2.hpp +103 -0
  155. netgen/include/meshing/geomsearch.hpp +69 -0
  156. netgen/include/meshing/global.hpp +54 -0
  157. netgen/include/meshing/hpref_hex.hpp +330 -0
  158. netgen/include/meshing/hpref_prism.hpp +3405 -0
  159. netgen/include/meshing/hpref_pyramid.hpp +154 -0
  160. netgen/include/meshing/hpref_quad.hpp +2082 -0
  161. netgen/include/meshing/hpref_segm.hpp +122 -0
  162. netgen/include/meshing/hpref_tet.hpp +4230 -0
  163. netgen/include/meshing/hpref_trig.hpp +848 -0
  164. netgen/include/meshing/hprefinement.hpp +366 -0
  165. netgen/include/meshing/improve2.hpp +178 -0
  166. netgen/include/meshing/improve3.hpp +151 -0
  167. netgen/include/meshing/localh.hpp +223 -0
  168. netgen/include/meshing/meshclass.hpp +1076 -0
  169. netgen/include/meshing/meshfunc.hpp +47 -0
  170. netgen/include/meshing/meshing.hpp +63 -0
  171. netgen/include/meshing/meshing2.hpp +163 -0
  172. netgen/include/meshing/meshing3.hpp +123 -0
  173. netgen/include/meshing/meshtool.hpp +90 -0
  174. netgen/include/meshing/meshtype.hpp +1930 -0
  175. netgen/include/meshing/msghandler.hpp +62 -0
  176. netgen/include/meshing/paralleltop.hpp +172 -0
  177. netgen/include/meshing/python_mesh.hpp +206 -0
  178. netgen/include/meshing/ruler2.hpp +172 -0
  179. netgen/include/meshing/ruler3.hpp +211 -0
  180. netgen/include/meshing/soldata.hpp +141 -0
  181. netgen/include/meshing/specials.hpp +17 -0
  182. netgen/include/meshing/surfacegeom.hpp +73 -0
  183. netgen/include/meshing/topology.hpp +1003 -0
  184. netgen/include/meshing/validate.hpp +21 -0
  185. netgen/include/meshing/visual_interface.hpp +71 -0
  186. netgen/include/mydefs.hpp +70 -0
  187. netgen/include/nginterface.h +474 -0
  188. netgen/include/nginterface_v2.hpp +406 -0
  189. netgen/include/nglib.h +697 -0
  190. netgen/include/nglib_occ.h +50 -0
  191. netgen/include/occ/occ_edge.hpp +47 -0
  192. netgen/include/occ/occ_face.hpp +52 -0
  193. netgen/include/occ/occ_solid.hpp +23 -0
  194. netgen/include/occ/occ_utils.hpp +376 -0
  195. netgen/include/occ/occ_vertex.hpp +30 -0
  196. netgen/include/occ/occgeom.hpp +659 -0
  197. netgen/include/occ/occmeshsurf.hpp +168 -0
  198. netgen/include/occ/vsocc.hpp +33 -0
  199. netgen/include/pybind11/LICENSE +29 -0
  200. netgen/include/pybind11/attr.h +722 -0
  201. netgen/include/pybind11/buffer_info.h +208 -0
  202. netgen/include/pybind11/cast.h +2361 -0
  203. netgen/include/pybind11/chrono.h +228 -0
  204. netgen/include/pybind11/common.h +2 -0
  205. netgen/include/pybind11/complex.h +74 -0
  206. netgen/include/pybind11/conduit/README.txt +15 -0
  207. netgen/include/pybind11/conduit/pybind11_conduit_v1.h +116 -0
  208. netgen/include/pybind11/conduit/pybind11_platform_abi_id.h +87 -0
  209. netgen/include/pybind11/conduit/wrap_include_python_h.h +72 -0
  210. netgen/include/pybind11/critical_section.h +56 -0
  211. netgen/include/pybind11/detail/class.h +823 -0
  212. netgen/include/pybind11/detail/common.h +1348 -0
  213. netgen/include/pybind11/detail/cpp_conduit.h +75 -0
  214. netgen/include/pybind11/detail/descr.h +226 -0
  215. netgen/include/pybind11/detail/dynamic_raw_ptr_cast_if_possible.h +39 -0
  216. netgen/include/pybind11/detail/exception_translation.h +71 -0
  217. netgen/include/pybind11/detail/function_record_pyobject.h +191 -0
  218. netgen/include/pybind11/detail/init.h +538 -0
  219. netgen/include/pybind11/detail/internals.h +799 -0
  220. netgen/include/pybind11/detail/native_enum_data.h +209 -0
  221. netgen/include/pybind11/detail/pybind11_namespace_macros.h +82 -0
  222. netgen/include/pybind11/detail/struct_smart_holder.h +378 -0
  223. netgen/include/pybind11/detail/type_caster_base.h +1591 -0
  224. netgen/include/pybind11/detail/typeid.h +65 -0
  225. netgen/include/pybind11/detail/using_smart_holder.h +22 -0
  226. netgen/include/pybind11/detail/value_and_holder.h +90 -0
  227. netgen/include/pybind11/eigen/common.h +9 -0
  228. netgen/include/pybind11/eigen/matrix.h +723 -0
  229. netgen/include/pybind11/eigen/tensor.h +521 -0
  230. netgen/include/pybind11/eigen.h +12 -0
  231. netgen/include/pybind11/embed.h +320 -0
  232. netgen/include/pybind11/eval.h +161 -0
  233. netgen/include/pybind11/functional.h +147 -0
  234. netgen/include/pybind11/gil.h +199 -0
  235. netgen/include/pybind11/gil_safe_call_once.h +102 -0
  236. netgen/include/pybind11/gil_simple.h +37 -0
  237. netgen/include/pybind11/iostream.h +265 -0
  238. netgen/include/pybind11/native_enum.h +67 -0
  239. netgen/include/pybind11/numpy.h +2312 -0
  240. netgen/include/pybind11/operators.h +202 -0
  241. netgen/include/pybind11/options.h +92 -0
  242. netgen/include/pybind11/pybind11.h +3645 -0
  243. netgen/include/pybind11/pytypes.h +2680 -0
  244. netgen/include/pybind11/stl/filesystem.h +114 -0
  245. netgen/include/pybind11/stl.h +666 -0
  246. netgen/include/pybind11/stl_bind.h +858 -0
  247. netgen/include/pybind11/subinterpreter.h +299 -0
  248. netgen/include/pybind11/trampoline_self_life_support.h +65 -0
  249. netgen/include/pybind11/type_caster_pyobject_ptr.h +61 -0
  250. netgen/include/pybind11/typing.h +298 -0
  251. netgen/include/pybind11/warnings.h +75 -0
  252. netgen/include/stlgeom/meshstlsurface.hpp +67 -0
  253. netgen/include/stlgeom/stlgeom.hpp +491 -0
  254. netgen/include/stlgeom/stlline.hpp +193 -0
  255. netgen/include/stlgeom/stltool.hpp +331 -0
  256. netgen/include/stlgeom/stltopology.hpp +419 -0
  257. netgen/include/stlgeom/vsstl.hpp +58 -0
  258. netgen/include/visualization/meshdoc.hpp +42 -0
  259. netgen/include/visualization/mvdraw.hpp +325 -0
  260. netgen/include/visualization/vispar.hpp +128 -0
  261. netgen/include/visualization/visual.hpp +28 -0
  262. netgen/include/visualization/visual_api.hpp +10 -0
  263. netgen/include/visualization/vssolution.hpp +399 -0
  264. netgen/lib/libnggui.lib +0 -0
  265. netgen/lib/ngcore.lib +0 -0
  266. netgen/lib/nglib.lib +0 -0
  267. netgen/lib/togl.lib +0 -0
  268. netgen/libnggui.dll +0 -0
  269. netgen/libngguipy.lib +0 -0
  270. netgen/libngguipy.pyd +0 -0
  271. netgen/libngpy/_NgOCC.pyi +1545 -0
  272. netgen/libngpy/__init__.pyi +7 -0
  273. netgen/libngpy/_csg.pyi +259 -0
  274. netgen/libngpy/_geom2d.pyi +323 -0
  275. netgen/libngpy/_meshing.pyi +1111 -0
  276. netgen/libngpy/_stl.pyi +131 -0
  277. netgen/libngpy.lib +0 -0
  278. netgen/libngpy.pyd +0 -0
  279. netgen/meshing.py +65 -0
  280. netgen/ngcore.dll +0 -0
  281. netgen/nglib.dll +0 -0
  282. netgen/occ.py +52 -0
  283. netgen/read_gmsh.py +259 -0
  284. netgen/read_meshio.py +22 -0
  285. netgen/stl.py +2 -0
  286. netgen/togl.dll +0 -0
  287. netgen/version.py +2 -0
  288. netgen/webgui.py +529 -0
  289. netgen_mesher-6.2.2506.post35.dev0.data/data/share/netgen/boundarycondition.geo +16 -0
  290. netgen_mesher-6.2.2506.post35.dev0.data/data/share/netgen/boxcyl.geo +32 -0
  291. netgen_mesher-6.2.2506.post35.dev0.data/data/share/netgen/circle_on_cube.geo +27 -0
  292. netgen_mesher-6.2.2506.post35.dev0.data/data/share/netgen/cone.geo +13 -0
  293. netgen_mesher-6.2.2506.post35.dev0.data/data/share/netgen/cube.geo +16 -0
  294. netgen_mesher-6.2.2506.post35.dev0.data/data/share/netgen/cubeandring.geo +55 -0
  295. netgen_mesher-6.2.2506.post35.dev0.data/data/share/netgen/cubeandspheres.geo +21 -0
  296. netgen_mesher-6.2.2506.post35.dev0.data/data/share/netgen/cubemcyl.geo +18 -0
  297. netgen_mesher-6.2.2506.post35.dev0.data/data/share/netgen/cubemsphere.geo +19 -0
  298. netgen_mesher-6.2.2506.post35.dev0.data/data/share/netgen/cylinder.geo +12 -0
  299. netgen_mesher-6.2.2506.post35.dev0.data/data/share/netgen/cylsphere.geo +12 -0
  300. netgen_mesher-6.2.2506.post35.dev0.data/data/share/netgen/doc/ng4.pdf +0 -0
  301. netgen_mesher-6.2.2506.post35.dev0.data/data/share/netgen/ellipsoid.geo +8 -0
  302. netgen_mesher-6.2.2506.post35.dev0.data/data/share/netgen/ellipticcyl.geo +10 -0
  303. netgen_mesher-6.2.2506.post35.dev0.data/data/share/netgen/extrusion.geo +99 -0
  304. netgen_mesher-6.2.2506.post35.dev0.data/data/share/netgen/fichera.geo +24 -0
  305. netgen_mesher-6.2.2506.post35.dev0.data/data/share/netgen/frame.step +11683 -0
  306. netgen_mesher-6.2.2506.post35.dev0.data/data/share/netgen/hinge.stl +8486 -0
  307. netgen_mesher-6.2.2506.post35.dev0.data/data/share/netgen/lshape3d.geo +26 -0
  308. netgen_mesher-6.2.2506.post35.dev0.data/data/share/netgen/manyholes.geo +26 -0
  309. netgen_mesher-6.2.2506.post35.dev0.data/data/share/netgen/manyholes2.geo +26 -0
  310. netgen_mesher-6.2.2506.post35.dev0.data/data/share/netgen/matrix.geo +27 -0
  311. netgen_mesher-6.2.2506.post35.dev0.data/data/share/netgen/ortho.geo +11 -0
  312. netgen_mesher-6.2.2506.post35.dev0.data/data/share/netgen/part1.stl +2662 -0
  313. netgen_mesher-6.2.2506.post35.dev0.data/data/share/netgen/period.geo +33 -0
  314. netgen_mesher-6.2.2506.post35.dev0.data/data/share/netgen/py_tutorials/exportNeutral.py +26 -0
  315. netgen_mesher-6.2.2506.post35.dev0.data/data/share/netgen/py_tutorials/mesh.py +19 -0
  316. netgen_mesher-6.2.2506.post35.dev0.data/data/share/netgen/py_tutorials/shaft.geo +65 -0
  317. netgen_mesher-6.2.2506.post35.dev0.data/data/share/netgen/revolution.geo +18 -0
  318. netgen_mesher-6.2.2506.post35.dev0.data/data/share/netgen/screw.step +1694 -0
  319. netgen_mesher-6.2.2506.post35.dev0.data/data/share/netgen/sculpture.geo +13 -0
  320. netgen_mesher-6.2.2506.post35.dev0.data/data/share/netgen/shaft.geo +65 -0
  321. netgen_mesher-6.2.2506.post35.dev0.data/data/share/netgen/shell.geo +10 -0
  322. netgen_mesher-6.2.2506.post35.dev0.data/data/share/netgen/sphere.geo +8 -0
  323. netgen_mesher-6.2.2506.post35.dev0.data/data/share/netgen/sphereincube.geo +17 -0
  324. netgen_mesher-6.2.2506.post35.dev0.data/data/share/netgen/square.in2d +35 -0
  325. netgen_mesher-6.2.2506.post35.dev0.data/data/share/netgen/squarecircle.in2d +48 -0
  326. netgen_mesher-6.2.2506.post35.dev0.data/data/share/netgen/squarehole.in2d +47 -0
  327. netgen_mesher-6.2.2506.post35.dev0.data/data/share/netgen/torus.geo +8 -0
  328. netgen_mesher-6.2.2506.post35.dev0.data/data/share/netgen/trafo.geo +57 -0
  329. netgen_mesher-6.2.2506.post35.dev0.data/data/share/netgen/twobricks.geo +15 -0
  330. netgen_mesher-6.2.2506.post35.dev0.data/data/share/netgen/twocubes.geo +18 -0
  331. netgen_mesher-6.2.2506.post35.dev0.data/data/share/netgen/twocyl.geo +16 -0
  332. netgen_mesher-6.2.2506.post35.dev0.dist-info/METADATA +15 -0
  333. netgen_mesher-6.2.2506.post35.dev0.dist-info/RECORD +340 -0
  334. netgen_mesher-6.2.2506.post35.dev0.dist-info/WHEEL +5 -0
  335. netgen_mesher-6.2.2506.post35.dev0.dist-info/entry_points.txt +2 -0
  336. netgen_mesher-6.2.2506.post35.dev0.dist-info/licenses/AUTHORS +1 -0
  337. netgen_mesher-6.2.2506.post35.dev0.dist-info/licenses/LICENSE +504 -0
  338. netgen_mesher-6.2.2506.post35.dev0.dist-info/top_level.txt +2 -0
  339. pyngcore/__init__.py +1 -0
  340. 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)