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,3645 @@
|
|
|
1
|
+
/*
|
|
2
|
+
pybind11/pybind11.h: Main header file of the C++11 python
|
|
3
|
+
binding generator library
|
|
4
|
+
|
|
5
|
+
Copyright (c) 2016 Wenzel Jakob <wenzel.jakob@epfl.ch>
|
|
6
|
+
|
|
7
|
+
All rights reserved. Use of this source code is governed by a
|
|
8
|
+
BSD-style license that can be found in the LICENSE file.
|
|
9
|
+
*/
|
|
10
|
+
|
|
11
|
+
#pragma once
|
|
12
|
+
#include "detail/class.h"
|
|
13
|
+
#include "detail/dynamic_raw_ptr_cast_if_possible.h"
|
|
14
|
+
#include "detail/exception_translation.h"
|
|
15
|
+
#include "detail/function_record_pyobject.h"
|
|
16
|
+
#include "detail/init.h"
|
|
17
|
+
#include "detail/native_enum_data.h"
|
|
18
|
+
#include "detail/using_smart_holder.h"
|
|
19
|
+
#include "attr.h"
|
|
20
|
+
#include "gil.h"
|
|
21
|
+
#include "gil_safe_call_once.h"
|
|
22
|
+
#include "options.h"
|
|
23
|
+
#include "trampoline_self_life_support.h"
|
|
24
|
+
#include "typing.h"
|
|
25
|
+
|
|
26
|
+
#include <cassert>
|
|
27
|
+
#include <cstdlib>
|
|
28
|
+
#include <cstring>
|
|
29
|
+
#include <memory>
|
|
30
|
+
#include <new>
|
|
31
|
+
#include <stack>
|
|
32
|
+
#include <string>
|
|
33
|
+
#include <utility>
|
|
34
|
+
#include <vector>
|
|
35
|
+
|
|
36
|
+
// See PR #5448. This warning suppression is needed for the PYBIND11_OVERRIDE macro family.
|
|
37
|
+
// NOTE that this is NOT embedded in a push/pop pair because that is very difficult to achieve.
|
|
38
|
+
#if defined(__clang_major__) && __clang_major__ < 14
|
|
39
|
+
PYBIND11_WARNING_DISABLE_CLANG("-Wgnu-zero-variadic-macro-arguments")
|
|
40
|
+
#endif
|
|
41
|
+
|
|
42
|
+
#if defined(__GNUG__) && !defined(__clang__)
|
|
43
|
+
# include <cxxabi.h>
|
|
44
|
+
#endif
|
|
45
|
+
|
|
46
|
+
PYBIND11_NAMESPACE_BEGIN(PYBIND11_NAMESPACE)
|
|
47
|
+
|
|
48
|
+
/* https://stackoverflow.com/questions/46798456/handling-gccs-noexcept-type-warning
|
|
49
|
+
This warning is about ABI compatibility, not code health.
|
|
50
|
+
It is only actually needed in a couple places, but apparently GCC 7 "generates this warning if
|
|
51
|
+
and only if the first template instantiation ... involves noexcept" [stackoverflow], therefore
|
|
52
|
+
it could get triggered from seemingly random places, depending on user code.
|
|
53
|
+
No other GCC version generates this warning.
|
|
54
|
+
*/
|
|
55
|
+
#if defined(__GNUC__) && __GNUC__ == 7
|
|
56
|
+
PYBIND11_WARNING_DISABLE_GCC("-Wnoexcept-type")
|
|
57
|
+
#endif
|
|
58
|
+
|
|
59
|
+
PYBIND11_WARNING_DISABLE_MSVC(4127)
|
|
60
|
+
|
|
61
|
+
PYBIND11_NAMESPACE_BEGIN(detail)
|
|
62
|
+
|
|
63
|
+
inline std::string replace_newlines_and_squash(const char *text) {
|
|
64
|
+
const char *whitespaces = " \t\n\r\f\v";
|
|
65
|
+
std::string result(text);
|
|
66
|
+
bool previous_is_whitespace = false;
|
|
67
|
+
|
|
68
|
+
if (result.size() >= 2) {
|
|
69
|
+
// Do not modify string representations
|
|
70
|
+
char first_char = result[0];
|
|
71
|
+
char last_char = result[result.size() - 1];
|
|
72
|
+
if (first_char == last_char && first_char == '\'') {
|
|
73
|
+
return result;
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
result.clear();
|
|
77
|
+
|
|
78
|
+
// Replace characters in whitespaces array with spaces and squash consecutive spaces
|
|
79
|
+
while (*text != '\0') {
|
|
80
|
+
if (std::strchr(whitespaces, *text)) {
|
|
81
|
+
if (!previous_is_whitespace) {
|
|
82
|
+
result += ' ';
|
|
83
|
+
previous_is_whitespace = true;
|
|
84
|
+
}
|
|
85
|
+
} else {
|
|
86
|
+
result += *text;
|
|
87
|
+
previous_is_whitespace = false;
|
|
88
|
+
}
|
|
89
|
+
++text;
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
// Strip leading and trailing whitespaces
|
|
93
|
+
const size_t str_begin = result.find_first_not_of(whitespaces);
|
|
94
|
+
if (str_begin == std::string::npos) {
|
|
95
|
+
return "";
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
const size_t str_end = result.find_last_not_of(whitespaces);
|
|
99
|
+
const size_t str_range = str_end - str_begin + 1;
|
|
100
|
+
|
|
101
|
+
return result.substr(str_begin, str_range);
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
/* Generate a proper function signature */
|
|
105
|
+
inline std::string generate_function_signature(const char *type_caster_name_field,
|
|
106
|
+
detail::function_record *func_rec,
|
|
107
|
+
const std::type_info *const *types,
|
|
108
|
+
size_t &type_index,
|
|
109
|
+
size_t &arg_index) {
|
|
110
|
+
std::string signature;
|
|
111
|
+
bool is_starred = false;
|
|
112
|
+
// `is_return_value.top()` is true if we are currently inside the return type of the
|
|
113
|
+
// signature. Using `@^`/`@$` we can force types to be arg/return types while `@!` pops
|
|
114
|
+
// back to the previous state.
|
|
115
|
+
std::stack<bool> is_return_value({false});
|
|
116
|
+
// The following characters have special meaning in the signature parsing. Literals
|
|
117
|
+
// containing these are escaped with `!`.
|
|
118
|
+
std::string special_chars("!@%{}-");
|
|
119
|
+
for (const auto *pc = type_caster_name_field; *pc != '\0'; ++pc) {
|
|
120
|
+
const auto c = *pc;
|
|
121
|
+
if (c == '{') {
|
|
122
|
+
// Write arg name for everything except *args and **kwargs.
|
|
123
|
+
is_starred = *(pc + 1) == '*';
|
|
124
|
+
if (is_starred) {
|
|
125
|
+
continue;
|
|
126
|
+
}
|
|
127
|
+
// Separator for keyword-only arguments, placed before the kw
|
|
128
|
+
// arguments start (unless we are already putting an *args)
|
|
129
|
+
if (!func_rec->has_args && arg_index == func_rec->nargs_pos) {
|
|
130
|
+
signature += "*, ";
|
|
131
|
+
}
|
|
132
|
+
if (arg_index < func_rec->args.size() && func_rec->args[arg_index].name) {
|
|
133
|
+
signature += func_rec->args[arg_index].name;
|
|
134
|
+
} else if (arg_index == 0 && func_rec->is_method) {
|
|
135
|
+
signature += "self";
|
|
136
|
+
} else {
|
|
137
|
+
signature += "arg" + std::to_string(arg_index - (func_rec->is_method ? 1 : 0));
|
|
138
|
+
}
|
|
139
|
+
signature += ": ";
|
|
140
|
+
} else if (c == '}') {
|
|
141
|
+
// Write default value if available.
|
|
142
|
+
if (!is_starred && arg_index < func_rec->args.size()
|
|
143
|
+
&& func_rec->args[arg_index].descr) {
|
|
144
|
+
signature += " = ";
|
|
145
|
+
signature += detail::replace_newlines_and_squash(func_rec->args[arg_index].descr);
|
|
146
|
+
}
|
|
147
|
+
// Separator for positional-only arguments (placed after the
|
|
148
|
+
// argument, rather than before like *
|
|
149
|
+
if (func_rec->nargs_pos_only > 0 && (arg_index + 1) == func_rec->nargs_pos_only) {
|
|
150
|
+
signature += ", /";
|
|
151
|
+
}
|
|
152
|
+
if (!is_starred) {
|
|
153
|
+
arg_index++;
|
|
154
|
+
}
|
|
155
|
+
} else if (c == '%') {
|
|
156
|
+
const std::type_info *t = types[type_index++];
|
|
157
|
+
if (!t) {
|
|
158
|
+
pybind11_fail("Internal error while parsing type signature (1)");
|
|
159
|
+
}
|
|
160
|
+
if (auto *tinfo = detail::get_type_info(*t)) {
|
|
161
|
+
handle th((PyObject *) tinfo->type);
|
|
162
|
+
signature += th.attr("__module__").cast<std::string>() + "."
|
|
163
|
+
+ th.attr("__qualname__").cast<std::string>();
|
|
164
|
+
} else if (auto th = detail::global_internals_native_enum_type_map_get_item(*t)) {
|
|
165
|
+
signature += th.attr("__module__").cast<std::string>() + "."
|
|
166
|
+
+ th.attr("__qualname__").cast<std::string>();
|
|
167
|
+
} else if (func_rec->is_new_style_constructor && arg_index == 0) {
|
|
168
|
+
// A new-style `__init__` takes `self` as `value_and_holder`.
|
|
169
|
+
// Rewrite it to the proper class type.
|
|
170
|
+
signature += func_rec->scope.attr("__module__").cast<std::string>() + "."
|
|
171
|
+
+ func_rec->scope.attr("__qualname__").cast<std::string>();
|
|
172
|
+
} else {
|
|
173
|
+
signature += detail::quote_cpp_type_name(detail::clean_type_id(t->name()));
|
|
174
|
+
}
|
|
175
|
+
} else if (c == '!' && special_chars.find(*(pc + 1)) != std::string::npos) {
|
|
176
|
+
// typing::Literal escapes special characters with !
|
|
177
|
+
signature += *++pc;
|
|
178
|
+
} else if (c == '@') {
|
|
179
|
+
// `@^ ... @!` and `@$ ... @!` are used to force arg/return value type (see
|
|
180
|
+
// typing::Callable/detail::arg_descr/detail::return_descr)
|
|
181
|
+
if (*(pc + 1) == '^') {
|
|
182
|
+
is_return_value.emplace(false);
|
|
183
|
+
++pc;
|
|
184
|
+
continue;
|
|
185
|
+
}
|
|
186
|
+
if (*(pc + 1) == '$') {
|
|
187
|
+
is_return_value.emplace(true);
|
|
188
|
+
++pc;
|
|
189
|
+
continue;
|
|
190
|
+
}
|
|
191
|
+
if (*(pc + 1) == '!') {
|
|
192
|
+
is_return_value.pop();
|
|
193
|
+
++pc;
|
|
194
|
+
continue;
|
|
195
|
+
}
|
|
196
|
+
// Handle types that differ depending on whether they appear
|
|
197
|
+
// in an argument or a return value position (see io_name<text1, text2>).
|
|
198
|
+
// For named arguments (py::arg()) with noconvert set, return value type is used.
|
|
199
|
+
++pc;
|
|
200
|
+
if (!is_return_value.top()
|
|
201
|
+
&& (!(arg_index < func_rec->args.size() && !func_rec->args[arg_index].convert))) {
|
|
202
|
+
while (*pc != '\0' && *pc != '@') {
|
|
203
|
+
signature += *pc++;
|
|
204
|
+
}
|
|
205
|
+
if (*pc == '@') {
|
|
206
|
+
++pc;
|
|
207
|
+
}
|
|
208
|
+
while (*pc != '\0' && *pc != '@') {
|
|
209
|
+
++pc;
|
|
210
|
+
}
|
|
211
|
+
} else {
|
|
212
|
+
while (*pc != '\0' && *pc != '@') {
|
|
213
|
+
++pc;
|
|
214
|
+
}
|
|
215
|
+
if (*pc == '@') {
|
|
216
|
+
++pc;
|
|
217
|
+
}
|
|
218
|
+
while (*pc != '\0' && *pc != '@') {
|
|
219
|
+
signature += *pc++;
|
|
220
|
+
}
|
|
221
|
+
}
|
|
222
|
+
} else {
|
|
223
|
+
if (c == '-' && *(pc + 1) == '>') {
|
|
224
|
+
is_return_value.emplace(true);
|
|
225
|
+
}
|
|
226
|
+
signature += c;
|
|
227
|
+
}
|
|
228
|
+
}
|
|
229
|
+
return signature;
|
|
230
|
+
}
|
|
231
|
+
|
|
232
|
+
template <typename T>
|
|
233
|
+
inline std::string generate_type_signature() {
|
|
234
|
+
static constexpr auto caster_name_field = make_caster<T>::name;
|
|
235
|
+
PYBIND11_DESCR_CONSTEXPR auto descr_types = decltype(caster_name_field)::types();
|
|
236
|
+
// Create a default function_record to ensure the function signature has the proper
|
|
237
|
+
// configuration e.g. no_convert.
|
|
238
|
+
auto func_rec = function_record();
|
|
239
|
+
size_t type_index = 0;
|
|
240
|
+
size_t arg_index = 0;
|
|
241
|
+
return generate_function_signature(
|
|
242
|
+
caster_name_field.text, &func_rec, descr_types.data(), type_index, arg_index);
|
|
243
|
+
}
|
|
244
|
+
|
|
245
|
+
#if defined(_MSC_VER)
|
|
246
|
+
# define PYBIND11_COMPAT_STRDUP _strdup
|
|
247
|
+
#else
|
|
248
|
+
# define PYBIND11_COMPAT_STRDUP strdup
|
|
249
|
+
#endif
|
|
250
|
+
|
|
251
|
+
PYBIND11_NAMESPACE_END(detail)
|
|
252
|
+
|
|
253
|
+
/// Wraps an arbitrary C++ function/method/lambda function/.. into a callable Python object
|
|
254
|
+
class cpp_function : public function {
|
|
255
|
+
public:
|
|
256
|
+
cpp_function() = default;
|
|
257
|
+
// NOLINTNEXTLINE(google-explicit-constructor)
|
|
258
|
+
cpp_function(std::nullptr_t) {}
|
|
259
|
+
cpp_function(std::nullptr_t, const is_setter &) {}
|
|
260
|
+
|
|
261
|
+
/// Construct a cpp_function from a vanilla function pointer
|
|
262
|
+
template <typename Return, typename... Args, typename... Extra>
|
|
263
|
+
// NOLINTNEXTLINE(google-explicit-constructor)
|
|
264
|
+
cpp_function(Return (*f)(Args...), const Extra &...extra) {
|
|
265
|
+
initialize(f, f, extra...);
|
|
266
|
+
}
|
|
267
|
+
|
|
268
|
+
/// Construct a cpp_function from a lambda function (possibly with internal state)
|
|
269
|
+
template <typename Func,
|
|
270
|
+
typename... Extra,
|
|
271
|
+
typename = detail::enable_if_t<detail::is_lambda<Func>::value>>
|
|
272
|
+
// NOLINTNEXTLINE(google-explicit-constructor)
|
|
273
|
+
cpp_function(Func &&f, const Extra &...extra) {
|
|
274
|
+
initialize(
|
|
275
|
+
std::forward<Func>(f), (detail::function_signature_t<Func> *) nullptr, extra...);
|
|
276
|
+
}
|
|
277
|
+
|
|
278
|
+
/// Construct a cpp_function from a class method (non-const, no ref-qualifier)
|
|
279
|
+
template <typename Return, typename Class, typename... Arg, typename... Extra>
|
|
280
|
+
// NOLINTNEXTLINE(google-explicit-constructor)
|
|
281
|
+
cpp_function(Return (Class::*f)(Arg...), const Extra &...extra) {
|
|
282
|
+
initialize(
|
|
283
|
+
[f](Class *c, Arg... args) -> Return { return (c->*f)(std::forward<Arg>(args)...); },
|
|
284
|
+
(Return (*)(Class *, Arg...)) nullptr,
|
|
285
|
+
extra...);
|
|
286
|
+
}
|
|
287
|
+
|
|
288
|
+
/// Construct a cpp_function from a class method (non-const, lvalue ref-qualifier)
|
|
289
|
+
/// A copy of the overload for non-const functions without explicit ref-qualifier
|
|
290
|
+
/// but with an added `&`.
|
|
291
|
+
template <typename Return, typename Class, typename... Arg, typename... Extra>
|
|
292
|
+
// NOLINTNEXTLINE(google-explicit-constructor)
|
|
293
|
+
cpp_function(Return (Class::*f)(Arg...) &, const Extra &...extra) {
|
|
294
|
+
initialize(
|
|
295
|
+
[f](Class *c, Arg... args) -> Return { return (c->*f)(std::forward<Arg>(args)...); },
|
|
296
|
+
(Return (*)(Class *, Arg...)) nullptr,
|
|
297
|
+
extra...);
|
|
298
|
+
}
|
|
299
|
+
|
|
300
|
+
/// Construct a cpp_function from a class method (const, no ref-qualifier)
|
|
301
|
+
template <typename Return, typename Class, typename... Arg, typename... Extra>
|
|
302
|
+
// NOLINTNEXTLINE(google-explicit-constructor)
|
|
303
|
+
cpp_function(Return (Class::*f)(Arg...) const, const Extra &...extra) {
|
|
304
|
+
initialize([f](const Class *c,
|
|
305
|
+
Arg... args) -> Return { return (c->*f)(std::forward<Arg>(args)...); },
|
|
306
|
+
(Return (*)(const Class *, Arg...)) nullptr,
|
|
307
|
+
extra...);
|
|
308
|
+
}
|
|
309
|
+
|
|
310
|
+
/// Construct a cpp_function from a class method (const, lvalue ref-qualifier)
|
|
311
|
+
/// A copy of the overload for const functions without explicit ref-qualifier
|
|
312
|
+
/// but with an added `&`.
|
|
313
|
+
template <typename Return, typename Class, typename... Arg, typename... Extra>
|
|
314
|
+
// NOLINTNEXTLINE(google-explicit-constructor)
|
|
315
|
+
cpp_function(Return (Class::*f)(Arg...) const &, const Extra &...extra) {
|
|
316
|
+
initialize([f](const Class *c,
|
|
317
|
+
Arg... args) -> Return { return (c->*f)(std::forward<Arg>(args)...); },
|
|
318
|
+
(Return (*)(const Class *, Arg...)) nullptr,
|
|
319
|
+
extra...);
|
|
320
|
+
}
|
|
321
|
+
|
|
322
|
+
/// Return the function name
|
|
323
|
+
object name() const { return attr("__name__"); }
|
|
324
|
+
|
|
325
|
+
protected:
|
|
326
|
+
struct InitializingFunctionRecordDeleter {
|
|
327
|
+
// `destruct(function_record, false)`: `initialize_generic` copies strings and
|
|
328
|
+
// takes care of cleaning up in case of exceptions. So pass `false` to `free_strings`.
|
|
329
|
+
void operator()(detail::function_record *rec) { destruct(rec, false); }
|
|
330
|
+
};
|
|
331
|
+
using unique_function_record
|
|
332
|
+
= std::unique_ptr<detail::function_record, InitializingFunctionRecordDeleter>;
|
|
333
|
+
|
|
334
|
+
/// Space optimization: don't inline this frequently instantiated fragment
|
|
335
|
+
PYBIND11_NOINLINE unique_function_record make_function_record() {
|
|
336
|
+
return unique_function_record(new detail::function_record());
|
|
337
|
+
}
|
|
338
|
+
|
|
339
|
+
/// Special internal constructor for functors, lambda functions, etc.
|
|
340
|
+
template <typename Func, typename Return, typename... Args, typename... Extra>
|
|
341
|
+
void initialize(Func &&f, Return (*)(Args...), const Extra &...extra) {
|
|
342
|
+
using namespace detail;
|
|
343
|
+
struct capture {
|
|
344
|
+
remove_reference_t<Func> f;
|
|
345
|
+
|
|
346
|
+
static capture *from_data(void **data) {
|
|
347
|
+
return PYBIND11_STD_LAUNDER(reinterpret_cast<capture *>(data));
|
|
348
|
+
}
|
|
349
|
+
};
|
|
350
|
+
|
|
351
|
+
/* Store the function including any extra state it might have (e.g. a lambda capture
|
|
352
|
+
* object) */
|
|
353
|
+
// The unique_ptr makes sure nothing is leaked in case of an exception.
|
|
354
|
+
auto unique_rec = make_function_record();
|
|
355
|
+
auto *rec = unique_rec.get();
|
|
356
|
+
|
|
357
|
+
/* Store the capture object directly in the function record if there is enough space */
|
|
358
|
+
if (sizeof(capture) <= sizeof(rec->data)) {
|
|
359
|
+
/* Without these pragmas, GCC warns that there might not be
|
|
360
|
+
enough space to use the placement new operator. However, the
|
|
361
|
+
'if' statement above ensures that this is the case. */
|
|
362
|
+
PYBIND11_WARNING_PUSH
|
|
363
|
+
|
|
364
|
+
#if defined(__GNUG__) && __GNUC__ >= 6
|
|
365
|
+
PYBIND11_WARNING_DISABLE_GCC("-Wplacement-new")
|
|
366
|
+
#endif
|
|
367
|
+
|
|
368
|
+
new (capture::from_data(rec->data)) capture{std::forward<Func>(f)};
|
|
369
|
+
|
|
370
|
+
#if !PYBIND11_HAS_STD_LAUNDER
|
|
371
|
+
PYBIND11_WARNING_DISABLE_GCC("-Wstrict-aliasing")
|
|
372
|
+
#endif
|
|
373
|
+
|
|
374
|
+
// UB without std::launder, but without breaking ABI and/or
|
|
375
|
+
// a significant refactoring it's "impossible" to solve.
|
|
376
|
+
if (!std::is_trivially_destructible<capture>::value) {
|
|
377
|
+
rec->free_data = [](function_record *r) {
|
|
378
|
+
auto data = capture::from_data(r->data);
|
|
379
|
+
(void) data; // suppress "unused variable" warnings
|
|
380
|
+
data->~capture();
|
|
381
|
+
};
|
|
382
|
+
}
|
|
383
|
+
PYBIND11_WARNING_POP
|
|
384
|
+
} else {
|
|
385
|
+
rec->data[0] = new capture{std::forward<Func>(f)};
|
|
386
|
+
rec->free_data = [](function_record *r) { delete ((capture *) r->data[0]); };
|
|
387
|
+
}
|
|
388
|
+
|
|
389
|
+
/* Type casters for the function arguments and return value */
|
|
390
|
+
using cast_in = argument_loader<Args...>;
|
|
391
|
+
using cast_out
|
|
392
|
+
= make_caster<conditional_t<std::is_void<Return>::value, void_type, Return>>;
|
|
393
|
+
|
|
394
|
+
static_assert(
|
|
395
|
+
expected_num_args<Extra...>(
|
|
396
|
+
sizeof...(Args), cast_in::args_pos >= 0, cast_in::has_kwargs),
|
|
397
|
+
"The number of argument annotations does not match the number of function arguments");
|
|
398
|
+
|
|
399
|
+
/* Dispatch code which converts function arguments and performs the actual function call */
|
|
400
|
+
rec->impl = [](function_call &call) -> handle {
|
|
401
|
+
cast_in args_converter;
|
|
402
|
+
|
|
403
|
+
/* Try to cast the function arguments into the C++ domain */
|
|
404
|
+
if (!args_converter.load_args(call)) {
|
|
405
|
+
return PYBIND11_TRY_NEXT_OVERLOAD;
|
|
406
|
+
}
|
|
407
|
+
|
|
408
|
+
/* Invoke call policy pre-call hook */
|
|
409
|
+
process_attributes<Extra...>::precall(call);
|
|
410
|
+
|
|
411
|
+
/* Get a pointer to the capture object */
|
|
412
|
+
const auto *data = (sizeof(capture) <= sizeof(call.func.data) ? &call.func.data
|
|
413
|
+
: call.func.data[0]);
|
|
414
|
+
auto *cap = const_cast<capture *>(reinterpret_cast<const capture *>(data));
|
|
415
|
+
|
|
416
|
+
/* Override policy for rvalues -- usually to enforce rvp::move on an rvalue */
|
|
417
|
+
return_value_policy policy
|
|
418
|
+
= return_value_policy_override<Return>::policy(call.func.policy);
|
|
419
|
+
|
|
420
|
+
/* Function scope guard -- defaults to the compile-to-nothing `void_type` */
|
|
421
|
+
using Guard = extract_guard_t<Extra...>;
|
|
422
|
+
|
|
423
|
+
/* Perform the function call */
|
|
424
|
+
handle result;
|
|
425
|
+
if (call.func.is_setter) {
|
|
426
|
+
(void) std::move(args_converter).template call<Return, Guard>(cap->f);
|
|
427
|
+
result = none().release();
|
|
428
|
+
} else {
|
|
429
|
+
result = cast_out::cast(
|
|
430
|
+
std::move(args_converter).template call<Return, Guard>(cap->f),
|
|
431
|
+
policy,
|
|
432
|
+
call.parent);
|
|
433
|
+
}
|
|
434
|
+
|
|
435
|
+
/* Invoke call policy post-call hook */
|
|
436
|
+
process_attributes<Extra...>::postcall(call, result);
|
|
437
|
+
|
|
438
|
+
return result;
|
|
439
|
+
};
|
|
440
|
+
|
|
441
|
+
rec->nargs_pos = cast_in::args_pos >= 0
|
|
442
|
+
? static_cast<std::uint16_t>(cast_in::args_pos)
|
|
443
|
+
: sizeof...(Args) - cast_in::has_kwargs; // Will get reduced more if
|
|
444
|
+
// we have a kw_only
|
|
445
|
+
rec->has_args = cast_in::args_pos >= 0;
|
|
446
|
+
rec->has_kwargs = cast_in::has_kwargs;
|
|
447
|
+
|
|
448
|
+
/* Process any user-provided function attributes */
|
|
449
|
+
process_attributes<Extra...>::init(extra..., rec);
|
|
450
|
+
|
|
451
|
+
{
|
|
452
|
+
constexpr bool has_kw_only_args = any_of<std::is_same<kw_only, Extra>...>::value,
|
|
453
|
+
has_pos_only_args = any_of<std::is_same<pos_only, Extra>...>::value,
|
|
454
|
+
has_arg_annotations = any_of<is_keyword<Extra>...>::value;
|
|
455
|
+
constexpr bool has_is_method = any_of<std::is_same<is_method, Extra>...>::value;
|
|
456
|
+
// The implicit `self` argument is not present and not counted in method definitions.
|
|
457
|
+
constexpr bool has_args = cast_in::args_pos >= 0;
|
|
458
|
+
constexpr bool is_method_with_self_arg_only = has_is_method && !has_args;
|
|
459
|
+
static_assert(has_arg_annotations || !has_kw_only_args,
|
|
460
|
+
"py::kw_only requires the use of argument annotations");
|
|
461
|
+
static_assert(((/* Need `py::arg("arg_name")` annotation in function/method. */
|
|
462
|
+
has_arg_annotations)
|
|
463
|
+
|| (/* Allow methods with no arguments `def method(self, /): ...`.
|
|
464
|
+
* A method has at least one argument `self`. There can be no
|
|
465
|
+
* `py::arg` annotation. E.g. `class.def("method", py::pos_only())`.
|
|
466
|
+
*/
|
|
467
|
+
is_method_with_self_arg_only))
|
|
468
|
+
|| !has_pos_only_args,
|
|
469
|
+
"py::pos_only requires the use of argument annotations (for docstrings "
|
|
470
|
+
"and aligning the annotations to the argument)");
|
|
471
|
+
|
|
472
|
+
static_assert(constexpr_sum(is_kw_only<Extra>::value...) <= 1,
|
|
473
|
+
"py::kw_only may be specified only once");
|
|
474
|
+
static_assert(constexpr_sum(is_pos_only<Extra>::value...) <= 1,
|
|
475
|
+
"py::pos_only may be specified only once");
|
|
476
|
+
constexpr auto kw_only_pos = constexpr_first<is_kw_only, Extra...>();
|
|
477
|
+
constexpr auto pos_only_pos = constexpr_first<is_pos_only, Extra...>();
|
|
478
|
+
static_assert(!(has_kw_only_args && has_pos_only_args) || pos_only_pos < kw_only_pos,
|
|
479
|
+
"py::pos_only must come before py::kw_only");
|
|
480
|
+
}
|
|
481
|
+
|
|
482
|
+
/* Generate a readable signature describing the function's arguments and return
|
|
483
|
+
value types */
|
|
484
|
+
static constexpr auto signature
|
|
485
|
+
= const_name("(") + cast_in::arg_names + const_name(") -> ") + cast_out::name;
|
|
486
|
+
PYBIND11_DESCR_CONSTEXPR auto types = decltype(signature)::types();
|
|
487
|
+
|
|
488
|
+
/* Register the function with Python from generic (non-templated) code */
|
|
489
|
+
// Pass on the ownership over the `unique_rec` to `initialize_generic`. `rec` stays valid.
|
|
490
|
+
initialize_generic(std::move(unique_rec), signature.text, types.data(), sizeof...(Args));
|
|
491
|
+
|
|
492
|
+
/* Stash some additional information used by an important optimization in 'functional.h' */
|
|
493
|
+
using FunctionType = Return (*)(Args...);
|
|
494
|
+
constexpr bool is_function_ptr
|
|
495
|
+
= std::is_convertible<Func, FunctionType>::value && sizeof(capture) == sizeof(void *);
|
|
496
|
+
PYBIND11_ENSURE_PRECONDITION_FOR_FUNCTIONAL_H_PERFORMANCE_OPTIMIZATIONS(
|
|
497
|
+
!is_function_ptr || std::is_standard_layout<capture>::value);
|
|
498
|
+
if (is_function_ptr) {
|
|
499
|
+
rec->is_stateless = true;
|
|
500
|
+
rec->data[1]
|
|
501
|
+
= const_cast<void *>(reinterpret_cast<const void *>(&typeid(FunctionType)));
|
|
502
|
+
}
|
|
503
|
+
}
|
|
504
|
+
|
|
505
|
+
// Utility class that keeps track of all duplicated strings, and cleans them up in its
|
|
506
|
+
// destructor, unless they are released. Basically a RAII-solution to deal with exceptions
|
|
507
|
+
// along the way.
|
|
508
|
+
class strdup_guard {
|
|
509
|
+
public:
|
|
510
|
+
strdup_guard() = default;
|
|
511
|
+
strdup_guard(const strdup_guard &) = delete;
|
|
512
|
+
strdup_guard &operator=(const strdup_guard &) = delete;
|
|
513
|
+
|
|
514
|
+
~strdup_guard() {
|
|
515
|
+
for (auto *s : strings) {
|
|
516
|
+
std::free(s);
|
|
517
|
+
}
|
|
518
|
+
}
|
|
519
|
+
char *operator()(const char *s) {
|
|
520
|
+
auto *t = PYBIND11_COMPAT_STRDUP(s);
|
|
521
|
+
strings.push_back(t);
|
|
522
|
+
return t;
|
|
523
|
+
}
|
|
524
|
+
void release() { strings.clear(); }
|
|
525
|
+
|
|
526
|
+
private:
|
|
527
|
+
std::vector<char *> strings;
|
|
528
|
+
};
|
|
529
|
+
|
|
530
|
+
/// Register a function call with Python (generic non-templated code goes here)
|
|
531
|
+
void initialize_generic(unique_function_record &&unique_rec,
|
|
532
|
+
const char *text,
|
|
533
|
+
const std::type_info *const *types,
|
|
534
|
+
size_t args) {
|
|
535
|
+
// Do NOT receive `unique_rec` by value. If this function fails to move out the unique_ptr,
|
|
536
|
+
// we do not want this to destruct the pointer. `initialize` (the caller) still relies on
|
|
537
|
+
// the pointee being alive after this call. Only move out if a `capsule` is going to keep
|
|
538
|
+
// it alive.
|
|
539
|
+
auto *rec = unique_rec.get();
|
|
540
|
+
|
|
541
|
+
// Keep track of strdup'ed strings, and clean them up as long as the function's capsule
|
|
542
|
+
// has not taken ownership yet (when `unique_rec.release()` is called).
|
|
543
|
+
// Note: This cannot easily be fixed by a `unique_ptr` with custom deleter, because the
|
|
544
|
+
// strings are only referenced before strdup'ing. So only *after* the following block could
|
|
545
|
+
// `destruct` safely be called, but even then, `repr` could still throw in the middle of
|
|
546
|
+
// copying all strings.
|
|
547
|
+
strdup_guard guarded_strdup;
|
|
548
|
+
|
|
549
|
+
/* Create copies of all referenced C-style strings */
|
|
550
|
+
rec->name = guarded_strdup(rec->name ? rec->name : "");
|
|
551
|
+
if (rec->doc) {
|
|
552
|
+
rec->doc = guarded_strdup(rec->doc);
|
|
553
|
+
}
|
|
554
|
+
for (auto &a : rec->args) {
|
|
555
|
+
if (a.name) {
|
|
556
|
+
a.name = guarded_strdup(a.name);
|
|
557
|
+
}
|
|
558
|
+
if (a.descr) {
|
|
559
|
+
a.descr = guarded_strdup(a.descr);
|
|
560
|
+
} else if (a.value) {
|
|
561
|
+
a.descr = guarded_strdup(repr(a.value).cast<std::string>().c_str());
|
|
562
|
+
}
|
|
563
|
+
}
|
|
564
|
+
|
|
565
|
+
rec->is_constructor = (std::strcmp(rec->name, "__init__") == 0)
|
|
566
|
+
|| (std::strcmp(rec->name, "__setstate__") == 0);
|
|
567
|
+
|
|
568
|
+
#if defined(PYBIND11_DETAILED_ERROR_MESSAGES) && !defined(PYBIND11_DISABLE_NEW_STYLE_INIT_WARNING)
|
|
569
|
+
if (rec->is_constructor && !rec->is_new_style_constructor) {
|
|
570
|
+
const auto class_name
|
|
571
|
+
= detail::get_fully_qualified_tp_name((PyTypeObject *) rec->scope.ptr());
|
|
572
|
+
const auto func_name = std::string(rec->name);
|
|
573
|
+
PyErr_WarnEx(PyExc_FutureWarning,
|
|
574
|
+
("pybind11-bound class '" + class_name
|
|
575
|
+
+ "' is using an old-style "
|
|
576
|
+
"placement-new '"
|
|
577
|
+
+ func_name
|
|
578
|
+
+ "' which has been deprecated. See "
|
|
579
|
+
"the upgrade guide in pybind11's docs. This message is only visible "
|
|
580
|
+
"when compiled in debug mode.")
|
|
581
|
+
.c_str(),
|
|
582
|
+
0);
|
|
583
|
+
}
|
|
584
|
+
#endif
|
|
585
|
+
|
|
586
|
+
size_t type_index = 0, arg_index = 0;
|
|
587
|
+
std::string signature
|
|
588
|
+
= detail::generate_function_signature(text, rec, types, type_index, arg_index);
|
|
589
|
+
|
|
590
|
+
if (arg_index != args - rec->has_args - rec->has_kwargs || types[type_index] != nullptr) {
|
|
591
|
+
pybind11_fail("Internal error while parsing type signature (2)");
|
|
592
|
+
}
|
|
593
|
+
|
|
594
|
+
rec->signature = guarded_strdup(signature.c_str());
|
|
595
|
+
rec->args.shrink_to_fit();
|
|
596
|
+
rec->nargs = (std::uint16_t) args;
|
|
597
|
+
|
|
598
|
+
if (rec->sibling && PYBIND11_INSTANCE_METHOD_CHECK(rec->sibling.ptr())) {
|
|
599
|
+
rec->sibling = PYBIND11_INSTANCE_METHOD_GET_FUNCTION(rec->sibling.ptr());
|
|
600
|
+
}
|
|
601
|
+
|
|
602
|
+
detail::function_record *chain = nullptr, *chain_start = rec;
|
|
603
|
+
if (rec->sibling) {
|
|
604
|
+
if (PyCFunction_Check(rec->sibling.ptr())) {
|
|
605
|
+
auto *self = PyCFunction_GET_SELF(rec->sibling.ptr());
|
|
606
|
+
if (self == nullptr) {
|
|
607
|
+
pybind11_fail(
|
|
608
|
+
"initialize_generic: Unexpected nullptr from PyCFunction_GET_SELF");
|
|
609
|
+
}
|
|
610
|
+
chain = detail::function_record_ptr_from_PyObject(self);
|
|
611
|
+
if (chain && !chain->scope.is(rec->scope)) {
|
|
612
|
+
/* Never append a method to an overload chain of a parent class;
|
|
613
|
+
instead, hide the parent's overloads in this case */
|
|
614
|
+
chain = nullptr;
|
|
615
|
+
}
|
|
616
|
+
}
|
|
617
|
+
// Don't trigger for things like the default __init__, which are wrapper_descriptors
|
|
618
|
+
// that we are intentionally replacing
|
|
619
|
+
else if (!rec->sibling.is_none() && rec->name[0] != '_') {
|
|
620
|
+
pybind11_fail("Cannot overload existing non-function object \""
|
|
621
|
+
+ std::string(rec->name) + "\" with a function of the same name");
|
|
622
|
+
}
|
|
623
|
+
}
|
|
624
|
+
|
|
625
|
+
if (!chain) {
|
|
626
|
+
/* No existing overload was found, create a new function object */
|
|
627
|
+
rec->def = new PyMethodDef();
|
|
628
|
+
std::memset(rec->def, 0, sizeof(PyMethodDef));
|
|
629
|
+
rec->def->ml_name = rec->name;
|
|
630
|
+
rec->def->ml_meth
|
|
631
|
+
= reinterpret_cast<PyCFunction>(reinterpret_cast<void (*)()>(dispatcher));
|
|
632
|
+
rec->def->ml_flags = METH_VARARGS | METH_KEYWORDS;
|
|
633
|
+
|
|
634
|
+
object py_func_rec = detail::function_record_PyObject_New();
|
|
635
|
+
((detail::function_record_PyObject *) py_func_rec.ptr())->cpp_func_rec
|
|
636
|
+
= unique_rec.release();
|
|
637
|
+
guarded_strdup.release();
|
|
638
|
+
|
|
639
|
+
object scope_module = detail::get_scope_module(rec->scope);
|
|
640
|
+
m_ptr = PyCFunction_NewEx(rec->def, py_func_rec.ptr(), scope_module.ptr());
|
|
641
|
+
if (!m_ptr) {
|
|
642
|
+
pybind11_fail("cpp_function::cpp_function(): Could not allocate function object");
|
|
643
|
+
}
|
|
644
|
+
} else {
|
|
645
|
+
/* Append at the beginning or end of the overload chain */
|
|
646
|
+
m_ptr = rec->sibling.ptr();
|
|
647
|
+
inc_ref();
|
|
648
|
+
if (chain->is_method != rec->is_method) {
|
|
649
|
+
pybind11_fail(
|
|
650
|
+
"overloading a method with both static and instance methods is not supported; "
|
|
651
|
+
#if !defined(PYBIND11_DETAILED_ERROR_MESSAGES)
|
|
652
|
+
"#define PYBIND11_DETAILED_ERROR_MESSAGES or compile in debug mode for more "
|
|
653
|
+
"details"
|
|
654
|
+
#else
|
|
655
|
+
"error while attempting to bind "
|
|
656
|
+
+ std::string(rec->is_method ? "instance" : "static") + " method "
|
|
657
|
+
+ std::string(pybind11::str(rec->scope.attr("__name__"))) + "."
|
|
658
|
+
+ std::string(rec->name) + signature
|
|
659
|
+
#endif
|
|
660
|
+
);
|
|
661
|
+
}
|
|
662
|
+
|
|
663
|
+
if (rec->prepend) {
|
|
664
|
+
// Beginning of chain; we need to replace the capsule's current head-of-the-chain
|
|
665
|
+
// pointer with this one, then make this one point to the previous head of the
|
|
666
|
+
// chain.
|
|
667
|
+
chain_start = rec;
|
|
668
|
+
rec->next = chain;
|
|
669
|
+
auto *py_func_rec
|
|
670
|
+
= (detail::function_record_PyObject *) PyCFunction_GET_SELF(m_ptr);
|
|
671
|
+
py_func_rec->cpp_func_rec = unique_rec.release();
|
|
672
|
+
guarded_strdup.release();
|
|
673
|
+
} else {
|
|
674
|
+
// Or end of chain (normal behavior)
|
|
675
|
+
chain_start = chain;
|
|
676
|
+
while (chain->next) {
|
|
677
|
+
chain = chain->next;
|
|
678
|
+
}
|
|
679
|
+
chain->next = unique_rec.release();
|
|
680
|
+
guarded_strdup.release();
|
|
681
|
+
}
|
|
682
|
+
}
|
|
683
|
+
|
|
684
|
+
std::string signatures;
|
|
685
|
+
int index = 0;
|
|
686
|
+
/* Create a nice pydoc rec including all signatures and
|
|
687
|
+
docstrings of the functions in the overload chain */
|
|
688
|
+
if (chain && options::show_function_signatures()
|
|
689
|
+
&& std::strcmp(rec->name, "_pybind11_conduit_v1_") != 0) {
|
|
690
|
+
// First a generic signature
|
|
691
|
+
signatures += rec->name;
|
|
692
|
+
signatures += "(*args, **kwargs)\n";
|
|
693
|
+
signatures += "Overloaded function.\n\n";
|
|
694
|
+
}
|
|
695
|
+
// Then specific overload signatures
|
|
696
|
+
bool first_user_def = true;
|
|
697
|
+
for (auto *it = chain_start; it != nullptr; it = it->next) {
|
|
698
|
+
if (options::show_function_signatures()
|
|
699
|
+
&& std::strcmp(rec->name, "_pybind11_conduit_v1_") != 0) {
|
|
700
|
+
if (index > 0) {
|
|
701
|
+
signatures += '\n';
|
|
702
|
+
}
|
|
703
|
+
if (chain) {
|
|
704
|
+
signatures += std::to_string(++index) + ". ";
|
|
705
|
+
}
|
|
706
|
+
signatures += rec->name;
|
|
707
|
+
signatures += it->signature;
|
|
708
|
+
signatures += '\n';
|
|
709
|
+
}
|
|
710
|
+
if (it->doc && it->doc[0] != '\0' && options::show_user_defined_docstrings()) {
|
|
711
|
+
// If we're appending another docstring, and aren't printing function signatures,
|
|
712
|
+
// we need to append a newline first:
|
|
713
|
+
if (!options::show_function_signatures()) {
|
|
714
|
+
if (first_user_def) {
|
|
715
|
+
first_user_def = false;
|
|
716
|
+
} else {
|
|
717
|
+
signatures += '\n';
|
|
718
|
+
}
|
|
719
|
+
}
|
|
720
|
+
if (options::show_function_signatures()) {
|
|
721
|
+
signatures += '\n';
|
|
722
|
+
}
|
|
723
|
+
signatures += it->doc;
|
|
724
|
+
if (options::show_function_signatures()) {
|
|
725
|
+
signatures += '\n';
|
|
726
|
+
}
|
|
727
|
+
}
|
|
728
|
+
}
|
|
729
|
+
|
|
730
|
+
auto *func = (PyCFunctionObject *) m_ptr;
|
|
731
|
+
// Install docstring if it's non-empty (when at least one option is enabled)
|
|
732
|
+
auto *doc = signatures.empty() ? nullptr : PYBIND11_COMPAT_STRDUP(signatures.c_str());
|
|
733
|
+
std::free(const_cast<char *>(PYBIND11_PYCFUNCTION_GET_DOC(func)));
|
|
734
|
+
PYBIND11_PYCFUNCTION_SET_DOC(func, doc);
|
|
735
|
+
|
|
736
|
+
if (rec->is_method) {
|
|
737
|
+
m_ptr = PYBIND11_INSTANCE_METHOD_NEW(m_ptr, rec->scope.ptr());
|
|
738
|
+
if (!m_ptr) {
|
|
739
|
+
pybind11_fail(
|
|
740
|
+
"cpp_function::cpp_function(): Could not allocate instance method object");
|
|
741
|
+
}
|
|
742
|
+
Py_DECREF(func);
|
|
743
|
+
}
|
|
744
|
+
}
|
|
745
|
+
|
|
746
|
+
friend void detail::function_record_PyTypeObject_methods::tp_dealloc_impl(PyObject *);
|
|
747
|
+
|
|
748
|
+
/// When a cpp_function is GCed, release any memory allocated by pybind11
|
|
749
|
+
static void destruct(detail::function_record *rec, bool free_strings = true) {
|
|
750
|
+
// If on Python 3.9, check the interpreter "MICRO" (patch) version.
|
|
751
|
+
// If this is running on 3.9.0, we have to work around a bug.
|
|
752
|
+
#if !defined(PYPY_VERSION) && PY_MAJOR_VERSION == 3 && PY_MINOR_VERSION == 9
|
|
753
|
+
static bool is_zero = Py_GetVersion()[4] == '0';
|
|
754
|
+
#endif
|
|
755
|
+
|
|
756
|
+
while (rec) {
|
|
757
|
+
detail::function_record *next = rec->next;
|
|
758
|
+
if (rec->free_data) {
|
|
759
|
+
rec->free_data(rec);
|
|
760
|
+
}
|
|
761
|
+
// During initialization, these strings might not have been copied yet,
|
|
762
|
+
// so they cannot be freed. Once the function has been created, they can.
|
|
763
|
+
// Check `make_function_record` for more details.
|
|
764
|
+
if (free_strings) {
|
|
765
|
+
std::free((char *) rec->name);
|
|
766
|
+
std::free((char *) rec->doc);
|
|
767
|
+
std::free((char *) rec->signature);
|
|
768
|
+
for (auto &arg : rec->args) {
|
|
769
|
+
std::free(const_cast<char *>(arg.name));
|
|
770
|
+
std::free(const_cast<char *>(arg.descr));
|
|
771
|
+
}
|
|
772
|
+
}
|
|
773
|
+
for (auto &arg : rec->args) {
|
|
774
|
+
arg.value.dec_ref();
|
|
775
|
+
}
|
|
776
|
+
if (rec->def) {
|
|
777
|
+
std::free(const_cast<char *>(rec->def->ml_doc));
|
|
778
|
+
// Python 3.9.0 decref's these in the wrong order; rec->def
|
|
779
|
+
// If loaded on 3.9.0, let these leak (use Python 3.9.1 at runtime to fix)
|
|
780
|
+
// See https://github.com/python/cpython/pull/22670
|
|
781
|
+
#if !defined(PYPY_VERSION) && PY_MAJOR_VERSION == 3 && PY_MINOR_VERSION == 9
|
|
782
|
+
if (!is_zero) {
|
|
783
|
+
delete rec->def;
|
|
784
|
+
}
|
|
785
|
+
#else
|
|
786
|
+
delete rec->def;
|
|
787
|
+
#endif
|
|
788
|
+
}
|
|
789
|
+
delete rec;
|
|
790
|
+
rec = next;
|
|
791
|
+
}
|
|
792
|
+
}
|
|
793
|
+
|
|
794
|
+
/// Main dispatch logic for calls to functions bound using pybind11
|
|
795
|
+
static PyObject *dispatcher(PyObject *self, PyObject *args_in, PyObject *kwargs_in) {
|
|
796
|
+
using namespace detail;
|
|
797
|
+
const function_record *overloads = function_record_ptr_from_PyObject(self);
|
|
798
|
+
assert(overloads != nullptr);
|
|
799
|
+
|
|
800
|
+
/* Iterator over the list of potentially admissible overloads */
|
|
801
|
+
const function_record *current_overload = overloads;
|
|
802
|
+
|
|
803
|
+
/* Need to know how many arguments + keyword arguments there are to pick the right
|
|
804
|
+
overload */
|
|
805
|
+
const auto n_args_in = (size_t) PyTuple_GET_SIZE(args_in);
|
|
806
|
+
|
|
807
|
+
handle parent = n_args_in > 0 ? PyTuple_GET_ITEM(args_in, 0) : nullptr,
|
|
808
|
+
result = PYBIND11_TRY_NEXT_OVERLOAD;
|
|
809
|
+
|
|
810
|
+
auto self_value_and_holder = value_and_holder();
|
|
811
|
+
if (overloads->is_constructor) {
|
|
812
|
+
if (!parent
|
|
813
|
+
|| !PyObject_TypeCheck(parent.ptr(), (PyTypeObject *) overloads->scope.ptr())) {
|
|
814
|
+
set_error(PyExc_TypeError,
|
|
815
|
+
"__init__(self, ...) called with invalid or missing `self` argument");
|
|
816
|
+
return nullptr;
|
|
817
|
+
}
|
|
818
|
+
|
|
819
|
+
auto *const tinfo = get_type_info((PyTypeObject *) overloads->scope.ptr());
|
|
820
|
+
auto *const pi = reinterpret_cast<instance *>(parent.ptr());
|
|
821
|
+
self_value_and_holder = pi->get_value_and_holder(tinfo, true);
|
|
822
|
+
|
|
823
|
+
// If this value is already registered it must mean __init__ is invoked multiple times;
|
|
824
|
+
// we really can't support that in C++, so just ignore the second __init__.
|
|
825
|
+
if (self_value_and_holder.instance_registered()) {
|
|
826
|
+
return none().release().ptr();
|
|
827
|
+
}
|
|
828
|
+
}
|
|
829
|
+
|
|
830
|
+
try {
|
|
831
|
+
// We do this in two passes: in the first pass, we load arguments with `convert=false`;
|
|
832
|
+
// in the second, we allow conversion (except for arguments with an explicit
|
|
833
|
+
// py::arg().noconvert()). This lets us prefer calls without conversion, with
|
|
834
|
+
// conversion as a fallback.
|
|
835
|
+
std::vector<function_call> second_pass;
|
|
836
|
+
|
|
837
|
+
// However, if there are no overloads, we can just skip the no-convert pass entirely
|
|
838
|
+
const bool overloaded
|
|
839
|
+
= current_overload != nullptr && current_overload->next != nullptr;
|
|
840
|
+
|
|
841
|
+
for (; current_overload != nullptr; current_overload = current_overload->next) {
|
|
842
|
+
|
|
843
|
+
/* For each overload:
|
|
844
|
+
1. Copy all positional arguments we were given, also checking to make sure that
|
|
845
|
+
named positional arguments weren't *also* specified via kwarg.
|
|
846
|
+
2. If we weren't given enough, try to make up the omitted ones by checking
|
|
847
|
+
whether they were provided by a kwarg matching the `py::arg("name")` name. If
|
|
848
|
+
so, use it (and remove it from kwargs); if not, see if the function binding
|
|
849
|
+
provided a default that we can use.
|
|
850
|
+
3. Ensure that either all keyword arguments were "consumed", or that the
|
|
851
|
+
function takes a kwargs argument to accept unconsumed kwargs.
|
|
852
|
+
4. Any positional arguments still left get put into a tuple (for args), and any
|
|
853
|
+
leftover kwargs get put into a dict.
|
|
854
|
+
5. Pack everything into a vector; if we have py::args or py::kwargs, they are an
|
|
855
|
+
extra tuple or dict at the end of the positional arguments.
|
|
856
|
+
6. Call the function call dispatcher (function_record::impl)
|
|
857
|
+
|
|
858
|
+
If one of these fail, move on to the next overload and keep trying until we get
|
|
859
|
+
a result other than PYBIND11_TRY_NEXT_OVERLOAD.
|
|
860
|
+
*/
|
|
861
|
+
|
|
862
|
+
const function_record &func = *current_overload;
|
|
863
|
+
size_t num_args = func.nargs; // Number of positional arguments that we need
|
|
864
|
+
if (func.has_args) {
|
|
865
|
+
--num_args; // (but don't count py::args
|
|
866
|
+
}
|
|
867
|
+
if (func.has_kwargs) {
|
|
868
|
+
--num_args; // or py::kwargs)
|
|
869
|
+
}
|
|
870
|
+
size_t pos_args = func.nargs_pos;
|
|
871
|
+
|
|
872
|
+
if (!func.has_args && n_args_in > pos_args) {
|
|
873
|
+
continue; // Too many positional arguments for this overload
|
|
874
|
+
}
|
|
875
|
+
|
|
876
|
+
if (n_args_in < pos_args && func.args.size() < pos_args) {
|
|
877
|
+
continue; // Not enough positional arguments given, and not enough defaults to
|
|
878
|
+
// fill in the blanks
|
|
879
|
+
}
|
|
880
|
+
|
|
881
|
+
function_call call(func, parent);
|
|
882
|
+
|
|
883
|
+
// Protect std::min with parentheses
|
|
884
|
+
size_t args_to_copy = (std::min) (pos_args, n_args_in);
|
|
885
|
+
size_t args_copied = 0;
|
|
886
|
+
|
|
887
|
+
// 0. Inject new-style `self` argument
|
|
888
|
+
if (func.is_new_style_constructor) {
|
|
889
|
+
// The `value` may have been preallocated by an old-style `__init__`
|
|
890
|
+
// if it was a preceding candidate for overload resolution.
|
|
891
|
+
if (self_value_and_holder) {
|
|
892
|
+
self_value_and_holder.type->dealloc(self_value_and_holder);
|
|
893
|
+
}
|
|
894
|
+
|
|
895
|
+
call.init_self = PyTuple_GET_ITEM(args_in, 0);
|
|
896
|
+
call.args.emplace_back(reinterpret_cast<PyObject *>(&self_value_and_holder));
|
|
897
|
+
call.args_convert.push_back(false);
|
|
898
|
+
++args_copied;
|
|
899
|
+
}
|
|
900
|
+
|
|
901
|
+
// 1. Copy any position arguments given.
|
|
902
|
+
bool bad_arg = false;
|
|
903
|
+
for (; args_copied < args_to_copy; ++args_copied) {
|
|
904
|
+
const argument_record *arg_rec
|
|
905
|
+
= args_copied < func.args.size() ? &func.args[args_copied] : nullptr;
|
|
906
|
+
if (kwargs_in && arg_rec && arg_rec->name
|
|
907
|
+
&& dict_getitemstring(kwargs_in, arg_rec->name)) {
|
|
908
|
+
bad_arg = true;
|
|
909
|
+
break;
|
|
910
|
+
}
|
|
911
|
+
|
|
912
|
+
handle arg(PyTuple_GET_ITEM(args_in, args_copied));
|
|
913
|
+
if (arg_rec && !arg_rec->none && arg.is_none()) {
|
|
914
|
+
bad_arg = true;
|
|
915
|
+
break;
|
|
916
|
+
}
|
|
917
|
+
call.args.push_back(arg);
|
|
918
|
+
call.args_convert.push_back(arg_rec ? arg_rec->convert : true);
|
|
919
|
+
}
|
|
920
|
+
if (bad_arg) {
|
|
921
|
+
continue; // Maybe it was meant for another overload (issue #688)
|
|
922
|
+
}
|
|
923
|
+
|
|
924
|
+
// Keep track of how many position args we copied out in case we need to come back
|
|
925
|
+
// to copy the rest into a py::args argument.
|
|
926
|
+
size_t positional_args_copied = args_copied;
|
|
927
|
+
|
|
928
|
+
// We'll need to copy this if we steal some kwargs for defaults
|
|
929
|
+
dict kwargs = reinterpret_borrow<dict>(kwargs_in);
|
|
930
|
+
|
|
931
|
+
// 1.5. Fill in any missing pos_only args from defaults if they exist
|
|
932
|
+
if (args_copied < func.nargs_pos_only) {
|
|
933
|
+
for (; args_copied < func.nargs_pos_only; ++args_copied) {
|
|
934
|
+
const auto &arg_rec = func.args[args_copied];
|
|
935
|
+
handle value;
|
|
936
|
+
|
|
937
|
+
if (arg_rec.value) {
|
|
938
|
+
value = arg_rec.value;
|
|
939
|
+
}
|
|
940
|
+
if (value) {
|
|
941
|
+
call.args.push_back(value);
|
|
942
|
+
call.args_convert.push_back(arg_rec.convert);
|
|
943
|
+
} else {
|
|
944
|
+
break;
|
|
945
|
+
}
|
|
946
|
+
}
|
|
947
|
+
|
|
948
|
+
if (args_copied < func.nargs_pos_only) {
|
|
949
|
+
continue; // Not enough defaults to fill the positional arguments
|
|
950
|
+
}
|
|
951
|
+
}
|
|
952
|
+
|
|
953
|
+
// 2. Check kwargs and, failing that, defaults that may help complete the list
|
|
954
|
+
if (args_copied < num_args) {
|
|
955
|
+
bool copied_kwargs = false;
|
|
956
|
+
|
|
957
|
+
for (; args_copied < num_args; ++args_copied) {
|
|
958
|
+
const auto &arg_rec = func.args[args_copied];
|
|
959
|
+
|
|
960
|
+
handle value;
|
|
961
|
+
if (kwargs_in && arg_rec.name) {
|
|
962
|
+
value = dict_getitemstring(kwargs.ptr(), arg_rec.name);
|
|
963
|
+
}
|
|
964
|
+
|
|
965
|
+
if (value) {
|
|
966
|
+
// Consume a kwargs value
|
|
967
|
+
if (!copied_kwargs) {
|
|
968
|
+
kwargs = reinterpret_steal<dict>(PyDict_Copy(kwargs.ptr()));
|
|
969
|
+
copied_kwargs = true;
|
|
970
|
+
}
|
|
971
|
+
if (PyDict_DelItemString(kwargs.ptr(), arg_rec.name) == -1) {
|
|
972
|
+
throw error_already_set();
|
|
973
|
+
}
|
|
974
|
+
} else if (arg_rec.value) {
|
|
975
|
+
value = arg_rec.value;
|
|
976
|
+
}
|
|
977
|
+
|
|
978
|
+
if (!arg_rec.none && value.is_none()) {
|
|
979
|
+
break;
|
|
980
|
+
}
|
|
981
|
+
|
|
982
|
+
if (value) {
|
|
983
|
+
// If we're at the py::args index then first insert a stub for it to be
|
|
984
|
+
// replaced later
|
|
985
|
+
if (func.has_args && call.args.size() == func.nargs_pos) {
|
|
986
|
+
call.args.push_back(none());
|
|
987
|
+
}
|
|
988
|
+
|
|
989
|
+
call.args.push_back(value);
|
|
990
|
+
call.args_convert.push_back(arg_rec.convert);
|
|
991
|
+
} else {
|
|
992
|
+
break;
|
|
993
|
+
}
|
|
994
|
+
}
|
|
995
|
+
|
|
996
|
+
if (args_copied < num_args) {
|
|
997
|
+
continue; // Not enough arguments, defaults, or kwargs to fill the
|
|
998
|
+
// positional arguments
|
|
999
|
+
}
|
|
1000
|
+
}
|
|
1001
|
+
|
|
1002
|
+
// 3. Check everything was consumed (unless we have a kwargs arg)
|
|
1003
|
+
if (kwargs && !kwargs.empty() && !func.has_kwargs) {
|
|
1004
|
+
continue; // Unconsumed kwargs, but no py::kwargs argument to accept them
|
|
1005
|
+
}
|
|
1006
|
+
|
|
1007
|
+
// 4a. If we have a py::args argument, create a new tuple with leftovers
|
|
1008
|
+
if (func.has_args) {
|
|
1009
|
+
tuple extra_args;
|
|
1010
|
+
if (args_to_copy == 0) {
|
|
1011
|
+
// We didn't copy out any position arguments from the args_in tuple, so we
|
|
1012
|
+
// can reuse it directly without copying:
|
|
1013
|
+
extra_args = reinterpret_borrow<tuple>(args_in);
|
|
1014
|
+
} else if (positional_args_copied >= n_args_in) {
|
|
1015
|
+
extra_args = tuple(0);
|
|
1016
|
+
} else {
|
|
1017
|
+
size_t args_size = n_args_in - positional_args_copied;
|
|
1018
|
+
extra_args = tuple(args_size);
|
|
1019
|
+
for (size_t i = 0; i < args_size; ++i) {
|
|
1020
|
+
extra_args[i] = PyTuple_GET_ITEM(args_in, positional_args_copied + i);
|
|
1021
|
+
}
|
|
1022
|
+
}
|
|
1023
|
+
if (call.args.size() <= func.nargs_pos) {
|
|
1024
|
+
call.args.push_back(extra_args);
|
|
1025
|
+
} else {
|
|
1026
|
+
call.args[func.nargs_pos] = extra_args;
|
|
1027
|
+
}
|
|
1028
|
+
call.args_convert.push_back(false);
|
|
1029
|
+
call.args_ref = std::move(extra_args);
|
|
1030
|
+
}
|
|
1031
|
+
|
|
1032
|
+
// 4b. If we have a py::kwargs, pass on any remaining kwargs
|
|
1033
|
+
if (func.has_kwargs) {
|
|
1034
|
+
if (!kwargs.ptr()) {
|
|
1035
|
+
kwargs = dict(); // If we didn't get one, send an empty one
|
|
1036
|
+
}
|
|
1037
|
+
call.args.push_back(kwargs);
|
|
1038
|
+
call.args_convert.push_back(false);
|
|
1039
|
+
call.kwargs_ref = std::move(kwargs);
|
|
1040
|
+
}
|
|
1041
|
+
|
|
1042
|
+
// 5. Put everything in a vector. Not technically step 5, we've been building it
|
|
1043
|
+
// in `call.args` all along.
|
|
1044
|
+
#if defined(PYBIND11_DETAILED_ERROR_MESSAGES)
|
|
1045
|
+
if (call.args.size() != func.nargs || call.args_convert.size() != func.nargs) {
|
|
1046
|
+
pybind11_fail("Internal error: function call dispatcher inserted wrong number "
|
|
1047
|
+
"of arguments!");
|
|
1048
|
+
}
|
|
1049
|
+
#endif
|
|
1050
|
+
|
|
1051
|
+
std::vector<bool> second_pass_convert;
|
|
1052
|
+
if (overloaded) {
|
|
1053
|
+
// We're in the first no-convert pass, so swap out the conversion flags for a
|
|
1054
|
+
// set of all-false flags. If the call fails, we'll swap the flags back in for
|
|
1055
|
+
// the conversion-allowed call below.
|
|
1056
|
+
second_pass_convert.resize(func.nargs, false);
|
|
1057
|
+
call.args_convert.swap(second_pass_convert);
|
|
1058
|
+
}
|
|
1059
|
+
|
|
1060
|
+
// 6. Call the function.
|
|
1061
|
+
try {
|
|
1062
|
+
loader_life_support guard{};
|
|
1063
|
+
result = func.impl(call);
|
|
1064
|
+
} catch (reference_cast_error &) {
|
|
1065
|
+
result = PYBIND11_TRY_NEXT_OVERLOAD;
|
|
1066
|
+
}
|
|
1067
|
+
|
|
1068
|
+
if (result.ptr() != PYBIND11_TRY_NEXT_OVERLOAD) {
|
|
1069
|
+
break;
|
|
1070
|
+
}
|
|
1071
|
+
|
|
1072
|
+
if (overloaded) {
|
|
1073
|
+
// The (overloaded) call failed; if the call has at least one argument that
|
|
1074
|
+
// permits conversion (i.e. it hasn't been explicitly specified `.noconvert()`)
|
|
1075
|
+
// then add this call to the list of second pass overloads to try.
|
|
1076
|
+
for (size_t i = func.is_method ? 1 : 0; i < pos_args; i++) {
|
|
1077
|
+
if (second_pass_convert[i]) {
|
|
1078
|
+
// Found one: swap the converting flags back in and store the call for
|
|
1079
|
+
// the second pass.
|
|
1080
|
+
call.args_convert.swap(second_pass_convert);
|
|
1081
|
+
second_pass.push_back(std::move(call));
|
|
1082
|
+
break;
|
|
1083
|
+
}
|
|
1084
|
+
}
|
|
1085
|
+
}
|
|
1086
|
+
}
|
|
1087
|
+
|
|
1088
|
+
if (overloaded && !second_pass.empty() && result.ptr() == PYBIND11_TRY_NEXT_OVERLOAD) {
|
|
1089
|
+
// The no-conversion pass finished without success, try again with conversion
|
|
1090
|
+
// allowed
|
|
1091
|
+
for (auto &call : second_pass) {
|
|
1092
|
+
try {
|
|
1093
|
+
loader_life_support guard{};
|
|
1094
|
+
result = call.func.impl(call);
|
|
1095
|
+
} catch (reference_cast_error &) {
|
|
1096
|
+
result = PYBIND11_TRY_NEXT_OVERLOAD;
|
|
1097
|
+
}
|
|
1098
|
+
|
|
1099
|
+
if (result.ptr() != PYBIND11_TRY_NEXT_OVERLOAD) {
|
|
1100
|
+
// The error reporting logic below expects 'current_overload' to be valid,
|
|
1101
|
+
// as it would be if we'd encountered this failure in the first-pass loop.
|
|
1102
|
+
if (!result) {
|
|
1103
|
+
current_overload = &call.func;
|
|
1104
|
+
}
|
|
1105
|
+
break;
|
|
1106
|
+
}
|
|
1107
|
+
}
|
|
1108
|
+
}
|
|
1109
|
+
} catch (error_already_set &e) {
|
|
1110
|
+
e.restore();
|
|
1111
|
+
return nullptr;
|
|
1112
|
+
#ifdef __GLIBCXX__
|
|
1113
|
+
} catch (abi::__forced_unwind &) {
|
|
1114
|
+
throw;
|
|
1115
|
+
#endif
|
|
1116
|
+
} catch (...) {
|
|
1117
|
+
try_translate_exceptions();
|
|
1118
|
+
return nullptr;
|
|
1119
|
+
}
|
|
1120
|
+
|
|
1121
|
+
auto append_note_if_missing_header_is_suspected = [](std::string &msg) {
|
|
1122
|
+
if (msg.find("std::") != std::string::npos) {
|
|
1123
|
+
msg += "\n\n"
|
|
1124
|
+
"Did you forget to `#include <pybind11/stl.h>`? Or <pybind11/complex.h>,\n"
|
|
1125
|
+
"<pybind11/functional.h>, <pybind11/chrono.h>, etc. Some automatic\n"
|
|
1126
|
+
"conversions are optional and require extra headers to be included\n"
|
|
1127
|
+
"when compiling your pybind11 module.";
|
|
1128
|
+
}
|
|
1129
|
+
};
|
|
1130
|
+
|
|
1131
|
+
if (result.ptr() == PYBIND11_TRY_NEXT_OVERLOAD) {
|
|
1132
|
+
if (overloads->is_operator) {
|
|
1133
|
+
return handle(Py_NotImplemented).inc_ref().ptr();
|
|
1134
|
+
}
|
|
1135
|
+
|
|
1136
|
+
std::string msg = std::string(overloads->name) + "(): incompatible "
|
|
1137
|
+
+ std::string(overloads->is_constructor ? "constructor" : "function")
|
|
1138
|
+
+ " arguments. The following argument types are supported:\n";
|
|
1139
|
+
|
|
1140
|
+
int ctr = 0;
|
|
1141
|
+
for (const function_record *it2 = overloads; it2 != nullptr; it2 = it2->next) {
|
|
1142
|
+
msg += " " + std::to_string(++ctr) + ". ";
|
|
1143
|
+
|
|
1144
|
+
bool wrote_sig = false;
|
|
1145
|
+
if (overloads->is_constructor) {
|
|
1146
|
+
// For a constructor, rewrite `(self: Object, arg0, ...) -> NoneType` as
|
|
1147
|
+
// `Object(arg0, ...)`
|
|
1148
|
+
std::string sig = it2->signature;
|
|
1149
|
+
size_t start = sig.find('(') + 7; // skip "(self: "
|
|
1150
|
+
if (start < sig.size()) {
|
|
1151
|
+
// End at the , for the next argument
|
|
1152
|
+
size_t end = sig.find(", "), next = end + 2;
|
|
1153
|
+
size_t ret = sig.rfind(" -> ");
|
|
1154
|
+
// Or the ), if there is no comma:
|
|
1155
|
+
if (end >= sig.size()) {
|
|
1156
|
+
next = end = sig.find(')');
|
|
1157
|
+
}
|
|
1158
|
+
if (start < end && next < sig.size()) {
|
|
1159
|
+
msg.append(sig, start, end - start);
|
|
1160
|
+
msg += '(';
|
|
1161
|
+
msg.append(sig, next, ret - next);
|
|
1162
|
+
wrote_sig = true;
|
|
1163
|
+
}
|
|
1164
|
+
}
|
|
1165
|
+
}
|
|
1166
|
+
if (!wrote_sig) {
|
|
1167
|
+
msg += it2->signature;
|
|
1168
|
+
}
|
|
1169
|
+
|
|
1170
|
+
msg += '\n';
|
|
1171
|
+
}
|
|
1172
|
+
msg += "\nInvoked with: ";
|
|
1173
|
+
auto args_ = reinterpret_borrow<tuple>(args_in);
|
|
1174
|
+
bool some_args = false;
|
|
1175
|
+
for (size_t ti = overloads->is_constructor ? 1 : 0; ti < args_.size(); ++ti) {
|
|
1176
|
+
if (!some_args) {
|
|
1177
|
+
some_args = true;
|
|
1178
|
+
} else {
|
|
1179
|
+
msg += ", ";
|
|
1180
|
+
}
|
|
1181
|
+
try {
|
|
1182
|
+
msg += pybind11::repr(args_[ti]);
|
|
1183
|
+
} catch (const error_already_set &) {
|
|
1184
|
+
msg += "<repr raised Error>";
|
|
1185
|
+
}
|
|
1186
|
+
}
|
|
1187
|
+
if (kwargs_in) {
|
|
1188
|
+
auto kwargs = reinterpret_borrow<dict>(kwargs_in);
|
|
1189
|
+
if (!kwargs.empty()) {
|
|
1190
|
+
if (some_args) {
|
|
1191
|
+
msg += "; ";
|
|
1192
|
+
}
|
|
1193
|
+
msg += "kwargs: ";
|
|
1194
|
+
bool first = true;
|
|
1195
|
+
for (const auto &kwarg : kwargs) {
|
|
1196
|
+
if (first) {
|
|
1197
|
+
first = false;
|
|
1198
|
+
} else {
|
|
1199
|
+
msg += ", ";
|
|
1200
|
+
}
|
|
1201
|
+
msg += pybind11::str("{}=").format(kwarg.first);
|
|
1202
|
+
try {
|
|
1203
|
+
msg += pybind11::repr(kwarg.second);
|
|
1204
|
+
} catch (const error_already_set &) {
|
|
1205
|
+
msg += "<repr raised Error>";
|
|
1206
|
+
}
|
|
1207
|
+
}
|
|
1208
|
+
}
|
|
1209
|
+
}
|
|
1210
|
+
|
|
1211
|
+
append_note_if_missing_header_is_suspected(msg);
|
|
1212
|
+
// Attach additional error info to the exception if supported
|
|
1213
|
+
if (PyErr_Occurred()) {
|
|
1214
|
+
// #HelpAppreciated: unit test coverage for this branch.
|
|
1215
|
+
raise_from(PyExc_TypeError, msg.c_str());
|
|
1216
|
+
return nullptr;
|
|
1217
|
+
}
|
|
1218
|
+
set_error(PyExc_TypeError, msg.c_str());
|
|
1219
|
+
return nullptr;
|
|
1220
|
+
}
|
|
1221
|
+
if (!result) {
|
|
1222
|
+
std::string msg = "Unable to convert function return value to a "
|
|
1223
|
+
"Python type! The signature was\n\t";
|
|
1224
|
+
assert(current_overload != nullptr);
|
|
1225
|
+
msg += current_overload->signature;
|
|
1226
|
+
append_note_if_missing_header_is_suspected(msg);
|
|
1227
|
+
// Attach additional error info to the exception if supported
|
|
1228
|
+
if (PyErr_Occurred()) {
|
|
1229
|
+
raise_from(PyExc_TypeError, msg.c_str());
|
|
1230
|
+
return nullptr;
|
|
1231
|
+
}
|
|
1232
|
+
set_error(PyExc_TypeError, msg.c_str());
|
|
1233
|
+
return nullptr;
|
|
1234
|
+
}
|
|
1235
|
+
if (overloads->is_constructor && !self_value_and_holder.holder_constructed()) {
|
|
1236
|
+
auto *pi = reinterpret_cast<instance *>(parent.ptr());
|
|
1237
|
+
self_value_and_holder.type->init_instance(pi, nullptr);
|
|
1238
|
+
}
|
|
1239
|
+
return result.ptr();
|
|
1240
|
+
}
|
|
1241
|
+
};
|
|
1242
|
+
|
|
1243
|
+
PYBIND11_NAMESPACE_BEGIN(detail)
|
|
1244
|
+
|
|
1245
|
+
PYBIND11_NAMESPACE_BEGIN(function_record_PyTypeObject_methods)
|
|
1246
|
+
|
|
1247
|
+
// This implementation needs the definition of `class cpp_function`.
|
|
1248
|
+
inline void tp_dealloc_impl(PyObject *self) {
|
|
1249
|
+
auto *py_func_rec = (function_record_PyObject *) self;
|
|
1250
|
+
cpp_function::destruct(py_func_rec->cpp_func_rec);
|
|
1251
|
+
py_func_rec->cpp_func_rec = nullptr;
|
|
1252
|
+
}
|
|
1253
|
+
|
|
1254
|
+
PYBIND11_NAMESPACE_END(function_record_PyTypeObject_methods)
|
|
1255
|
+
|
|
1256
|
+
template <>
|
|
1257
|
+
struct handle_type_name<cpp_function> {
|
|
1258
|
+
static constexpr auto name = const_name("collections.abc.Callable");
|
|
1259
|
+
};
|
|
1260
|
+
|
|
1261
|
+
PYBIND11_NAMESPACE_END(detail)
|
|
1262
|
+
|
|
1263
|
+
// Use to activate Py_MOD_GIL_NOT_USED.
|
|
1264
|
+
class mod_gil_not_used {
|
|
1265
|
+
public:
|
|
1266
|
+
explicit mod_gil_not_used(bool flag = true) : flag_(flag) {}
|
|
1267
|
+
bool flag() const { return flag_; }
|
|
1268
|
+
|
|
1269
|
+
private:
|
|
1270
|
+
bool flag_;
|
|
1271
|
+
};
|
|
1272
|
+
|
|
1273
|
+
class multiple_interpreters {
|
|
1274
|
+
public:
|
|
1275
|
+
enum class level {
|
|
1276
|
+
not_supported, /// Use to activate Py_MOD_MULTIPLE_INTERPRETERS_NOT_SUPPORTED
|
|
1277
|
+
shared_gil, /// Use to activate Py_MOD_MULTIPLE_INTERPRETERS_SUPPORTED
|
|
1278
|
+
per_interpreter_gil /// Use to activate Py_MOD_PER_INTERPRETER_GIL_SUPPORTED
|
|
1279
|
+
};
|
|
1280
|
+
|
|
1281
|
+
static multiple_interpreters not_supported() {
|
|
1282
|
+
return multiple_interpreters(level::not_supported);
|
|
1283
|
+
}
|
|
1284
|
+
static multiple_interpreters shared_gil() { return multiple_interpreters(level::shared_gil); }
|
|
1285
|
+
static multiple_interpreters per_interpreter_gil() {
|
|
1286
|
+
return multiple_interpreters(level::per_interpreter_gil);
|
|
1287
|
+
}
|
|
1288
|
+
|
|
1289
|
+
explicit constexpr multiple_interpreters(level l) : level_(l) {}
|
|
1290
|
+
level value() const { return level_; }
|
|
1291
|
+
|
|
1292
|
+
private:
|
|
1293
|
+
level level_;
|
|
1294
|
+
};
|
|
1295
|
+
|
|
1296
|
+
PYBIND11_NAMESPACE_BEGIN(detail)
|
|
1297
|
+
|
|
1298
|
+
inline bool gil_not_used_option() { return false; }
|
|
1299
|
+
template <typename F, typename... O>
|
|
1300
|
+
bool gil_not_used_option(F &&, O &&...o);
|
|
1301
|
+
template <typename... O>
|
|
1302
|
+
inline bool gil_not_used_option(mod_gil_not_used f, O &&...o) {
|
|
1303
|
+
return f.flag() || gil_not_used_option(o...);
|
|
1304
|
+
}
|
|
1305
|
+
template <typename F, typename... O>
|
|
1306
|
+
inline bool gil_not_used_option(F &&, O &&...o) {
|
|
1307
|
+
return gil_not_used_option(o...);
|
|
1308
|
+
}
|
|
1309
|
+
|
|
1310
|
+
#ifdef Py_mod_multiple_interpreters
|
|
1311
|
+
inline void *multi_interp_slot() { return Py_MOD_MULTIPLE_INTERPRETERS_NOT_SUPPORTED; }
|
|
1312
|
+
template <typename... O>
|
|
1313
|
+
inline void *multi_interp_slot(multiple_interpreters mi, O &&...o) {
|
|
1314
|
+
switch (mi.value()) {
|
|
1315
|
+
case multiple_interpreters::level::per_interpreter_gil:
|
|
1316
|
+
return Py_MOD_PER_INTERPRETER_GIL_SUPPORTED;
|
|
1317
|
+
case multiple_interpreters::level::shared_gil:
|
|
1318
|
+
return Py_MOD_MULTIPLE_INTERPRETERS_SUPPORTED;
|
|
1319
|
+
case multiple_interpreters::level::not_supported:
|
|
1320
|
+
return Py_MOD_MULTIPLE_INTERPRETERS_NOT_SUPPORTED;
|
|
1321
|
+
}
|
|
1322
|
+
// silence warnings with this unreachable line:
|
|
1323
|
+
return multi_interp_slot(o...);
|
|
1324
|
+
}
|
|
1325
|
+
template <typename F, typename... O>
|
|
1326
|
+
inline void *multi_interp_slot(F &&, O &&...o) {
|
|
1327
|
+
return multi_interp_slot(o...);
|
|
1328
|
+
}
|
|
1329
|
+
#endif
|
|
1330
|
+
|
|
1331
|
+
/*
|
|
1332
|
+
Return a borrowed reference to the named module if it has been successfully initialized within this
|
|
1333
|
+
interpreter before. nullptr if it has not been successfully initialized.
|
|
1334
|
+
*/
|
|
1335
|
+
inline PyObject *get_cached_module(pybind11::str const &nameobj) {
|
|
1336
|
+
dict state = detail::get_python_state_dict();
|
|
1337
|
+
if (!state.contains("__pybind11_module_cache")) {
|
|
1338
|
+
return nullptr;
|
|
1339
|
+
}
|
|
1340
|
+
dict cache = state["__pybind11_module_cache"];
|
|
1341
|
+
if (!cache.contains(nameobj)) {
|
|
1342
|
+
return nullptr;
|
|
1343
|
+
}
|
|
1344
|
+
return cache[nameobj].ptr();
|
|
1345
|
+
}
|
|
1346
|
+
|
|
1347
|
+
/*
|
|
1348
|
+
Add successfully initialized a module object to the internal cache.
|
|
1349
|
+
|
|
1350
|
+
The module must have a __spec__ attribute with a name attribute.
|
|
1351
|
+
*/
|
|
1352
|
+
inline void cache_completed_module(pybind11::object const &mod) {
|
|
1353
|
+
dict state = detail::get_python_state_dict();
|
|
1354
|
+
if (!state.contains("__pybind11_module_cache")) {
|
|
1355
|
+
state["__pybind11_module_cache"] = dict();
|
|
1356
|
+
}
|
|
1357
|
+
state["__pybind11_module_cache"][mod.attr("__spec__").attr("name")] = mod;
|
|
1358
|
+
}
|
|
1359
|
+
|
|
1360
|
+
/*
|
|
1361
|
+
A Py_mod_create slot function which will return the previously created module from the cache if one
|
|
1362
|
+
exists, and otherwise will create a new module object.
|
|
1363
|
+
*/
|
|
1364
|
+
inline PyObject *cached_create_module(PyObject *spec, PyModuleDef *) {
|
|
1365
|
+
(void) &cache_completed_module; // silence unused-function warnings, it is used in a macro
|
|
1366
|
+
|
|
1367
|
+
auto nameobj = getattr(reinterpret_borrow<object>(spec), "name", none());
|
|
1368
|
+
if (nameobj.is_none()) {
|
|
1369
|
+
set_error(PyExc_ImportError, "module spec is missing a name");
|
|
1370
|
+
return nullptr;
|
|
1371
|
+
}
|
|
1372
|
+
|
|
1373
|
+
auto *mod = get_cached_module(nameobj);
|
|
1374
|
+
if (mod) {
|
|
1375
|
+
Py_INCREF(mod);
|
|
1376
|
+
} else {
|
|
1377
|
+
mod = PyModule_NewObject(nameobj.ptr());
|
|
1378
|
+
}
|
|
1379
|
+
return mod;
|
|
1380
|
+
}
|
|
1381
|
+
|
|
1382
|
+
/// Must be a POD type, and must hold enough entries for all of the possible slots PLUS ONE for
|
|
1383
|
+
/// the sentinel (0) end slot.
|
|
1384
|
+
using slots_array = std::array<PyModuleDef_Slot, 5>;
|
|
1385
|
+
|
|
1386
|
+
/// Initialize an array of slots based on the supplied exec slot and options.
|
|
1387
|
+
template <typename... Options>
|
|
1388
|
+
inline slots_array init_slots(int (*exec_fn)(PyObject *), Options &&...options) noexcept {
|
|
1389
|
+
/* NOTE: slots_array MUST be large enough to hold all possible options. If you add an option
|
|
1390
|
+
here, you MUST also increase the size of slots_array in the type alias above! */
|
|
1391
|
+
slots_array mod_def_slots;
|
|
1392
|
+
size_t next_slot = 0;
|
|
1393
|
+
|
|
1394
|
+
mod_def_slots[next_slot++] = {Py_mod_create, reinterpret_cast<void *>(&cached_create_module)};
|
|
1395
|
+
|
|
1396
|
+
if (exec_fn != nullptr) {
|
|
1397
|
+
mod_def_slots[next_slot++] = {Py_mod_exec, reinterpret_cast<void *>(exec_fn)};
|
|
1398
|
+
}
|
|
1399
|
+
|
|
1400
|
+
#ifdef Py_mod_multiple_interpreters
|
|
1401
|
+
mod_def_slots[next_slot++] = {Py_mod_multiple_interpreters, multi_interp_slot(options...)};
|
|
1402
|
+
#endif
|
|
1403
|
+
|
|
1404
|
+
if (gil_not_used_option(options...)) {
|
|
1405
|
+
#if defined(Py_mod_gil) && defined(Py_GIL_DISABLED)
|
|
1406
|
+
mod_def_slots[next_slot++] = {Py_mod_gil, Py_MOD_GIL_NOT_USED};
|
|
1407
|
+
#endif
|
|
1408
|
+
}
|
|
1409
|
+
|
|
1410
|
+
// slots must have a zero end sentinel
|
|
1411
|
+
mod_def_slots[next_slot++] = {0, nullptr};
|
|
1412
|
+
|
|
1413
|
+
return mod_def_slots;
|
|
1414
|
+
}
|
|
1415
|
+
|
|
1416
|
+
PYBIND11_NAMESPACE_END(detail)
|
|
1417
|
+
|
|
1418
|
+
/// Wrapper for Python extension modules
|
|
1419
|
+
class module_ : public object {
|
|
1420
|
+
public:
|
|
1421
|
+
PYBIND11_OBJECT_DEFAULT(module_, object, PyModule_Check)
|
|
1422
|
+
|
|
1423
|
+
/// Create a new top-level Python module with the given name and docstring
|
|
1424
|
+
PYBIND11_DEPRECATED("Use PYBIND11_MODULE or module_::create_extension_module instead")
|
|
1425
|
+
explicit module_(const char *name, const char *doc = nullptr) {
|
|
1426
|
+
*this = create_extension_module(name, doc, new PyModuleDef());
|
|
1427
|
+
}
|
|
1428
|
+
|
|
1429
|
+
/** \rst
|
|
1430
|
+
Create Python binding for a new function within the module scope. ``Func``
|
|
1431
|
+
can be a plain C++ function, a function pointer, or a lambda function. For
|
|
1432
|
+
details on the ``Extra&& ... extra`` argument, see section :ref:`extras`.
|
|
1433
|
+
\endrst */
|
|
1434
|
+
template <typename Func, typename... Extra>
|
|
1435
|
+
module_ &def(const char *name_, Func &&f, const Extra &...extra) {
|
|
1436
|
+
cpp_function func(std::forward<Func>(f),
|
|
1437
|
+
name(name_),
|
|
1438
|
+
scope(*this),
|
|
1439
|
+
sibling(getattr(*this, name_, none())),
|
|
1440
|
+
extra...);
|
|
1441
|
+
// NB: allow overwriting here because cpp_function sets up a chain with the intention of
|
|
1442
|
+
// overwriting (and has already checked internally that it isn't overwriting
|
|
1443
|
+
// non-functions).
|
|
1444
|
+
add_object(name_, func, true /* overwrite */);
|
|
1445
|
+
return *this;
|
|
1446
|
+
}
|
|
1447
|
+
|
|
1448
|
+
/** \rst
|
|
1449
|
+
Create and return a new Python submodule with the given name and docstring.
|
|
1450
|
+
This also works recursively, i.e.
|
|
1451
|
+
|
|
1452
|
+
.. code-block:: cpp
|
|
1453
|
+
|
|
1454
|
+
py::module_ m("example", "pybind11 example plugin");
|
|
1455
|
+
py::module_ m2 = m.def_submodule("sub", "A submodule of 'example'");
|
|
1456
|
+
py::module_ m3 = m2.def_submodule("subsub", "A submodule of 'example.sub'");
|
|
1457
|
+
\endrst */
|
|
1458
|
+
module_ def_submodule(const char *name, const char *doc = nullptr) {
|
|
1459
|
+
const char *this_name = PyModule_GetName(m_ptr);
|
|
1460
|
+
if (this_name == nullptr) {
|
|
1461
|
+
throw error_already_set();
|
|
1462
|
+
}
|
|
1463
|
+
std::string full_name = std::string(this_name) + '.' + name;
|
|
1464
|
+
handle submodule = PyImport_AddModule(full_name.c_str());
|
|
1465
|
+
if (!submodule) {
|
|
1466
|
+
throw error_already_set();
|
|
1467
|
+
}
|
|
1468
|
+
auto result = reinterpret_borrow<module_>(submodule);
|
|
1469
|
+
if (doc && options::show_user_defined_docstrings()) {
|
|
1470
|
+
result.attr("__doc__") = pybind11::str(doc);
|
|
1471
|
+
}
|
|
1472
|
+
|
|
1473
|
+
#if defined(GRAALVM_PYTHON) && (!defined(GRAALPY_VERSION_NUM) || GRAALPY_VERSION_NUM < 0x190000)
|
|
1474
|
+
// GraalPy doesn't support PyModule_GetFilenameObject,
|
|
1475
|
+
// so getting by attribute (see PR #5584)
|
|
1476
|
+
handle this_module = m_ptr;
|
|
1477
|
+
if (object this_file = getattr(this_module, "__file__", none())) {
|
|
1478
|
+
result.attr("__file__") = this_file;
|
|
1479
|
+
}
|
|
1480
|
+
#else
|
|
1481
|
+
handle this_file = PyModule_GetFilenameObject(m_ptr);
|
|
1482
|
+
if (this_file) {
|
|
1483
|
+
result.attr("__file__") = this_file;
|
|
1484
|
+
} else if (PyErr_ExceptionMatches(PyExc_SystemError) != 0) {
|
|
1485
|
+
PyErr_Clear();
|
|
1486
|
+
} else {
|
|
1487
|
+
throw error_already_set();
|
|
1488
|
+
}
|
|
1489
|
+
#endif
|
|
1490
|
+
attr(name) = result;
|
|
1491
|
+
return result;
|
|
1492
|
+
}
|
|
1493
|
+
|
|
1494
|
+
/// Import and return a module or throws `error_already_set`.
|
|
1495
|
+
static module_ import(const char *name) {
|
|
1496
|
+
PyObject *obj = PyImport_ImportModule(name);
|
|
1497
|
+
if (!obj) {
|
|
1498
|
+
throw error_already_set();
|
|
1499
|
+
}
|
|
1500
|
+
return reinterpret_steal<module_>(obj);
|
|
1501
|
+
}
|
|
1502
|
+
|
|
1503
|
+
/// Reload the module or throws `error_already_set`.
|
|
1504
|
+
void reload() {
|
|
1505
|
+
PyObject *obj = PyImport_ReloadModule(ptr());
|
|
1506
|
+
if (!obj) {
|
|
1507
|
+
throw error_already_set();
|
|
1508
|
+
}
|
|
1509
|
+
*this = reinterpret_steal<module_>(obj);
|
|
1510
|
+
}
|
|
1511
|
+
|
|
1512
|
+
/** \rst
|
|
1513
|
+
Adds an object to the module using the given name. Throws if an object with the given name
|
|
1514
|
+
already exists.
|
|
1515
|
+
|
|
1516
|
+
``overwrite`` should almost always be false: attempting to overwrite objects that pybind11
|
|
1517
|
+
has established will, in most cases, break things.
|
|
1518
|
+
\endrst */
|
|
1519
|
+
PYBIND11_NOINLINE void add_object(const char *name, handle obj, bool overwrite = false) {
|
|
1520
|
+
if (!overwrite && hasattr(*this, name)) {
|
|
1521
|
+
pybind11_fail(
|
|
1522
|
+
"Error during initialization: multiple incompatible definitions with name \""
|
|
1523
|
+
+ std::string(name) + "\"");
|
|
1524
|
+
}
|
|
1525
|
+
|
|
1526
|
+
PyModule_AddObject(ptr(), name, obj.inc_ref().ptr() /* steals a reference */);
|
|
1527
|
+
}
|
|
1528
|
+
|
|
1529
|
+
// DEPRECATED (since PR #5688): Use PyModuleDef directly instead.
|
|
1530
|
+
using module_def = PyModuleDef;
|
|
1531
|
+
|
|
1532
|
+
/** \rst
|
|
1533
|
+
Create a new top-level module that can be used as the main module of a C extension.
|
|
1534
|
+
|
|
1535
|
+
``def`` should point to a statically allocated PyModuleDef.
|
|
1536
|
+
\endrst */
|
|
1537
|
+
static module_ create_extension_module(const char *name,
|
|
1538
|
+
const char *doc,
|
|
1539
|
+
PyModuleDef *def,
|
|
1540
|
+
mod_gil_not_used gil_not_used
|
|
1541
|
+
= mod_gil_not_used(false)) {
|
|
1542
|
+
// Placement new (not an allocation).
|
|
1543
|
+
new (def) PyModuleDef{/* m_base */ PyModuleDef_HEAD_INIT,
|
|
1544
|
+
/* m_name */ name,
|
|
1545
|
+
/* m_doc */ options::show_user_defined_docstrings() ? doc : nullptr,
|
|
1546
|
+
/* m_size */ -1,
|
|
1547
|
+
/* m_methods */ nullptr,
|
|
1548
|
+
/* m_slots */ nullptr,
|
|
1549
|
+
/* m_traverse */ nullptr,
|
|
1550
|
+
/* m_clear */ nullptr,
|
|
1551
|
+
/* m_free */ nullptr};
|
|
1552
|
+
auto *m = PyModule_Create(def);
|
|
1553
|
+
if (m == nullptr) {
|
|
1554
|
+
if (PyErr_Occurred()) {
|
|
1555
|
+
throw error_already_set();
|
|
1556
|
+
}
|
|
1557
|
+
pybind11_fail("Internal error in module_::create_extension_module()");
|
|
1558
|
+
}
|
|
1559
|
+
if (gil_not_used.flag()) {
|
|
1560
|
+
#ifdef Py_GIL_DISABLED
|
|
1561
|
+
PyUnstable_Module_SetGIL(m, Py_MOD_GIL_NOT_USED);
|
|
1562
|
+
#endif
|
|
1563
|
+
}
|
|
1564
|
+
// TODO: Should be reinterpret_steal for Python 3, but Python also steals it again when
|
|
1565
|
+
// returned from PyInit_...
|
|
1566
|
+
// For Python 2, reinterpret_borrow was correct.
|
|
1567
|
+
return reinterpret_borrow<module_>(m);
|
|
1568
|
+
}
|
|
1569
|
+
};
|
|
1570
|
+
|
|
1571
|
+
PYBIND11_NAMESPACE_BEGIN(detail)
|
|
1572
|
+
|
|
1573
|
+
template <>
|
|
1574
|
+
struct handle_type_name<module_> {
|
|
1575
|
+
static constexpr auto name = const_name("types.ModuleType");
|
|
1576
|
+
};
|
|
1577
|
+
|
|
1578
|
+
PYBIND11_NAMESPACE_END(detail)
|
|
1579
|
+
|
|
1580
|
+
// When inside a namespace (or anywhere as long as it's not the first item on a line),
|
|
1581
|
+
// C++20 allows "module" to be used. This is provided for backward compatibility, and for
|
|
1582
|
+
// simplicity, if someone wants to use py::module for example, that is perfectly safe.
|
|
1583
|
+
using module = module_;
|
|
1584
|
+
|
|
1585
|
+
/// \ingroup python_builtins
|
|
1586
|
+
/// Return a dictionary representing the global variables in the current execution frame,
|
|
1587
|
+
/// or ``__main__.__dict__`` if there is no frame (usually when the interpreter is embedded).
|
|
1588
|
+
inline dict globals() {
|
|
1589
|
+
#if PY_VERSION_HEX >= 0x030d0000
|
|
1590
|
+
PyObject *p = PyEval_GetFrameGlobals();
|
|
1591
|
+
return p ? reinterpret_steal<dict>(p)
|
|
1592
|
+
: reinterpret_borrow<dict>(module_::import("__main__").attr("__dict__").ptr());
|
|
1593
|
+
#else
|
|
1594
|
+
PyObject *p = PyEval_GetGlobals();
|
|
1595
|
+
return reinterpret_borrow<dict>(p ? p : module_::import("__main__").attr("__dict__").ptr());
|
|
1596
|
+
#endif
|
|
1597
|
+
}
|
|
1598
|
+
|
|
1599
|
+
PYBIND11_NAMESPACE_BEGIN(detail)
|
|
1600
|
+
/// Generic support for creating new Python heap types
|
|
1601
|
+
class generic_type : public object {
|
|
1602
|
+
public:
|
|
1603
|
+
PYBIND11_OBJECT_DEFAULT(generic_type, object, PyType_Check)
|
|
1604
|
+
protected:
|
|
1605
|
+
void initialize(const type_record &rec) {
|
|
1606
|
+
if (rec.scope && hasattr(rec.scope, "__dict__")
|
|
1607
|
+
&& rec.scope.attr("__dict__").contains(rec.name)) {
|
|
1608
|
+
pybind11_fail("generic_type: cannot initialize type \"" + std::string(rec.name)
|
|
1609
|
+
+ "\": an object with that name is already defined");
|
|
1610
|
+
}
|
|
1611
|
+
|
|
1612
|
+
if ((rec.module_local ? get_local_type_info(*rec.type) : get_global_type_info(*rec.type))
|
|
1613
|
+
!= nullptr) {
|
|
1614
|
+
pybind11_fail("generic_type: type \"" + std::string(rec.name)
|
|
1615
|
+
+ "\" is already registered!");
|
|
1616
|
+
}
|
|
1617
|
+
|
|
1618
|
+
m_ptr = make_new_python_type(rec);
|
|
1619
|
+
|
|
1620
|
+
/* Register supplemental type information in C++ dict */
|
|
1621
|
+
auto *tinfo = new detail::type_info();
|
|
1622
|
+
tinfo->type = (PyTypeObject *) m_ptr;
|
|
1623
|
+
tinfo->cpptype = rec.type;
|
|
1624
|
+
tinfo->type_size = rec.type_size;
|
|
1625
|
+
tinfo->type_align = rec.type_align;
|
|
1626
|
+
tinfo->operator_new = rec.operator_new;
|
|
1627
|
+
tinfo->holder_size_in_ptrs = size_in_ptrs(rec.holder_size);
|
|
1628
|
+
tinfo->init_instance = rec.init_instance;
|
|
1629
|
+
tinfo->dealloc = rec.dealloc;
|
|
1630
|
+
tinfo->get_trampoline_self_life_support = rec.get_trampoline_self_life_support;
|
|
1631
|
+
tinfo->simple_type = true;
|
|
1632
|
+
tinfo->simple_ancestors = true;
|
|
1633
|
+
tinfo->module_local = rec.module_local;
|
|
1634
|
+
tinfo->holder_enum_v = rec.holder_enum_v;
|
|
1635
|
+
|
|
1636
|
+
with_internals([&](internals &internals) {
|
|
1637
|
+
auto tindex = std::type_index(*rec.type);
|
|
1638
|
+
tinfo->direct_conversions = &internals.direct_conversions[tindex];
|
|
1639
|
+
if (rec.module_local) {
|
|
1640
|
+
get_local_internals().registered_types_cpp[tindex] = tinfo;
|
|
1641
|
+
} else {
|
|
1642
|
+
internals.registered_types_cpp[tindex] = tinfo;
|
|
1643
|
+
}
|
|
1644
|
+
|
|
1645
|
+
PYBIND11_WARNING_PUSH
|
|
1646
|
+
#if defined(__GNUC__) && __GNUC__ == 12
|
|
1647
|
+
// When using GCC 12 these warnings are disabled as they trigger
|
|
1648
|
+
// false positive warnings. Discussed here:
|
|
1649
|
+
// https://gcc.gnu.org/bugzilla/show_bug.cgi?id=115824.
|
|
1650
|
+
PYBIND11_WARNING_DISABLE_GCC("-Warray-bounds")
|
|
1651
|
+
PYBIND11_WARNING_DISABLE_GCC("-Wstringop-overread")
|
|
1652
|
+
#endif
|
|
1653
|
+
internals.registered_types_py[(PyTypeObject *) m_ptr] = {tinfo};
|
|
1654
|
+
PYBIND11_WARNING_POP
|
|
1655
|
+
});
|
|
1656
|
+
|
|
1657
|
+
if (rec.bases.size() > 1 || rec.multiple_inheritance) {
|
|
1658
|
+
mark_parents_nonsimple(tinfo->type);
|
|
1659
|
+
tinfo->simple_ancestors = false;
|
|
1660
|
+
} else if (rec.bases.size() == 1) {
|
|
1661
|
+
auto *parent_tinfo = get_type_info((PyTypeObject *) rec.bases[0].ptr());
|
|
1662
|
+
assert(parent_tinfo != nullptr);
|
|
1663
|
+
bool parent_simple_ancestors = parent_tinfo->simple_ancestors;
|
|
1664
|
+
tinfo->simple_ancestors = parent_simple_ancestors;
|
|
1665
|
+
// The parent can no longer be a simple type if it has MI and has a child
|
|
1666
|
+
parent_tinfo->simple_type = parent_tinfo->simple_type && parent_simple_ancestors;
|
|
1667
|
+
}
|
|
1668
|
+
|
|
1669
|
+
if (rec.module_local) {
|
|
1670
|
+
// Stash the local typeinfo and loader so that external modules can access it.
|
|
1671
|
+
tinfo->module_local_load = &type_caster_generic::local_load;
|
|
1672
|
+
setattr(m_ptr, PYBIND11_MODULE_LOCAL_ID, capsule(tinfo));
|
|
1673
|
+
}
|
|
1674
|
+
}
|
|
1675
|
+
|
|
1676
|
+
/// Helper function which tags all parents of a type using mult. inheritance
|
|
1677
|
+
void mark_parents_nonsimple(PyTypeObject *value) {
|
|
1678
|
+
auto t = reinterpret_borrow<tuple>(value->tp_bases);
|
|
1679
|
+
for (handle h : t) {
|
|
1680
|
+
auto *tinfo2 = get_type_info((PyTypeObject *) h.ptr());
|
|
1681
|
+
if (tinfo2) {
|
|
1682
|
+
tinfo2->simple_type = false;
|
|
1683
|
+
}
|
|
1684
|
+
mark_parents_nonsimple((PyTypeObject *) h.ptr());
|
|
1685
|
+
}
|
|
1686
|
+
}
|
|
1687
|
+
|
|
1688
|
+
void install_buffer_funcs(buffer_info *(*get_buffer)(PyObject *, void *),
|
|
1689
|
+
void *get_buffer_data) {
|
|
1690
|
+
auto *type = (PyHeapTypeObject *) m_ptr;
|
|
1691
|
+
auto *tinfo = detail::get_type_info(&type->ht_type);
|
|
1692
|
+
|
|
1693
|
+
if (!type->ht_type.tp_as_buffer) {
|
|
1694
|
+
pybind11_fail("To be able to register buffer protocol support for the type '"
|
|
1695
|
+
+ get_fully_qualified_tp_name(tinfo->type)
|
|
1696
|
+
+ "' the associated class<>(..) invocation must "
|
|
1697
|
+
"include the pybind11::buffer_protocol() annotation!");
|
|
1698
|
+
}
|
|
1699
|
+
|
|
1700
|
+
tinfo->get_buffer = get_buffer;
|
|
1701
|
+
tinfo->get_buffer_data = get_buffer_data;
|
|
1702
|
+
}
|
|
1703
|
+
|
|
1704
|
+
// rec_func must be set for either fget or fset.
|
|
1705
|
+
void def_property_static_impl(const char *name,
|
|
1706
|
+
handle fget,
|
|
1707
|
+
handle fset,
|
|
1708
|
+
detail::function_record *rec_func) {
|
|
1709
|
+
const auto is_static = (rec_func != nullptr) && !(rec_func->is_method && rec_func->scope);
|
|
1710
|
+
const auto has_doc = (rec_func != nullptr) && (rec_func->doc != nullptr)
|
|
1711
|
+
&& pybind11::options::show_user_defined_docstrings();
|
|
1712
|
+
auto property = handle(
|
|
1713
|
+
(PyObject *) (is_static ? get_internals().static_property_type : &PyProperty_Type));
|
|
1714
|
+
attr(name) = property(fget.ptr() ? fget : none(),
|
|
1715
|
+
fset.ptr() ? fset : none(),
|
|
1716
|
+
/*deleter*/ none(),
|
|
1717
|
+
pybind11::str(has_doc ? rec_func->doc : ""));
|
|
1718
|
+
}
|
|
1719
|
+
};
|
|
1720
|
+
|
|
1721
|
+
/// Set the pointer to operator new if it exists. The cast is needed because it can be overloaded.
|
|
1722
|
+
template <typename T,
|
|
1723
|
+
typename = void_t<decltype(static_cast<void *(*) (size_t)>(T::operator new))>>
|
|
1724
|
+
void set_operator_new(type_record *r) {
|
|
1725
|
+
r->operator_new = &T::operator new;
|
|
1726
|
+
}
|
|
1727
|
+
|
|
1728
|
+
template <typename>
|
|
1729
|
+
void set_operator_new(...) {}
|
|
1730
|
+
|
|
1731
|
+
template <typename T, typename SFINAE = void>
|
|
1732
|
+
struct has_operator_delete : std::false_type {};
|
|
1733
|
+
template <typename T>
|
|
1734
|
+
struct has_operator_delete<T, void_t<decltype(static_cast<void (*)(void *)>(T::operator delete))>>
|
|
1735
|
+
: std::true_type {};
|
|
1736
|
+
template <typename T, typename SFINAE = void>
|
|
1737
|
+
struct has_operator_delete_size : std::false_type {};
|
|
1738
|
+
template <typename T>
|
|
1739
|
+
struct has_operator_delete_size<
|
|
1740
|
+
T,
|
|
1741
|
+
void_t<decltype(static_cast<void (*)(void *, size_t)>(T::operator delete))>> : std::true_type {
|
|
1742
|
+
};
|
|
1743
|
+
/// Call class-specific delete if it exists or global otherwise. Can also be an overload set.
|
|
1744
|
+
template <typename T, enable_if_t<has_operator_delete<T>::value, int> = 0>
|
|
1745
|
+
void call_operator_delete(T *p, size_t, size_t) {
|
|
1746
|
+
T::operator delete(p);
|
|
1747
|
+
}
|
|
1748
|
+
template <typename T,
|
|
1749
|
+
enable_if_t<!has_operator_delete<T>::value && has_operator_delete_size<T>::value, int>
|
|
1750
|
+
= 0>
|
|
1751
|
+
void call_operator_delete(T *p, size_t s, size_t) {
|
|
1752
|
+
T::operator delete(p, s);
|
|
1753
|
+
}
|
|
1754
|
+
|
|
1755
|
+
inline void call_operator_delete(void *p, size_t s, size_t a) {
|
|
1756
|
+
(void) s;
|
|
1757
|
+
(void) a;
|
|
1758
|
+
#if defined(__cpp_aligned_new) && (!defined(_MSC_VER) || _MSC_VER >= 1912)
|
|
1759
|
+
if (a > __STDCPP_DEFAULT_NEW_ALIGNMENT__) {
|
|
1760
|
+
# ifdef __cpp_sized_deallocation
|
|
1761
|
+
::operator delete(p, s, std::align_val_t(a));
|
|
1762
|
+
# else
|
|
1763
|
+
::operator delete(p, std::align_val_t(a));
|
|
1764
|
+
# endif
|
|
1765
|
+
return;
|
|
1766
|
+
}
|
|
1767
|
+
#endif
|
|
1768
|
+
#ifdef __cpp_sized_deallocation
|
|
1769
|
+
::operator delete(p, s);
|
|
1770
|
+
#else
|
|
1771
|
+
::operator delete(p);
|
|
1772
|
+
#endif
|
|
1773
|
+
}
|
|
1774
|
+
|
|
1775
|
+
inline void add_class_method(object &cls, const char *name_, const cpp_function &cf) {
|
|
1776
|
+
cls.attr(cf.name()) = cf;
|
|
1777
|
+
if (std::strcmp(name_, "__eq__") == 0 && !cls.attr("__dict__").contains("__hash__")) {
|
|
1778
|
+
cls.attr("__hash__") = none();
|
|
1779
|
+
}
|
|
1780
|
+
}
|
|
1781
|
+
|
|
1782
|
+
PYBIND11_NAMESPACE_END(detail)
|
|
1783
|
+
|
|
1784
|
+
/// Given a pointer to a member function, cast it to its `Derived` version.
|
|
1785
|
+
/// Forward everything else unchanged.
|
|
1786
|
+
template <typename /*Derived*/, typename F>
|
|
1787
|
+
auto method_adaptor(F &&f) -> decltype(std::forward<F>(f)) {
|
|
1788
|
+
return std::forward<F>(f);
|
|
1789
|
+
}
|
|
1790
|
+
|
|
1791
|
+
template <typename Derived, typename Return, typename Class, typename... Args>
|
|
1792
|
+
auto method_adaptor(Return (Class::*pmf)(Args...)) -> Return (Derived::*)(Args...) {
|
|
1793
|
+
static_assert(
|
|
1794
|
+
detail::is_accessible_base_of<Class, Derived>::value,
|
|
1795
|
+
"Cannot bind an inaccessible base class method; use a lambda definition instead");
|
|
1796
|
+
return pmf;
|
|
1797
|
+
}
|
|
1798
|
+
|
|
1799
|
+
template <typename Derived, typename Return, typename Class, typename... Args>
|
|
1800
|
+
auto method_adaptor(Return (Class::*pmf)(Args...) const) -> Return (Derived::*)(Args...) const {
|
|
1801
|
+
static_assert(
|
|
1802
|
+
detail::is_accessible_base_of<Class, Derived>::value,
|
|
1803
|
+
"Cannot bind an inaccessible base class method; use a lambda definition instead");
|
|
1804
|
+
return pmf;
|
|
1805
|
+
}
|
|
1806
|
+
|
|
1807
|
+
PYBIND11_NAMESPACE_BEGIN(detail)
|
|
1808
|
+
|
|
1809
|
+
// Helper for the property_cpp_function static member functions below.
|
|
1810
|
+
// The only purpose of these functions is to support .def_readonly & .def_readwrite.
|
|
1811
|
+
// In this context, the PM template parameter is certain to be a Pointer to a Member.
|
|
1812
|
+
// The main purpose of must_be_member_function_pointer is to make this obvious, and to guard
|
|
1813
|
+
// against accidents. As a side-effect, it also explains why the syntactical overhead for
|
|
1814
|
+
// perfect forwarding is not needed.
|
|
1815
|
+
template <typename PM>
|
|
1816
|
+
using must_be_member_function_pointer = enable_if_t<std::is_member_pointer<PM>::value, int>;
|
|
1817
|
+
|
|
1818
|
+
// Note that property_cpp_function is intentionally in the main pybind11 namespace,
|
|
1819
|
+
// because user-defined specializations could be useful.
|
|
1820
|
+
|
|
1821
|
+
// Classic (non-smart_holder) implementations for .def_readonly and .def_readwrite
|
|
1822
|
+
// getter and setter functions.
|
|
1823
|
+
// WARNING: This classic implementation can lead to dangling pointers for raw pointer members.
|
|
1824
|
+
// See test_ptr() in tests/test_class_sh_property.py
|
|
1825
|
+
// However, this implementation works as-is (and safely) for smart_holder std::shared_ptr members.
|
|
1826
|
+
template <typename T, typename D>
|
|
1827
|
+
struct property_cpp_function_classic {
|
|
1828
|
+
template <typename PM, must_be_member_function_pointer<PM> = 0>
|
|
1829
|
+
static cpp_function readonly(PM pm, const handle &hdl) {
|
|
1830
|
+
return cpp_function([pm](const T &c) -> const D & { return c.*pm; }, is_method(hdl));
|
|
1831
|
+
}
|
|
1832
|
+
|
|
1833
|
+
template <typename PM, must_be_member_function_pointer<PM> = 0>
|
|
1834
|
+
static cpp_function read(PM pm, const handle &hdl) {
|
|
1835
|
+
return readonly(pm, hdl);
|
|
1836
|
+
}
|
|
1837
|
+
|
|
1838
|
+
template <typename PM, must_be_member_function_pointer<PM> = 0>
|
|
1839
|
+
static cpp_function write(PM pm, const handle &hdl) {
|
|
1840
|
+
return cpp_function([pm](T &c, const D &value) { c.*pm = value; }, is_method(hdl));
|
|
1841
|
+
}
|
|
1842
|
+
};
|
|
1843
|
+
|
|
1844
|
+
PYBIND11_NAMESPACE_END(detail)
|
|
1845
|
+
|
|
1846
|
+
template <typename T, typename D, typename SFINAE = void>
|
|
1847
|
+
struct property_cpp_function : detail::property_cpp_function_classic<T, D> {};
|
|
1848
|
+
|
|
1849
|
+
PYBIND11_NAMESPACE_BEGIN(detail)
|
|
1850
|
+
|
|
1851
|
+
template <typename T, typename D, typename SFINAE = void>
|
|
1852
|
+
struct both_t_and_d_use_type_caster_base : std::false_type {};
|
|
1853
|
+
|
|
1854
|
+
// `T` is assumed to be equivalent to `intrinsic_t<T>`.
|
|
1855
|
+
// `D` is may or may not be equivalent to `intrinsic_t<D>`.
|
|
1856
|
+
template <typename T, typename D>
|
|
1857
|
+
struct both_t_and_d_use_type_caster_base<
|
|
1858
|
+
T,
|
|
1859
|
+
D,
|
|
1860
|
+
enable_if_t<all_of<std::is_base_of<type_caster_base<T>, type_caster<T>>,
|
|
1861
|
+
std::is_base_of<type_caster_base<intrinsic_t<D>>, make_caster<D>>>::value>>
|
|
1862
|
+
: std::true_type {};
|
|
1863
|
+
|
|
1864
|
+
// Specialization for raw pointer members, using smart_holder if that is the class_ holder,
|
|
1865
|
+
// or falling back to the classic implementation if not.
|
|
1866
|
+
// WARNING: Like the classic implementation, this implementation can lead to dangling pointers.
|
|
1867
|
+
// See test_ptr() in tests/test_class_sh_property.py
|
|
1868
|
+
// However, the read functions return a shared_ptr to the member, emulating the PyCLIF approach:
|
|
1869
|
+
// https://github.com/google/clif/blob/c371a6d4b28d25d53a16e6d2a6d97305fb1be25a/clif/python/instance.h#L233
|
|
1870
|
+
// This prevents disowning of the Python object owning the raw pointer member.
|
|
1871
|
+
template <typename T, typename D>
|
|
1872
|
+
struct property_cpp_function_sh_raw_ptr_member {
|
|
1873
|
+
using drp = typename std::remove_pointer<D>::type;
|
|
1874
|
+
|
|
1875
|
+
template <typename PM, must_be_member_function_pointer<PM> = 0>
|
|
1876
|
+
static cpp_function readonly(PM pm, const handle &hdl) {
|
|
1877
|
+
type_info *tinfo = get_type_info(typeid(T), /*throw_if_missing=*/true);
|
|
1878
|
+
if (tinfo->holder_enum_v == holder_enum_t::smart_holder) {
|
|
1879
|
+
return cpp_function(
|
|
1880
|
+
[pm](handle c_hdl) -> std::shared_ptr<drp> {
|
|
1881
|
+
std::shared_ptr<T> c_sp
|
|
1882
|
+
= type_caster<std::shared_ptr<T>>::shared_ptr_with_responsible_parent(
|
|
1883
|
+
c_hdl);
|
|
1884
|
+
D ptr = (*c_sp).*pm;
|
|
1885
|
+
return std::shared_ptr<drp>(c_sp, ptr);
|
|
1886
|
+
},
|
|
1887
|
+
is_method(hdl));
|
|
1888
|
+
}
|
|
1889
|
+
return property_cpp_function_classic<T, D>::readonly(pm, hdl);
|
|
1890
|
+
}
|
|
1891
|
+
|
|
1892
|
+
template <typename PM, must_be_member_function_pointer<PM> = 0>
|
|
1893
|
+
static cpp_function read(PM pm, const handle &hdl) {
|
|
1894
|
+
return readonly(pm, hdl);
|
|
1895
|
+
}
|
|
1896
|
+
|
|
1897
|
+
template <typename PM, must_be_member_function_pointer<PM> = 0>
|
|
1898
|
+
static cpp_function write(PM pm, const handle &hdl) {
|
|
1899
|
+
type_info *tinfo = get_type_info(typeid(T), /*throw_if_missing=*/true);
|
|
1900
|
+
if (tinfo->holder_enum_v == holder_enum_t::smart_holder) {
|
|
1901
|
+
return cpp_function([pm](T &c, D value) { c.*pm = std::forward<D>(std::move(value)); },
|
|
1902
|
+
is_method(hdl));
|
|
1903
|
+
}
|
|
1904
|
+
return property_cpp_function_classic<T, D>::write(pm, hdl);
|
|
1905
|
+
}
|
|
1906
|
+
};
|
|
1907
|
+
|
|
1908
|
+
// Specialization for members held by-value, using smart_holder if that is the class_ holder,
|
|
1909
|
+
// or falling back to the classic implementation if not.
|
|
1910
|
+
// The read functions return a shared_ptr to the member, emulating the PyCLIF approach:
|
|
1911
|
+
// https://github.com/google/clif/blob/c371a6d4b28d25d53a16e6d2a6d97305fb1be25a/clif/python/instance.h#L233
|
|
1912
|
+
// This prevents disowning of the Python object owning the member.
|
|
1913
|
+
template <typename T, typename D>
|
|
1914
|
+
struct property_cpp_function_sh_member_held_by_value {
|
|
1915
|
+
template <typename PM, must_be_member_function_pointer<PM> = 0>
|
|
1916
|
+
static cpp_function readonly(PM pm, const handle &hdl) {
|
|
1917
|
+
type_info *tinfo = get_type_info(typeid(T), /*throw_if_missing=*/true);
|
|
1918
|
+
if (tinfo->holder_enum_v == holder_enum_t::smart_holder) {
|
|
1919
|
+
return cpp_function(
|
|
1920
|
+
[pm](handle c_hdl) -> std::shared_ptr<typename std::add_const<D>::type> {
|
|
1921
|
+
std::shared_ptr<T> c_sp
|
|
1922
|
+
= type_caster<std::shared_ptr<T>>::shared_ptr_with_responsible_parent(
|
|
1923
|
+
c_hdl);
|
|
1924
|
+
return std::shared_ptr<typename std::add_const<D>::type>(c_sp,
|
|
1925
|
+
&(c_sp.get()->*pm));
|
|
1926
|
+
},
|
|
1927
|
+
is_method(hdl));
|
|
1928
|
+
}
|
|
1929
|
+
return property_cpp_function_classic<T, D>::readonly(pm, hdl);
|
|
1930
|
+
}
|
|
1931
|
+
|
|
1932
|
+
template <typename PM, must_be_member_function_pointer<PM> = 0>
|
|
1933
|
+
static cpp_function read(PM pm, const handle &hdl) {
|
|
1934
|
+
type_info *tinfo = get_type_info(typeid(T), /*throw_if_missing=*/true);
|
|
1935
|
+
if (tinfo->holder_enum_v == holder_enum_t::smart_holder) {
|
|
1936
|
+
return cpp_function(
|
|
1937
|
+
[pm](handle c_hdl) -> std::shared_ptr<D> {
|
|
1938
|
+
std::shared_ptr<T> c_sp
|
|
1939
|
+
= type_caster<std::shared_ptr<T>>::shared_ptr_with_responsible_parent(
|
|
1940
|
+
c_hdl);
|
|
1941
|
+
return std::shared_ptr<D>(c_sp, &(c_sp.get()->*pm));
|
|
1942
|
+
},
|
|
1943
|
+
is_method(hdl));
|
|
1944
|
+
}
|
|
1945
|
+
return property_cpp_function_classic<T, D>::read(pm, hdl);
|
|
1946
|
+
}
|
|
1947
|
+
|
|
1948
|
+
template <typename PM, must_be_member_function_pointer<PM> = 0>
|
|
1949
|
+
static cpp_function write(PM pm, const handle &hdl) {
|
|
1950
|
+
type_info *tinfo = get_type_info(typeid(T), /*throw_if_missing=*/true);
|
|
1951
|
+
if (tinfo->holder_enum_v == holder_enum_t::smart_holder) {
|
|
1952
|
+
return cpp_function([pm](T &c, const D &value) { c.*pm = value; }, is_method(hdl));
|
|
1953
|
+
}
|
|
1954
|
+
return property_cpp_function_classic<T, D>::write(pm, hdl);
|
|
1955
|
+
}
|
|
1956
|
+
};
|
|
1957
|
+
|
|
1958
|
+
// Specialization for std::unique_ptr members, using smart_holder if that is the class_ holder,
|
|
1959
|
+
// or falling back to the classic implementation if not.
|
|
1960
|
+
// read disowns the member unique_ptr.
|
|
1961
|
+
// write disowns the passed Python object.
|
|
1962
|
+
// readonly is disabled (static_assert) because there is no safe & intuitive way to make the member
|
|
1963
|
+
// accessible as a Python object without disowning the member unique_ptr. A .def_readonly disowning
|
|
1964
|
+
// the unique_ptr member is deemed highly prone to misunderstandings.
|
|
1965
|
+
template <typename T, typename D>
|
|
1966
|
+
struct property_cpp_function_sh_unique_ptr_member {
|
|
1967
|
+
template <typename PM, must_be_member_function_pointer<PM> = 0>
|
|
1968
|
+
static cpp_function readonly(PM, const handle &) {
|
|
1969
|
+
static_assert(!is_instantiation<std::unique_ptr, D>::value,
|
|
1970
|
+
"def_readonly cannot be used for std::unique_ptr members.");
|
|
1971
|
+
return cpp_function{}; // Unreachable.
|
|
1972
|
+
}
|
|
1973
|
+
|
|
1974
|
+
template <typename PM, must_be_member_function_pointer<PM> = 0>
|
|
1975
|
+
static cpp_function read(PM pm, const handle &hdl) {
|
|
1976
|
+
type_info *tinfo = get_type_info(typeid(T), /*throw_if_missing=*/true);
|
|
1977
|
+
if (tinfo->holder_enum_v == holder_enum_t::smart_holder) {
|
|
1978
|
+
return cpp_function(
|
|
1979
|
+
[pm](handle c_hdl) -> D {
|
|
1980
|
+
std::shared_ptr<T> c_sp
|
|
1981
|
+
= type_caster<std::shared_ptr<T>>::shared_ptr_with_responsible_parent(
|
|
1982
|
+
c_hdl);
|
|
1983
|
+
return D{std::move(c_sp.get()->*pm)};
|
|
1984
|
+
},
|
|
1985
|
+
is_method(hdl));
|
|
1986
|
+
}
|
|
1987
|
+
return property_cpp_function_classic<T, D>::read(pm, hdl);
|
|
1988
|
+
}
|
|
1989
|
+
|
|
1990
|
+
template <typename PM, must_be_member_function_pointer<PM> = 0>
|
|
1991
|
+
static cpp_function write(PM pm, const handle &hdl) {
|
|
1992
|
+
return cpp_function([pm](T &c, D &&value) { c.*pm = std::move(value); }, is_method(hdl));
|
|
1993
|
+
}
|
|
1994
|
+
};
|
|
1995
|
+
|
|
1996
|
+
PYBIND11_NAMESPACE_END(detail)
|
|
1997
|
+
|
|
1998
|
+
template <typename T, typename D>
|
|
1999
|
+
struct property_cpp_function<
|
|
2000
|
+
T,
|
|
2001
|
+
D,
|
|
2002
|
+
detail::enable_if_t<detail::all_of<std::is_pointer<D>,
|
|
2003
|
+
detail::both_t_and_d_use_type_caster_base<T, D>>::value>>
|
|
2004
|
+
: detail::property_cpp_function_sh_raw_ptr_member<T, D> {};
|
|
2005
|
+
|
|
2006
|
+
template <typename T, typename D>
|
|
2007
|
+
struct property_cpp_function<T,
|
|
2008
|
+
D,
|
|
2009
|
+
detail::enable_if_t<detail::all_of<
|
|
2010
|
+
detail::none_of<std::is_pointer<D>,
|
|
2011
|
+
std::is_array<D>,
|
|
2012
|
+
detail::is_instantiation<std::unique_ptr, D>,
|
|
2013
|
+
detail::is_instantiation<std::shared_ptr, D>>,
|
|
2014
|
+
detail::both_t_and_d_use_type_caster_base<T, D>>::value>>
|
|
2015
|
+
: detail::property_cpp_function_sh_member_held_by_value<T, D> {};
|
|
2016
|
+
|
|
2017
|
+
template <typename T, typename D>
|
|
2018
|
+
struct property_cpp_function<
|
|
2019
|
+
T,
|
|
2020
|
+
D,
|
|
2021
|
+
detail::enable_if_t<detail::all_of<
|
|
2022
|
+
detail::is_instantiation<std::unique_ptr, D>,
|
|
2023
|
+
detail::both_t_and_d_use_type_caster_base<T, typename D::element_type>>::value>>
|
|
2024
|
+
: detail::property_cpp_function_sh_unique_ptr_member<T, D> {};
|
|
2025
|
+
|
|
2026
|
+
#ifdef PYBIND11_RUN_TESTING_WITH_SMART_HOLDER_AS_DEFAULT_BUT_NEVER_USE_IN_PRODUCTION_PLEASE
|
|
2027
|
+
// NOTE: THIS IS MEANT FOR STRESS-TESTING OR TRIAGING ONLY!
|
|
2028
|
+
// Running the pybind11 unit tests with smart_holder as the default holder is to ensure
|
|
2029
|
+
// that `py::smart_holder` / `py::classh` is backward-compatible with all pre-existing
|
|
2030
|
+
// functionality.
|
|
2031
|
+
// Be careful not to link translation units compiled with different default holders, because
|
|
2032
|
+
// this will cause ODR violations (https://en.wikipedia.org/wiki/One_Definition_Rule).
|
|
2033
|
+
template <typename>
|
|
2034
|
+
using default_holder_type = smart_holder;
|
|
2035
|
+
#else
|
|
2036
|
+
template <typename T>
|
|
2037
|
+
using default_holder_type = std::unique_ptr<T>;
|
|
2038
|
+
#endif
|
|
2039
|
+
|
|
2040
|
+
template <typename type_, typename... options>
|
|
2041
|
+
class class_ : public detail::generic_type {
|
|
2042
|
+
template <typename T>
|
|
2043
|
+
using is_holder = detail::is_holder_type<type_, T>;
|
|
2044
|
+
template <typename T>
|
|
2045
|
+
using is_subtype = detail::is_strict_base_of<type_, T>;
|
|
2046
|
+
template <typename T>
|
|
2047
|
+
using is_base = detail::is_strict_base_of<T, type_>;
|
|
2048
|
+
// struct instead of using here to help MSVC:
|
|
2049
|
+
template <typename T>
|
|
2050
|
+
struct is_valid_class_option : detail::any_of<is_holder<T>, is_subtype<T>, is_base<T>> {};
|
|
2051
|
+
|
|
2052
|
+
public:
|
|
2053
|
+
using type = type_;
|
|
2054
|
+
using type_alias = detail::exactly_one_t<is_subtype, void, options...>;
|
|
2055
|
+
constexpr static bool has_alias = !std::is_void<type_alias>::value;
|
|
2056
|
+
using holder_type = detail::exactly_one_t<is_holder, default_holder_type<type>, options...>;
|
|
2057
|
+
|
|
2058
|
+
static_assert(detail::all_of<is_valid_class_option<options>...>::value,
|
|
2059
|
+
"Unknown/invalid class_ template parameters provided");
|
|
2060
|
+
|
|
2061
|
+
static_assert(!has_alias || std::is_polymorphic<type>::value,
|
|
2062
|
+
"Cannot use an alias class (aka trampoline) with a non-polymorphic type");
|
|
2063
|
+
|
|
2064
|
+
#ifndef PYBIND11_RUN_TESTING_WITH_SMART_HOLDER_AS_DEFAULT_BUT_NEVER_USE_IN_PRODUCTION_PLEASE
|
|
2065
|
+
static_assert(!has_alias || !detail::is_smart_holder<holder_type>::value
|
|
2066
|
+
|| std::is_base_of<trampoline_self_life_support, type_alias>::value,
|
|
2067
|
+
"Alias class (aka trampoline) must inherit from"
|
|
2068
|
+
" pybind11::trampoline_self_life_support if used in combination with"
|
|
2069
|
+
" pybind11::smart_holder");
|
|
2070
|
+
#endif
|
|
2071
|
+
static_assert(!has_alias || detail::is_smart_holder<holder_type>::value
|
|
2072
|
+
|| !std::is_base_of<trampoline_self_life_support, type_alias>::value,
|
|
2073
|
+
"pybind11::trampoline_self_life_support is a smart_holder feature, therefore"
|
|
2074
|
+
" an alias class (aka trampoline) should inherit from"
|
|
2075
|
+
" pybind11::trampoline_self_life_support only if used in combination with"
|
|
2076
|
+
" pybind11::smart_holder");
|
|
2077
|
+
|
|
2078
|
+
PYBIND11_OBJECT(class_, generic_type, PyType_Check)
|
|
2079
|
+
|
|
2080
|
+
template <typename... Extra>
|
|
2081
|
+
class_(handle scope, const char *name, const Extra &...extra) {
|
|
2082
|
+
using namespace detail;
|
|
2083
|
+
|
|
2084
|
+
// MI can only be specified via class_ template options, not constructor parameters
|
|
2085
|
+
static_assert(
|
|
2086
|
+
none_of<is_pyobject<Extra>...>::value || // no base class arguments, or:
|
|
2087
|
+
(constexpr_sum(is_pyobject<Extra>::value...) == 1 && // Exactly one base
|
|
2088
|
+
constexpr_sum(is_base<options>::value...) == 0 && // no template option bases
|
|
2089
|
+
// no multiple_inheritance attr
|
|
2090
|
+
none_of<std::is_same<multiple_inheritance, Extra>...>::value),
|
|
2091
|
+
"Error: multiple inheritance bases must be specified via class_ template options");
|
|
2092
|
+
|
|
2093
|
+
type_record record;
|
|
2094
|
+
record.scope = scope;
|
|
2095
|
+
record.name = name;
|
|
2096
|
+
record.type = &typeid(type);
|
|
2097
|
+
record.type_size = sizeof(conditional_t<has_alias, type_alias, type>);
|
|
2098
|
+
record.type_align = alignof(conditional_t<has_alias, type_alias, type> &);
|
|
2099
|
+
record.holder_size = sizeof(holder_type);
|
|
2100
|
+
record.init_instance = init_instance;
|
|
2101
|
+
|
|
2102
|
+
if (detail::is_instantiation<std::unique_ptr, holder_type>::value) {
|
|
2103
|
+
record.holder_enum_v = detail::holder_enum_t::std_unique_ptr;
|
|
2104
|
+
} else if (detail::is_instantiation<std::shared_ptr, holder_type>::value) {
|
|
2105
|
+
record.holder_enum_v = detail::holder_enum_t::std_shared_ptr;
|
|
2106
|
+
} else if (std::is_same<holder_type, smart_holder>::value) {
|
|
2107
|
+
record.holder_enum_v = detail::holder_enum_t::smart_holder;
|
|
2108
|
+
} else {
|
|
2109
|
+
record.holder_enum_v = detail::holder_enum_t::custom_holder;
|
|
2110
|
+
}
|
|
2111
|
+
|
|
2112
|
+
set_operator_new<type>(&record);
|
|
2113
|
+
|
|
2114
|
+
/* Register base classes specified via template arguments to class_, if any */
|
|
2115
|
+
PYBIND11_EXPAND_SIDE_EFFECTS(add_base<options>(record));
|
|
2116
|
+
|
|
2117
|
+
/* Process optional arguments, if any */
|
|
2118
|
+
process_attributes<Extra...>::init(extra..., &record);
|
|
2119
|
+
|
|
2120
|
+
if (record.release_gil_before_calling_cpp_dtor) {
|
|
2121
|
+
record.dealloc = dealloc_release_gil_before_calling_cpp_dtor;
|
|
2122
|
+
} else {
|
|
2123
|
+
record.dealloc = dealloc_without_manipulating_gil;
|
|
2124
|
+
}
|
|
2125
|
+
|
|
2126
|
+
if (std::is_base_of<trampoline_self_life_support, type_alias>::value) {
|
|
2127
|
+
// Store a cross-DSO-safe getter.
|
|
2128
|
+
// This lambda is defined in the same DSO that instantiates
|
|
2129
|
+
// class_<type, alias_type>, but it can be called safely from any other DSO.
|
|
2130
|
+
record.get_trampoline_self_life_support = [](void *type_ptr) {
|
|
2131
|
+
return dynamic_raw_ptr_cast_if_possible<trampoline_self_life_support>(
|
|
2132
|
+
static_cast<type *>(type_ptr));
|
|
2133
|
+
};
|
|
2134
|
+
}
|
|
2135
|
+
|
|
2136
|
+
generic_type::initialize(record);
|
|
2137
|
+
|
|
2138
|
+
if (has_alias) {
|
|
2139
|
+
with_internals([&](internals &internals) {
|
|
2140
|
+
auto &instances = record.module_local ? get_local_internals().registered_types_cpp
|
|
2141
|
+
: internals.registered_types_cpp;
|
|
2142
|
+
instances[std::type_index(typeid(type_alias))]
|
|
2143
|
+
= instances[std::type_index(typeid(type))];
|
|
2144
|
+
});
|
|
2145
|
+
}
|
|
2146
|
+
def("_pybind11_conduit_v1_", cpp_conduit_method);
|
|
2147
|
+
}
|
|
2148
|
+
|
|
2149
|
+
template <typename Base, detail::enable_if_t<is_base<Base>::value, int> = 0>
|
|
2150
|
+
static void add_base(detail::type_record &rec) {
|
|
2151
|
+
rec.add_base(typeid(Base), [](void *src) -> void * {
|
|
2152
|
+
return static_cast<Base *>(reinterpret_cast<type *>(src));
|
|
2153
|
+
});
|
|
2154
|
+
}
|
|
2155
|
+
|
|
2156
|
+
template <typename Base, detail::enable_if_t<!is_base<Base>::value, int> = 0>
|
|
2157
|
+
static void add_base(detail::type_record &) {}
|
|
2158
|
+
|
|
2159
|
+
template <typename Func, typename... Extra>
|
|
2160
|
+
class_ &def(const char *name_, Func &&f, const Extra &...extra) {
|
|
2161
|
+
cpp_function cf(method_adaptor<type>(std::forward<Func>(f)),
|
|
2162
|
+
name(name_),
|
|
2163
|
+
is_method(*this),
|
|
2164
|
+
sibling(getattr(*this, name_, none())),
|
|
2165
|
+
extra...);
|
|
2166
|
+
add_class_method(*this, name_, cf);
|
|
2167
|
+
return *this;
|
|
2168
|
+
}
|
|
2169
|
+
|
|
2170
|
+
template <typename Func, typename... Extra>
|
|
2171
|
+
class_ &def_static(const char *name_, Func &&f, const Extra &...extra) {
|
|
2172
|
+
static_assert(!std::is_member_function_pointer<Func>::value,
|
|
2173
|
+
"def_static(...) called with a non-static member function pointer");
|
|
2174
|
+
cpp_function cf(std::forward<Func>(f),
|
|
2175
|
+
name(name_),
|
|
2176
|
+
scope(*this),
|
|
2177
|
+
sibling(getattr(*this, name_, none())),
|
|
2178
|
+
extra...);
|
|
2179
|
+
auto cf_name = cf.name();
|
|
2180
|
+
attr(std::move(cf_name)) = staticmethod(std::move(cf));
|
|
2181
|
+
return *this;
|
|
2182
|
+
}
|
|
2183
|
+
|
|
2184
|
+
template <typename T, typename... Extra, detail::enable_if_t<T::op_enable_if_hook, int> = 0>
|
|
2185
|
+
class_ &def(const T &op, const Extra &...extra) {
|
|
2186
|
+
op.execute(*this, extra...);
|
|
2187
|
+
return *this;
|
|
2188
|
+
}
|
|
2189
|
+
|
|
2190
|
+
template <typename T, typename... Extra, detail::enable_if_t<T::op_enable_if_hook, int> = 0>
|
|
2191
|
+
class_ &def_cast(const T &op, const Extra &...extra) {
|
|
2192
|
+
op.execute_cast(*this, extra...);
|
|
2193
|
+
return *this;
|
|
2194
|
+
}
|
|
2195
|
+
|
|
2196
|
+
template <typename... Args, typename... Extra>
|
|
2197
|
+
class_ &def(const detail::initimpl::constructor<Args...> &init, const Extra &...extra) {
|
|
2198
|
+
PYBIND11_WORKAROUND_INCORRECT_MSVC_C4100(init);
|
|
2199
|
+
init.execute(*this, extra...);
|
|
2200
|
+
return *this;
|
|
2201
|
+
}
|
|
2202
|
+
|
|
2203
|
+
template <typename... Args, typename... Extra>
|
|
2204
|
+
class_ &def(const detail::initimpl::alias_constructor<Args...> &init, const Extra &...extra) {
|
|
2205
|
+
PYBIND11_WORKAROUND_INCORRECT_MSVC_C4100(init);
|
|
2206
|
+
init.execute(*this, extra...);
|
|
2207
|
+
return *this;
|
|
2208
|
+
}
|
|
2209
|
+
|
|
2210
|
+
template <typename... Args, typename... Extra>
|
|
2211
|
+
class_ &def(detail::initimpl::factory<Args...> &&init, const Extra &...extra) {
|
|
2212
|
+
std::move(init).execute(*this, extra...);
|
|
2213
|
+
return *this;
|
|
2214
|
+
}
|
|
2215
|
+
|
|
2216
|
+
template <typename... Args, typename... Extra>
|
|
2217
|
+
class_ &def(detail::initimpl::pickle_factory<Args...> &&pf, const Extra &...extra) {
|
|
2218
|
+
std::move(pf).execute(*this, extra...);
|
|
2219
|
+
return *this;
|
|
2220
|
+
}
|
|
2221
|
+
|
|
2222
|
+
template <typename Func>
|
|
2223
|
+
class_ &def_buffer(Func &&func) {
|
|
2224
|
+
struct capture {
|
|
2225
|
+
Func func;
|
|
2226
|
+
};
|
|
2227
|
+
auto *ptr = new capture{std::forward<Func>(func)};
|
|
2228
|
+
install_buffer_funcs(
|
|
2229
|
+
[](PyObject *obj, void *ptr) -> buffer_info * {
|
|
2230
|
+
detail::make_caster<type> caster;
|
|
2231
|
+
if (!caster.load(obj, false)) {
|
|
2232
|
+
return nullptr;
|
|
2233
|
+
}
|
|
2234
|
+
return new buffer_info(((capture *) ptr)->func(std::move(caster)));
|
|
2235
|
+
},
|
|
2236
|
+
ptr);
|
|
2237
|
+
weakref(m_ptr, cpp_function([ptr](handle wr) {
|
|
2238
|
+
delete ptr;
|
|
2239
|
+
wr.dec_ref();
|
|
2240
|
+
}))
|
|
2241
|
+
.release();
|
|
2242
|
+
return *this;
|
|
2243
|
+
}
|
|
2244
|
+
|
|
2245
|
+
template <typename Return, typename Class, typename... Args>
|
|
2246
|
+
class_ &def_buffer(Return (Class::*func)(Args...)) {
|
|
2247
|
+
return def_buffer([func](type &obj) { return (obj.*func)(); });
|
|
2248
|
+
}
|
|
2249
|
+
|
|
2250
|
+
template <typename Return, typename Class, typename... Args>
|
|
2251
|
+
class_ &def_buffer(Return (Class::*func)(Args...) const) {
|
|
2252
|
+
return def_buffer([func](const type &obj) { return (obj.*func)(); });
|
|
2253
|
+
}
|
|
2254
|
+
|
|
2255
|
+
template <typename C, typename D, typename... Extra>
|
|
2256
|
+
class_ &def_readwrite(const char *name, D C::*pm, const Extra &...extra) {
|
|
2257
|
+
static_assert(std::is_same<C, type>::value || std::is_base_of<C, type>::value,
|
|
2258
|
+
"def_readwrite() requires a class member (or base class member)");
|
|
2259
|
+
def_property(name,
|
|
2260
|
+
property_cpp_function<type, D>::read(pm, *this),
|
|
2261
|
+
property_cpp_function<type, D>::write(pm, *this),
|
|
2262
|
+
return_value_policy::reference_internal,
|
|
2263
|
+
extra...);
|
|
2264
|
+
return *this;
|
|
2265
|
+
}
|
|
2266
|
+
|
|
2267
|
+
template <typename C, typename D, typename... Extra>
|
|
2268
|
+
class_ &def_readonly(const char *name, const D C::*pm, const Extra &...extra) {
|
|
2269
|
+
static_assert(std::is_same<C, type>::value || std::is_base_of<C, type>::value,
|
|
2270
|
+
"def_readonly() requires a class member (or base class member)");
|
|
2271
|
+
def_property_readonly(name,
|
|
2272
|
+
property_cpp_function<type, D>::readonly(pm, *this),
|
|
2273
|
+
return_value_policy::reference_internal,
|
|
2274
|
+
extra...);
|
|
2275
|
+
return *this;
|
|
2276
|
+
}
|
|
2277
|
+
|
|
2278
|
+
template <typename D, typename... Extra>
|
|
2279
|
+
class_ &def_readwrite_static(const char *name, D *pm, const Extra &...extra) {
|
|
2280
|
+
cpp_function fget([pm](const object &) -> const D & { return *pm; }, scope(*this)),
|
|
2281
|
+
fset([pm](const object &, const D &value) { *pm = value; }, scope(*this));
|
|
2282
|
+
def_property_static(name, fget, fset, return_value_policy::reference, extra...);
|
|
2283
|
+
return *this;
|
|
2284
|
+
}
|
|
2285
|
+
|
|
2286
|
+
template <typename D, typename... Extra>
|
|
2287
|
+
class_ &def_readonly_static(const char *name, const D *pm, const Extra &...extra) {
|
|
2288
|
+
cpp_function fget([pm](const object &) -> const D & { return *pm; }, scope(*this));
|
|
2289
|
+
def_property_readonly_static(name, fget, return_value_policy::reference, extra...);
|
|
2290
|
+
return *this;
|
|
2291
|
+
}
|
|
2292
|
+
|
|
2293
|
+
/// Uses return_value_policy::reference_internal by default
|
|
2294
|
+
template <typename Getter, typename... Extra>
|
|
2295
|
+
class_ &def_property_readonly(const char *name, const Getter &fget, const Extra &...extra) {
|
|
2296
|
+
return def_property_readonly(name,
|
|
2297
|
+
cpp_function(method_adaptor<type>(fget)),
|
|
2298
|
+
return_value_policy::reference_internal,
|
|
2299
|
+
extra...);
|
|
2300
|
+
}
|
|
2301
|
+
|
|
2302
|
+
/// Uses cpp_function's return_value_policy by default
|
|
2303
|
+
template <typename... Extra>
|
|
2304
|
+
class_ &
|
|
2305
|
+
def_property_readonly(const char *name, const cpp_function &fget, const Extra &...extra) {
|
|
2306
|
+
return def_property(name, fget, nullptr, extra...);
|
|
2307
|
+
}
|
|
2308
|
+
|
|
2309
|
+
/// Uses return_value_policy::reference by default
|
|
2310
|
+
template <typename Getter, typename... Extra>
|
|
2311
|
+
class_ &
|
|
2312
|
+
def_property_readonly_static(const char *name, const Getter &fget, const Extra &...extra) {
|
|
2313
|
+
return def_property_readonly_static(
|
|
2314
|
+
name, cpp_function(fget), return_value_policy::reference, extra...);
|
|
2315
|
+
}
|
|
2316
|
+
|
|
2317
|
+
/// Uses cpp_function's return_value_policy by default
|
|
2318
|
+
template <typename... Extra>
|
|
2319
|
+
class_ &def_property_readonly_static(const char *name,
|
|
2320
|
+
const cpp_function &fget,
|
|
2321
|
+
const Extra &...extra) {
|
|
2322
|
+
return def_property_static(name, fget, nullptr, extra...);
|
|
2323
|
+
}
|
|
2324
|
+
|
|
2325
|
+
/// Uses return_value_policy::reference_internal by default
|
|
2326
|
+
template <typename Getter, typename Setter, typename... Extra>
|
|
2327
|
+
class_ &
|
|
2328
|
+
def_property(const char *name, const Getter &fget, const Setter &fset, const Extra &...extra) {
|
|
2329
|
+
return def_property(
|
|
2330
|
+
name, fget, cpp_function(method_adaptor<type>(fset), is_setter()), extra...);
|
|
2331
|
+
}
|
|
2332
|
+
template <typename Getter, typename... Extra>
|
|
2333
|
+
class_ &def_property(const char *name,
|
|
2334
|
+
const Getter &fget,
|
|
2335
|
+
const cpp_function &fset,
|
|
2336
|
+
const Extra &...extra) {
|
|
2337
|
+
return def_property(name,
|
|
2338
|
+
cpp_function(method_adaptor<type>(fget)),
|
|
2339
|
+
fset,
|
|
2340
|
+
return_value_policy::reference_internal,
|
|
2341
|
+
extra...);
|
|
2342
|
+
}
|
|
2343
|
+
|
|
2344
|
+
/// Uses cpp_function's return_value_policy by default
|
|
2345
|
+
template <typename... Extra>
|
|
2346
|
+
class_ &def_property(const char *name,
|
|
2347
|
+
const cpp_function &fget,
|
|
2348
|
+
const cpp_function &fset,
|
|
2349
|
+
const Extra &...extra) {
|
|
2350
|
+
return def_property_static(name, fget, fset, is_method(*this), extra...);
|
|
2351
|
+
}
|
|
2352
|
+
|
|
2353
|
+
/// Uses return_value_policy::reference by default
|
|
2354
|
+
template <typename Getter, typename... Extra>
|
|
2355
|
+
class_ &def_property_static(const char *name,
|
|
2356
|
+
const Getter &fget,
|
|
2357
|
+
const cpp_function &fset,
|
|
2358
|
+
const Extra &...extra) {
|
|
2359
|
+
return def_property_static(
|
|
2360
|
+
name, cpp_function(fget), fset, return_value_policy::reference, extra...);
|
|
2361
|
+
}
|
|
2362
|
+
|
|
2363
|
+
/// Uses cpp_function's return_value_policy by default
|
|
2364
|
+
template <typename... Extra>
|
|
2365
|
+
class_ &def_property_static(const char *name,
|
|
2366
|
+
const cpp_function &fget,
|
|
2367
|
+
const cpp_function &fset,
|
|
2368
|
+
const Extra &...extra) {
|
|
2369
|
+
static_assert(0 == detail::constexpr_sum(std::is_base_of<arg, Extra>::value...),
|
|
2370
|
+
"Argument annotations are not allowed for properties");
|
|
2371
|
+
auto rec_fget = get_function_record(fget), rec_fset = get_function_record(fset);
|
|
2372
|
+
auto *rec_active = rec_fget;
|
|
2373
|
+
if (rec_fget) {
|
|
2374
|
+
char *doc_prev = rec_fget->doc; /* 'extra' field may include a property-specific
|
|
2375
|
+
documentation string */
|
|
2376
|
+
detail::process_attributes<Extra...>::init(extra..., rec_fget);
|
|
2377
|
+
if (rec_fget->doc && rec_fget->doc != doc_prev) {
|
|
2378
|
+
std::free(doc_prev);
|
|
2379
|
+
rec_fget->doc = PYBIND11_COMPAT_STRDUP(rec_fget->doc);
|
|
2380
|
+
}
|
|
2381
|
+
}
|
|
2382
|
+
if (rec_fset) {
|
|
2383
|
+
char *doc_prev = rec_fset->doc;
|
|
2384
|
+
detail::process_attributes<Extra...>::init(extra..., rec_fset);
|
|
2385
|
+
if (rec_fset->doc && rec_fset->doc != doc_prev) {
|
|
2386
|
+
std::free(doc_prev);
|
|
2387
|
+
rec_fset->doc = PYBIND11_COMPAT_STRDUP(rec_fset->doc);
|
|
2388
|
+
}
|
|
2389
|
+
if (!rec_active) {
|
|
2390
|
+
rec_active = rec_fset;
|
|
2391
|
+
}
|
|
2392
|
+
}
|
|
2393
|
+
def_property_static_impl(name, fget, fset, rec_active);
|
|
2394
|
+
return *this;
|
|
2395
|
+
}
|
|
2396
|
+
|
|
2397
|
+
private:
|
|
2398
|
+
/// Initialize holder object, variant 1: object derives from enable_shared_from_this
|
|
2399
|
+
template <typename T>
|
|
2400
|
+
static void init_holder(detail::instance *inst,
|
|
2401
|
+
detail::value_and_holder &v_h,
|
|
2402
|
+
const holder_type * /* unused */,
|
|
2403
|
+
const std::enable_shared_from_this<T> * /* dummy */) {
|
|
2404
|
+
|
|
2405
|
+
auto sh = std::dynamic_pointer_cast<typename holder_type::element_type>(
|
|
2406
|
+
detail::try_get_shared_from_this(v_h.value_ptr<type>()));
|
|
2407
|
+
if (sh) {
|
|
2408
|
+
new (std::addressof(v_h.holder<holder_type>())) holder_type(std::move(sh));
|
|
2409
|
+
v_h.set_holder_constructed();
|
|
2410
|
+
}
|
|
2411
|
+
|
|
2412
|
+
if (!v_h.holder_constructed() && inst->owned) {
|
|
2413
|
+
new (std::addressof(v_h.holder<holder_type>())) holder_type(v_h.value_ptr<type>());
|
|
2414
|
+
v_h.set_holder_constructed();
|
|
2415
|
+
}
|
|
2416
|
+
}
|
|
2417
|
+
|
|
2418
|
+
static void init_holder_from_existing(const detail::value_and_holder &v_h,
|
|
2419
|
+
const holder_type *holder_ptr,
|
|
2420
|
+
std::true_type /*is_copy_constructible*/) {
|
|
2421
|
+
new (std::addressof(v_h.holder<holder_type>()))
|
|
2422
|
+
holder_type(*reinterpret_cast<const holder_type *>(holder_ptr));
|
|
2423
|
+
}
|
|
2424
|
+
|
|
2425
|
+
static void init_holder_from_existing(const detail::value_and_holder &v_h,
|
|
2426
|
+
const holder_type *holder_ptr,
|
|
2427
|
+
std::false_type /*is_copy_constructible*/) {
|
|
2428
|
+
new (std::addressof(v_h.holder<holder_type>()))
|
|
2429
|
+
holder_type(std::move(*const_cast<holder_type *>(holder_ptr)));
|
|
2430
|
+
}
|
|
2431
|
+
|
|
2432
|
+
/// Initialize holder object, variant 2: try to construct from existing holder object, if
|
|
2433
|
+
/// possible
|
|
2434
|
+
static void init_holder(detail::instance *inst,
|
|
2435
|
+
detail::value_and_holder &v_h,
|
|
2436
|
+
const holder_type *holder_ptr,
|
|
2437
|
+
const void * /* dummy -- not enable_shared_from_this<T>) */) {
|
|
2438
|
+
if (holder_ptr) {
|
|
2439
|
+
init_holder_from_existing(v_h, holder_ptr, std::is_copy_constructible<holder_type>());
|
|
2440
|
+
v_h.set_holder_constructed();
|
|
2441
|
+
} else if (detail::always_construct_holder<holder_type>::value || inst->owned) {
|
|
2442
|
+
new (std::addressof(v_h.holder<holder_type>())) holder_type(v_h.value_ptr<type>());
|
|
2443
|
+
v_h.set_holder_constructed();
|
|
2444
|
+
}
|
|
2445
|
+
}
|
|
2446
|
+
|
|
2447
|
+
/// Performs instance initialization including constructing a holder and registering the known
|
|
2448
|
+
/// instance. Should be called as soon as the `type` value_ptr is set for an instance. Takes
|
|
2449
|
+
/// an optional pointer to an existing holder to use; if not specified and the instance is
|
|
2450
|
+
/// `.owned`, a new holder will be constructed to manage the value pointer.
|
|
2451
|
+
template <typename H = holder_type,
|
|
2452
|
+
detail::enable_if_t<!detail::is_smart_holder<H>::value, int> = 0>
|
|
2453
|
+
static void init_instance(detail::instance *inst, const void *holder_ptr) {
|
|
2454
|
+
auto v_h = inst->get_value_and_holder(detail::get_type_info(typeid(type)));
|
|
2455
|
+
if (!v_h.instance_registered()) {
|
|
2456
|
+
register_instance(inst, v_h.value_ptr(), v_h.type);
|
|
2457
|
+
v_h.set_instance_registered();
|
|
2458
|
+
}
|
|
2459
|
+
init_holder(inst, v_h, (const holder_type *) holder_ptr, v_h.value_ptr<type>());
|
|
2460
|
+
}
|
|
2461
|
+
|
|
2462
|
+
template <typename WrappedType>
|
|
2463
|
+
static bool try_initialization_using_shared_from_this(holder_type *, WrappedType *, ...) {
|
|
2464
|
+
return false;
|
|
2465
|
+
}
|
|
2466
|
+
|
|
2467
|
+
// Adopting existing approach used by type_caster_base, although it leads to somewhat fuzzy
|
|
2468
|
+
// ownership semantics: if we detected via shared_from_this that a shared_ptr exists already,
|
|
2469
|
+
// it is reused, irrespective of the return_value_policy in effect.
|
|
2470
|
+
// "SomeBaseOfWrappedType" is needed because std::enable_shared_from_this is not necessarily a
|
|
2471
|
+
// direct base of WrappedType.
|
|
2472
|
+
template <typename WrappedType, typename SomeBaseOfWrappedType>
|
|
2473
|
+
static bool try_initialization_using_shared_from_this(
|
|
2474
|
+
holder_type *uninitialized_location,
|
|
2475
|
+
WrappedType *value_ptr_w_t,
|
|
2476
|
+
const std::enable_shared_from_this<SomeBaseOfWrappedType> *) {
|
|
2477
|
+
auto shd_ptr = std::dynamic_pointer_cast<WrappedType>(
|
|
2478
|
+
detail::try_get_shared_from_this(value_ptr_w_t));
|
|
2479
|
+
if (!shd_ptr) {
|
|
2480
|
+
return false;
|
|
2481
|
+
}
|
|
2482
|
+
// Note: inst->owned ignored.
|
|
2483
|
+
new (uninitialized_location) holder_type(holder_type::from_shared_ptr(shd_ptr));
|
|
2484
|
+
return true;
|
|
2485
|
+
}
|
|
2486
|
+
|
|
2487
|
+
template <typename H = holder_type,
|
|
2488
|
+
detail::enable_if_t<detail::is_smart_holder<H>::value, int> = 0>
|
|
2489
|
+
static void init_instance(detail::instance *inst, const void *holder_const_void_ptr) {
|
|
2490
|
+
// Need for const_cast is a consequence of the type_info::init_instance type:
|
|
2491
|
+
// void (*init_instance)(instance *, const void *);
|
|
2492
|
+
auto *holder_void_ptr = const_cast<void *>(holder_const_void_ptr);
|
|
2493
|
+
|
|
2494
|
+
auto v_h = inst->get_value_and_holder(detail::get_type_info(typeid(type)));
|
|
2495
|
+
if (!v_h.instance_registered()) {
|
|
2496
|
+
register_instance(inst, v_h.value_ptr(), v_h.type);
|
|
2497
|
+
v_h.set_instance_registered();
|
|
2498
|
+
}
|
|
2499
|
+
auto *uninitialized_location = std::addressof(v_h.holder<holder_type>());
|
|
2500
|
+
auto *value_ptr_w_t = v_h.value_ptr<type>();
|
|
2501
|
+
// Try downcast from `type` to `type_alias`:
|
|
2502
|
+
inst->is_alias
|
|
2503
|
+
= detail::dynamic_raw_ptr_cast_if_possible<type_alias>(value_ptr_w_t) != nullptr;
|
|
2504
|
+
if (holder_void_ptr) {
|
|
2505
|
+
// Note: inst->owned ignored.
|
|
2506
|
+
auto *holder_ptr = static_cast<holder_type *>(holder_void_ptr);
|
|
2507
|
+
new (uninitialized_location) holder_type(std::move(*holder_ptr));
|
|
2508
|
+
} else if (!try_initialization_using_shared_from_this(
|
|
2509
|
+
uninitialized_location, value_ptr_w_t, value_ptr_w_t)) {
|
|
2510
|
+
if (inst->owned) {
|
|
2511
|
+
new (uninitialized_location) holder_type(holder_type::from_raw_ptr_take_ownership(
|
|
2512
|
+
value_ptr_w_t, /*void_cast_raw_ptr*/ inst->is_alias));
|
|
2513
|
+
} else {
|
|
2514
|
+
new (uninitialized_location)
|
|
2515
|
+
holder_type(holder_type::from_raw_ptr_unowned(value_ptr_w_t));
|
|
2516
|
+
}
|
|
2517
|
+
}
|
|
2518
|
+
v_h.set_holder_constructed();
|
|
2519
|
+
}
|
|
2520
|
+
|
|
2521
|
+
// Deallocates an instance; via holder, if constructed; otherwise via operator delete.
|
|
2522
|
+
// NOTE: The Python error indicator needs to cleared BEFORE this function is called.
|
|
2523
|
+
// This is because we could be deallocating while cleaning up after a Python exception.
|
|
2524
|
+
// If the error indicator is not cleared but the C++ destructor code makes Python C API
|
|
2525
|
+
// calls, those calls are likely to generate a new exception, and pybind11 will then
|
|
2526
|
+
// throw `error_already_set` from the C++ destructor. This is forbidden and will
|
|
2527
|
+
// trigger std::terminate().
|
|
2528
|
+
static void dealloc_impl(detail::value_and_holder &v_h) {
|
|
2529
|
+
if (v_h.holder_constructed()) {
|
|
2530
|
+
v_h.holder<holder_type>().~holder_type();
|
|
2531
|
+
v_h.set_holder_constructed(false);
|
|
2532
|
+
} else {
|
|
2533
|
+
detail::call_operator_delete(
|
|
2534
|
+
v_h.value_ptr<type>(), v_h.type->type_size, v_h.type->type_align);
|
|
2535
|
+
}
|
|
2536
|
+
v_h.value_ptr() = nullptr;
|
|
2537
|
+
}
|
|
2538
|
+
|
|
2539
|
+
static void dealloc_without_manipulating_gil(detail::value_and_holder &v_h) {
|
|
2540
|
+
error_scope scope;
|
|
2541
|
+
dealloc_impl(v_h);
|
|
2542
|
+
}
|
|
2543
|
+
|
|
2544
|
+
static void dealloc_release_gil_before_calling_cpp_dtor(detail::value_and_holder &v_h) {
|
|
2545
|
+
error_scope scope;
|
|
2546
|
+
// Intentionally not using `gil_scoped_release` because the non-simple
|
|
2547
|
+
// version unconditionally calls `get_internals()`.
|
|
2548
|
+
// `Py_BEGIN_ALLOW_THREADS`, `Py_END_ALLOW_THREADS` cannot be used
|
|
2549
|
+
// because those macros include `{` and `}`.
|
|
2550
|
+
PyThreadState *py_ts = PyEval_SaveThread();
|
|
2551
|
+
try {
|
|
2552
|
+
dealloc_impl(v_h);
|
|
2553
|
+
} catch (...) {
|
|
2554
|
+
// This code path is expected to be unreachable unless there is a
|
|
2555
|
+
// bug in pybind11 itself.
|
|
2556
|
+
// An alternative would be to mark this function, or
|
|
2557
|
+
// `dealloc_impl()`, with `nothrow`, but that would be a subtle
|
|
2558
|
+
// behavior change and could make debugging more difficult.
|
|
2559
|
+
PyEval_RestoreThread(py_ts);
|
|
2560
|
+
throw;
|
|
2561
|
+
}
|
|
2562
|
+
PyEval_RestoreThread(py_ts);
|
|
2563
|
+
}
|
|
2564
|
+
|
|
2565
|
+
static detail::function_record *get_function_record(handle h) {
|
|
2566
|
+
h = detail::get_function(h);
|
|
2567
|
+
if (!h) {
|
|
2568
|
+
return nullptr;
|
|
2569
|
+
}
|
|
2570
|
+
|
|
2571
|
+
handle func_self = PyCFunction_GET_SELF(h.ptr());
|
|
2572
|
+
if (!func_self) {
|
|
2573
|
+
throw error_already_set();
|
|
2574
|
+
}
|
|
2575
|
+
return detail::function_record_ptr_from_PyObject(func_self.ptr());
|
|
2576
|
+
}
|
|
2577
|
+
};
|
|
2578
|
+
|
|
2579
|
+
// Supports easier switching between py::class_<T> and py::class_<T, py::smart_holder>:
|
|
2580
|
+
// users can simply replace the `_` in `class_` with `h` or vice versa.
|
|
2581
|
+
template <typename type_, typename... options>
|
|
2582
|
+
using classh = class_<type_, smart_holder, options...>;
|
|
2583
|
+
|
|
2584
|
+
/// Binds an existing constructor taking arguments Args...
|
|
2585
|
+
template <typename... Args>
|
|
2586
|
+
detail::initimpl::constructor<Args...> init() {
|
|
2587
|
+
return {};
|
|
2588
|
+
}
|
|
2589
|
+
/// Like `init<Args...>()`, but the instance is always constructed through the alias class (even
|
|
2590
|
+
/// when not inheriting on the Python side).
|
|
2591
|
+
template <typename... Args>
|
|
2592
|
+
detail::initimpl::alias_constructor<Args...> init_alias() {
|
|
2593
|
+
return {};
|
|
2594
|
+
}
|
|
2595
|
+
|
|
2596
|
+
/// Binds a factory function as a constructor
|
|
2597
|
+
template <typename Func, typename Ret = detail::initimpl::factory<Func>>
|
|
2598
|
+
Ret init(Func &&f) {
|
|
2599
|
+
return {std::forward<Func>(f)};
|
|
2600
|
+
}
|
|
2601
|
+
|
|
2602
|
+
/// Dual-argument factory function: the first function is called when no alias is needed, the
|
|
2603
|
+
/// second when an alias is needed (i.e. due to python-side inheritance). Arguments must be
|
|
2604
|
+
/// identical.
|
|
2605
|
+
template <typename CFunc, typename AFunc, typename Ret = detail::initimpl::factory<CFunc, AFunc>>
|
|
2606
|
+
Ret init(CFunc &&c, AFunc &&a) {
|
|
2607
|
+
return {std::forward<CFunc>(c), std::forward<AFunc>(a)};
|
|
2608
|
+
}
|
|
2609
|
+
|
|
2610
|
+
/// Binds pickling functions `__getstate__` and `__setstate__` and ensures that the type
|
|
2611
|
+
/// returned by `__getstate__` is the same as the argument accepted by `__setstate__`.
|
|
2612
|
+
template <typename GetState, typename SetState>
|
|
2613
|
+
detail::initimpl::pickle_factory<GetState, SetState> pickle(GetState &&g, SetState &&s) {
|
|
2614
|
+
return {std::forward<GetState>(g), std::forward<SetState>(s)};
|
|
2615
|
+
}
|
|
2616
|
+
|
|
2617
|
+
PYBIND11_NAMESPACE_BEGIN(detail)
|
|
2618
|
+
|
|
2619
|
+
inline str enum_name(handle arg) {
|
|
2620
|
+
dict entries = type::handle_of(arg).attr("__entries");
|
|
2621
|
+
for (auto kv : entries) {
|
|
2622
|
+
if (handle(kv.second[int_(0)]).equal(arg)) {
|
|
2623
|
+
return pybind11::str(kv.first);
|
|
2624
|
+
}
|
|
2625
|
+
}
|
|
2626
|
+
return "???";
|
|
2627
|
+
}
|
|
2628
|
+
|
|
2629
|
+
struct enum_base {
|
|
2630
|
+
enum_base(const handle &base, const handle &parent) : m_base(base), m_parent(parent) {}
|
|
2631
|
+
|
|
2632
|
+
PYBIND11_NOINLINE void init(bool is_arithmetic, bool is_convertible) {
|
|
2633
|
+
m_base.attr("__entries") = dict();
|
|
2634
|
+
auto property = handle((PyObject *) &PyProperty_Type);
|
|
2635
|
+
auto static_property = handle((PyObject *) get_internals().static_property_type);
|
|
2636
|
+
|
|
2637
|
+
m_base.attr("__repr__") = cpp_function(
|
|
2638
|
+
[](const object &arg) -> str {
|
|
2639
|
+
handle type = type::handle_of(arg);
|
|
2640
|
+
object type_name = type.attr("__name__");
|
|
2641
|
+
return pybind11::str("<{}.{}: {}>")
|
|
2642
|
+
.format(std::move(type_name), enum_name(arg), int_(arg));
|
|
2643
|
+
},
|
|
2644
|
+
name("__repr__"),
|
|
2645
|
+
is_method(m_base),
|
|
2646
|
+
pos_only());
|
|
2647
|
+
|
|
2648
|
+
m_base.attr("name")
|
|
2649
|
+
= property(cpp_function(&enum_name, name("name"), is_method(m_base), pos_only()));
|
|
2650
|
+
|
|
2651
|
+
m_base.attr("__str__") = cpp_function(
|
|
2652
|
+
[](handle arg) -> str {
|
|
2653
|
+
object type_name = type::handle_of(arg).attr("__name__");
|
|
2654
|
+
return pybind11::str("{}.{}").format(std::move(type_name), enum_name(arg));
|
|
2655
|
+
},
|
|
2656
|
+
name("__str__"),
|
|
2657
|
+
is_method(m_base),
|
|
2658
|
+
pos_only());
|
|
2659
|
+
|
|
2660
|
+
if (options::show_enum_members_docstring()) {
|
|
2661
|
+
m_base.attr("__doc__") = static_property(
|
|
2662
|
+
cpp_function(
|
|
2663
|
+
[](handle arg) -> std::string {
|
|
2664
|
+
std::string docstring;
|
|
2665
|
+
dict entries = arg.attr("__entries");
|
|
2666
|
+
if (((PyTypeObject *) arg.ptr())->tp_doc) {
|
|
2667
|
+
docstring += std::string(
|
|
2668
|
+
reinterpret_cast<PyTypeObject *>(arg.ptr())->tp_doc);
|
|
2669
|
+
docstring += "\n\n";
|
|
2670
|
+
}
|
|
2671
|
+
docstring += "Members:";
|
|
2672
|
+
for (auto kv : entries) {
|
|
2673
|
+
auto key = std::string(pybind11::str(kv.first));
|
|
2674
|
+
auto comment = kv.second[int_(1)];
|
|
2675
|
+
docstring += "\n\n ";
|
|
2676
|
+
docstring += key;
|
|
2677
|
+
if (!comment.is_none()) {
|
|
2678
|
+
docstring += " : ";
|
|
2679
|
+
docstring += pybind11::str(comment).cast<std::string>();
|
|
2680
|
+
}
|
|
2681
|
+
}
|
|
2682
|
+
return docstring;
|
|
2683
|
+
},
|
|
2684
|
+
name("__doc__")),
|
|
2685
|
+
none(),
|
|
2686
|
+
none(),
|
|
2687
|
+
"");
|
|
2688
|
+
}
|
|
2689
|
+
|
|
2690
|
+
m_base.attr("__members__") = static_property(cpp_function(
|
|
2691
|
+
[](handle arg) -> dict {
|
|
2692
|
+
dict entries = arg.attr("__entries"),
|
|
2693
|
+
m;
|
|
2694
|
+
for (auto kv : entries) {
|
|
2695
|
+
m[kv.first] = kv.second[int_(0)];
|
|
2696
|
+
}
|
|
2697
|
+
return m;
|
|
2698
|
+
},
|
|
2699
|
+
name("__members__")),
|
|
2700
|
+
none(),
|
|
2701
|
+
none(),
|
|
2702
|
+
"");
|
|
2703
|
+
|
|
2704
|
+
#define PYBIND11_ENUM_OP_STRICT(op, expr, strict_behavior) \
|
|
2705
|
+
m_base.attr(op) = cpp_function( \
|
|
2706
|
+
[](const object &a, const object &b) { \
|
|
2707
|
+
if (!type::handle_of(a).is(type::handle_of(b))) \
|
|
2708
|
+
strict_behavior; /* NOLINT(bugprone-macro-parentheses) */ \
|
|
2709
|
+
return expr; \
|
|
2710
|
+
}, \
|
|
2711
|
+
name(op), \
|
|
2712
|
+
is_method(m_base), \
|
|
2713
|
+
arg("other"), \
|
|
2714
|
+
pos_only())
|
|
2715
|
+
|
|
2716
|
+
#define PYBIND11_ENUM_OP_CONV(op, expr) \
|
|
2717
|
+
m_base.attr(op) = cpp_function( \
|
|
2718
|
+
[](const object &a_, const object &b_) { \
|
|
2719
|
+
int_ a(a_), b(b_); \
|
|
2720
|
+
return expr; \
|
|
2721
|
+
}, \
|
|
2722
|
+
name(op), \
|
|
2723
|
+
is_method(m_base), \
|
|
2724
|
+
arg("other"), \
|
|
2725
|
+
pos_only())
|
|
2726
|
+
|
|
2727
|
+
#define PYBIND11_ENUM_OP_CONV_LHS(op, expr) \
|
|
2728
|
+
m_base.attr(op) = cpp_function( \
|
|
2729
|
+
[](const object &a_, const object &b) { \
|
|
2730
|
+
int_ a(a_); \
|
|
2731
|
+
return expr; \
|
|
2732
|
+
}, \
|
|
2733
|
+
name(op), \
|
|
2734
|
+
is_method(m_base), \
|
|
2735
|
+
arg("other"), \
|
|
2736
|
+
pos_only())
|
|
2737
|
+
|
|
2738
|
+
if (is_convertible) {
|
|
2739
|
+
PYBIND11_ENUM_OP_CONV_LHS("__eq__", !b.is_none() && a.equal(b));
|
|
2740
|
+
PYBIND11_ENUM_OP_CONV_LHS("__ne__", b.is_none() || !a.equal(b));
|
|
2741
|
+
|
|
2742
|
+
if (is_arithmetic) {
|
|
2743
|
+
PYBIND11_ENUM_OP_CONV("__lt__", a < b);
|
|
2744
|
+
PYBIND11_ENUM_OP_CONV("__gt__", a > b);
|
|
2745
|
+
PYBIND11_ENUM_OP_CONV("__le__", a <= b);
|
|
2746
|
+
PYBIND11_ENUM_OP_CONV("__ge__", a >= b);
|
|
2747
|
+
PYBIND11_ENUM_OP_CONV("__and__", a & b);
|
|
2748
|
+
PYBIND11_ENUM_OP_CONV("__rand__", a & b);
|
|
2749
|
+
PYBIND11_ENUM_OP_CONV("__or__", a | b);
|
|
2750
|
+
PYBIND11_ENUM_OP_CONV("__ror__", a | b);
|
|
2751
|
+
PYBIND11_ENUM_OP_CONV("__xor__", a ^ b);
|
|
2752
|
+
PYBIND11_ENUM_OP_CONV("__rxor__", a ^ b);
|
|
2753
|
+
m_base.attr("__invert__")
|
|
2754
|
+
= cpp_function([](const object &arg) { return ~(int_(arg)); },
|
|
2755
|
+
name("__invert__"),
|
|
2756
|
+
is_method(m_base),
|
|
2757
|
+
pos_only());
|
|
2758
|
+
}
|
|
2759
|
+
} else {
|
|
2760
|
+
PYBIND11_ENUM_OP_STRICT("__eq__", int_(a).equal(int_(b)), return false);
|
|
2761
|
+
PYBIND11_ENUM_OP_STRICT("__ne__", !int_(a).equal(int_(b)), return true);
|
|
2762
|
+
|
|
2763
|
+
if (is_arithmetic) {
|
|
2764
|
+
#define PYBIND11_THROW throw type_error("Expected an enumeration of matching type!");
|
|
2765
|
+
PYBIND11_ENUM_OP_STRICT("__lt__", int_(a) < int_(b), PYBIND11_THROW);
|
|
2766
|
+
PYBIND11_ENUM_OP_STRICT("__gt__", int_(a) > int_(b), PYBIND11_THROW);
|
|
2767
|
+
PYBIND11_ENUM_OP_STRICT("__le__", int_(a) <= int_(b), PYBIND11_THROW);
|
|
2768
|
+
PYBIND11_ENUM_OP_STRICT("__ge__", int_(a) >= int_(b), PYBIND11_THROW);
|
|
2769
|
+
#undef PYBIND11_THROW
|
|
2770
|
+
}
|
|
2771
|
+
}
|
|
2772
|
+
|
|
2773
|
+
#undef PYBIND11_ENUM_OP_CONV_LHS
|
|
2774
|
+
#undef PYBIND11_ENUM_OP_CONV
|
|
2775
|
+
#undef PYBIND11_ENUM_OP_STRICT
|
|
2776
|
+
|
|
2777
|
+
m_base.attr("__getstate__") = cpp_function([](const object &arg) { return int_(arg); },
|
|
2778
|
+
name("__getstate__"),
|
|
2779
|
+
is_method(m_base),
|
|
2780
|
+
pos_only());
|
|
2781
|
+
|
|
2782
|
+
m_base.attr("__hash__") = cpp_function([](const object &arg) { return int_(arg); },
|
|
2783
|
+
name("__hash__"),
|
|
2784
|
+
is_method(m_base),
|
|
2785
|
+
pos_only());
|
|
2786
|
+
}
|
|
2787
|
+
|
|
2788
|
+
PYBIND11_NOINLINE void value(char const *name_, object value, const char *doc = nullptr) {
|
|
2789
|
+
dict entries = m_base.attr("__entries");
|
|
2790
|
+
str name(name_);
|
|
2791
|
+
if (entries.contains(name)) {
|
|
2792
|
+
std::string type_name = (std::string) str(m_base.attr("__name__"));
|
|
2793
|
+
throw value_error(std::move(type_name) + ": element \"" + std::string(name_)
|
|
2794
|
+
+ "\" already exists!");
|
|
2795
|
+
}
|
|
2796
|
+
|
|
2797
|
+
entries[name] = pybind11::make_tuple(value, doc);
|
|
2798
|
+
m_base.attr(std::move(name)) = std::move(value);
|
|
2799
|
+
}
|
|
2800
|
+
|
|
2801
|
+
PYBIND11_NOINLINE void export_values() {
|
|
2802
|
+
dict entries = m_base.attr("__entries");
|
|
2803
|
+
for (auto kv : entries) {
|
|
2804
|
+
m_parent.attr(kv.first) = kv.second[int_(0)];
|
|
2805
|
+
}
|
|
2806
|
+
}
|
|
2807
|
+
|
|
2808
|
+
handle m_base;
|
|
2809
|
+
handle m_parent;
|
|
2810
|
+
};
|
|
2811
|
+
|
|
2812
|
+
template <bool is_signed, size_t length>
|
|
2813
|
+
struct equivalent_integer {};
|
|
2814
|
+
template <>
|
|
2815
|
+
struct equivalent_integer<true, 1> {
|
|
2816
|
+
using type = int8_t;
|
|
2817
|
+
};
|
|
2818
|
+
template <>
|
|
2819
|
+
struct equivalent_integer<false, 1> {
|
|
2820
|
+
using type = uint8_t;
|
|
2821
|
+
};
|
|
2822
|
+
template <>
|
|
2823
|
+
struct equivalent_integer<true, 2> {
|
|
2824
|
+
using type = int16_t;
|
|
2825
|
+
};
|
|
2826
|
+
template <>
|
|
2827
|
+
struct equivalent_integer<false, 2> {
|
|
2828
|
+
using type = uint16_t;
|
|
2829
|
+
};
|
|
2830
|
+
template <>
|
|
2831
|
+
struct equivalent_integer<true, 4> {
|
|
2832
|
+
using type = int32_t;
|
|
2833
|
+
};
|
|
2834
|
+
template <>
|
|
2835
|
+
struct equivalent_integer<false, 4> {
|
|
2836
|
+
using type = uint32_t;
|
|
2837
|
+
};
|
|
2838
|
+
template <>
|
|
2839
|
+
struct equivalent_integer<true, 8> {
|
|
2840
|
+
using type = int64_t;
|
|
2841
|
+
};
|
|
2842
|
+
template <>
|
|
2843
|
+
struct equivalent_integer<false, 8> {
|
|
2844
|
+
using type = uint64_t;
|
|
2845
|
+
};
|
|
2846
|
+
|
|
2847
|
+
template <typename IntLike>
|
|
2848
|
+
using equivalent_integer_t =
|
|
2849
|
+
typename equivalent_integer<std::is_signed<IntLike>::value, sizeof(IntLike)>::type;
|
|
2850
|
+
|
|
2851
|
+
PYBIND11_NAMESPACE_END(detail)
|
|
2852
|
+
|
|
2853
|
+
/// Binds C++ enumerations and enumeration classes to Python
|
|
2854
|
+
template <typename Type>
|
|
2855
|
+
class enum_ : public class_<Type> {
|
|
2856
|
+
public:
|
|
2857
|
+
using Base = class_<Type>;
|
|
2858
|
+
using Base::attr;
|
|
2859
|
+
using Base::def;
|
|
2860
|
+
using Base::def_property_readonly;
|
|
2861
|
+
using Base::def_property_readonly_static;
|
|
2862
|
+
using Underlying = typename std::underlying_type<Type>::type;
|
|
2863
|
+
// Scalar is the integer representation of underlying type
|
|
2864
|
+
using Scalar = detail::conditional_t<detail::any_of<detail::is_std_char_type<Underlying>,
|
|
2865
|
+
std::is_same<Underlying, bool>>::value,
|
|
2866
|
+
detail::equivalent_integer_t<Underlying>,
|
|
2867
|
+
Underlying>;
|
|
2868
|
+
|
|
2869
|
+
template <typename... Extra>
|
|
2870
|
+
enum_(const handle &scope, const char *name, const Extra &...extra)
|
|
2871
|
+
: class_<Type>(scope, name, extra...), m_base(*this, scope) {
|
|
2872
|
+
{
|
|
2873
|
+
if (detail::global_internals_native_enum_type_map_contains(
|
|
2874
|
+
std::type_index(typeid(Type)))) {
|
|
2875
|
+
pybind11_fail("pybind11::enum_ \"" + std::string(name)
|
|
2876
|
+
+ "\" is already registered as a pybind11::native_enum!");
|
|
2877
|
+
}
|
|
2878
|
+
}
|
|
2879
|
+
|
|
2880
|
+
constexpr bool is_arithmetic = detail::any_of<std::is_same<arithmetic, Extra>...>::value;
|
|
2881
|
+
constexpr bool is_convertible = std::is_convertible<Type, Underlying>::value;
|
|
2882
|
+
m_base.init(is_arithmetic, is_convertible);
|
|
2883
|
+
|
|
2884
|
+
def(init([](Scalar i) { return static_cast<Type>(i); }), arg("value"));
|
|
2885
|
+
def_property_readonly("value", [](Type value) { return (Scalar) value; }, pos_only());
|
|
2886
|
+
def("__int__", [](Type value) { return (Scalar) value; }, pos_only());
|
|
2887
|
+
def("__index__", [](Type value) { return (Scalar) value; }, pos_only());
|
|
2888
|
+
attr("__setstate__") = cpp_function(
|
|
2889
|
+
[](detail::value_and_holder &v_h, Scalar arg) {
|
|
2890
|
+
detail::initimpl::setstate<Base>(
|
|
2891
|
+
v_h, static_cast<Type>(arg), Py_TYPE(v_h.inst) != v_h.type->type);
|
|
2892
|
+
},
|
|
2893
|
+
detail::is_new_style_constructor(),
|
|
2894
|
+
pybind11::name("__setstate__"),
|
|
2895
|
+
is_method(*this),
|
|
2896
|
+
arg("state"),
|
|
2897
|
+
pos_only());
|
|
2898
|
+
}
|
|
2899
|
+
|
|
2900
|
+
/// Export enumeration entries into the parent scope
|
|
2901
|
+
enum_ &export_values() {
|
|
2902
|
+
m_base.export_values();
|
|
2903
|
+
return *this;
|
|
2904
|
+
}
|
|
2905
|
+
|
|
2906
|
+
/// Add an enumeration entry
|
|
2907
|
+
enum_ &value(char const *name, Type value, const char *doc = nullptr) {
|
|
2908
|
+
m_base.value(name, pybind11::cast(value, return_value_policy::copy), doc);
|
|
2909
|
+
return *this;
|
|
2910
|
+
}
|
|
2911
|
+
|
|
2912
|
+
private:
|
|
2913
|
+
detail::enum_base m_base;
|
|
2914
|
+
};
|
|
2915
|
+
|
|
2916
|
+
PYBIND11_NAMESPACE_BEGIN(detail)
|
|
2917
|
+
|
|
2918
|
+
PYBIND11_NOINLINE void keep_alive_impl(handle nurse, handle patient) {
|
|
2919
|
+
if (!nurse || !patient) {
|
|
2920
|
+
pybind11_fail("Could not activate keep_alive!");
|
|
2921
|
+
}
|
|
2922
|
+
|
|
2923
|
+
if (patient.is_none() || nurse.is_none()) {
|
|
2924
|
+
return; /* Nothing to keep alive or nothing to be kept alive by */
|
|
2925
|
+
}
|
|
2926
|
+
|
|
2927
|
+
auto tinfo = all_type_info(Py_TYPE(nurse.ptr()));
|
|
2928
|
+
if (!tinfo.empty()) {
|
|
2929
|
+
/* It's a pybind-registered type, so we can store the patient in the
|
|
2930
|
+
* internal list. */
|
|
2931
|
+
add_patient(nurse.ptr(), patient.ptr());
|
|
2932
|
+
} else {
|
|
2933
|
+
/* Fall back to clever approach based on weak references taken from
|
|
2934
|
+
* Boost.Python. This is not used for pybind-registered types because
|
|
2935
|
+
* the objects can be destroyed out-of-order in a GC pass. */
|
|
2936
|
+
cpp_function disable_lifesupport([patient](handle weakref) {
|
|
2937
|
+
patient.dec_ref();
|
|
2938
|
+
weakref.dec_ref();
|
|
2939
|
+
});
|
|
2940
|
+
|
|
2941
|
+
weakref wr(nurse, disable_lifesupport);
|
|
2942
|
+
|
|
2943
|
+
patient.inc_ref(); /* reference patient and leak the weak reference */
|
|
2944
|
+
(void) wr.release();
|
|
2945
|
+
}
|
|
2946
|
+
}
|
|
2947
|
+
|
|
2948
|
+
PYBIND11_NOINLINE void
|
|
2949
|
+
keep_alive_impl(size_t Nurse, size_t Patient, function_call &call, handle ret) {
|
|
2950
|
+
auto get_arg = [&](size_t n) {
|
|
2951
|
+
if (n == 0) {
|
|
2952
|
+
return ret;
|
|
2953
|
+
}
|
|
2954
|
+
if (n == 1 && call.init_self) {
|
|
2955
|
+
return call.init_self;
|
|
2956
|
+
}
|
|
2957
|
+
if (n <= call.args.size()) {
|
|
2958
|
+
return call.args[n - 1];
|
|
2959
|
+
}
|
|
2960
|
+
return handle();
|
|
2961
|
+
};
|
|
2962
|
+
|
|
2963
|
+
keep_alive_impl(get_arg(Nurse), get_arg(Patient));
|
|
2964
|
+
}
|
|
2965
|
+
|
|
2966
|
+
inline std::pair<decltype(internals::registered_types_py)::iterator, bool>
|
|
2967
|
+
all_type_info_get_cache(PyTypeObject *type) {
|
|
2968
|
+
auto res = with_internals([type](internals &internals) {
|
|
2969
|
+
auto ins = internals
|
|
2970
|
+
.registered_types_py
|
|
2971
|
+
#ifdef __cpp_lib_unordered_map_try_emplace
|
|
2972
|
+
.try_emplace(type);
|
|
2973
|
+
#else
|
|
2974
|
+
.emplace(type, std::vector<detail::type_info *>());
|
|
2975
|
+
#endif
|
|
2976
|
+
if (ins.second) {
|
|
2977
|
+
// For free-threading mode, this call must be under
|
|
2978
|
+
// the with_internals() mutex lock, to avoid that other threads
|
|
2979
|
+
// continue running with the empty ins.first->second.
|
|
2980
|
+
all_type_info_populate(type, ins.first->second);
|
|
2981
|
+
}
|
|
2982
|
+
return ins;
|
|
2983
|
+
});
|
|
2984
|
+
if (res.second) {
|
|
2985
|
+
// New cache entry created; set up a weak reference to automatically remove it if the type
|
|
2986
|
+
// gets destroyed:
|
|
2987
|
+
weakref((PyObject *) type, cpp_function([type](handle wr) {
|
|
2988
|
+
with_internals([type](internals &internals) {
|
|
2989
|
+
internals.registered_types_py.erase(type);
|
|
2990
|
+
|
|
2991
|
+
// TODO consolidate the erasure code in pybind11_meta_dealloc() in class.h
|
|
2992
|
+
auto &cache = internals.inactive_override_cache;
|
|
2993
|
+
for (auto it = cache.begin(), last = cache.end(); it != last;) {
|
|
2994
|
+
if (it->first == reinterpret_cast<PyObject *>(type)) {
|
|
2995
|
+
it = cache.erase(it);
|
|
2996
|
+
} else {
|
|
2997
|
+
++it;
|
|
2998
|
+
}
|
|
2999
|
+
}
|
|
3000
|
+
});
|
|
3001
|
+
|
|
3002
|
+
wr.dec_ref();
|
|
3003
|
+
}))
|
|
3004
|
+
.release();
|
|
3005
|
+
}
|
|
3006
|
+
|
|
3007
|
+
return res;
|
|
3008
|
+
}
|
|
3009
|
+
|
|
3010
|
+
/* There are a large number of apparently unused template arguments because
|
|
3011
|
+
* each combination requires a separate py::class_ registration.
|
|
3012
|
+
*/
|
|
3013
|
+
template <typename Access,
|
|
3014
|
+
return_value_policy Policy,
|
|
3015
|
+
typename Iterator,
|
|
3016
|
+
typename Sentinel,
|
|
3017
|
+
typename ValueType,
|
|
3018
|
+
typename... Extra>
|
|
3019
|
+
struct iterator_state {
|
|
3020
|
+
Iterator it;
|
|
3021
|
+
Sentinel end;
|
|
3022
|
+
bool first_or_done;
|
|
3023
|
+
};
|
|
3024
|
+
|
|
3025
|
+
// Note: these helpers take the iterator by non-const reference because some
|
|
3026
|
+
// iterators in the wild can't be dereferenced when const. The & after Iterator
|
|
3027
|
+
// is required for MSVC < 16.9. SFINAE cannot be reused for result_type due to
|
|
3028
|
+
// bugs in ICC, NVCC, and PGI compilers. See PR #3293.
|
|
3029
|
+
template <typename Iterator, typename SFINAE = decltype(*std::declval<Iterator &>())>
|
|
3030
|
+
struct iterator_access {
|
|
3031
|
+
using result_type = decltype(*std::declval<Iterator &>());
|
|
3032
|
+
// NOLINTNEXTLINE(readability-const-return-type) // PR #3263
|
|
3033
|
+
result_type operator()(Iterator &it) const { return *it; }
|
|
3034
|
+
};
|
|
3035
|
+
|
|
3036
|
+
template <typename Iterator, typename SFINAE = decltype((*std::declval<Iterator &>()).first)>
|
|
3037
|
+
class iterator_key_access {
|
|
3038
|
+
private:
|
|
3039
|
+
using pair_type = decltype(*std::declval<Iterator &>());
|
|
3040
|
+
|
|
3041
|
+
public:
|
|
3042
|
+
/* If either the pair itself or the element of the pair is a reference, we
|
|
3043
|
+
* want to return a reference, otherwise a value. When the decltype
|
|
3044
|
+
* expression is parenthesized it is based on the value category of the
|
|
3045
|
+
* expression; otherwise it is the declared type of the pair member.
|
|
3046
|
+
* The use of declval<pair_type> in the second branch rather than directly
|
|
3047
|
+
* using *std::declval<Iterator &>() is a workaround for nvcc
|
|
3048
|
+
* (it's not used in the first branch because going via decltype and back
|
|
3049
|
+
* through declval does not perfectly preserve references).
|
|
3050
|
+
*/
|
|
3051
|
+
using result_type
|
|
3052
|
+
= conditional_t<std::is_reference<decltype(*std::declval<Iterator &>())>::value,
|
|
3053
|
+
decltype(((*std::declval<Iterator &>()).first)),
|
|
3054
|
+
decltype(std::declval<pair_type>().first)>;
|
|
3055
|
+
result_type operator()(Iterator &it) const { return (*it).first; }
|
|
3056
|
+
};
|
|
3057
|
+
|
|
3058
|
+
template <typename Iterator, typename SFINAE = decltype((*std::declval<Iterator &>()).second)>
|
|
3059
|
+
class iterator_value_access {
|
|
3060
|
+
private:
|
|
3061
|
+
using pair_type = decltype(*std::declval<Iterator &>());
|
|
3062
|
+
|
|
3063
|
+
public:
|
|
3064
|
+
using result_type
|
|
3065
|
+
= conditional_t<std::is_reference<decltype(*std::declval<Iterator &>())>::value,
|
|
3066
|
+
decltype(((*std::declval<Iterator &>()).second)),
|
|
3067
|
+
decltype(std::declval<pair_type>().second)>;
|
|
3068
|
+
result_type operator()(Iterator &it) const { return (*it).second; }
|
|
3069
|
+
};
|
|
3070
|
+
|
|
3071
|
+
template <typename Access,
|
|
3072
|
+
return_value_policy Policy,
|
|
3073
|
+
typename Iterator,
|
|
3074
|
+
typename Sentinel,
|
|
3075
|
+
typename ValueType,
|
|
3076
|
+
typename... Extra>
|
|
3077
|
+
// NOLINTNEXTLINE(performance-unnecessary-value-param)
|
|
3078
|
+
iterator make_iterator_impl(Iterator first, Sentinel last, Extra &&...extra) {
|
|
3079
|
+
using state = detail::iterator_state<Access, Policy, Iterator, Sentinel, ValueType, Extra...>;
|
|
3080
|
+
// TODO: state captures only the types of Extra, not the values
|
|
3081
|
+
|
|
3082
|
+
if (!detail::get_type_info(typeid(state), false)) {
|
|
3083
|
+
class_<state>(handle(), "iterator", pybind11::module_local())
|
|
3084
|
+
.def(
|
|
3085
|
+
"__iter__", [](state &s) -> state & { return s; }, pos_only())
|
|
3086
|
+
.def(
|
|
3087
|
+
"__next__",
|
|
3088
|
+
[](state &s) -> ValueType {
|
|
3089
|
+
if (!s.first_or_done) {
|
|
3090
|
+
++s.it;
|
|
3091
|
+
} else {
|
|
3092
|
+
s.first_or_done = false;
|
|
3093
|
+
}
|
|
3094
|
+
if (s.it == s.end) {
|
|
3095
|
+
s.first_or_done = true;
|
|
3096
|
+
throw stop_iteration();
|
|
3097
|
+
}
|
|
3098
|
+
return Access()(s.it);
|
|
3099
|
+
// NOLINTNEXTLINE(readability-const-return-type) // PR #3263
|
|
3100
|
+
},
|
|
3101
|
+
std::forward<Extra>(extra)...,
|
|
3102
|
+
pos_only(),
|
|
3103
|
+
Policy);
|
|
3104
|
+
}
|
|
3105
|
+
|
|
3106
|
+
return cast(state{std::forward<Iterator>(first), std::forward<Sentinel>(last), true});
|
|
3107
|
+
}
|
|
3108
|
+
|
|
3109
|
+
PYBIND11_NAMESPACE_END(detail)
|
|
3110
|
+
|
|
3111
|
+
/// Makes a python iterator from a first and past-the-end C++ InputIterator.
|
|
3112
|
+
template <return_value_policy Policy = return_value_policy::reference_internal,
|
|
3113
|
+
typename Iterator,
|
|
3114
|
+
typename Sentinel,
|
|
3115
|
+
typename ValueType = typename detail::iterator_access<Iterator>::result_type,
|
|
3116
|
+
typename... Extra>
|
|
3117
|
+
// NOLINTNEXTLINE(performance-unnecessary-value-param)
|
|
3118
|
+
typing::Iterator<ValueType> make_iterator(Iterator first, Sentinel last, Extra &&...extra) {
|
|
3119
|
+
return detail::make_iterator_impl<detail::iterator_access<Iterator>,
|
|
3120
|
+
Policy,
|
|
3121
|
+
Iterator,
|
|
3122
|
+
Sentinel,
|
|
3123
|
+
ValueType,
|
|
3124
|
+
Extra...>(std::forward<Iterator>(first),
|
|
3125
|
+
std::forward<Sentinel>(last),
|
|
3126
|
+
std::forward<Extra>(extra)...);
|
|
3127
|
+
}
|
|
3128
|
+
|
|
3129
|
+
/// Makes a python iterator over the keys (`.first`) of a iterator over pairs from a
|
|
3130
|
+
/// first and past-the-end InputIterator.
|
|
3131
|
+
template <return_value_policy Policy = return_value_policy::reference_internal,
|
|
3132
|
+
typename Iterator,
|
|
3133
|
+
typename Sentinel,
|
|
3134
|
+
typename KeyType = typename detail::iterator_key_access<Iterator>::result_type,
|
|
3135
|
+
typename... Extra>
|
|
3136
|
+
typing::Iterator<KeyType> make_key_iterator(Iterator first, Sentinel last, Extra &&...extra) {
|
|
3137
|
+
return detail::make_iterator_impl<detail::iterator_key_access<Iterator>,
|
|
3138
|
+
Policy,
|
|
3139
|
+
Iterator,
|
|
3140
|
+
Sentinel,
|
|
3141
|
+
KeyType,
|
|
3142
|
+
Extra...>(std::forward<Iterator>(first),
|
|
3143
|
+
std::forward<Sentinel>(last),
|
|
3144
|
+
std::forward<Extra>(extra)...);
|
|
3145
|
+
}
|
|
3146
|
+
|
|
3147
|
+
/// Makes a python iterator over the values (`.second`) of a iterator over pairs from a
|
|
3148
|
+
/// first and past-the-end InputIterator.
|
|
3149
|
+
template <return_value_policy Policy = return_value_policy::reference_internal,
|
|
3150
|
+
typename Iterator,
|
|
3151
|
+
typename Sentinel,
|
|
3152
|
+
typename ValueType = typename detail::iterator_value_access<Iterator>::result_type,
|
|
3153
|
+
typename... Extra>
|
|
3154
|
+
typing::Iterator<ValueType> make_value_iterator(Iterator first, Sentinel last, Extra &&...extra) {
|
|
3155
|
+
return detail::make_iterator_impl<detail::iterator_value_access<Iterator>,
|
|
3156
|
+
Policy,
|
|
3157
|
+
Iterator,
|
|
3158
|
+
Sentinel,
|
|
3159
|
+
ValueType,
|
|
3160
|
+
Extra...>(std::forward<Iterator>(first),
|
|
3161
|
+
std::forward<Sentinel>(last),
|
|
3162
|
+
std::forward<Extra>(extra)...);
|
|
3163
|
+
}
|
|
3164
|
+
|
|
3165
|
+
/// Makes an iterator over values of an stl container or other container supporting
|
|
3166
|
+
/// `std::begin()`/`std::end()`
|
|
3167
|
+
template <return_value_policy Policy = return_value_policy::reference_internal,
|
|
3168
|
+
typename Type,
|
|
3169
|
+
typename ValueType = typename detail::iterator_access<
|
|
3170
|
+
decltype(std::begin(std::declval<Type &>()))>::result_type,
|
|
3171
|
+
typename... Extra>
|
|
3172
|
+
typing::Iterator<ValueType> make_iterator(Type &value, Extra &&...extra) {
|
|
3173
|
+
return make_iterator<Policy>(
|
|
3174
|
+
std::begin(value), std::end(value), std::forward<Extra>(extra)...);
|
|
3175
|
+
}
|
|
3176
|
+
|
|
3177
|
+
/// Makes an iterator over the keys (`.first`) of a stl map-like container supporting
|
|
3178
|
+
/// `std::begin()`/`std::end()`
|
|
3179
|
+
template <return_value_policy Policy = return_value_policy::reference_internal,
|
|
3180
|
+
typename Type,
|
|
3181
|
+
typename KeyType = typename detail::iterator_key_access<
|
|
3182
|
+
decltype(std::begin(std::declval<Type &>()))>::result_type,
|
|
3183
|
+
typename... Extra>
|
|
3184
|
+
typing::Iterator<KeyType> make_key_iterator(Type &value, Extra &&...extra) {
|
|
3185
|
+
return make_key_iterator<Policy>(
|
|
3186
|
+
std::begin(value), std::end(value), std::forward<Extra>(extra)...);
|
|
3187
|
+
}
|
|
3188
|
+
|
|
3189
|
+
/// Makes an iterator over the values (`.second`) of a stl map-like container supporting
|
|
3190
|
+
/// `std::begin()`/`std::end()`
|
|
3191
|
+
template <return_value_policy Policy = return_value_policy::reference_internal,
|
|
3192
|
+
typename Type,
|
|
3193
|
+
typename ValueType = typename detail::iterator_value_access<
|
|
3194
|
+
decltype(std::begin(std::declval<Type &>()))>::result_type,
|
|
3195
|
+
typename... Extra>
|
|
3196
|
+
typing::Iterator<ValueType> make_value_iterator(Type &value, Extra &&...extra) {
|
|
3197
|
+
return make_value_iterator<Policy>(
|
|
3198
|
+
std::begin(value), std::end(value), std::forward<Extra>(extra)...);
|
|
3199
|
+
}
|
|
3200
|
+
|
|
3201
|
+
template <typename InputType, typename OutputType>
|
|
3202
|
+
void implicitly_convertible() {
|
|
3203
|
+
static int tss_sentinel_pointee = 1; // arbitrary value
|
|
3204
|
+
struct set_flag {
|
|
3205
|
+
thread_specific_storage<int> &flag;
|
|
3206
|
+
explicit set_flag(thread_specific_storage<int> &flag_) : flag(flag_) {
|
|
3207
|
+
flag = &tss_sentinel_pointee; // trick: the pointer itself is the sentinel
|
|
3208
|
+
}
|
|
3209
|
+
~set_flag() { flag.reset(nullptr); }
|
|
3210
|
+
|
|
3211
|
+
// Prevent copying/moving to ensure RAII guard is used safely
|
|
3212
|
+
set_flag(const set_flag &) = delete;
|
|
3213
|
+
set_flag(set_flag &&) = delete;
|
|
3214
|
+
set_flag &operator=(const set_flag &) = delete;
|
|
3215
|
+
set_flag &operator=(set_flag &&) = delete;
|
|
3216
|
+
};
|
|
3217
|
+
auto implicit_caster = [](PyObject *obj, PyTypeObject *type) -> PyObject * {
|
|
3218
|
+
static thread_specific_storage<int> currently_used;
|
|
3219
|
+
if (currently_used) { // implicit conversions are non-reentrant
|
|
3220
|
+
return nullptr;
|
|
3221
|
+
}
|
|
3222
|
+
set_flag flag_helper(currently_used);
|
|
3223
|
+
if (!detail::make_caster<InputType>().load(obj, false)) {
|
|
3224
|
+
return nullptr;
|
|
3225
|
+
}
|
|
3226
|
+
tuple args(1);
|
|
3227
|
+
args[0] = obj;
|
|
3228
|
+
PyObject *result = PyObject_Call((PyObject *) type, args.ptr(), nullptr);
|
|
3229
|
+
if (result == nullptr) {
|
|
3230
|
+
PyErr_Clear();
|
|
3231
|
+
}
|
|
3232
|
+
return result;
|
|
3233
|
+
};
|
|
3234
|
+
|
|
3235
|
+
if (auto *tinfo = detail::get_type_info(typeid(OutputType))) {
|
|
3236
|
+
tinfo->implicit_conversions.emplace_back(std::move(implicit_caster));
|
|
3237
|
+
} else {
|
|
3238
|
+
pybind11_fail("implicitly_convertible: Unable to find type " + type_id<OutputType>());
|
|
3239
|
+
}
|
|
3240
|
+
}
|
|
3241
|
+
|
|
3242
|
+
inline void register_exception_translator(ExceptionTranslator &&translator) {
|
|
3243
|
+
detail::with_exception_translators(
|
|
3244
|
+
[&](std::forward_list<ExceptionTranslator> &exception_translators,
|
|
3245
|
+
std::forward_list<ExceptionTranslator> &local_exception_translators) {
|
|
3246
|
+
(void) local_exception_translators;
|
|
3247
|
+
exception_translators.push_front(std::forward<ExceptionTranslator>(translator));
|
|
3248
|
+
});
|
|
3249
|
+
}
|
|
3250
|
+
|
|
3251
|
+
/**
|
|
3252
|
+
* Add a new module-local exception translator. Locally registered functions
|
|
3253
|
+
* will be tried before any globally registered exception translators, which
|
|
3254
|
+
* will only be invoked if the module-local handlers do not deal with
|
|
3255
|
+
* the exception.
|
|
3256
|
+
*/
|
|
3257
|
+
inline void register_local_exception_translator(ExceptionTranslator &&translator) {
|
|
3258
|
+
detail::with_exception_translators(
|
|
3259
|
+
[&](std::forward_list<ExceptionTranslator> &exception_translators,
|
|
3260
|
+
std::forward_list<ExceptionTranslator> &local_exception_translators) {
|
|
3261
|
+
(void) exception_translators;
|
|
3262
|
+
local_exception_translators.push_front(std::forward<ExceptionTranslator>(translator));
|
|
3263
|
+
});
|
|
3264
|
+
}
|
|
3265
|
+
|
|
3266
|
+
/**
|
|
3267
|
+
* Wrapper to generate a new Python exception type.
|
|
3268
|
+
*
|
|
3269
|
+
* This should only be used with py::set_error() for now.
|
|
3270
|
+
* It is not (yet) possible to use as a py::base.
|
|
3271
|
+
* Template type argument is reserved for future use.
|
|
3272
|
+
*/
|
|
3273
|
+
template <typename type>
|
|
3274
|
+
class exception : public object {
|
|
3275
|
+
public:
|
|
3276
|
+
exception() = default;
|
|
3277
|
+
exception(handle scope, const char *name, handle base = PyExc_Exception) {
|
|
3278
|
+
std::string full_name
|
|
3279
|
+
= scope.attr("__name__").cast<std::string>() + std::string(".") + name;
|
|
3280
|
+
m_ptr = PyErr_NewException(const_cast<char *>(full_name.c_str()), base.ptr(), nullptr);
|
|
3281
|
+
if (hasattr(scope, "__dict__") && scope.attr("__dict__").contains(name)) {
|
|
3282
|
+
pybind11_fail("Error during initialization: multiple incompatible "
|
|
3283
|
+
"definitions with name \""
|
|
3284
|
+
+ std::string(name) + "\"");
|
|
3285
|
+
}
|
|
3286
|
+
scope.attr(name) = *this;
|
|
3287
|
+
}
|
|
3288
|
+
|
|
3289
|
+
// Sets the current python exception to this exception object with the given message
|
|
3290
|
+
PYBIND11_DEPRECATED("Please use py::set_error() instead "
|
|
3291
|
+
"(https://github.com/pybind/pybind11/pull/4772)")
|
|
3292
|
+
void operator()(const char *message) const { set_error(*this, message); }
|
|
3293
|
+
};
|
|
3294
|
+
|
|
3295
|
+
PYBIND11_NAMESPACE_BEGIN(detail)
|
|
3296
|
+
|
|
3297
|
+
template <>
|
|
3298
|
+
struct handle_type_name<exception<void>> {
|
|
3299
|
+
static constexpr auto name = const_name("Exception");
|
|
3300
|
+
};
|
|
3301
|
+
|
|
3302
|
+
// Helper function for register_exception and register_local_exception
|
|
3303
|
+
template <typename CppException>
|
|
3304
|
+
exception<CppException> &
|
|
3305
|
+
register_exception_impl(handle scope, const char *name, handle base, bool isLocal) {
|
|
3306
|
+
PYBIND11_CONSTINIT static gil_safe_call_once_and_store<exception<CppException>> exc_storage;
|
|
3307
|
+
exc_storage.call_once_and_store_result(
|
|
3308
|
+
[&]() { return exception<CppException>(scope, name, base); });
|
|
3309
|
+
|
|
3310
|
+
auto register_func
|
|
3311
|
+
= isLocal ? ®ister_local_exception_translator : ®ister_exception_translator;
|
|
3312
|
+
|
|
3313
|
+
register_func([](std::exception_ptr p) {
|
|
3314
|
+
if (!p) {
|
|
3315
|
+
return;
|
|
3316
|
+
}
|
|
3317
|
+
try {
|
|
3318
|
+
std::rethrow_exception(p);
|
|
3319
|
+
} catch (const CppException &e) {
|
|
3320
|
+
set_error(exc_storage.get_stored(), e.what());
|
|
3321
|
+
}
|
|
3322
|
+
});
|
|
3323
|
+
return exc_storage.get_stored();
|
|
3324
|
+
}
|
|
3325
|
+
|
|
3326
|
+
PYBIND11_NAMESPACE_END(detail)
|
|
3327
|
+
|
|
3328
|
+
/**
|
|
3329
|
+
* Registers a Python exception in `m` of the given `name` and installs a translator to
|
|
3330
|
+
* translate the C++ exception to the created Python exception using the what() method.
|
|
3331
|
+
* This is intended for simple exception translations; for more complex translation, register the
|
|
3332
|
+
* exception object and translator directly.
|
|
3333
|
+
*/
|
|
3334
|
+
template <typename CppException>
|
|
3335
|
+
exception<CppException> &
|
|
3336
|
+
register_exception(handle scope, const char *name, handle base = PyExc_Exception) {
|
|
3337
|
+
return detail::register_exception_impl<CppException>(scope, name, base, false /* isLocal */);
|
|
3338
|
+
}
|
|
3339
|
+
|
|
3340
|
+
/**
|
|
3341
|
+
* Registers a Python exception in `m` of the given `name` and installs a translator to
|
|
3342
|
+
* translate the C++ exception to the created Python exception using the what() method.
|
|
3343
|
+
* This translator will only be used for exceptions that are thrown in this module and will be
|
|
3344
|
+
* tried before global exception translators, including those registered with register_exception.
|
|
3345
|
+
* This is intended for simple exception translations; for more complex translation, register the
|
|
3346
|
+
* exception object and translator directly.
|
|
3347
|
+
*/
|
|
3348
|
+
template <typename CppException>
|
|
3349
|
+
exception<CppException> &
|
|
3350
|
+
register_local_exception(handle scope, const char *name, handle base = PyExc_Exception) {
|
|
3351
|
+
return detail::register_exception_impl<CppException>(scope, name, base, true /* isLocal */);
|
|
3352
|
+
}
|
|
3353
|
+
|
|
3354
|
+
PYBIND11_NAMESPACE_BEGIN(detail)
|
|
3355
|
+
PYBIND11_NOINLINE void print(const tuple &args, const dict &kwargs) {
|
|
3356
|
+
auto strings = tuple(args.size());
|
|
3357
|
+
for (size_t i = 0; i < args.size(); ++i) {
|
|
3358
|
+
strings[i] = str(args[i]);
|
|
3359
|
+
}
|
|
3360
|
+
auto sep = kwargs.contains("sep") ? kwargs["sep"] : str(" ");
|
|
3361
|
+
auto line = sep.attr("join")(std::move(strings));
|
|
3362
|
+
|
|
3363
|
+
object file;
|
|
3364
|
+
if (kwargs.contains("file")) {
|
|
3365
|
+
file = kwargs["file"].cast<object>();
|
|
3366
|
+
} else {
|
|
3367
|
+
try {
|
|
3368
|
+
file = module_::import("sys").attr("stdout");
|
|
3369
|
+
} catch (const error_already_set &) {
|
|
3370
|
+
/* If print() is called from code that is executed as
|
|
3371
|
+
part of garbage collection during interpreter shutdown,
|
|
3372
|
+
importing 'sys' can fail. Give up rather than crashing the
|
|
3373
|
+
interpreter in this case. */
|
|
3374
|
+
return;
|
|
3375
|
+
}
|
|
3376
|
+
}
|
|
3377
|
+
|
|
3378
|
+
auto write = file.attr("write");
|
|
3379
|
+
write(std::move(line));
|
|
3380
|
+
write(kwargs.contains("end") ? kwargs["end"] : str("\n"));
|
|
3381
|
+
|
|
3382
|
+
if (kwargs.contains("flush") && kwargs["flush"].cast<bool>()) {
|
|
3383
|
+
file.attr("flush")();
|
|
3384
|
+
}
|
|
3385
|
+
}
|
|
3386
|
+
PYBIND11_NAMESPACE_END(detail)
|
|
3387
|
+
|
|
3388
|
+
template <return_value_policy policy = return_value_policy::automatic_reference, typename... Args>
|
|
3389
|
+
void print(Args &&...args) {
|
|
3390
|
+
auto c = detail::collect_arguments<policy>(std::forward<Args>(args)...);
|
|
3391
|
+
detail::print(c.args(), c.kwargs());
|
|
3392
|
+
}
|
|
3393
|
+
|
|
3394
|
+
inline void
|
|
3395
|
+
error_already_set::m_fetched_error_deleter(detail::error_fetch_and_normalize *raw_ptr) {
|
|
3396
|
+
gil_scoped_acquire gil;
|
|
3397
|
+
error_scope scope;
|
|
3398
|
+
delete raw_ptr;
|
|
3399
|
+
}
|
|
3400
|
+
|
|
3401
|
+
inline const char *error_already_set::what() const noexcept {
|
|
3402
|
+
gil_scoped_acquire gil;
|
|
3403
|
+
error_scope scope;
|
|
3404
|
+
return m_fetched_error->error_string().c_str();
|
|
3405
|
+
}
|
|
3406
|
+
|
|
3407
|
+
PYBIND11_NAMESPACE_BEGIN(detail)
|
|
3408
|
+
|
|
3409
|
+
inline function
|
|
3410
|
+
get_type_override(const void *this_ptr, const type_info *this_type, const char *name) {
|
|
3411
|
+
handle self = get_object_handle(this_ptr, this_type);
|
|
3412
|
+
if (!self) {
|
|
3413
|
+
return function();
|
|
3414
|
+
}
|
|
3415
|
+
handle type = type::handle_of(self);
|
|
3416
|
+
auto key = std::make_pair(type.ptr(), name);
|
|
3417
|
+
|
|
3418
|
+
/* Cache functions that aren't overridden in Python to avoid
|
|
3419
|
+
many costly Python dictionary lookups below */
|
|
3420
|
+
bool not_overridden = with_internals([&key](internals &internals) {
|
|
3421
|
+
auto &cache = internals.inactive_override_cache;
|
|
3422
|
+
return cache.find(key) != cache.end();
|
|
3423
|
+
});
|
|
3424
|
+
if (not_overridden) {
|
|
3425
|
+
return function();
|
|
3426
|
+
}
|
|
3427
|
+
|
|
3428
|
+
function override = getattr(self, name, function());
|
|
3429
|
+
if (override.is_cpp_function()) {
|
|
3430
|
+
with_internals([&](internals &internals) {
|
|
3431
|
+
internals.inactive_override_cache.insert(std::move(key));
|
|
3432
|
+
});
|
|
3433
|
+
return function();
|
|
3434
|
+
}
|
|
3435
|
+
|
|
3436
|
+
/* Don't call dispatch code if invoked from overridden function.
|
|
3437
|
+
Unfortunately this doesn't work on PyPy and GraalPy. */
|
|
3438
|
+
#if !defined(PYPY_VERSION) && !defined(GRAALVM_PYTHON)
|
|
3439
|
+
# if PY_VERSION_HEX >= 0x03090000
|
|
3440
|
+
PyFrameObject *frame = PyThreadState_GetFrame(PyThreadState_Get());
|
|
3441
|
+
if (frame != nullptr) {
|
|
3442
|
+
PyCodeObject *f_code = PyFrame_GetCode(frame);
|
|
3443
|
+
// f_code is guaranteed to not be NULL
|
|
3444
|
+
if ((std::string) str(f_code->co_name) == name && f_code->co_argcount > 0) {
|
|
3445
|
+
# if PY_VERSION_HEX >= 0x030d0000
|
|
3446
|
+
PyObject *locals = PyEval_GetFrameLocals();
|
|
3447
|
+
# else
|
|
3448
|
+
PyObject *locals = PyEval_GetLocals();
|
|
3449
|
+
Py_XINCREF(locals);
|
|
3450
|
+
# endif
|
|
3451
|
+
if (locals != nullptr) {
|
|
3452
|
+
# if PY_VERSION_HEX >= 0x030b0000
|
|
3453
|
+
PyObject *co_varnames = PyCode_GetVarnames(f_code);
|
|
3454
|
+
# else
|
|
3455
|
+
PyObject *co_varnames = PyObject_GetAttrString((PyObject *) f_code, "co_varnames");
|
|
3456
|
+
# endif
|
|
3457
|
+
PyObject *self_arg = PyTuple_GET_ITEM(co_varnames, 0);
|
|
3458
|
+
Py_DECREF(co_varnames);
|
|
3459
|
+
PyObject *self_caller = dict_getitem(locals, self_arg);
|
|
3460
|
+
Py_DECREF(locals);
|
|
3461
|
+
if (self_caller == self.ptr()) {
|
|
3462
|
+
Py_DECREF(f_code);
|
|
3463
|
+
Py_DECREF(frame);
|
|
3464
|
+
return function();
|
|
3465
|
+
}
|
|
3466
|
+
}
|
|
3467
|
+
}
|
|
3468
|
+
Py_DECREF(f_code);
|
|
3469
|
+
Py_DECREF(frame);
|
|
3470
|
+
}
|
|
3471
|
+
# else
|
|
3472
|
+
PyFrameObject *frame = PyThreadState_Get()->frame;
|
|
3473
|
+
if (frame != nullptr && (std::string) str(frame->f_code->co_name) == name
|
|
3474
|
+
&& frame->f_code->co_argcount > 0) {
|
|
3475
|
+
PyFrame_FastToLocals(frame);
|
|
3476
|
+
PyObject *self_caller
|
|
3477
|
+
= dict_getitem(frame->f_locals, PyTuple_GET_ITEM(frame->f_code->co_varnames, 0));
|
|
3478
|
+
if (self_caller == self.ptr()) {
|
|
3479
|
+
return function();
|
|
3480
|
+
}
|
|
3481
|
+
}
|
|
3482
|
+
# endif
|
|
3483
|
+
|
|
3484
|
+
#else
|
|
3485
|
+
/* PyPy currently doesn't provide a detailed cpyext emulation of
|
|
3486
|
+
frame objects, so we have to emulate this using Python. This
|
|
3487
|
+
is going to be slow..*/
|
|
3488
|
+
dict d;
|
|
3489
|
+
d["self"] = self;
|
|
3490
|
+
d["name"] = pybind11::str(name);
|
|
3491
|
+
PyObject *result
|
|
3492
|
+
= PyRun_String("import inspect\n"
|
|
3493
|
+
"frame = inspect.currentframe()\n"
|
|
3494
|
+
"if frame is not None:\n"
|
|
3495
|
+
" frame = frame.f_back\n"
|
|
3496
|
+
" if frame is not None and str(frame.f_code.co_name) == name and "
|
|
3497
|
+
"frame.f_code.co_argcount > 0:\n"
|
|
3498
|
+
" self_caller = frame.f_locals[frame.f_code.co_varnames[0]]\n"
|
|
3499
|
+
" if self_caller == self:\n"
|
|
3500
|
+
" self = None\n",
|
|
3501
|
+
Py_file_input,
|
|
3502
|
+
d.ptr(),
|
|
3503
|
+
d.ptr());
|
|
3504
|
+
if (result == nullptr)
|
|
3505
|
+
throw error_already_set();
|
|
3506
|
+
Py_DECREF(result);
|
|
3507
|
+
if (d["self"].is_none())
|
|
3508
|
+
return function();
|
|
3509
|
+
#endif
|
|
3510
|
+
|
|
3511
|
+
return override;
|
|
3512
|
+
}
|
|
3513
|
+
PYBIND11_NAMESPACE_END(detail)
|
|
3514
|
+
|
|
3515
|
+
/** \rst
|
|
3516
|
+
Try to retrieve a python method by the provided name from the instance pointed to by the
|
|
3517
|
+
this_ptr.
|
|
3518
|
+
|
|
3519
|
+
:this_ptr: The pointer to the object the overridden method should be retrieved for. This should
|
|
3520
|
+
be the first non-trampoline class encountered in the inheritance chain.
|
|
3521
|
+
:name: The name of the overridden Python method to retrieve.
|
|
3522
|
+
:return: The Python method by this name from the object or an empty function wrapper.
|
|
3523
|
+
\endrst */
|
|
3524
|
+
template <class T>
|
|
3525
|
+
function get_override(const T *this_ptr, const char *name) {
|
|
3526
|
+
auto *tinfo = detail::get_type_info(typeid(T));
|
|
3527
|
+
return tinfo ? detail::get_type_override(this_ptr, tinfo, name) : function();
|
|
3528
|
+
}
|
|
3529
|
+
|
|
3530
|
+
#define PYBIND11_OVERRIDE_IMPL(ret_type, cname, name, ...) \
|
|
3531
|
+
do { \
|
|
3532
|
+
pybind11::gil_scoped_acquire gil; \
|
|
3533
|
+
pybind11::function override \
|
|
3534
|
+
= pybind11::get_override(static_cast<const cname *>(this), name); \
|
|
3535
|
+
if (override) { \
|
|
3536
|
+
auto o = override(__VA_ARGS__); \
|
|
3537
|
+
PYBIND11_WARNING_PUSH \
|
|
3538
|
+
PYBIND11_WARNING_DISABLE_MSVC(4127) \
|
|
3539
|
+
if (pybind11::detail::cast_is_temporary_value_reference<ret_type>::value \
|
|
3540
|
+
&& !pybind11::detail::is_same_ignoring_cvref<ret_type, PyObject *>::value) { \
|
|
3541
|
+
static pybind11::detail::override_caster_t<ret_type> caster; \
|
|
3542
|
+
return pybind11::detail::cast_ref<ret_type>(std::move(o), caster); \
|
|
3543
|
+
} \
|
|
3544
|
+
PYBIND11_WARNING_POP \
|
|
3545
|
+
return pybind11::detail::cast_safe<ret_type>(std::move(o)); \
|
|
3546
|
+
} \
|
|
3547
|
+
} while (false)
|
|
3548
|
+
|
|
3549
|
+
/** \rst
|
|
3550
|
+
Macro to populate the virtual method in the trampoline class. This macro tries to look up a
|
|
3551
|
+
method named 'fn' from the Python side, deals with the :ref:`gil` and necessary argument
|
|
3552
|
+
conversions to call this method and return the appropriate type.
|
|
3553
|
+
See :ref:`overriding_virtuals` for more information. This macro should be used when the method
|
|
3554
|
+
name in C is not the same as the method name in Python. For example with `__str__`.
|
|
3555
|
+
|
|
3556
|
+
.. code-block:: cpp
|
|
3557
|
+
|
|
3558
|
+
std::string toString() override {
|
|
3559
|
+
PYBIND11_OVERRIDE_NAME(
|
|
3560
|
+
std::string, // Return type (ret_type)
|
|
3561
|
+
Animal, // Parent class (cname)
|
|
3562
|
+
"__str__", // Name of method in Python (name)
|
|
3563
|
+
toString, // Name of function in C++ (fn)
|
|
3564
|
+
);
|
|
3565
|
+
}
|
|
3566
|
+
\endrst */
|
|
3567
|
+
#define PYBIND11_OVERRIDE_NAME(ret_type, cname, name, fn, ...) \
|
|
3568
|
+
do { \
|
|
3569
|
+
PYBIND11_OVERRIDE_IMPL(PYBIND11_TYPE(ret_type), PYBIND11_TYPE(cname), name, __VA_ARGS__); \
|
|
3570
|
+
return cname::fn(__VA_ARGS__); \
|
|
3571
|
+
} while (false)
|
|
3572
|
+
|
|
3573
|
+
/** \rst
|
|
3574
|
+
Macro for pure virtual functions, this function is identical to
|
|
3575
|
+
:c:macro:`PYBIND11_OVERRIDE_NAME`, except that it throws if no override can be found.
|
|
3576
|
+
\endrst */
|
|
3577
|
+
#define PYBIND11_OVERRIDE_PURE_NAME(ret_type, cname, name, fn, ...) \
|
|
3578
|
+
do { \
|
|
3579
|
+
PYBIND11_OVERRIDE_IMPL(PYBIND11_TYPE(ret_type), PYBIND11_TYPE(cname), name, __VA_ARGS__); \
|
|
3580
|
+
pybind11::pybind11_fail( \
|
|
3581
|
+
"Tried to call pure virtual function \"" PYBIND11_STRINGIFY(cname) "::" name "\""); \
|
|
3582
|
+
} while (false)
|
|
3583
|
+
|
|
3584
|
+
/** \rst
|
|
3585
|
+
Macro to populate the virtual method in the trampoline class. This macro tries to look up the
|
|
3586
|
+
method from the Python side, deals with the :ref:`gil` and necessary argument conversions to
|
|
3587
|
+
call this method and return the appropriate type. This macro should be used if the method name
|
|
3588
|
+
in C and in Python are identical.
|
|
3589
|
+
See :ref:`overriding_virtuals` for more information.
|
|
3590
|
+
|
|
3591
|
+
.. code-block:: cpp
|
|
3592
|
+
|
|
3593
|
+
class PyAnimal : public Animal {
|
|
3594
|
+
public:
|
|
3595
|
+
// Inherit the constructors
|
|
3596
|
+
using Animal::Animal;
|
|
3597
|
+
|
|
3598
|
+
// Trampoline (need one for each virtual function)
|
|
3599
|
+
std::string go(int n_times) override {
|
|
3600
|
+
PYBIND11_OVERRIDE_PURE(
|
|
3601
|
+
std::string, // Return type (ret_type)
|
|
3602
|
+
Animal, // Parent class (cname)
|
|
3603
|
+
go, // Name of function in C++ (must match Python name) (fn)
|
|
3604
|
+
n_times // Argument(s) (...)
|
|
3605
|
+
);
|
|
3606
|
+
}
|
|
3607
|
+
};
|
|
3608
|
+
\endrst */
|
|
3609
|
+
#define PYBIND11_OVERRIDE(ret_type, cname, fn, ...) \
|
|
3610
|
+
PYBIND11_OVERRIDE_NAME(PYBIND11_TYPE(ret_type), PYBIND11_TYPE(cname), #fn, fn, __VA_ARGS__)
|
|
3611
|
+
|
|
3612
|
+
/** \rst
|
|
3613
|
+
Macro for pure virtual functions, this function is identical to :c:macro:`PYBIND11_OVERRIDE`,
|
|
3614
|
+
except that it throws if no override can be found.
|
|
3615
|
+
\endrst */
|
|
3616
|
+
#define PYBIND11_OVERRIDE_PURE(ret_type, cname, fn, ...) \
|
|
3617
|
+
PYBIND11_OVERRIDE_PURE_NAME( \
|
|
3618
|
+
PYBIND11_TYPE(ret_type), PYBIND11_TYPE(cname), #fn, fn, __VA_ARGS__)
|
|
3619
|
+
|
|
3620
|
+
// Deprecated versions
|
|
3621
|
+
|
|
3622
|
+
PYBIND11_DEPRECATED("get_type_overload has been deprecated")
|
|
3623
|
+
inline function
|
|
3624
|
+
get_type_overload(const void *this_ptr, const detail::type_info *this_type, const char *name) {
|
|
3625
|
+
return detail::get_type_override(this_ptr, this_type, name);
|
|
3626
|
+
}
|
|
3627
|
+
|
|
3628
|
+
template <class T>
|
|
3629
|
+
inline function get_overload(const T *this_ptr, const char *name) {
|
|
3630
|
+
return get_override(this_ptr, name);
|
|
3631
|
+
}
|
|
3632
|
+
|
|
3633
|
+
#define PYBIND11_OVERLOAD_INT(ret_type, cname, name, ...) \
|
|
3634
|
+
PYBIND11_OVERRIDE_IMPL(PYBIND11_TYPE(ret_type), PYBIND11_TYPE(cname), name, __VA_ARGS__)
|
|
3635
|
+
#define PYBIND11_OVERLOAD_NAME(ret_type, cname, name, fn, ...) \
|
|
3636
|
+
PYBIND11_OVERRIDE_NAME(PYBIND11_TYPE(ret_type), PYBIND11_TYPE(cname), name, fn, __VA_ARGS__)
|
|
3637
|
+
#define PYBIND11_OVERLOAD_PURE_NAME(ret_type, cname, name, fn, ...) \
|
|
3638
|
+
PYBIND11_OVERRIDE_PURE_NAME( \
|
|
3639
|
+
PYBIND11_TYPE(ret_type), PYBIND11_TYPE(cname), name, fn, __VA_ARGS__);
|
|
3640
|
+
#define PYBIND11_OVERLOAD(ret_type, cname, fn, ...) \
|
|
3641
|
+
PYBIND11_OVERRIDE(PYBIND11_TYPE(ret_type), PYBIND11_TYPE(cname), fn, __VA_ARGS__)
|
|
3642
|
+
#define PYBIND11_OVERLOAD_PURE(ret_type, cname, fn, ...) \
|
|
3643
|
+
PYBIND11_OVERRIDE_PURE(PYBIND11_TYPE(ret_type), PYBIND11_TYPE(cname), fn, __VA_ARGS__);
|
|
3644
|
+
|
|
3645
|
+
PYBIND11_NAMESPACE_END(PYBIND11_NAMESPACE)
|