34 std::vector<PyCallable*>* overloads =
nullptr) {
39 PyObject* pyncl = PyUnicode_FromString(ncl.c_str());
46 PyType_Type.tp_setattro(pyclass, pyncl, (
PyObject*)pytmpl);
56 for (
auto clb : *overloads)
59 for (
auto clb : *overloads)
75 return PyType_Type.tp_alloc(meta,
nitems);
93 return PyType_Type.tp_dealloc((
PyObject*)scope);
99 return PyUnicode_FromString(
"CPPInstance_Type");
100 return PyUnicode_FromString(
107 return PyUnicode_FromString(
"cppjit.gbl");
115 return PyUnicode_FromString(
const_cast<char*
>(
"cppjit.gbl"));
128 PyUnicode_AppendAndDel(&pymodule, PyUnicode_FromString(
"."));
129 PyUnicode_AppendAndDel(&pymodule, pymodname);
142 return PyUnicode_FromString((
"cppjit.gbl." + modname).c_str());
148 PyErr_SetString(PyExc_AttributeError,
149 "attribute \'__module__\' of 'cppjit.CPPScope\' objects is "
154 const char* newname = PyUnicode_AsUTF8(
value);
159 Py_ssize_t sz = PyUnicode_GET_LENGTH(
value);
171 return PyUnicode_FromFormat(
172 const_cast<char*
>(
"<class cppjit.CPPInstance at %p>"), scope);
176 return PyType_Type.tp_repr((
PyObject*)scope);
181 return PyType_Type.tp_repr((
PyObject*)scope);
190 PyUnicode_FromFormat(
"<%s %s.%s at %p>", kind, PyUnicode_AsUTF8(modname),
191 clName.c_str(), scope);
226 result->fOperators =
nullptr;
227 result->fModuleName =
nullptr;
237 !strstr(subtype->tp_name,
"_meta") ) {
254 if (3 <= PyTuple_GET_SIZE(args)) {
255 PyObject* dct = PyTuple_GET_ITEM(args, 2);
256 Py_ssize_t sz = PyDict_Size(dct);
259 if (1 < PyTuple_GET_SIZE(PyTuple_GET_ITEM(args, 1)))
261 std::ostringstream errmsg;
263 PyErr_Format(PyExc_TypeError,
264 "no python-side overrides supported (%s)",
265 errmsg.str().c_str());
271 PyObject* bname = PyUnicode_FromString(
282 }
else if (sz == (Py_ssize_t)-1)
308 result->fImp.fCppObjects =
nullptr;
311 result->fImp.fUsing =
nullptr;
315 if (PyErr_Occurred()) {
325 if (
name.empty() || std::isdigit((
unsigned char)
name[0]))
327 for (
char c :
name) {
328 if (!std::isalnum((
unsigned char)
c) &&
c !=
'_')
338 const std::vector<interop::TCppScope_t>& uv =
346 klass->
fImp.
fUsing =
new std::vector<PyObject*>;
349 for (
auto uid : uv) {
353 klass->
fImp.
fUsing->push_back(PyWeakref_NewRef(pyuscope,
nullptr));
356 PyUnicode_FromString((
"__lifeline_" + uname).c_str());
357 PyType_Type.tp_setattro(pyclass, llname, pyuscope);
371 std::set<PyObject*>& visited) {
377 if (visited.insert(pyuscope).second) {
378 found = _PyType_Lookup((PyTypeObject*)pyuscope, pyname) ||
379 _PyType_Lookup(Py_TYPE(pyuscope), pyname) ||
394 PyObject*
attr = PyType_Type.tp_getattro(pyclass, pyname);
398 PyObject* possibly_shadowed =
nullptr;
409 PyObject* attr_from_dict = PyObject_GetItem(dct, pyname);
411 if (attr_from_dict) {
413 return attr_from_dict;
415 possibly_shadowed =
attr;
427 return possibly_shadowed;
430 std::string
name = PyUnicode_AsUTF8(pyname);
431 if (
name.size() >= 5 &&
name.compare(0, 2,
"__") == 0 &&
433 return possibly_shadowed;
436 std::vector<Utility::PyError_t> errors;
447 bool templated_functions_checked =
false;
458 const std::vector<interop::TCppMethod_t> methods =
460 if (!methods.empty()) {
462 std::vector<PyCallable*> overloads;
463 for (
auto method : methods) {
464 overloads.push_back(
new CPPFunction(scope, method));
474 templated_functions_checked =
true;
487 const std::string& cpd =
504 if (!
attr && !templated_functions_checked) {
509 PyErr_Format(PyExc_TypeError,
"\'%s\' is not a known C++ template",
524 PyErr_Format(PyExc_TypeError,
"\'%s\' is not a known C++ enum",
533 PyType_Type.tp_setattro((
PyObject*)Py_TYPE(pyclass), pyname,
attr);
537 attr = PyType_Type.tp_getattro(pyclass, pyname);
538 if (!
attr && PyErr_Occurred())
541 PyType_Type.tp_setattro(pyclass, pyname,
attr);
549 const std::vector<PyObject*>& using_scopes =
GetUsingScopes(pyclass);
556 bool search_using = !using_scopes.empty();
559 std::set<PyObject*> visited{pyclass};
565 for (
auto pyref : using_scopes) {
570 attr = PyObject_GetAttr(pyuscope, pyname);
584 if (possibly_shadowed) {
586 Py_DECREF(possibly_shadowed);
588 attr = possibly_shadowed;
589 PyType_Type.tp_setattro(pyclass, pyname,
attr);
598 PyObject *pytype = 0, *pyvalue = 0, *pytrace = 0;
599 PyErr_Fetch(&pytype, &pyvalue, &pytrace);
600 PyObject* sklass = PyObject_Str(pyclass);
601 PyErr_Restore(pytype, pyvalue, pytrace);
603 topmsg = PyUnicode_FromFormat(
604 "%s has no attribute \'%s\'. Full details:", PyUnicode_AsUTF8(sklass),
605 PyUnicode_AsUTF8(pyname));
608 topmsg = PyUnicode_FromFormat(
"no such attribute \'%s\'. Full details:",
609 PyUnicode_AsUTF8(pyname));
611 SetDetailedException(std::move(errors), topmsg ,
612 PyExc_AttributeError );
628 std::string
name = PyUnicode_AsUTF8(pyname);
638 return PyType_Type.tp_setattro(pyclass, pyname, pyval);
646 if (!PyArg_ParseTuple(args,
const_cast<char*
>(
"i|i:__cpp_reflex__"), &request,
667 PyErr_Format(PyExc_ValueError,
"unsupported reflex request %d or format %d",
684 return PyList_New(0);
687 PyErr_SetString(PyExc_TypeError,
"C++ proxy scope expected");
695 std::set<std::string> cppnames;
699 std::set<std::string> dir_cppnames;
700 for (
const std::string&
name : cppnames) {
701 if (
name.find(
"__", 0, 2) != std::string::npos ||
702 name.find(
"<") != std::string::npos ||
703 name.find(
"operator", 0, 8) != std::string::npos)
705 dir_cppnames.insert(
name);
709 for (Py_ssize_t i = 0; i < PyList_GET_SIZE(dirlist); ++i)
710 dir_cppnames.insert(PyUnicode_AsUTF8(PyList_GET_ITEM(dirlist, i)));
713 dirlist = PyList_New(dir_cppnames.size());
717 for (
const auto&
name : dir_cppnames) {
718 PyList_SET_ITEM(dirlist, i++, PyUnicode_FromString(
name.c_str()));
725 {(
char*)
"__cpp_reflex__", (PyCFunction)
meta_reflex, METH_VARARGS,
726 (
char*)
"C++ datamember reflection information"},
727 {(
char*)
"__dir__", (PyCFunction)
meta_dir, METH_NOARGS,
nullptr},
728 {(
char*)
nullptr,
nullptr, 0,
nullptr}};
732 {(
char*)
"__cpp_name__", (getter)
meta_getcppname,
nullptr,
nullptr,
nullptr},
735 {(
char*)
nullptr,
nullptr,
nullptr,
nullptr,
nullptr}};
739 PyVarObject_HEAD_INIT(&PyType_Type, 0)(
char*)
"cppjit.CPPScope",
757 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE |
758 Py_TPFLAGS_TYPE_SUBCLASS,
759 (
char*)
"cpyrt metatype (internal)",
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 result
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void value
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 nitems
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 format
Utility::PyOperators * fOperators
std::vector< PyObject * > * fUsing
union cppjit::cpyrt::CPPScope::@183 fImp
CppToPyMap_t * fCppObjects
interop::TCppScope_t fCppType
void AdoptTemplate(PyCallable *pc)
void AdoptMethod(PyCallable *pc)
#define CPYRT_PYTYPE_TAIL
static PyObject * cpyrt_GetWeakRef(PyObject *ref)
std::string clean_type(const std::string &cppname, bool template_strip=true, bool const_strip=true)
std::string compound(const std::string &name)
void cppscope_to_pyscope(std::string &cppscope)
size_t FetchError(std::vector< PyError_t > &, bool is_cpp=false)
static int meta_setattro(PyObject *pyclass, PyObject *pyname, PyObject *pyval)
static PyObject * meta_reflex(CPPScope *klass, PyObject *args)
bool InsertDispatcher(CPPScope *klass, PyObject *bases, PyObject *dct, std::ostringstream &err)
TemplateProxy * TemplateProxy_New(const std::string &cppname, const std::string &pyname, PyObject *pyclass)
static const std::vector< PyObject * > & GetUsingScopes(PyObject *pyclass)
PyObject * CreateExcScopeProxy(PyObject *pyscope, PyObject *pyname, PyObject *parent)
static PyObject * meta_alloc(PyTypeObject *meta, Py_ssize_t nitems)
PyTypeObject CPPScope_Type
PyTypeObject TypedefPointerToClass_Type
static PyObject * meta_dir(CPPScope *klass)
PyTypeObject CPPInstance_Type
PyObject * GetScopeProxy(interop::TCppScope_t)
static void meta_dealloc(CPPScope *scope)
static PyObject * meta_getmodule(CPPScope *scope, void *)
static PyObject * pt_new(PyTypeObject *subtype, PyObject *args, PyObject *kwds)
static PyGetSetDef meta_getset[]
bool TemplateProxy_CheckExact(T *object)
static PyObject * meta_repr(CPPScope *scope)
PyObject * CreateScopeProxy(PyObject *, PyObject *args)
bool CPPDataMember_Check(T *object)
bool CPPScope_CheckExact(T *object)
std::unordered_map< interop::TCppObject_t, PyObject * > CppToPyMap_t
Type object to hold class reference (this is only semantically a presentation of CPPScope instances,...
static PyObject * add_template(PyObject *pyclass, const std::string &name, std::vector< PyCallable * > *overloads=nullptr)
static PyMethodDef meta_methods[]
bool CPPScope_Check(T *object)
static bool IsPlainIdentifier(const std::string &name)
CPPEnum * CPPEnum_New(const std::string &name, interop::TCppScope_t scope)
static int meta_setmodule(CPPScope *scope, PyObject *value, void *)
static bool HasPythonAttrInUsing(PyObject *pyclass, PyObject *pyname, std::set< PyObject * > &visited)
CPPOverload * CPPOverload_New(const std::string &name, std::vector< PyCallable * > &methods)
CPPDataMember * CPPDataMember_New(interop::TCppScope_t scope, interop::TCppScope_t var)
static PyObject * meta_getattro(PyObject *pyclass, PyObject *pyname)
static PyObject * meta_getcppname(CPPScope *scope, void *)
const RequestId_t IS_AGGREGATE
const RequestId_t IS_NAMESPACE
TCppType_t GetTypeFromScope(TCppScope_t klass)
std::string GetTypeAsString(TCppType_t type)
bool ExistsMethodTemplate(TCppScope_t scope, const std::string &name)
bool IsBuiltin(const std::string &type_name)
bool HasVirtualDestructor(TCppScope_t type)
TCppScope_t GetParentScope(TCppScope_t scope)
bool IsSubclass(TCppScope_t derived, TCppScope_t base)
TCppScope_t GetNamed(const std::string &scope_name, TCppScope_t parent_scope=TCppScope_t{})
Cpp::FuncRef TCppMethod_t
bool IsTypedefed(TCppScope_t scope)
bool IsEnumScope(TCppScope_t scope)
bool GetSmartPtrInfo(TCppScope_t klass, TCppScope_t *raw, TCppMethod_t *deref)
TCppType_t ResolveType(TCppType_t cppitem_name)
TCppScope_t GetUnderlyingScope(TCppScope_t scope)
TCppScope_t GetGlobalScope()
bool IsVisibleName(const std::string &name, TCppScope_t parent_scope=TCppScope_t{})
std::vector< TCppMethod_t > GetMethodsFromName(TCppScope_t scope, const std::string &name)
bool IsNamespace(TCppScope_t scope)
TCppScope_t GetScopeFromType(TCppType_t type)
std::string GetBaseName(TCppScope_t klass, TCppIndex_t ibase)
TCppScope_t GetScope(const std::string &scope_name, TCppScope_t parent_scope=TCppScope_t{})
bool IsEnumConstant(TCppScope_t scope)
std::string GetFinalName(TCppScope_t type)
bool IsVariable(TCppScope_t scope)
std::vector< TCppScope_t > GetUsingNamespaces(TCppScope_t)
bool IsAggregate(TCppScope_t type)
std::string GetScopedFinalName(TCppScope_t type)
void GetAllCppNames(TCppScope_t scope, std::set< std::string > &cppnames)
Custom "builtins," detectable by type, for pass by ref and improved performance.
PyObject_HEAD interop::TCppScope_t fCppType