57 PyObject* pymetabases = PyTuple_New(PyTuple_GET_SIZE(pybases));
58 for (
int i = 0; i < PyTuple_GET_SIZE(pybases); ++i) {
61 PyTuple_SET_ITEM(pymetabases, i, btype);
67 PyObject* args = Py_BuildValue((
char*)
"sO{}", (
name+
"_meta").c_str(), pymetabases);
69 Py_DECREF(pymetabases);
81 args = Py_BuildValue((
char*)
"sO{}",
name.c_str(), pybases);
83 ((PyTypeObject*)pymeta)->tp_new((PyTypeObject*)pymeta, args,
nullptr);
114 if (
CPPScope_Check(parent)) PyType_Type.tp_setattro(parent, pyname, newscope);
115 else PyObject_SetAttr(parent, pyname, newscope);
138 PyObject* pyclass,
const std::string& mtCppName,
const std::string& mtName)
143 if (!
attr) PyErr_Clear();
148 PyType_Type.tp_setattro(pyclass, pyname, (
PyObject*)pytmpl);
163 bool hasConstructor =
false;
167 typedef std::vector<PyCallable*> Callables_t;
168 typedef std::map<std::string, Callables_t> CallableCache_t;
169 CallableCache_t cache;
172 getattrofunc oldgetattro =
Py_TYPE(pyclass)->tp_getattro;
173 Py_TYPE(pyclass)->tp_getattro = PyType_Type.tp_getattro;
189 bool setupSetItem =
false;
192 bool isStubbedOperator =
false;
199 if (mtCppName[0] ==
'~')
209 bool isCall = mtName ==
"__call__";
210 if (isCall || mtName ==
"__getitem__") {
213 if (!cpd.empty() && cpd[cpd.size()-1] ==
'&' && \
214 qual_return.find(
"const", 0, 5) == std::string::npos) {
215 if (isCall && !potGetItem) potGetItem = method;
227 bool storeOnTemplate =
229 if (storeOnTemplate) {
239 else if (isNamespace)
241 else if (isConstructor) {
243 hasConstructor =
true;
251 }
else if (isStubbedOperator) {
256 if (storeOnTemplate) {
259 PyObject*
attr = PyObject_GetAttrString(pyclass,
const_cast<char*
>(mtName.c_str()));
269 if (pysi && !precursor) Py_DECREF(pysi);
272 Py_XDECREF(precursor);
273 PyObject_SetAttrString(pyclass,
const_cast<char*
>(
"__setitem__"), (
PyObject*)pysi);
282 Callables_t& md = (*(cache.insert(
283 std::make_pair(mtName, Callables_t())).first)).second;
284 md.push_back(pycall);
288 Callables_t& setitem = (*(cache.insert(
289 std::make_pair(std::string(
"__setitem__"), Callables_t())).first)).second;
290 setitem.push_back(
new CPPSetItem(scope, method));
309 if (!isConstructor) {
311 if (mtName0 != mtName1)
317 if (!hasConstructor) {
321 else if (isNamespace)
328 cache[
"__init__"].push_back(defctor);
333 Callables_t& getitem = (*(cache.insert(
334 std::make_pair(std::string(
"__getitem__"), Callables_t())).first)).second;
335 getitem.push_back(
new CPPGetItem(scope, potGetItem));
340 for (CallableCache_t::iterator imd = cache.begin(); imd != cache.end(); ++imd) {
349 for (
auto cit : imd->second)
352 if (!
attr) PyErr_Clear();
356 PyType_Type.tp_setattro(pyclass, pymname, (
PyObject*)method);
380 PyObject* eset = PyObject_GetAttrString(pyclass,
403 Py_TYPE(pyclass)->tp_getattro = oldgetattro;
417 std::deque<Cppyy::TCppType_t> bids;
418 for (
size_t ibase = 0; ibase < nbases; ++ibase) {
423 for (
size_t ibase2 = 0; ibase2 < uqb.size(); ++ibase2) {
424 if (uqb[ibase2] ==
name) {
437 uqb.push_front(
name);
439 }
else if (decision == 2) {
450 std::deque<std::string> uqb;
454 size_t nbases = uqb.size();
456 PyObject* pybases = PyTuple_New(nbases ? nbases : 1);
465 for (std::deque<std::string>::size_type ibase = 0; ibase < nbases; ++ibase) {
472 PyTuple_SET_ITEM(pybases, ibase, pyclass);
478 PyObject* newpybases = PyTuple_New(nbases+1);
481 for (
int ibase = 0; ibase < (
int)nbases; ++ibase) {
482 PyObject* pyclass = PyTuple_GET_ITEM(pybases, ibase);
484 PyTuple_SET_ITEM(newpybases, ibase+1, pyclass);
487 pybases = newpybases;
500 PyClassMap_t::iterator pci =
gPyClasses.find(scope);
526 if (PyErr_Occurred())
538 std::string scName =
"";
543 PyObject* parname = PyObject_GetAttr(parent, PyStrings::gName);
545 PyErr_Format(PyExc_SystemError,
"given scope has no name for %s",
name.c_str());
552 if (PyErr_Occurred())
561 const std::string& lookup = scName.empty() ?
name : (scName+
"::"+
name);
567 PyObject* pytemplate = PyObject_CallFunction(
568 pytcl,
const_cast<char*
>(
"s"),
const_cast<char*
>(lookup.c_str()));
589 if (tc && PyCallable_Check(tc)) {
590 PyObject* nt = PyObject_CallFunction(tc, (
char*)
"ss",
name.c_str(), scName.c_str());
603 PyErr_Format(PyExc_TypeError,
"\'%s\' is not a known C++ class", lookup.c_str());
621 if (actual != lookup) {
623 if (!pyscope) PyErr_Clear();
627 std::string::size_type last = 0;
633 for (std::string::size_type pos = 0; pos <
name.size(); ++pos) {
634 std::string::value_type
c =
name[pos];
643 else if (tpl_open == 0 && \
644 c ==
':' && pos+1 <
name.size() &&
name[ pos+1 ] ==
':') {
646 const std::string& part =
name.substr(last, pos-last);
648 PyObject* next = PyObject_GetAttrString(
649 parent ? parent :
gThisModule,
const_cast<char*
>(part.c_str()));
671 std::string unscoped =
name.substr(last, std::string::npos);
672 PyObject* ret = PyObject_GetAttrString(parent, unscoped.c_str());
705 if (pyscope && !(((
CPPScope*)pyscope)->
fFlags & CPPScope::kIsInComplete)) {
706 gPyClasses[klass] = PyWeakref_NewRef(pyscope,
nullptr);
716 PyObject* pyfullname = PyObject_GetAttr(pyscope, PyStrings::gModule);
719 PyObject* modules = PySys_GetObject(
const_cast<char*
>(
"modules"));
720 if (modules && PyDict_Check(modules))
721 PyDict_SetItem(modules, pyfullname, pyscope);
722 Py_DECREF(pyfullname);
728 if (pyscope && !(((
CPPScope*)pyscope)->
fFlags & CPPScope::kIsInComplete))
746 std::deque<std::string> uqb;
748 size_t nbases = uqb.size();
768 for (std::deque<std::string>::size_type ibase = 0; ibase < nbases; ++ibase) {
772 const std::string& parentname = TypeManip::extract_namespace(finalname);
779 PyObject* excbase = PyObject_GetAttrString(base_parent,
780 parentname.empty() ? finalname.c_str() : finalname.substr(parentname.size()+2, std::string::npos).c_str());
781 Py_DECREF(base_parent);
788 Py_XDECREF(best_base);
790 if (finalname !=
"std::exception")
798 PyTuple_SET_ITEM(pybases, 0, best_base);
801 PyObject* args = Py_BuildValue((
char*)
"OO{}", pyname, pybases);
805 PyObject* dct = PyTuple_GET_ITEM(args, 2);
806 PyDict_SetItem(dct, PyStrings::gUnderlying, pyscope);
807 PyDict_SetItem(dct, PyStrings::gName, PyObject_GetAttr(pyscope, PyStrings::gName));
808 PyDict_SetItem(dct, PyStrings::gCppName, PyObject_GetAttr(pyscope, PyStrings::gCppName));
809 PyDict_SetItem(dct, PyStrings::gModule, PyObject_GetAttr(pyscope, PyStrings::gModule));
812 PyObject* exc_pyscope = PyType_Type.tp_new(&PyType_Type, args,
nullptr);
817 PyType_Type.tp_setattro(parent, pyname, exc_pyscope);
828 PyErr_SetString(PyExc_TypeError,
"attempt to bind C++ object w/o class");
837 bool isRef = flags & CPPInstance::kIsReference;
838 bool isValue = flags & CPPInstance::kIsValue;
841 if (address && !isValue && !(flags & (CPPInstance::kNoWrapConv|CPPInstance::kNoMemReg))) {
842 PyObject* oldPyObject = MemoryRegulator::RetrievePyObject(
843 isRef ? *(
void**)address : address, pyclass);
846 if (oldPyObject && (!(flags & CPPInstance::kIsPtrPtr) ||
853 PyObject* smart_type = (flags != CPPInstance::kNoWrapConv && (((
CPPClass*)pyclass)->fFlags & CPPScope::kIsSmart)) ? pyclass :
nullptr;
858 pyclass = smart_type;
859 smart_type =
nullptr;
866 (
CPPInstance*)((PyTypeObject*)pyclass)->tp_new((PyTypeObject*)pyclass, args,
nullptr);
871 unsigned objflags = flags & \
872 (CPPInstance::kIsReference | CPPInstance::kIsPtrPtr | CPPInstance::kIsValue | CPPInstance::kIsOwner | CPPInstance::kIsActual);
879 if (address && !isRef && !(flags & (CPPInstance::kNoWrapConv|CPPInstance::kNoMemReg)))
880 MemoryRegulator::RegisterPyObject(pyobj, pyobj->
GetObject());
884 if (((
CPPClass*)pyclass)->fFlags & CPPScope::kIsException) {
905 PyErr_SetString(PyExc_TypeError,
"attempt to bind C++ object w/o class");
909 bool isRef = flags & CPPInstance::kIsReference;
915 unsigned new_flags = flags;
920 if (clActual != klass) {
922 clActual, klass, address, -1 ,
true );
924 address = (
void*)((intptr_t)address +
offset);
928 new_flags |= CPPInstance::kIsActual;
static PyObject * CPyCppyy_GetWeakRef(PyObject *ref)
#define CPyCppyy_PyText_InternFromString
#define CPyCppyy_PyText_AsString
#define CPyCppyy_PyText_AppendAndDel
#define CPyCppyy_PyText_FromString
Cppyy::TCppType_t fUnderlyingType
static PyClassMap_t gPyClasses
std::map< Cppyy::TCppScope_t, PyObject * > PyClassMap_t
std::ios_base::fmtflags fFlags
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
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 cname
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void char Point_t Rectangle_t WindowAttributes_t attr
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 Atom_t Int_t ULong_t ULong_t unsigned char prop_list Atom_t Atom_t Atom_t Time_t property
void Set(void *address, EFlags flags=kDefault)
void SetSmart(PyObject *smart_type)
const std::string & GetName() const
void AdoptTemplate(PyCallable *pc)
void AdoptMethod(PyCallable *pc)
void MergeOverload(CPPOverload *mp)
std::string compound(const std::string &name)
std::string MapOperatorName(const std::string &name, bool bTakesParames, bool *stubbed=nullptr)
CPPOverload * CPPOverload_New(const std::string &name, std::vector< PyCallable * > &methods)
PyTypeObject CPPInstance_Type
PyTypeObject CPPExcInstance_Type
PyObject * GetScopeProxy(Cppyy::TCppScope_t)
static PyObject * GetAttrDirect(PyObject *pyclass, PyObject *pyname)
PyObject * CreateScopeProxy(Cppyy::TCppScope_t, const unsigned flags=0)
static PyObject * CreateNewCppProxyClass(Cppyy::TCppScope_t klass, PyObject *pybases)
bool Pythonize(PyObject *pyclass, const std::string &name)
static int BuildScopeProxyDict(Cppyy::TCppScope_t scope, PyObject *pyclass, const unsigned int flags)
std::set< Cppyy::TCppType_t > gPinnedTypes
PyObject * BindCppObjectNoCast(Cppyy::TCppObject_t object, Cppyy::TCppType_t klass, const unsigned flags=0)
bool CPPOverload_Check(T *object)
bool CPPScope_Check(T *object)
static void sync_templates(PyObject *pyclass, const std::string &mtCppName, const std::string &mtName)
static PyObject * BuildCppClassBases(Cppyy::TCppType_t klass)
static void AddScopeToParent(PyObject *parent, const std::string &name, PyObject *newscope)
PyObject * TupleOfInstances_New(Cppyy::TCppObject_t address, Cppyy::TCppType_t klass, cdims_t dims)
CPPScope * CPPScopeMeta_New(Cppyy::TCppScope_t klass, PyObject *args)
CPPDataMember * CPPDataMember_New(Cppyy::TCppScope_t scope, Cppyy::TCppIndex_t idata)
PyObject * CreateExcScopeProxy(PyObject *pyscope, PyObject *pyname, PyObject *parent)
static void AddPropertyToClass(PyObject *pyclass, Cppyy::TCppScope_t scope, Cppyy::TCppIndex_t idata)
PyObject * BindCppObjectArray(Cppyy::TCppObject_t address, Cppyy::TCppType_t klass, cdims_t dims)
PyObject * BindCppObject(Cppyy::TCppObject_t object, Cppyy::TCppType_t klass, const unsigned flags=0)
bool TemplateProxy_Check(T *object)
TemplateProxy * TemplateProxy_New(const std::string &cppname, const std::string &pyname, PyObject *pyclass)
static void CollectUniqueBases(Cppyy::TCppType_t klass, std::deque< std::string > &uqb)
RPY_EXPORTED TCppIndex_t GetNumTemplatedMethods(TCppScope_t scope, bool accept_namespace=false)
RPY_EXPORTED ptrdiff_t GetBaseOffset(TCppType_t derived, TCppType_t base, TCppObject_t address, int direction, bool rerror=false)
RPY_EXPORTED bool IsEnumData(TCppScope_t scope, TCppIndex_t idata)
RPY_EXPORTED bool IsAbstract(TCppType_t type)
RPY_EXPORTED bool IsTemplate(const std::string &template_name)
RPY_EXPORTED bool IsEnum(const std::string &type_name)
RPY_EXPORTED bool ExistsMethodTemplate(TCppScope_t scope, const std::string &name)
RPY_EXPORTED TCppIndex_t GetNumDatamembers(TCppScope_t scope, bool accept_namespace=false)
RPY_EXPORTED std::string GetMethodName(TCppMethod_t)
RPY_EXPORTED bool IsSubtype(TCppType_t derived, TCppType_t base)
RPY_EXPORTED bool IsConstructor(TCppMethod_t method)
RPY_EXPORTED TCppIndex_t GetNumMethods(TCppScope_t scope, bool accept_namespace=false)
RPY_EXPORTED std::string ResolveName(const std::string &cppitem_name)
RPY_EXPORTED TCppIndex_t GetMethodNumArgs(TCppMethod_t)
RPY_EXPORTED TCppType_t GetActualClass(TCppType_t klass, TCppObject_t obj)
RPY_EXPORTED std::string GetBaseName(TCppType_t type, TCppIndex_t ibase)
RPY_EXPORTED bool IsNamespace(TCppScope_t scope)
RPY_EXPORTED std::string GetScopedFinalName(TCppType_t type)
RPY_EXPORTED bool IsPublicData(TCppScope_t scope, TCppIndex_t idata)
RPY_EXPORTED bool IsComplete(const std::string &type_name)
RPY_EXPORTED bool IsStaticMethod(TCppMethod_t method)
RPY_EXPORTED bool IsStaticData(TCppScope_t scope, TCppIndex_t idata)
RPY_EXPORTED std::string GetDatamemberType(TCppScope_t scope, TCppIndex_t idata)
RPY_EXPORTED TCppMethod_t GetMethod(TCppScope_t scope, TCppIndex_t imeth)
RPY_EXPORTED std::string GetTemplatedMethodName(TCppScope_t scope, TCppIndex_t imeth)
RPY_EXPORTED TCppScope_t GetScope(const std::string &scope_name)
RPY_EXPORTED bool IsTemplatedConstructor(TCppScope_t scope, TCppIndex_t imeth)
RPY_EXPORTED TCppIndex_t GetNumBases(TCppType_t type)
RPY_EXPORTED std::string GetMethodResultType(TCppMethod_t)
RPY_EXPORTED std::string GetFinalName(TCppType_t type)
RPY_EXPORTED bool IsMethodTemplate(TCppScope_t scope, TCppIndex_t imeth)
RPY_EXPORTED std::string GetDatamemberName(TCppScope_t scope, TCppIndex_t idata)
RPY_EXPORTED bool IsPublicMethod(TCppMethod_t method)
RPY_EXPORTED intptr_t GetDatamemberOffset(TCppScope_t scope, TCppIndex_t idata)
PyObject_HEAD PyObject * dict