19#define CPYCPPYY_INTERNAL 1
24 void* addr,
const std::string& classname,
bool python_owns =
false);
26#undef CPYCPPYY_INTERNAL
42#if PY_VERSION_HEX < 0x030b0000
45#if PY_VERSION_HEX >= 0x03030000
46 typedef struct PyDictKeyEntry {
53 typedef struct _dictkeysobject {
58#if PY_VERSION_HEX >= 0x03060000
69 PyDictKeyEntry dk_entries[1];
73#define CPYCPPYY_GET_DICT_LOOKUP(mp) \
74 ((dict_lookup_func&)mp->ma_keys->dk_lookup)
78#define CPYCPPYY_GET_DICT_LOOKUP(mp) \
79 ((dict_lookup_func&)mp->ma_lookup)
93 Py_FatalError(
"deallocating nullptr");
103#if PY_VERSION_HEX < 0x03000000
109#
if PY_VERSION_HEX < 0x03000000
113#
if PY_VERSION_HEX < 0x03000000
117#
if PY_VERSION_HEX < 0x03000000
121#
if PY_VERSION_HEX >= 0x02020000
123#
if PY_VERSION_HEX < 0x03000000
130#
if PY_VERSION_HEX >= 0x02050000
133#
if PY_VERSION_HEX >= 0x03050000
149 (hashfunc)_Py_HashPointer,
150 0, 0, 0, 0, 0, Py_TPFLAGS_DEFAULT, 0, 0, 0, 0, 0, 0, 0,
151 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
152#if PY_VERSION_HEX >= 0x02030000
155#if PY_VERSION_HEX >= 0x02060000
158#if PY_VERSION_HEX >= 0x03040000
161#if PY_VERSION_HEX >= 0x03080000
164#if PY_VERSION_HEX >= 0x030c0000
167#if PY_VERSION_HEX >= 0x030d0000
180 Py_FatalError(
"deallocating default");
192 (hashfunc)_Py_HashPointer,
193 0, 0, 0, 0, 0, Py_TPFLAGS_DEFAULT, 0, 0, 0, 0, 0, 0, 0,
194 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
195#if PY_VERSION_HEX >= 0x02030000
198#if PY_VERSION_HEX >= 0x02060000
201#if PY_VERSION_HEX >= 0x03040000
204#if PY_VERSION_HEX >= 0x03080000
207#if PY_VERSION_HEX >= 0x030c0000
210#if PY_VERSION_HEX >= 0x030d0000
217PyObject _CPyCppyy_NullPtrStruct = {_PyObject_EXTRA_INIT
219#if PY_VERSION_HEX >= 0x30c00b1
226PyObject _CPyCppyy_DefaultStruct = {_PyObject_EXTRA_INIT
228#if PY_VERSION_HEX >= 0x30c00b1
259 static std::map<std::string, std::vector<PyObject*>> pyzMap;
272#if PY_VERSION_HEX < 0x030b0000
278 PyObject* cppyy = PyImport_AddModule((
char*)
"cppyy");
279 fGbl = PyObject_GetAttrString(cppyy, (
char*)
"gbl");
281 ~GblGetter() { Py_DECREF(fGbl); }
291#if PY_VERSION_HEX >= 0x03060000
297#define CPYCPPYY_ORGDICT_LOOKUP(mp, key, hash, value_addr, hashpos) \
298 OrgDictLookup(mp, key, hash, value_addr, hashpos)
303#elif PY_VERSION_HEX >= 0x03030000
304inline PyDictKeyEntry* OrgDictLookup(
310#define CPYCPPYY_ORGDICT_LOOKUP(mp, key, hash, value_addr, hashpos) \
311 OrgDictLookup(mp, key, hash, value_addr)
313PyDictKeyEntry* CPyCppyyLookDictString(
318inline PyDictEntry* OrgDictLookup(PyDictObject* mp,
PyObject* key,
long hash)
323#define CPYCPPYY_ORGDICT_LOOKUP(mp, key, hash, value_addr, hashpos) \
324 OrgDictLookup(mp, key, hash)
326PyDictEntry* CPyCppyyLookDictString(PyDictObject* mp,
PyObject* key,
long hash)
329 static GblGetter gbl;
330#if PY_VERSION_HEX >= 0x03060000
341#if PY_VERSION_HEX >= 0x03060000
344 if (!ep || (ep->me_key && ep->me_value))
349 if (PyDict_GetItem(PyEval_GetBuiltins(), key) != 0)
356 PyObject* val = PyObject_GetAttr(*gbl, key);
366 PyObject* actual_val =
Py_TYPE(val)->tp_descr_get(val,
nullptr,
nullptr);
373 if (PyDict_SetItem((
PyObject*)mp, key, val) == 0) {
376#if PY_VERSION_HEX >= 0x03060000
379 ep->me_key =
nullptr;
380 ep->me_value =
nullptr;
390#if PY_VERSION_HEX >= 0x03030000
391 if (mp->ma_keys->dk_usable <= 0) {
396 const int maxinsert = 5;
398 for (
int varmax = 1; varmax <= maxinsert; ++varmax) {
399 for (
int ivar = 0; ivar < varmax; ++ivar) {
401 PyDict_SetItem((
PyObject*)mp, buf[ivar], Py_None);
403 for (
int ivar = 0; ivar < varmax; ++ivar) {
404 PyDict_DelItem((
PyObject*)mp, buf[ivar]);
405 Py_DECREF(buf[ivar]);
407 if (0 < mp->ma_keys->dk_usable)
430#if PY_VERSION_HEX < 0x030b0000
436 PyDictObject* dict =
nullptr;
437 if (!PyArg_ParseTuple(args,
const_cast<char*
>(
"O!"), &PyDict_Type, &dict))
444 PyErr_Warn(PyExc_RuntimeWarning, (
char*)
"lazy lookup is no longer supported");
459 PyErr_Format(PyExc_TypeError,
"too few arguments for template instantiation");
464 const std::string& tmpl_name =
466 if (!tmpl_name.size())
473static char* GCIA_kwlist[] = {(
char*)
"instance", (
char*)
"field", (
char*)
"byref", NULL};
474static void* GetCPPInstanceAddress(
const char* fname,
PyObject* args,
PyObject* kwds)
478 if (PyArg_ParseTupleAndKeywords(args, kwds,
const_cast<char*
>(
"O|O!b"), GCIA_kwlist,
493 void* addr = (
void*)pyprop->
GetAddress(pyobj);
500 PyErr_Format(PyExc_TypeError,
507 if (!byref)
return ((
CPPInstance*)pyobj)->GetObject();
513 if (req ==
"Instance_AsVoidPtr")
515 else if (req ==
"Instance_FromVoidPtr")
520 if (!PyErr_Occurred())
521 PyErr_Format(PyExc_ValueError,
"invalid argument for %s", fname);
529 void* addr = GetCPPInstanceAddress(
"addressof", args, kwds);
531 return PyLong_FromLongLong((intptr_t)addr);
532 else if (!PyErr_Occurred()) {
533 return PyLong_FromLong(0);
534 }
else if (PyTuple_CheckExact(args) && PyTuple_GET_SIZE(args) == 1) {
536 PyObject* arg0 = PyTuple_GET_ITEM(args, 0);
539 if (arg0 ==
gNullPtrObject || (PyInt_Check(arg0) && PyInt_AsLong(arg0) == 0))
540 return PyLong_FromLong(0);
544 const auto& methods = ((
CPPOverload*)arg0)->fMethodInfo->fMethods;
545 if (methods.size() != 1) {
546 PyErr_SetString(PyExc_TypeError,
"overload is not unambiguous");
551 return PyLong_FromLongLong((intptr_t)caddr);
555 if (PyCFunction_Check(arg0)) {
556 void* caddr = (
void*)PyCFunction_GetFunction(arg0);
557 return PyLong_FromLongLong((intptr_t)caddr);
562 if (addr)
return PyLong_FromLongLong((intptr_t)addr);
566 if (!PyErr_Occurred()) {
567 if (PyTuple_CheckExact(args) && PyTuple_GET_SIZE(args)) {
568 PyObject* str = PyObject_Str(PyTuple_GET_ITEM(args, 0));
572 PyErr_Format(PyExc_TypeError,
"unknown object at %p", (
void*)PyTuple_GET_ITEM(args, 0));
583 void* addr = GetCPPInstanceAddress(
"as_cobject", args, kwds);
593 void* addr = GetCPPInstanceAddress(
"as_capsule", args, kwds);
595#if PY_VERSION_HEX < 0x02060000
596 return PyCObject_FromVoidPtr(addr,
nullptr);
598 return PyCapsule_New(addr,
nullptr,
nullptr);
607 void* addr = GetCPPInstanceAddress(
"as_ctypes", args, kwds);
612 static PyTypeObject* ct_cvoidp =
nullptr;
614 PyObject* ctmod = PyImport_ImportModule(
"ctypes");
615 if (!ctmod)
return nullptr;
617 ct_cvoidp = (PyTypeObject*)PyObject_GetAttrString(ctmod,
"c_void_p");
619 if (!ct_cvoidp)
return nullptr;
620 Py_DECREF(ct_cvoidp);
623 PyObject* ref = ct_cvoidp->tp_new(ct_cvoidp,
nullptr,
nullptr);
634 PyErr_SetString(PyExc_TypeError,
"C++ object proxy expected");
645 PyExc_TypeError,
"object is not a proxy to an array of PODs of known size");
654 view.len = view.itemsize * array_len;
660 view.suboffsets = NULL;
661 view.internal = NULL;
663 return PyMemoryView_FromBuffer(&view);
672 PyErr_Format(PyExc_TypeError,
673 "bind_object takes 2 positional arguments but (" PY_SSIZE_T_FORMAT " were given)", argc);
679 PyObject* arg1 = PyTuple_GET_ITEM(args, 1);
682 cast_type = ((
CPPClass*)arg1)->fCppType;
688 if (!cast_type && arg1) {
694 PyErr_SetString(PyExc_TypeError,
695 "bind_object expects a valid class or class name as an argument");
700 PyObject* arg0 = PyTuple_GET_ITEM(args, 0);
711 if (cur_type == cast_type && !isPython) {
727 PyErr_SetString(PyExc_TypeError,
728 "provided instance and provided target type are unrelated");
748 if (owns && pyobj) arg0_pyobj->
CppOwns();
754 void* cast_address = (
void*)((intptr_t)address +
offset);
755 PyObject* pyobj = ((PyTypeObject*)arg1)->tp_new((PyTypeObject*)arg1,
nullptr,
nullptr);
756 ((
CPPInstance*)pyobj)->GetObjectRaw() = cast_address;
766 if (res) Py_DECREF(res);
769 Py_DECREF(dispproxy);
781 void* addr =
nullptr;
782 if (arg0 != &_CPyCppyy_NullPtrStruct) {
784 if (PyErr_Occurred()) {
787 addr = PyLong_AsVoidPtr(arg0);
788 if (PyErr_Occurred()) {
793 if (!addr || !buflen) {
794 PyErr_SetString(PyExc_TypeError,
795 "bind_object requires a CObject/Capsule, long integer, buffer, or instance as first argument");
802 bool do_cast =
false;
804 PyObject* cast = PyDict_GetItemString(kwds,
"cast");
805 do_cast = cast && PyObject_IsTrue(cast);
819 PyErr_SetString(PyExc_TypeError,
"C++ object expected");
833 PyObject* pythonizor =
nullptr;
const char* scope;
834 if (!PyArg_ParseTuple(args,
const_cast<char*
>(
"Os"), &pythonizor, &scope))
837 if (!PyCallable_Check(pythonizor)) {
838 PyObject* pystr = PyObject_Str(pythonizor);
839 PyErr_Format(PyExc_TypeError,
845 Py_INCREF(pythonizor);
856 PyObject* pythonizor =
nullptr;
const char* scope;
857 if (!PyArg_ParseTuple(args,
const_cast<char*
>(
"Os"), &pythonizor, &scope))
861 auto p1 = pyzMap.find(scope);
862 if (p1 != pyzMap.end()) {
863 auto p2 = std::find(p1->second.begin(), p1->second.end(), pythonizor);
864 if (p2 != p1->second.end()) {
865 p1->second.erase(p2);
879 PyErr_SetString(PyExc_TypeError,
"C++ class expected");
892 const char *reducable, *reduced;
893 if (!PyArg_ParseTuple(args,
const_cast<char*
>(
"ss"), &reducable, &reduced))
907 if (!PyArg_ParseTuple(args,
const_cast<char*
>(
"O!"), &PyInt_Type, &policy))
912 long l = PyInt_AS_LONG(policy);
914 return PyInt_FromLong(old);
917 PyErr_Format(PyExc_ValueError,
"Unknown policy %ld",
l);
927 if (!PyArg_ParseTuple(args,
const_cast<char*
>(
"O"), &setProtected))
942 if (!PyArg_ParseTuple(args,
const_cast<char*
>(
"O!O!"),
946 (
bool)PyLong_AsLong(pykeep) ? pyobj->
PythonOwns() : pyobj->CppOwns();
955 const char* type_name;
956 if (!PyArg_ParseTuple(args,
const_cast<char*
>(
"s"), &type_name))
985 return Py_BuildValue(
"s", capturedError.c_str());
993 METH_VARARGS, (
char*)
"cppyy internal function"},
994 {(
char*)
"MakeCppTemplateClass", (PyCFunction)MakeCppTemplateClass,
995 METH_VARARGS, (
char*)
"cppyy internal function"},
996 {(
char*)
"_set_cpp_lazy_lookup", (PyCFunction)SetCppLazyLookup,
997 METH_VARARGS, (
char*)
"cppyy internal function"},
999 METH_NOARGS, (
char*)
"cppyy internal function"},
1000 {(
char*)
"addressof", (PyCFunction)addressof,
1001 METH_VARARGS | METH_KEYWORDS, (
char*)
"Retrieve address of proxied object or field as a value."},
1002 {(
char*)
"as_cobject", (PyCFunction)AsCObject,
1003 METH_VARARGS | METH_KEYWORDS, (
char*)
"Retrieve address of proxied object or field in a CObject."},
1004 {(
char*)
"as_capsule", (PyCFunction)AsCapsule,
1005 METH_VARARGS | METH_KEYWORDS, (
char*)
"Retrieve address of proxied object or field in a PyCapsule."},
1006 {(
char*)
"as_ctypes", (PyCFunction)AsCTypes,
1007 METH_VARARGS | METH_KEYWORDS, (
char*)
"Retrieve address of proxied object or field in a ctypes c_void_p."},
1008 {(
char*)
"as_memoryview", (PyCFunction)AsMemoryView,
1009 METH_O, (
char*)
"Represent an array of objects as raw memory."},
1010 {(
char*)
"bind_object", (PyCFunction)BindObject,
1011 METH_VARARGS | METH_KEYWORDS, (
char*)
"Create an object of given type, from given address."},
1012 {(
char*)
"move", (PyCFunction)Move,
1013 METH_O, (
char*)
"Cast the C++ object to become movable."},
1014 {(
char*)
"add_pythonization", (PyCFunction)AddPythonization,
1015 METH_VARARGS, (
char*)
"Add a pythonizor."},
1016 {(
char*)
"remove_pythonization", (PyCFunction)RemovePythonization,
1017 METH_VARARGS, (
char*)
"Remove a pythonizor."},
1018 {(
char*)
"_pin_type", (PyCFunction)PinType,
1019 METH_O, (
char*)
"Install a type pinning."},
1020 {(
char*)
"_add_type_reducer", (PyCFunction)AddTypeReducer,
1021 METH_VARARGS, (
char*)
"Add a type reducer."},
1022 {(
char*)
"SetMemoryPolicy", (PyCFunction)SetMemoryPolicy,
1023 METH_VARARGS, (
char*)
"Determines object ownership model."},
1024 {(
char*)
"SetGlobalSignalPolicy", (PyCFunction)SetGlobalSignalPolicy,
1025 METH_VARARGS, (
char*)
"Trap signals in safe mode to prevent interpreter abort."},
1026 {(
char*)
"SetOwnership", (PyCFunction)SetOwnership,
1027 METH_VARARGS, (
char*)
"Modify held C++ object ownership."},
1028 {(
char*)
"AddSmartPtrType", (PyCFunction)AddSmartPtrType,
1029 METH_VARARGS, (
char*)
"Add a smart pointer to the list of known smart pointer types."},
1030 {(
char*)
"_begin_capture_stderr", (PyCFunction)BeginCaptureStderr,
1031 METH_NOARGS, (
char*)
"Begin capturing stderr to a in memory buffer."},
1032 {(
char*)
"_end_capture_stderr", (PyCFunction)EndCaptureStderr,
1033 METH_NOARGS, (
char*)
"End capturing stderr and returns the captured buffer."},
1034 {
nullptr,
nullptr, 0,
nullptr}
1038#if PY_VERSION_HEX >= 0x03000000
1043#define GETSTATE(m) ((struct module_state*)PyModule_GetState(m))
1045static int cpycppyymodule_traverse(
PyObject*
m, visitproc visit,
void* arg)
1051static int cpycppyymodule_clear(
PyObject*
m)
1059 PyModuleDef_HEAD_INIT,
1065 cpycppyymodule_traverse,
1066 cpycppyymodule_clear,
1072#define CPYCPPYY_INIT_ERROR return nullptr
1073extern "C" PyObject* PyInit_libcppyy()
1075#define CPYCPPYY_INIT_ERROR return
1086#if PY_VERSION_HEX < 0x03090000
1087 PyEval_InitThreads();
1090#if PY_VERSION_HEX < 0x030b0000
1094 PyObject* notstring = PyInt_FromLong(5);
1095 PyDict_SetItem(dict, notstring, notstring);
1096 Py_DECREF(notstring);
1097#if PY_VERSION_HEX >= 0x03030000
1106#if PY_VERSION_HEX >= 0x03000000
1122 PyModule_AddObject(
gThisModule,
"UserExceptions", PyDict_New());
1149#if PY_VERSION_HEX < 0x03000000
1189 PyObject* cppfatal = PyErr_NewException((
char*)
"cppyy.ll.FatalError",
nullptr,
nullptr);
1190 PyModule_AddObject(
gThisModule, (
char*)
"FatalError", cppfatal);
1192 gBusException = PyErr_NewException((
char*)
"cppyy.ll.BusError", cppfatal,
nullptr);
1194 gSegvException = PyErr_NewException((
char*)
"cppyy.ll.SegmentationViolation", cppfatal,
nullptr);
1196 gIllException = PyErr_NewException((
char*)
"cppyy.ll.IllegalInstruction", cppfatal,
nullptr);
1198 gAbrtException = PyErr_NewException((
char*)
"cppyy.ll.AbortSignal", cppfatal,
nullptr);
1202 PyModule_AddObject(
gThisModule, (
char*)
"kMemoryHeuristics",
1204 PyModule_AddObject(
gThisModule, (
char*)
"kMemoryStrict",
1212#if PY_VERSION_HEX >= 0x03000000
static PyObject * default_repr(PyObject *)
#define CPYCPPYY_ORGDICT_LOOKUP(mp, key, hash, value_addr, hashpos)
static PyObject * nullptr_repr(PyObject *)
static PyNumberMethods nullptr_as_number
#define CPYCPPYY_INIT_ERROR
static void default_dealloc(PyObject *)
static PyTypeObject PyDefault_t_Type
static void nullptr_dealloc(PyObject *)
static int nullptr_nonzero(PyObject *)
static PyMethodDef gCPyCppyyMethods[]
static PyTypeObject PyNullPtr_t_Type
#define CPYCPPYY_GET_DICT_LOOKUP(mp)
PyDictEntry *(* dict_lookup_func)(PyDictObject *, PyObject *, long)
#define PY_SSIZE_T_FORMAT
static void * CPyCppyy_PyCapsule_GetPointer(PyObject *capsule, const char *)
#define CPyCppyy_PyText_AsString
static PyObject * CPyCppyy_PyCapsule_New(void *cobj, const char *, void(*destr)(void *))
static PyObject * PyObject_CallMethodOneArg(PyObject *obj, PyObject *name, PyObject *arg)
#define CPyCppyy_PyText_FromFormat
#define CPyCppyy_PyText_Type
#define CPyCppyy_PyText_FromString
#define CPyCppyy_PyText_Check
#define PyVarObject_HEAD_INIT(type, size)
static struct PyModuleDef moduledef
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void char Point_t Rectangle_t WindowAttributes_t Float_t Float_t Float_t Int_t Int_t UInt_t UInt_t Rectangle_t Int_t Int_t Window_t TString Int_t GCValues_t GetPrimarySelectionOwner GetDisplay GetScreen GetColormap GetNativeEvent const char const char dpyName wid window const char font_name cursor keysym reg const char only_if_exist regb h Point_t winding char text const char depth char const char Int_t count const char ColorStruct_t color const char Pixmap_t Pixmap_t PictureAttributes_t attr const char char ret_data h unsigned char height h offset
TTime operator*(const TTime &t1, const TTime &t2)
void * GetAddress(CPPInstance *pyobj)
Cppyy::TCppType_t ObjectIsA(bool check_smart=true) const
Py_ssize_t GetBuffer(PyObject *pyobject, char tc, int size, void *&buf, bool check=true)
std::string ConstructTemplateArgs(PyObject *pyname, PyObject *tpArgs, PyObject *args=nullptr, ArgPreference=kNone, int argoff=0, int *pcnt=nullptr)
bool InitProxy(PyObject *module, PyTypeObject *pytype, const char *name)
PyTypeObject CPPInstance_Type
PyObject * gAbrtException
PyObject * gDefaultObject
PyTypeObject VectorIter_Type
PyTypeObject CPPExcInstance_Type
PyObject * GetScopeProxy(Cppyy::TCppScope_t)
std::ostringstream gCapturedError
dict_lookup_func gDictLookupOrg
PyTypeObject CustomInstanceMethod_Type
PyObject * CreateScopeProxy(Cppyy::TCppScope_t, const unsigned flags=0)
bool CPPDataMember_CheckExact(T *object)
PyTypeObject RefFloat_Type
Custom "builtins," detectable by type, for pass by ref and improved performance.
PyObject * gSegvException
std::set< Cppyy::TCppType_t > gPinnedTypes
PyObject * DestroyPyStrings()
PyObject * BindCppObjectNoCast(Cppyy::TCppObject_t object, Cppyy::TCppType_t klass, const unsigned flags=0)
std::map< std::string, std::vector< PyObject * > > & pythonizations()
bool CPPScope_Check(T *object)
CPYCPPYY_EXTERN PyObject * Instance_FromVoidPtr(void *addr, const std::string &classname, bool python_owns=false)
bool CPPInstance_Check(T *object)
PyTypeObject IndexIter_Type
PyObject * gNullPtrObject
PyTypeObject CPPOverload_Type
PyTypeObject TemplateProxy_Type
PyTypeObject InstanceArrayIter_Type
bool CPPDataMember_Check(T *object)
PyObject * BindCppObject(Cppyy::TCppObject_t object, Cppyy::TCppType_t klass, const unsigned flags=0)
CPYCPPYY_EXTERN void * Instance_AsVoidPtr(PyObject *pyobject)
PyTypeObject CPPScope_Type
PyTypeObject LowLevelView_Type
bool CPPOverload_CheckExact(T *object)
PyTypeObject CPPDataMember_Type
std::streambuf * gOldErrorBuffer
PyTypeObject TupleOfInstances_Type
Representation of C-style array of instances.
RPY_EXPORTED ptrdiff_t GetBaseOffset(TCppType_t derived, TCppType_t base, TCppObject_t address, int direction, bool rerror=false)
RPY_EXPORTED size_t SizeOf(TCppType_t klass)
RPY_EXPORTED void AddSmartPtrType(const std::string &)
RPY_EXPORTED bool IsSubtype(TCppType_t derived, TCppType_t base)
RPY_EXPORTED void AddTypeReducer(const std::string &reducable, const std::string &reduced)
RPY_EXPORTED bool IsAggregate(TCppType_t type)
RPY_EXPORTED TCppScope_t GetScope(const std::string &scope_name)
void(off) SmallVectorTemplateBase< T
static ECallFlags sMemoryPolicy
static bool SetGlobalSignalPolicy(bool setProtected)
static bool SetMemoryPolicy(ECallFlags e)
PyObject_HEAD char * b_ptr