Update of /cvsroot/pure-data/externals/grill/py/source In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv27765/source
Modified Files: clmeth.cpp py.cpp pyargs.cpp pybase.cpp pybase.h pyext.cpp pyext.h pymeth.cpp Log Message: python-like dotted module.function syntax cleaned up float vs. int pyext tags better definition of output values (atoms, lists, anythings) multiply inlets for py (hot and cold inlets) better exception handling and error message fixes for atomic pyext._outlet messages
Index: clmeth.cpp =================================================================== RCS file: /cvsroot/pure-data/externals/grill/py/source/clmeth.cpp,v retrieving revision 1.23 retrieving revision 1.24 diff -C2 -d -r1.23 -r1.24 *** clmeth.cpp 15 Jul 2005 16:13:43 -0000 1.23 --- clmeth.cpp 18 Jul 2005 18:03:12 -0000 1.24 *************** *** 168,172 ****
PyObject *val; - bool tp; #if 0 if(sz == 3) { --- 168,171 ----
Index: pyargs.cpp =================================================================== RCS file: /cvsroot/pure-data/externals/grill/py/source/pyargs.cpp,v retrieving revision 1.18 retrieving revision 1.19 diff -C2 -d -r1.18 -r1.19 *** pyargs.cpp 15 Jul 2005 16:13:43 -0000 1.18 --- pyargs.cpp 18 Jul 2005 18:03:12 -0000 1.19 *************** *** 127,130 **** --- 127,171 ---- }
+ inline bool issym(PyObject *p) + { + return PyString_Check(p) || pySymbol_Check(p); + } + + inline bool isseq(PyObject *p) + { + return PySequence_Check(p) && !issym(p); + } + + const t_symbol *pybase::getone(t_atom &at,PyObject *arg) + { + if(PyInt_Check(arg)) { flext::SetInt(at,PyInt_AsLong(arg)); return sym_fint; } + else if(PyLong_Check(arg)) { flext::SetInt(at,PyLong_AsLong(arg)); return sym_fint; } + else if(PyFloat_Check(arg)) { flext::SetFloat(at,(float)PyFloat_AsDouble(arg)); return flext::sym_float; } + else if(pySymbol_Check(arg)) { flext::SetSymbol(at,pySymbol_AS_SYMBOL(arg)); return flext::sym_symbol; } + else if(PyString_Check(arg)) { flext::SetString(at,PyString_AS_STRING(arg)); return flext::sym_symbol; } + else { + PyObject *tp = PyObject_Type(arg); + PyObject *stp = tp?PyObject_Str(tp):NULL; + char *tmp = ""; + if(stp) tmp = PyString_AS_STRING(stp); + flext::post("py/pyext: Could not convert argument %s",tmp); + Py_XDECREF(stp); + Py_XDECREF(tp); + + flext::SetSymbol(at,flext::sym__); + return sym_symbol; + } + } + + const t_symbol *pybase::getlist(t_atom *lst,PyObject *seq,int cnt,int offs) + { + for(int ix = 0; ix < cnt; ++ix) { + PyObject *arg = PySequence_GetItem(seq,ix+offs); // new reference + getone(lst[ix],arg); + Py_DECREF(arg); + } + return flext::sym_list; + } + const t_symbol *pybase::GetPyArgs(AtomList &lst,PyObject *pValue,int offs) { *************** *** 135,198 ****
// analyze return value or tuple - int rargc = 0; - retval tp = nothing; - - if(PyString_Check(pValue) || pySymbol_Check(pValue)) { - rargc = 1; - tp = atom; - } - else if(PySequence_Check(pValue)) { - rargc = PySequence_Size(pValue); - tp = sequ; - } - else { - rargc = 1; - tp = atom; - } - // else - // Py_DECREF(pValue); - - lst(offs+rargc); - const t_symbol *sym = NULL;
! for(int ix = 0; ix < rargc; ++ix) { ! PyObject *arg; ! if(tp == sequ) ! arg = PySequence_GetItem(pValue,ix); // new reference ! else ! arg = pValue; ! ! t_atom &at = lst[offs+ix]; ! if(PyInt_Check(arg)) { SetInt(at,PyInt_AsLong(arg)); sym = sym_fint; } ! else if(PyLong_Check(arg)) { SetInt(at,PyLong_AsLong(arg)); sym = sym_fint; } ! else if(PyFloat_Check(arg)) { SetFloat(at,(float)PyFloat_AsDouble(arg)); sym = sym_float; } ! else if(pySymbol_Check(arg)) { SetSymbol(at,pySymbol_AS_SYMBOL(arg)); sym = sym_symbol; } ! else if(PyString_Check(arg)) { SetString(at,PyString_AS_STRING(arg)); sym = sym_symbol; } ! /* ! else if(ix == 0 && self && PyInstance_Check(arg)) { ! // assumed to be self ... that should be checked _somehow_ !!! ! Py_INCREF(arg); ! *self = arg; ! } ! */ ! else { ! PyObject *tp = PyObject_Type(arg); ! PyObject *stp = tp?PyObject_Str(tp):NULL; ! char *tmp = ""; ! if(stp) tmp = PyString_AS_STRING(stp); ! post("py/pyext: Could not convert argument %s",tmp); ! Py_XDECREF(stp); ! Py_XDECREF(tp);
! SetSymbol(at,sym__); sym = sym_symbol; ! }
! if(tp == sequ) ! Py_DECREF(arg); } - - if(sym && tp == sequ) sym = sym_list;
return sym; --- 176,209 ----
// analyze return value or tuple int rargc = 0; const t_symbol *sym = NULL;
! if(isseq(pValue)) { ! int rargc = PySequence_Size(pValue); ! if(rargc == 2) { ! // check if syntax is symbol/string, list -> anything message ! PyObject *s = PySequence_GetItem(pValue,0); ! PyObject *l = PySequence_GetItem(pValue,1);
! if(issym(s) && isseq(l)) { ! // is anything message ! rargc = PySequence_Size(l); ! lst(offs+rargc); ! getlist(lst.Atoms(),l,rargc); ! sym = pyObject_AsSymbol(s); ! }
! Py_DECREF(s); ! Py_DECREF(l); ! } ! else { ! lst(offs+rargc); ! sym = getlist(lst.Atoms(),pValue,rargc); ! } ! } ! else { ! lst(offs+1); ! sym = getone(lst[offs],pValue); }
return sym;
Index: pymeth.cpp =================================================================== RCS file: /cvsroot/pure-data/externals/grill/py/source/pymeth.cpp,v retrieving revision 1.1 retrieving revision 1.2 diff -C2 -d -r1.1 -r1.2 *** pymeth.cpp 9 Jul 2005 13:03:34 -0000 1.1 --- pymeth.cpp 18 Jul 2005 18:03:12 -0000 1.2 *************** *** 132,136 **** private:
! virtual bool callpy(PyObject *fun,PyObject *args);
static void Setup(t_classid c); --- 132,136 ---- private:
! virtual void callpy(PyObject *fun,PyObject *args);
static void Setup(t_classid c); *************** *** 361,377 **** }
! bool pymeth::callpy(PyObject *fun,PyObject *args) { PyObject *ret = PyObject_CallObject(fun,args); ! if(ret == NULL) { ! // function not found resp. arguments not matching ! PyErr_Print(); ! return false; ! } ! else { ! if(ret != Py_None && !OutObject(this,0,ret) && PyErr_Occurred()) ! PyErr_Print(); Py_DECREF(ret); - return true; } } --- 361,370 ---- }
! void pymeth::callpy(PyObject *fun,PyObject *args) { PyObject *ret = PyObject_CallObject(fun,args); ! if(ret) { ! OutObject(this,0,ret); // exception might be raised here Py_DECREF(ret); } } *************** *** 422,426 **** }
! ret = gencall(function,pargs); // references are stolen } else --- 415,420 ---- }
! gencall(function,pargs); // references are stolen ! ret = true; } else
Index: pyext.h =================================================================== RCS file: /cvsroot/pure-data/externals/grill/py/source/pyext.h,v retrieving revision 1.24 retrieving revision 1.25 diff -C2 -d -r1.24 -r1.25 *** pyext.h 8 Jul 2005 14:30:31 -0000 1.24 --- pyext.h 18 Jul 2005 18:03:12 -0000 1.25 *************** *** 115,119 ****
virtual bool thrcall(void *data); ! virtual bool callpy(PyObject *fun,PyObject *args); static bool stcallpy(PyObject *fun,PyObject *args);
--- 115,119 ----
virtual bool thrcall(void *data); ! virtual void callpy(PyObject *fun,PyObject *args); static bool stcallpy(PyObject *fun,PyObject *args);
Index: pybase.h =================================================================== RCS file: /cvsroot/pure-data/externals/grill/py/source/pybase.h,v retrieving revision 1.2 retrieving revision 1.3 diff -C2 -d -r1.2 -r1.3 *** pybase.h 9 Jul 2005 13:03:34 -0000 1.2 --- pybase.h 18 Jul 2005 18:03:12 -0000 1.3 *************** *** 90,94 **** static bool IsAtom(const t_symbol *s) { return s == sym_float || s == sym_int || s == sym_symbol || s == sym_pointer; }
! enum retval { nothing,atom,sequ };
// --- module stuff ----- --- 90,94 ---- static bool IsAtom(const t_symbol *s) { return s == sym_float || s == sym_int || s == sym_symbol || s == sym_pointer; }
! // enum retval { nothing,atom,sequ };
// --- module stuff ----- *************** *** 137,142 ****
bool gencall(PyObject *fun,PyObject *args); virtual bool thrcall(void *data) = 0; ! virtual bool callpy(PyObject *fun,PyObject *args) = 0;
#if FLEXT_SYS == FLEXT_SYS_MAX --- 137,156 ----
bool gencall(PyObject *fun,PyObject *args); + + bool docall(PyObject *fun,PyObject *args) + { + callpy(fun,args); + if(PyErr_Occurred()) { + exchandle(); + return false; + } + else + return true; + } + virtual bool thrcall(void *data) = 0; ! virtual void callpy(PyObject *fun,PyObject *args) = 0; ! ! void exchandle();
#if FLEXT_SYS == FLEXT_SYS_MAX *************** *** 165,168 **** --- 179,185 ---- static const t_symbol *sym_fint; // float or int symbol, depending on native number message type
+ static const t_symbol *getone(t_atom &at,PyObject *arg); + static const t_symbol *getlist(t_atom *lst,PyObject *seq,int cnt,int offs = 0); + public:
Index: pybase.cpp =================================================================== RCS file: /cvsroot/pure-data/externals/grill/py/source/pybase.cpp,v retrieving revision 1.2 retrieving revision 1.3 diff -C2 -d -r1.2 -r1.3 *** pybase.cpp 9 Jul 2005 13:03:34 -0000 1.2 --- pybase.cpp 18 Jul 2005 18:03:12 -0000 1.3 *************** *** 569,573 **** switch(detach) { case 0: ! ret = callpy(pmeth,pargs); Py_DECREF(pargs); Py_DECREF(pmeth); --- 569,573 ---- switch(detach) { case 0: ! ret = docall(pmeth,pargs); Py_DECREF(pargs); Py_DECREF(pmeth); *************** *** 592,595 **** --- 592,613 ---- }
+ void pybase::exchandle() + { + #if 0 + // want to use that, but exception keeps a reference to the object + PyErr_Print(); + #else + // must use that instead... clear the exception + PyObject *type,*value,*traceback; + PyErr_Fetch(&type,&value,&traceback); + PyErr_NormalizeException(&type,&value,&traceback); + PyErr_Display(type,value,traceback); + + Py_XDECREF(type); + Py_XDECREF(value); + Py_XDECREF(traceback); + #endif + } + void pybase::work_wrapper(void *data) { *************** *** 604,608 **** // call worker work_data *w = (work_data *)data; ! callpy(w->fun,w->args); delete w;
--- 622,626 ---- // call worker work_data *w = (work_data *)data; ! docall(w->fun,w->args); delete w;
*************** *** 635,639 **** ++thrcount; state = PyLock(my); ! callpy(el->fun,el->args); Py_XDECREF(el->fun); Py_XDECREF(el->args); --- 653,657 ---- ++thrcount; state = PyLock(my); ! docall(el->fun,el->args); Py_XDECREF(el->fun); Py_XDECREF(el->args);
Index: pyext.cpp =================================================================== RCS file: /cvsroot/pure-data/externals/grill/py/source/pyext.cpp,v retrieving revision 1.36 retrieving revision 1.37 diff -C2 -d -r1.36 -r1.37 *** pyext.cpp 9 Jul 2005 13:03:34 -0000 1.36 --- pyext.cpp 18 Jul 2005 18:03:12 -0000 1.37 *************** *** 507,522 **** }
! bool pyext::callpy(PyObject *fun,PyObject *args) { PyObject *ret = PyObject_CallObject(fun,args); ! if(ret == NULL) { ! // function not found resp. arguments not matching ! PyErr_Print(); ! return false; ! } ! else { if(!PyObject_Not(ret)) post("pyext - returned value is ignored"); Py_DECREF(ret); - return true; } } --- 507,517 ---- }
! void pyext::callpy(PyObject *fun,PyObject *args) { PyObject *ret = PyObject_CallObject(fun,args); ! if(ret) { ! // function worked fine if(!PyObject_Not(ret)) post("pyext - returned value is ignored"); Py_DECREF(ret); } } *************** *** 537,542 **** Py_DECREF(pmeth); } ! else ! ret = gencall(pmeth,pargs); } return ret; --- 532,539 ---- Py_DECREF(pmeth); } ! else { ! gencall(pmeth,pargs); ! ret = true; ! } } return ret;
Index: py.cpp =================================================================== RCS file: /cvsroot/pure-data/externals/grill/py/source/py.cpp,v retrieving revision 1.28 retrieving revision 1.29 diff -C2 -d -r1.28 -r1.29 *** py.cpp 15 Jul 2005 16:13:43 -0000 1.28 --- py.cpp 18 Jul 2005 18:03:12 -0000 1.29 *************** *** 55,59 **** private:
! virtual bool callpy(PyObject *fun,PyObject *args);
static void Setup(t_classid c); --- 55,59 ---- private:
! virtual void callpy(PyObject *fun,PyObject *args);
static void Setup(t_classid c); *************** *** 344,360 **** }
! bool pyobj::callpy(PyObject *fun,PyObject *args) { PyObject *ret = PyObject_CallObject(fun,args); ! if(ret == NULL) { ! // function not found resp. arguments not matching ! PyErr_Print(); ! return false; ! } ! else { ! if(!OutObject(this,0,ret) && PyErr_Occurred()) ! PyErr_Print(); Py_DECREF(ret); - return true; } } --- 344,353 ---- }
! void pyobj::callpy(PyObject *fun,PyObject *args) { PyObject *ret = PyObject_CallObject(fun,args); ! if(ret) { ! OutObject(this,0,ret); // exception might be raised here Py_DECREF(ret); } } *************** *** 398,402 **** pargs = MakePyArgs(n?s:NULL,argc,argv);
! ret = gencall(function,pargs); // references are stolen } else --- 391,396 ---- pargs = MakePyArgs(n?s:NULL,argc,argv);
! gencall(function,pargs); // references are stolen ! ret = true; } else *************** *** 409,413 **** if(func) { PyObject *pargs = MakePyArgs(sym_list,argc,argv); ! ret = gencall(func,pargs); } } --- 403,408 ---- if(func) { PyObject *pargs = MakePyArgs(sym_list,argc,argv); ! gencall(func,pargs); ! ret = true; } }