File indexing completed on 2026-01-09 10:20:47
0001
0002
0003
0004
0005
0006
0007 #pragma once
0008
0009 #include <pybind11/attr.h>
0010 #include <pybind11/conduit/pybind11_platform_abi_id.h>
0011 #include <pybind11/pytypes.h>
0012
0013 #include "common.h"
0014
0015 #include <cstring>
0016 #include <utility>
0017
0018 PYBIND11_NAMESPACE_BEGIN(PYBIND11_NAMESPACE)
0019 PYBIND11_NAMESPACE_BEGIN(detail)
0020
0021 struct function_record_PyObject {
0022 PyObject_HEAD
0023 function_record *cpp_func_rec;
0024 };
0025
0026 PYBIND11_NAMESPACE_BEGIN(function_record_PyTypeObject_methods)
0027
0028 PyObject *tp_new_impl(PyTypeObject *type, PyObject *args, PyObject *kwds);
0029 PyObject *tp_alloc_impl(PyTypeObject *type, Py_ssize_t nitems);
0030 int tp_init_impl(PyObject *self, PyObject *args, PyObject *kwds);
0031 void tp_dealloc_impl(PyObject *self);
0032 void tp_free_impl(void *self);
0033
0034 static PyObject *reduce_ex_impl(PyObject *self, PyObject *, PyObject *);
0035
0036 static PyMethodDef tp_methods_impl[]
0037 = {{"__reduce_ex__",
0038
0039
0040
0041
0042
0043 reinterpret_cast<PyCFunction>(reinterpret_cast<void *>(reduce_ex_impl)),
0044 METH_VARARGS | METH_KEYWORDS,
0045 nullptr},
0046 {nullptr, nullptr, 0, nullptr}};
0047
0048
0049
0050
0051
0052
0053
0054
0055
0056
0057
0058
0059
0060
0061
0062
0063
0064
0065
0066 #define PYBIND11_DETAIL_FUNCTION_RECORD_TP_PLAINNAME \
0067 "pybind11_detail_function_record_" PYBIND11_DETAIL_FUNCTION_RECORD_ABI_ID \
0068 "_" PYBIND11_PLATFORM_ABI_ID
0069 constexpr char tp_plainname_impl[] = PYBIND11_DETAIL_FUNCTION_RECORD_TP_PLAINNAME;
0070 constexpr char tp_qualname_impl[]
0071 = PYBIND11_DUMMY_MODULE_NAME "." PYBIND11_DETAIL_FUNCTION_RECORD_TP_PLAINNAME;
0072
0073 PYBIND11_NAMESPACE_END(function_record_PyTypeObject_methods)
0074
0075 static PyType_Slot function_record_PyType_Slots[] = {
0076 {Py_tp_dealloc,
0077 reinterpret_cast<void *>(function_record_PyTypeObject_methods::tp_dealloc_impl)},
0078 {Py_tp_methods,
0079 reinterpret_cast<void *>(function_record_PyTypeObject_methods::tp_methods_impl)},
0080 {Py_tp_init, reinterpret_cast<void *>(function_record_PyTypeObject_methods::tp_init_impl)},
0081 {Py_tp_alloc, reinterpret_cast<void *>(function_record_PyTypeObject_methods::tp_alloc_impl)},
0082 {Py_tp_new, reinterpret_cast<void *>(function_record_PyTypeObject_methods::tp_new_impl)},
0083 {Py_tp_free, reinterpret_cast<void *>(function_record_PyTypeObject_methods::tp_free_impl)},
0084 {0, nullptr}};
0085
0086 static PyType_Spec function_record_PyType_Spec
0087 = {function_record_PyTypeObject_methods::tp_qualname_impl,
0088 sizeof(function_record_PyObject),
0089 0,
0090 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HEAPTYPE,
0091 function_record_PyType_Slots};
0092
0093 inline PyTypeObject *get_function_record_PyTypeObject() {
0094 PyTypeObject *&py_type_obj = detail::get_local_internals().function_record_py_type;
0095 if (!py_type_obj) {
0096 PyObject *py_obj = PyType_FromSpec(&function_record_PyType_Spec);
0097 if (py_obj == nullptr) {
0098 throw error_already_set();
0099 }
0100 py_type_obj = reinterpret_cast<PyTypeObject *>(py_obj);
0101 }
0102 return py_type_obj;
0103 }
0104
0105 inline bool is_function_record_PyObject(PyObject *obj) {
0106 if (PyType_Check(obj) != 0) {
0107 return false;
0108 }
0109 PyTypeObject *obj_type = Py_TYPE(obj);
0110
0111 PyTypeObject *frtype = get_function_record_PyTypeObject();
0112
0113
0114 if (obj_type == frtype) {
0115 return true;
0116 }
0117
0118 if (strcmp(obj_type->tp_name, function_record_PyTypeObject_methods::tp_qualname_impl) == 0
0119 || strcmp(obj_type->tp_name, function_record_PyTypeObject_methods::tp_plainname_impl)
0120 == 0) {
0121 return true;
0122 }
0123 return false;
0124 }
0125
0126 inline function_record *function_record_ptr_from_PyObject(PyObject *obj) {
0127 if (is_function_record_PyObject(obj)) {
0128 return ((detail::function_record_PyObject *) obj)->cpp_func_rec;
0129 }
0130 return nullptr;
0131 }
0132
0133 inline object function_record_PyObject_New() {
0134 auto *py_func_rec = PyObject_New(function_record_PyObject, get_function_record_PyTypeObject());
0135 if (py_func_rec == nullptr) {
0136 throw error_already_set();
0137 }
0138 py_func_rec->cpp_func_rec = nullptr;
0139 return reinterpret_steal<object>((PyObject *) py_func_rec);
0140 }
0141
0142 PYBIND11_NAMESPACE_BEGIN(function_record_PyTypeObject_methods)
0143
0144
0145 inline PyObject *tp_new_impl(PyTypeObject *, PyObject *, PyObject *) {
0146 pybind11_fail("UNEXPECTED CALL OF function_record_PyTypeObject_methods::tp_new_impl");
0147
0148 }
0149
0150 inline PyObject *tp_alloc_impl(PyTypeObject *, Py_ssize_t) {
0151 pybind11_fail("UNEXPECTED CALL OF function_record_PyTypeObject_methods::tp_alloc_impl");
0152
0153 }
0154
0155 inline int tp_init_impl(PyObject *, PyObject *, PyObject *) {
0156 pybind11_fail("UNEXPECTED CALL OF function_record_PyTypeObject_methods::tp_init_impl");
0157
0158 }
0159
0160 inline void tp_free_impl(void *) {
0161 pybind11_fail("UNEXPECTED CALL OF function_record_PyTypeObject_methods::tp_free_impl");
0162 }
0163
0164 inline PyObject *reduce_ex_impl(PyObject *self, PyObject *, PyObject *) {
0165
0166 const function_record *rec = function_record_ptr_from_PyObject(self);
0167 if (rec == nullptr) {
0168 pybind11_fail(
0169 "FATAL: function_record_PyTypeObject reduce_ex_impl(): cannot obtain cpp_func_rec.");
0170 }
0171 if (rec->name != nullptr && rec->name[0] != '\0' && rec->scope
0172 && PyModule_Check(rec->scope.ptr()) != 0) {
0173 object scope_module = get_scope_module(rec->scope);
0174 if (scope_module) {
0175 auto builtins = reinterpret_borrow<dict>(PyEval_GetBuiltins());
0176 auto builtins_eval = builtins["eval"];
0177 auto reconstruct_args = make_tuple(str("__import__('importlib').import_module('")
0178 + scope_module + str("')"));
0179 return make_tuple(std::move(builtins_eval), std::move(reconstruct_args))
0180 .release()
0181 .ptr();
0182 }
0183 }
0184 set_error(PyExc_RuntimeError, repr(self) + str(" is not pickleable."));
0185 return nullptr;
0186 }
0187
0188 PYBIND11_NAMESPACE_END(function_record_PyTypeObject_methods)
0189
0190 PYBIND11_NAMESPACE_END(detail)
0191 PYBIND11_NAMESPACE_END(PYBIND11_NAMESPACE)