48 Py_DECREF(
fArgs[iarg]);
52 PyMem_Free((
void*)
fArgs);
63 Py_ssize_t maxargs = (Py_ssize_t)
fConverters.size();
65 if (maxargs != actual) {
66 if (actual < (Py_ssize_t)fArgsRequired) {
67 SetPyError_(PyUnicode_FromFormat(
68 "takes at least %d arguments (%zd given)", fArgsRequired, actual));
70 }
else if (maxargs < actual) {
71 SetPyError_(PyUnicode_FromFormat(
72 "takes at most %zd arguments (%zd given)", maxargs, actual));
84 fDeclaringScope =
nullptr;
86 fArgIndices =
nullptr;
93 if (fExecutor && fExecutor->HasState())
98 if (
p &&
p->HasState())
104 fArgIndices =
nullptr;
116 result = fExecutor->Execute(
121 }
catch (std::exception&
e) {
139 pyexc_type = PyObject_GetAttrString(
143 : finalname.substr(parentname.size() + 2, std::string::npos)
154 PyObject_CallFunctionObjArgs(pyclass, source,
nullptr);
166 if (pyexc_type && pyexc_obj) {
167 PyErr_SetObject(pyexc_type, pyexc_obj);
168 Py_DECREF(pyexc_obj);
169 Py_DECREF(pyexc_type);
171 PyErr_Format(PyExc_Exception,
"%s (C++ exception)",
e.what());
172 Py_XDECREF(pyexc_obj);
173 Py_XDECREF(pyexc_type);
180 PyErr_SetString(PyExc_Exception,
"unhandled, unknown C++ exception");
187 if (PyErr_Occurred()) {
188 if (ResultIsPyObject())
204 for (
int iarg = 0; iarg < (
int)nArgs; ++iarg) {
208 PyErr_Format(PyExc_TypeError,
"argument type %s not handled",
223 executor = (
bool)fMethod ==
true
255#if PY_VERSION_HEX >= 0x030c0000
256 PyObject* evalue = PyErr_Occurred() ? PyErr_GetRaisedException() :
nullptr;
263 if (PyErr_Occurred()) {
264 PyErr_Fetch(&etype, &evalue, &etrace);
268 const bool isCppExc =
276 if (evalue && !isCppExc) {
277#if PY_VERSION_HEX >= 0x030c0000
278 PyObject* tb = PyException_GetTraceback(evalue);
281 PyErr_SetRaisedException(evalue);
286 PyErr_Restore(etype, evalue, etrace);
291 PyObject* descr = PyObject_Str(evalue);
293 details = PyUnicode_AsUTF8(descr);
299 const char* cdoc = PyUnicode_AsUTF8(doc);
300 const char* cmsg = msg ? PyUnicode_AsUTF8(msg) :
nullptr;
301 PyObject* errtype = etype ? etype : PyExc_TypeError;
303 const char*
cname = pyname ? PyUnicode_AsUTF8(pyname) :
"Exception";
308 if (details.empty()) {
309 PyErr_Format(errtype,
"%s =>\n %s: %s", cdoc,
cname, cmsg ? cmsg :
"");
311 PyErr_Format(errtype,
"%s =>\n %s: %s (%s)", cdoc,
cname, cmsg,
314 PyErr_Format(errtype,
"%s =>\n %s: %s", cdoc,
cname, details.c_str());
319 Py_XDECREF(topMessage);
322 PyUnicode_FromFormat(
"%s =>\n %s: %s | ", cdoc,
cname, cmsg);
324 topMessage = PyUnicode_FromFormat(
"%s =>\n %s: ", cdoc,
cname);
327#if PY_VERSION_HEX >= 0x030c0000
328 PyErr_SetRaisedException(evalue);
330 PyErr_Restore(etype, evalue, etrace);
339extern std::unordered_map<interop::TCppType_t, interop::TCppType_t>
345 : fMethod(method), fScope(scope), fDeclaringScope(nullptr),
346 fExecutor(nullptr), fArgIndices(nullptr), fArgsRequired(-1) {
357 :
PyCallable(other), fMethod(other.fMethod), fScope(other.fScope) {
363 if (
this != &other) {
406 return PyUnicode_FromFormat(
410 GetSignatureString(fa).c_str());
415 PyObject* cppname = PyUnicode_FromString(
416 (GetReturnTypeName() +
" (" +
419 PyUnicode_AppendAndDel(&cppname, GetSignature(
false ));
429 std::string rtn = GetReturnTypeName();
437 return PyUnicode_FromString(rtn.c_str());
475 for (
int iarg = 0; iarg < (
int)nArgs; ++iarg) {
482 std::string compact = aname;
483 compact.erase(std::remove(compact.begin(), compact.end(),
' '),
486 if (compact.find(
"void*") != std::string::npos) {
490 if (strstr(aname.c_str(),
"std::complex"))
494 if (strstr(aname.c_str(),
"bool"))
496 else if (strstr(aname.c_str(),
"long long"))
498 else if (strstr(aname.c_str(),
"long"))
501 else if (strstr(aname.c_str(),
"short"))
505 else if (strstr(aname.c_str(),
"float"))
507 else if (strstr(aname.c_str(),
"long double"))
509 else if (strstr(aname.c_str(),
"double"))
513 else if (strstr(aname.c_str(),
"char") && aname[aname.size() - 1] !=
'*')
538 if (aname.find(
"initializer_list") != std::string::npos) {
540 }
else if (aname.rfind(
"&&", aname.size() - 2) != std::string::npos) {
544 if (aname[aname.size() - 1] ==
'&')
579 for (
int iarg = 0; iarg < (
int)nArgs; ++iarg) {
581 if (aname.find(
"void *") != 0)
595 int co_argcount = (
int)GetMaxArgs() ;
599 PyObject* co_varnames = PyTuple_New(co_argcount + 1 );
600 PyTuple_SET_ITEM(co_varnames, 0, PyUnicode_FromString(
"self"));
601 for (
int iarg = 0; iarg < co_argcount; ++iarg) {
604 if (!parname.empty()) {
609 PyObject* pyspec = PyUnicode_FromString(argrep.c_str());
610 PyTuple_SET_ITEM(co_varnames, iarg + 1, pyspec);
618 if (iarg >= (
int)GetMaxArgs())
623 PyDict_GetItemString(PySys_GetObject((
char*)
"modules"),
"cppjit.gbl");
626 if (!defvalue.empty()) {
627 PyObject** dctptr = _PyObject_GetDictPtr(gbl);
628 if (!(dctptr && *dctptr))
634 if (defvalue.rfind(
'(') != std::string::npos) {
637 std::string possible_scope = defvalue.substr(0, defvalue.rfind(
'('));
639 std::string cand_scope =
652 defvalue = cand_scope +
653 defvalue.substr(defvalue.rfind(
'('), std::string::npos);
665 char c = defvalue.back();
666 if (
c ==
'F' ||
c ==
'D' ||
c ==
'L') {
668 if (2 < defvalue.size() && defvalue[defvalue.size() - 2] ==
'U')
670 defvalue = defvalue.substr(0, defvalue.size() -
offset);
671 }
else if (defvalue ==
"true") {
673 }
else if (defvalue ==
"false") {
682 PyObject* pycode = Py_CompileString(
683 (
char*)defvalue.c_str(),
"cppjit_default_compiler", Py_eval_input);
685 pyval = PyEval_EvalCode(pycode, gdct, gdct);
689 if (!pyval && PyErr_Occurred() && silent) {
691 pyval = PyUnicode_FromString(
699 PyErr_Format(PyExc_TypeError,
"Could not construct default value for: %s",
721 Py_ssize_t
n = PyTuple_Size(args_tuple);
730 for (
int i = 0; i <
n; i++) {
731 PyObject* pItem = PyTuple_GetItem(args_tuple, i);
732 if (!PyUnicode_Check(pItem)) {
733 PyErr_SetString(PyExc_TypeError,
734 "argument types should be in string format");
737 std::string
req_type(PyUnicode_AsUTF8(pItem));
742 if (arg_score >= 10) {
756 if (fArgsRequired != -1)
759 if (!InitConverters_())
762 if (!InitExecutor_(fExecutor, ctxt))
774 if (!PyTuple_CheckExact(cargs.
fKwds)) {
775 SetPyError_(PyUnicode_FromString(
"received unknown keyword names object"));
778 Py_ssize_t nKeys = PyTuple_GET_SIZE(cargs.
fKwds);
780 if (nKeys == 0 && !self_in)
784 fArgIndices =
new std::unordered_map<std::string, int>{};
791 if (!VerifyArgCount_(nArgs + nKeys))
798 Py_ssize_t maxpos = -1;
801 for (Py_ssize_t ikey = 0; ikey < nKeys; ++ikey) {
802 key = PyTuple_GET_ITEM(cargs.
fKwds, ikey);
804 const char* ckey = PyUnicode_AsUTF8(key);
808 auto p = fArgIndices->find(ckey);
809 if (
p == fArgIndices->end()) {
810 SetPyError_(PyUnicode_FromFormat(
811 "%s::%s got an unexpected keyword argument \'%s\'",
817 maxpos =
p->second > maxpos ?
p->second : maxpos;
823 Py_ssize_t maxargs = maxpos + 1;
828 for (Py_ssize_t i = 0; i < maxargs; ++i)
832 Py_ssize_t start = 0;
839 for (Py_ssize_t i = start; i < nArgs; ++i) {
841 SetPyError_(PyUnicode_FromFormat(
842 "%s::%s got multiple values for argument %d",
856 for (Py_ssize_t i = nArgs; i < maxargs; ++i) {
863 item = GetArgDefault((
int)i,
false );
878 cargs.
fArgs = newArgs;
890 return ProcessKwds(
nullptr, cargs);
918 return ProcessKwds(
nullptr, cargs);
925 SetPyError_(PyUnicode_FromFormat(
926 "unbound method %s::%s must be called with a %s instance as first "
938 if (!VerifyArgCount_(argc))
950 for (
int i = 0; i < (
int)argc; ++i) {
954 PyUnicode_FromFormat(
"could not convert argument %d: %s", i + 1,
972 if (!
result && PyErr_Occurred())
983 if (fArgsRequired == -1 && !Initialize(ctxt))
988 if (!ProcessArgs(cargs))
997 if (!ConvertAndSetArgs(cargs.fArgs, cargs.fNArgsf, ctxt))
1006 PyErr_SetString(PyExc_ReferenceError,
"no C++ object available");
1019 if (!fDeclaringScope) {
1022 if (!fDeclaringScope)
1023 fDeclaringScope = fScope;
1027 if (derived && derived != fDeclaringScope)
1047 return PyUnicode_FromString(GetSignatureString(fa).c_str());
1063 int argcount = GetMaxArgs();
1064 PyObject* signature_names = PyTuple_New(argcount);
1066 for (
int iarg = 0; iarg < argcount; ++iarg) {
1068 PyObject* argname_py = PyUnicode_FromString(argname_cpp.c_str());
1069 PyTuple_SET_ITEM(signature_names, iarg, argname_py);
1072 return signature_names;
1090 PyObject* signature_types_dict = PyDict_New();
1093 std::string return_type = GetReturnTypeName();
1094 PyObject* return_type_py = PyUnicode_FromString(return_type.c_str());
1095 PyDict_SetItem(signature_types_dict, PyUnicode_FromString(
"return_type"),
1099 int argcount = GetMaxArgs();
1100 PyObject* parameter_types = PyTuple_New(argcount);
1102 for (
int iarg = 0; iarg < argcount; ++iarg) {
1103 const std::string& argtype_cpp =
1105 PyObject* argtype_py = PyUnicode_FromString(argtype_cpp.c_str());
1106 PyTuple_SET_ITEM(parameter_types, iarg, argtype_py);
1109 PyDict_SetItem(signature_types_dict, PyUnicode_FromString(
"input_types"),
1114 PyDict_SetItem(signature_types_dict, PyUnicode_FromString(
"is_const"),
1115 PyBool_FromLong(IsConst()));
1117 return signature_types_dict;
std::unordered_map< interop::TCppType_t, interop::TCppType_t > TypeReductionMap
std::vector< Converter * > fConverters
winID h TVirtualViewer3D TVirtualGLPainter p
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 result
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 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 req_type
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
interop::TCppScope_t ObjectIsA(bool check_smart=true) const
PyObject * GetTypeName() override
virtual bool InitExecutor_(Executor *&, CallContext *ctxt=nullptr)
int GetArgMatchScore(PyObject *args_tuple) override
bool Initialize(CallContext *ctxt=nullptr)
std::string GetReturnTypeName()
void SetPyError_(PyObject *msg)
PyObject * GetScopeProxy() override
PyObject * GetPrototype(bool show_formalargs=true) override
Construct a Python string from the method's prototype.
PyObject * GetSignatureTypes() override
Returns a dictionary with the types of the signature of this method.
PyObject * Call(CPPInstance *&self, cpyrt_PyArgs_t args, size_t nargsf, PyObject *kwds, CallContext *ctxt=nullptr) override
virtual bool ProcessArgs(PyCallArgs &args)
CPPMethod(interop::TCppScope_t scope, interop::TCppMethod_t method)
PyObject * Execute(void *self, ptrdiff_t offset, CallContext *ctxt=nullptr)
PyObject * Reflex(interop::Reflex::RequestId_t request, interop::Reflex::FormatId_t=interop::Reflex::OPTIMAL) override
int GetMaxArgs() override
std::string GetSignatureString(bool show_formalargs=true)
PyObject * GetCoVarNames() override
interop::TCppFuncAddr_t GetFunctionAddress() override
interop::TCppMethod_t fMethod
PyObject * GetSignature(bool show_formalargs=true) override
PyObject * ExecuteFast(void *, ptrdiff_t, CallContext *)
CPPMethod & operator=(const CPPMethod &)
bool VerifyArgCount_(Py_ssize_t)
interop::TCppScope_t fScope
PyObject * GetArgDefault(int iarg, bool silent=true) override
int GetPriority() override
bool ProcessKwds(PyObject *self_in, PyCallArgs &args)
bool ConvertAndSetArgs(cpyrt_PyArgs_t, size_t nargsf, CallContext *ctxt=nullptr)
PyObject * GetSignatureNames() override
Returns a tuple with the names of the input parameters of this method.
void Copy_(const CPPMethod &)
virtual PyObject * Reflex(interop::Reflex::RequestId_t request, interop::Reflex::FormatId_t format=interop::Reflex::OPTIMAL)
static PyObject * cpyrt_PyArgs_SET_ITEM(cpyrt_PyArgs_t args, Py_ssize_t i, PyObject *item)
static void cpyrt_PyArgs_DEL(cpyrt_PyArgs_t args)
PyObject *const * cpyrt_PyArgs_t
static Py_ssize_t cpyrt_PyArgs_GET_SIZE(cpyrt_PyArgs_t, size_t nargsf)
static cpyrt_PyArgs_t cpyrt_PyArgs_New(Py_ssize_t N)
static PyObject * cpyrt_PyArgs_GET_ITEM(cpyrt_PyArgs_t args, Py_ssize_t i)
std::string extract_namespace(const std::string &name)
std::string clean_type(const std::string &cppname, bool template_strip=true, bool const_strip=true)
void cppscope_to_pyscope(std::string &cppscope)
CPYRT_EXTERN Converter * CreateConverter(const std::string &name, cdims_t=0)
PyObject * gSegvException
PyObject * GetScopeProxy(interop::TCppScope_t)
PyObject * CreateScopeProxy(PyObject *, PyObject *args)
CPYRT_EXTERN Executor * CreateExecutor(const std::string &name, cdims_t=0)
PyObject * gAbrtException
PyTypeObject CPPExcInstance_Type
PyObject * BindCppObjectNoCast(interop::TCppObject_t object, interop::TCppScope_t klass, const unsigned flags=0)
bool CPPInstance_Check(T *object)
const FormatId_t AS_STRING
const RequestId_t RETURN_TYPE
TCppScope_t GetFullScope(const std::string &scope_name)
Cpp::ObjectRef TCppObject_t
std::string GetTypeAsString(TCppType_t type)
bool IsBuiltin(const std::string &type_name)
std::string GetName(TCppScope_t)
TCppMethod_t AdaptFunctionForLambdaReturn(TCppMethod_t fn)
bool IsConstructor(TCppMethod_t method)
TCppScope_t GetActualClass(TCppScope_t klass, TCppObject_t obj)
std::string GetMethodArgTypeAsString(TCppMethod_t method, TCppIndex_t iarg)
TCppIndex_t GetMethodReqArgs(TCppMethod_t)
TCppScope_t GetParentScope(TCppScope_t scope)
std::string GetMethodReturnTypeAsString(TCppMethod_t)
TCppIndex_t GetMethodNumArgs(TCppMethod_t)
TCppIndex_t CompareMethodArgType(TCppMethod_t, TCppIndex_t iarg, const std::string &req_type)
bool IsSubclass(TCppScope_t derived, TCppScope_t base)
Cpp::FuncRef TCppMethod_t
TCppType_t GetMethodArgType(TCppMethod_t, TCppIndex_t iarg)
bool IsEnumScope(TCppScope_t scope)
TCppMethod_t ReduceReturnType(TCppMethod_t fn, TCppType_t reduce)
std::string GetMethodArgName(TCppMethod_t, TCppIndex_t iarg)
TCppFuncAddr_t GetFunctionAddress(TCppMethod_t method, bool check_enabled=true)
TCppType_t GetMethodReturnType(TCppMethod_t)
TCppType_t ResolveType(TCppType_t cppitem_name)
std::string GetMethodSignature(TCppMethod_t, bool show_formal_args, TCppIndex_t max_args=(TCppIndex_t) -1)
TCppScope_t GetGlobalScope()
TCppIndex_t GetNumBasesLongestBranch(TCppScope_t klass)
TCppScope_t GetScope(const std::string &scope_name, TCppScope_t parent_scope=TCppScope_t{})
std::string GetFinalName(TCppScope_t type)
bool IsLambdaClass(TCppType_t type)
bool IsConstMethod(TCppMethod_t)
ptrdiff_t GetBaseOffset(TCppScope_t derived, TCppScope_t base, TCppObject_t address, int direction, bool rerror=false)
std::string GetMethodArgDefault(TCppMethod_t, TCppIndex_t iarg)
bool IsStaticMethod(TCppMethod_t method)
std::string GetScopedFinalName(TCppScope_t type)
bool IsEnumType(TCppType_t type)
bool IsComplete(TCppScope_t type)
Parameter * GetArgs(size_t sz)
interop::TCppScope_t fCurScope