Update of /cvsroot/pure-data/externals/grill/py/source
In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv29671/source
Modified Files:
clmeth.cpp main.cpp main.h modmeth.cpp py.cpp pyargs.cpp
pybuffer.cpp pyext.cpp pyext.h
Log Message:
fixed reference count bug
cleaner error reporting
more optimizations
added generic numpy support (not working)
fixes for maxmsp
Index: clmeth.cpp
===================================================================
RCS file: /cvsroot/pure-data/externals/grill/py/source/clmeth.cpp,v
retrieving revision 1.16
retrieving revision 1.17
diff -C2 -d -r1.16 -r1.17
*** clmeth.cpp 13 Mar 2005 04:59:47 -0000 1.16
--- clmeth.cpp 31 Mar 2005 03:54:10 -0000 1.17
***************
*** 174,179 ****
val = PySequence_GetSlice(args,2,sz); // new ref
! AtomList *lst = GetPyArgs(val);
! if(lst) {
int o = PyInt_AsLong(outl);
if(o >= 1 && o <= ext->Outlets()) {
--- 174,179 ----
val = PySequence_GetSlice(args,2,sz); // new ref
! AtomListStatic<16> lst;
! if(GetPyArgs(lst,val)) {
int o = PyInt_AsLong(outl);
if(o >= 1 && o <= ext->Outlets()) {
***************
*** 183,192 ****
// by using the queue there is no immediate call of the next object
// deadlock would occur if this was another py/pyext object!
! if(lst->Count() && IsSymbol((*lst)[0]))
! ext->ToOutAnything(o-1,GetSymbol((*lst)[0]),lst->Count()-1,lst->Atoms()+1);
! else if(lst->Count() > 1)
! ext->ToOutList(o-1,*lst);
else
! ext->ToOutAtom(o-1,*lst->Atoms());
}
else
--- 183,192 ----
// by using the queue there is no immediate call of the next object
// deadlock would occur if this was another py/pyext object!
! if(lst.Count() && IsSymbol(lst[0]))
! ext->ToOutAnything(o-1,GetSymbol(lst[0]),lst.Count()-1,lst.Atoms()+1);
! else if(lst.Count() > 1)
! ext->ToOutList(o-1,lst);
else
! ext->ToOutAtom(o-1,*lst.Atoms());
}
else
***************
*** 197,201 ****
else
post("py/pyext - No data to send");
- if(lst) delete lst;
if(!tp) Py_DECREF(val);
--- 197,200 ----
***************
*** 297,307 ****
val = PyTuple_GetSlice(args,1,sz); // new ref
! AtomList *lst = GetPyArgs(val);
! if(lst) {
t_glist *gl = ext->thisCanvas(); //canvas_getcurrent();
t_class **cl = (t_pd *)gl;
! if(cl) {
! pd_forwardmess(cl,lst->Count(),lst->Atoms());
! }
#ifdef FLEXT_DEBUG
else
--- 296,305 ----
val = PyTuple_GetSlice(args,1,sz); // new ref
! AtomListStatic<16> lst;
! if(GetPyArgs(lst,val)) {
t_glist *gl = ext->thisCanvas(); //canvas_getcurrent();
t_class **cl = (t_pd *)gl;
! if(cl)
! pd_forwardmess(cl,lst.Count(),lst.Atoms());
#ifdef FLEXT_DEBUG
else
***************
*** 312,316 ****
else
post("py/pyext - No data to send");
- if(lst) delete lst;
if(!tp) Py_DECREF(val);
--- 310,313 ----
Index: pyargs.cpp
===================================================================
RCS file: /cvsroot/pure-data/externals/grill/py/source/pyargs.cpp,v
retrieving revision 1.14
retrieving revision 1.15
diff -C2 -d -r1.14 -r1.15
*** pyargs.cpp 13 Mar 2005 04:59:47 -0000 1.14
--- pyargs.cpp 31 Mar 2005 03:54:11 -0000 1.15
***************
*** 85,92 ****
}
! flext::AtomList *pybase::GetPyArgs(PyObject *pValue,PyObject **self)
{
! if(pValue == NULL) return NULL;
! AtomList *ret = NULL;
// analyze return value or tuple
--- 85,91 ----
}
! bool pybase::GetPyArgs(AtomList &lst,PyObject *pValue,int offs,PyObject **self)
{
! if(pValue == NULL) return false;
// analyze return value or tuple
***************
*** 104,115 ****
tp = sequ;
}
! else if(pValue == Py_None)
! Py_DECREF(pValue);
! else {
rargc = 1;
tp = atom;
}
! ret = new AtomList(rargc);
for(int ix = 0; ix < rargc; ++ix) {
--- 103,114 ----
tp = sequ;
}
! else if(pValue != Py_None) {
rargc = 1;
tp = atom;
}
+ // else
+ // Py_DECREF(pValue);
! lst(offs+rargc);
for(int ix = 0; ix < rargc; ++ix) {
***************
*** 120,128 ****
arg = pValue;
! if(PyInt_Check(arg)) SetInt((*ret)[ix],PyInt_AsLong(arg));
! else if(PyLong_Check(arg)) SetInt((*ret)[ix],PyLong_AsLong(arg));
! else if(PyFloat_Check(arg)) SetFloat((*ret)[ix],(float)PyFloat_AsDouble(arg));
! else if(pySymbol_Check(arg)) SetSymbol((*ret)[ix],pySymbol_AS_SYMBOL(arg));
! else if(PyString_Check(arg)) SetString((*ret)[ix],PyString_AS_STRING(arg));
else if(ix == 0 && self && PyInstance_Check(arg)) {
// assumed to be self ... that should be checked _somehow_ !!!
--- 119,128 ----
arg = pValue;
! t_atom &at = lst[offs+ix];
! if(PyInt_Check(arg)) SetInt(at,PyInt_AsLong(arg));
! else if(PyLong_Check(arg)) SetInt(at,PyLong_AsLong(arg));
! else if(PyFloat_Check(arg)) SetFloat(at,(float)PyFloat_AsDouble(arg));
! else if(pySymbol_Check(arg)) SetSymbol(at,pySymbol_AS_SYMBOL(arg));
! else if(PyString_Check(arg)) SetString(at,PyString_AS_STRING(arg));
else if(ix == 0 && self && PyInstance_Check(arg)) {
// assumed to be self ... that should be checked _somehow_ !!!
***************
*** 141,152 ****
}
! if(tp == sequ) Py_DECREF(arg);
}
! if(!ok) {
! delete ret;
! ret = NULL;
! }
! return ret;
}
-
--- 141,148 ----
}
! if(tp == sequ)
! Py_DECREF(arg);
}
! return ok;
}
Index: pybuffer.cpp
===================================================================
RCS file: /cvsroot/pure-data/externals/grill/py/source/pybuffer.cpp,v
retrieving revision 1.5
retrieving revision 1.6
diff -C2 -d -r1.5 -r1.6
*** pybuffer.cpp 25 Mar 2005 04:54:16 -0000 1.5
--- pybuffer.cpp 31 Mar 2005 03:54:11 -0000 1.6
***************
*** 218,223 ****
}
}
! else
! Py_INCREF(ret = Py_None);
return ret;
}
--- 218,225 ----
}
}
! else {
! Py_INCREF(Py_None);
! ret = Py_None;
! }
return ret;
}
***************
*** 275,280 ****
ret = nobj;
}
! else
! Py_INCREF(ret = Py_None);
}
else
--- 277,284 ----
ret = nobj;
}
! else {
! Py_INCREF(Py_None);
! ret = Py_None;
! }
}
else
Index: main.cpp
===================================================================
RCS file: /cvsroot/pure-data/externals/grill/py/source/main.cpp,v
retrieving revision 1.32
retrieving revision 1.33
diff -C2 -d -r1.32 -r1.33
*** main.cpp 18 Mar 2005 04:58:20 -0000 1.32
--- main.cpp 31 Mar 2005 03:54:10 -0000 1.33
***************
*** 206,214 ****
PyErr_Print(); // no method found
else {
! AtomList *l = GetPyArgs(pvar);
! if(l) {
! lst = *l; delete l;
! }
! else
post("py/pyext - Argument list could not be created");
Py_DECREF(pvar);
--- 206,210 ----
PyErr_Print(); // no method found
else {
! if(!GetPyArgs(lst,pvar))
post("py/pyext - Argument list could not be created");
Py_DECREF(pvar);
***************
*** 268,274 ****
}
! void pybase::SetArgs(int argc,const t_atom *argv)
{
// script arguments
char **sargv = new char *[argc+1];
for(int i = 0; i <= argc; ++i) {
--- 264,272 ----
}
! void pybase::SetArgs()
{
// script arguments
+ int argc = args.Count();
+ const t_atom *argv = args.Atoms();
char **sargv = new char *[argc+1];
for(int i = 0; i <= argc; ++i) {
***************
*** 287,301 ****
}
! void pybase::ImportModule(const char *name)
{
! if(!name) return;
module = PyImport_ImportModule((char *)name); // increases module_obj ref count by one
! if(!module) {
! PyErr_Print();
! dict = NULL;
! }
! else
! dict = PyModule_GetDict(module);
}
--- 285,297 ----
}
! bool pybase::ImportModule(const char *name)
{
! if(!name) return false;
+ SetArgs();
module = PyImport_ImportModule((char *)name); // increases module_obj ref count by one
! dict = module?PyModule_GetDict(module):NULL;
!
! return module != NULL;
}
***************
*** 316,325 ****
}
! void pybase::ReloadModule()
{
if(module) {
PyObject *newmod = PyImport_ReloadModule(module);
if(!newmod) {
- PyErr_Print();
// old module still exists?!
// dict = NULL;
--- 312,322 ----
}
! bool pybase::ReloadModule()
{
+ bool ok = false;
if(module) {
+ SetArgs();
PyObject *newmod = PyImport_ReloadModule(module);
if(!newmod) {
// old module still exists?!
// dict = NULL;
***************
*** 329,336 ****
module = newmod;
dict = PyModule_GetDict(module); // borrowed
}
}
! else
post("py/pyext - No module to reload");
}
--- 326,335 ----
module = newmod;
dict = PyModule_GetDict(module); // borrowed
+ ok = true;
}
}
! else
post("py/pyext - No module to reload");
+ return ok;
}
Index: pyext.h
===================================================================
RCS file: /cvsroot/pure-data/externals/grill/py/source/pyext.h,v
retrieving revision 1.20
retrieving revision 1.21
diff -C2 -d -r1.20 -r1.21
*** pyext.h 13 Mar 2005 04:59:47 -0000 1.20
--- pyext.h 31 Mar 2005 03:54:11 -0000 1.21
***************
*** 63,68 ****
void m_reload();
! void m_reload_(int argc,const t_atom *argv);
! void ms_args(const AtomList &a) { m_reload_(a.Count(),a.Atoms()); }
void m_dir_() { m__dir(pyobj); }
void mg_dir_(AtomList &lst) { GetDir(pyobj,lst); }
--- 63,68 ----
void m_reload();
! void m_reload_(int argc,const t_atom *argv) { initargs(argc,argv); m_reload(); }
! void ms_initargs(const AtomList &a) { m_reload_(a.Count(),a.Atoms()); }
void m_dir_() { m__dir(pyobj); }
void mg_dir_(AtomList &lst) { GetDir(pyobj,lst); }
***************
*** 77,81 ****
int siginlets,sigoutlets;
! virtual void Reload();
virtual bool DoInit();
virtual void DoExit();
--- 77,83 ----
int siginlets,sigoutlets;
! AtomListStatic<16> initargs;
!
! virtual bool Reload();
virtual bool DoInit();
virtual void DoExit();
***************
*** 92,98 ****
void ClearBinding();
bool MakeInstance();
! void InitInOut(int &inlets,int &outlets);
!
! AtomList args;
static PyObject *class_obj,*class_dict;
--- 94,98 ----
void ClearBinding();
bool MakeInstance();
! bool InitInOut(int &inlets,int &outlets);
static PyObject *class_obj,*class_dict;
***************
*** 125,130 ****
FLEXT_CALLBACK(m_doc_)
! FLEXT_ATTRGET_V(args)
! FLEXT_CALLSET_V(ms_args)
FLEXT_CALLBACK_S(m_get)
--- 125,130 ----
FLEXT_CALLBACK(m_doc_)
! FLEXT_ATTRGET_V(initargs)
! FLEXT_CALLSET_V(ms_initargs)
FLEXT_CALLBACK_S(m_get)
Index: modmeth.cpp
===================================================================
RCS file: /cvsroot/pure-data/externals/grill/py/source/modmeth.cpp,v
retrieving revision 1.17
retrieving revision 1.18
diff -C2 -d -r1.17 -r1.18
*** modmeth.cpp 13 Mar 2005 04:59:47 -0000 1.17
--- modmeth.cpp 31 Mar 2005 03:54:11 -0000 1.18
***************
*** 127,137 ****
val = PySequence_GetSlice(args,1,sz); // new ref
! AtomList *lst = GetPyArgs(val);
! if(lst) {
bool ok;
! if(lst->Count() && IsSymbol((*lst)[0]))
! ok = Forward(recv,GetSymbol((*lst)[0]),lst->Count()-1,lst->Atoms()+1);
else
! ok = Forward(recv,*lst);
#ifdef FLEXT_DEBUG
--- 127,137 ----
val = PySequence_GetSlice(args,1,sz); // new ref
! AtomListStatic<16> lst;
! if(GetPyArgs(lst,val)) {
bool ok;
! if(lst.Count() && IsSymbol(lst[0]))
! ok = Forward(recv,GetSymbol(lst[0]),lst.Count()-1,lst.Atoms()+1);
else
! ok = Forward(recv,lst);
#ifdef FLEXT_DEBUG
***************
*** 140,146 ****
#endif
}
! else
post("py/pyext - No data to send");
- if(lst) delete lst;
if(!tp) Py_DECREF(val);
--- 140,147 ----
#endif
}
! else if(PyErr_Occurred())
! PyErr_Print();
! else
post("py/pyext - No data to send");
if(!tp) Py_DECREF(val);
***************
*** 184,188 ****
if(value_getfloat(const_cast<t_symbol *>(sym),&f)) {
post("py/pyext - Could not get value '%s'",GetString(sym));
! Py_INCREF(ret = Py_None);
}
else
--- 185,190 ----
if(value_getfloat(const_cast<t_symbol *>(sym),&f)) {
post("py/pyext - Could not get value '%s'",GetString(sym));
! Py_INCREF(Py_None);
! ret = Py_None;
}
else
***************
*** 191,195 ****
else {
post("py/pyext - Syntax: _getvalue [name]");
! Py_INCREF(ret = Py_None);
}
return ret;
--- 193,198 ----
else {
post("py/pyext - Syntax: _getvalue [name]");
! Py_INCREF(Py_None);
! ret = Py_None;
}
return ret;
Index: pyext.cpp
===================================================================
RCS file: /cvsroot/pure-data/externals/grill/py/source/pyext.cpp,v
retrieving revision 1.30
retrieving revision 1.31
diff -C2 -d -r1.30 -r1.31
*** pyext.cpp 14 Mar 2005 04:58:13 -0000 1.30
--- pyext.cpp 31 Mar 2005 03:54:11 -0000 1.31
***************
*** 36,40 ****
FLEXT_CADDATTR_GET(c,"dir+",mg_dir_);
! FLEXT_CADDATTR_VAR(c,"args",args,ms_args);
FLEXT_CADDMETHOD_(c,0,"get",m_get);
--- 36,40 ----
FLEXT_CADDATTR_GET(c,"dir+",mg_dir_);
! FLEXT_CADDATTR_VAR(c,"args",initargs,ms_initargs);
FLEXT_CADDMETHOD_(c,0,"get",m_get);
***************
*** 130,134 ****
}
! const t_atom *clname = NULL;
PyThreadState *state = PyLockSys();
--- 130,134 ----
}
! const t_symbol *clname = NULL;
PyThreadState *state = PyLockSys();
***************
*** 150,171 ****
#pragma message("Adding current dir to path is not implemented")
#endif
! const t_atom &scr = argv[apre];
!
! if(!IsString(scr))
! post("%s - script name argument is invalid",thisName());
! else {
GetModulePath(GetString(scr),dir,sizeof(dir));
// add to path
AddToPath(dir);
! SetArgs(0,NULL);
ImportModule(GetString(scr));
}
++apre;
// check for alias creation names
! if(strrchr(thisName(),'.')) clname = &scr;
}
--- 150,170 ----
#pragma message("Adding current dir to path is not implemented")
#endif
! const t_symbol *scr = GetASymbol(argv[apre]);
! if(scr) {
GetModulePath(GetString(scr),dir,sizeof(dir));
// add to path
AddToPath(dir);
! // SetArgs(0,NULL);
ImportModule(GetString(scr));
}
+ else
+ post("%s - script name argument is invalid",thisName());
++apre;
// check for alias creation names
! if(strrchr(thisName(),'.')) clname = scr;
}
***************
*** 173,186 ****
if(argc > apre || clname) {
! if(!clname) clname = &argv[apre++];
// class name
! if(!IsString(*clname))
post("%s - class name argument is invalid",thisName());
else
! methname = GetSymbol(*clname);
}
! if(argc > apre) args(argc-apre,argv+apre);
PyUnlock(state);
--- 172,187 ----
if(argc > apre || clname) {
! if(!clname) clname = GetASymbol(argv[apre++]);
// class name
! if(!clname)
post("%s - class name argument is invalid",thisName());
else
! methname = clname;
}
! if(argc > apre) initargs(argc-apre,argv+apre);
!
! Report();
PyUnlock(state);
***************
*** 232,252 ****
// call init now, after _this has been set, which is
// important for eventual callbacks from __init__ to c
! PyObject *pargs = MakePyArgs(NULL,args.Count(),args.Atoms(),-1,true);
! if(!pargs) PyErr_Print();
! PyObject *init = PyObject_GetAttrString(pyobj,"__init__"); // get ref
! if(init) {
! if(PyMethod_Check(init)) {
! PyObject *res = PyObject_CallObject(init,pargs);
! if(!res)
! PyErr_Print();
! else
! Py_DECREF(res);
! }
! Py_DECREF(init);
! }
!
! Py_XDECREF(pargs);
! return true;
}
--- 233,257 ----
// call init now, after _this has been set, which is
// important for eventual callbacks from __init__ to c
! PyObject *pargs = MakePyArgs(NULL,initargs.Count(),initargs.Atoms(),-1,true);
! if(pargs) {
! bool ok = true;
! PyObject *init = PyObject_GetAttrString(pyobj,"__init__"); // get ref
! if(init) {
! if(PyMethod_Check(init)) {
! PyObject *res = PyObject_CallObject(init,pargs);
! if(!res)
! ok = false;
! else
! Py_DECREF(res);
! }
! Py_DECREF(init);
! }
!
! Py_DECREF(pargs);
! return ok;
! }
! else
! return false;
}
***************
*** 270,273 ****
--- 275,279 ----
}
else
+ // _del has not been found - don't care
PyErr_Clear();
***************
*** 281,285 ****
}
! void pyext::InitInOut(int &inl,int &outl)
{
if(inl >= 0) {
--- 287,291 ----
}
! bool pyext::InitInOut(int &inl,int &outl)
{
if(inl >= 0) {
***************
*** 294,299 ****
}
- DoInit(); // call __init__ constructor
// __init__ can override the number of inlets and outlets
if(inl < 0) {
--- 300,306 ----
}
// __init__ can override the number of inlets and outlets
+ if(!DoInit()) // call __init__ constructor
+ return false;
if(inl < 0) {
***************
*** 331,334 ****
--- 338,343 ----
PyErr_Clear();
}
+
+ return true;
}
***************
*** 359,363 ****
}
! void pyext::Reload()
{
DoExit();
--- 368,372 ----
}
! bool pyext::Reload()
{
DoExit();
***************
*** 365,378 ****
// by here, the Python class destructor should have been called!
! SetArgs(0,NULL);
! ReloadModule();
! MakeInstance();
! int inl = -1,outl = -1;
! InitInOut(inl,outl);
! if(inl != inlets || outl != outlets)
! post("%s - Inlet and outlet count can't be changed by reload",thisName());
}
--- 374,391 ----
// by here, the Python class destructor should have been called!
! // SetArgs(0,NULL);
! bool ok = ReloadModule();
! if(ok) ok = MakeInstance();
! if(ok) {
! int inl = -1,outl = -1;
! ok = InitInOut(inl,outl);
! if(inl != inlets || outl != outlets)
! post("%s - Inlet and outlet count can't be changed by reload",thisName());
! }
!
! return ok;
}
***************
*** 391,401 ****
SetThis();
! PyUnlock(state);
! }
! void pyext::m_reload_(int argc,const t_atom *argv)
! {
! args(argc,argv);
! m_reload();
}
--- 404,410 ----
SetThis();
! Report();
! PyUnlock(state);
}
***************
*** 405,428 ****
PyObject *pvar = PyObject_GetAttrString(pyobj,const_cast<char *>(GetString(s))); /* fetch bound method */
! if(!pvar) {
! PyErr_Clear(); // no method found
! post("%s - get: Python variable %s not found",thisName(),GetString(s));
! }
! else {
! AtomList *lst = GetPyArgs(pvar);
! if(lst) {
// dump value to attribute outlet
! AtomAnything out(sym_get,lst->Count()+1);
! SetSymbol(out[0],s);
! out.Set(lst->Count(),lst->Atoms(),1);
! delete lst;
!
! ToOutAnything(GetOutAttr(),out);
}
! else
! post("%s - get: List could not be created",thisName());
Py_DECREF(pvar);
}
PyUnlock(state);
}
--- 414,430 ----
PyObject *pvar = PyObject_GetAttrString(pyobj,const_cast<char *>(GetString(s))); /* fetch bound method */
! if(pvar) {
! AtomListStatic<16> lst;
! if(GetPyArgs(lst,pvar,1)) {
// dump value to attribute outlet
! SetSymbol(lst[0],s);
! ToOutAnything(GetOutAttr(),sym_get,lst.Count(),lst.Atoms());
}
!
Py_DECREF(pvar);
}
+ Report();
+
PyUnlock(state);
}
***************
*** 438,451 ****
else {
char *ch = const_cast<char *>(GetString(argv[0]));
! if(!PyObject_HasAttrString(pyobj,ch)) {
! PyErr_Clear(); // no method found
! post("%s - set: Python variable %s not found",thisName(),ch);
! }
! else {
PyObject *pval = MakePyArgs(NULL,argc-1,argv+1,-1,false);
!
! if(!pval)
! PyErr_Print();
! else {
if(PySequence_Size(pval) == 1) {
// reduce lists of one element to element itself
--- 440,446 ----
else {
char *ch = const_cast<char *>(GetString(argv[0]));
! if(PyObject_HasAttrString(pyobj,ch)) {
PyObject *pval = MakePyArgs(NULL,argc-1,argv+1,-1,false);
! if(pval) {
if(PySequence_Size(pval) == 1) {
// reduce lists of one element to element itself
***************
*** 462,465 ****
--- 457,462 ----
}
+ Report();
+
PyUnlock(state);
}
Index: main.h
===================================================================
RCS file: /cvsroot/pure-data/externals/grill/py/source/main.h,v
retrieving revision 1.37
retrieving revision 1.38
diff -C2 -d -r1.37 -r1.38
*** main.h 14 Mar 2005 04:58:13 -0000 1.37
--- main.h 31 Mar 2005 03:54:11 -0000 1.38
***************
*** 53,57 ****
static PyObject *MakePyArgs(const t_symbol *s,int argc,const t_atom *argv,int inlet = -1,bool withself = false);
! static AtomList *GetPyArgs(PyObject *pValue,PyObject **self = NULL);
static void lib_setup();
--- 53,57 ----
static PyObject *MakePyArgs(const t_symbol *s,int argc,const t_atom *argv,int inlet = -1,bool withself = false);
! static bool GetPyArgs(AtomList &lst,PyObject *pValue,int offs = 0,PyObject **self = NULL);
static void lib_setup();
***************
*** 74,92 ****
void GetDir(PyObject *obj,AtomList &lst);
void GetModulePath(const char *mod,char *dir,int len);
void AddToPath(const char *dir);
! void SetArgs(int argc,const t_atom *argv);
! void ImportModule(const char *name);
void UnimportModule();
! void ReloadModule();
void Register(const char *reg);
void Unregister(const char *reg);
void Reregister(const char *reg);
! virtual void Reload() = 0;
void OpenEditor();
void Respond(bool b);
static bool IsAnything(const t_symbol *s) { return s && s != sym_float && s != sym_int && s != sym_symbol && s != sym_list && s != sym_pointer; }
--- 74,96 ----
void GetDir(PyObject *obj,AtomList &lst);
+ AtomListStatic<16> args;
+
void GetModulePath(const char *mod,char *dir,int len);
void AddToPath(const char *dir);
! void SetArgs();
! bool ImportModule(const char *name);
void UnimportModule();
! bool ReloadModule();
void Register(const char *reg);
void Unregister(const char *reg);
void Reregister(const char *reg);
! virtual bool Reload() = 0;
void OpenEditor();
void Respond(bool b);
+ void Report() { while(PyErr_Occurred()) PyErr_Print(); }
+
static bool IsAnything(const t_symbol *s) { return s && s != sym_float && s != sym_int && s != sym_symbol && s != sym_list && s != sym_pointer; }
Index: py.cpp
===================================================================
RCS file: /cvsroot/pure-data/externals/grill/py/source/py.cpp,v
retrieving revision 1.21
retrieving revision 1.22
diff -C2 -d -r1.21 -r1.22
*** py.cpp 14 Mar 2005 04:58:13 -0000 1.21
--- py.cpp 31 Mar 2005 03:54:11 -0000 1.22
***************
*** 31,35 ****
void m_reload();
! void m_reload_(int argc,const t_atom *argv);
void m_set(int argc,const t_atom *argv);
void m_dir_() { m__dir(function); }
--- 31,35 ----
void m_reload();
! void m_reload_(int argc,const t_atom *argv) { args(argc,argv); m_reload(); }
void m_set(int argc,const t_atom *argv);
void m_dir_() { m__dir(function); }
***************
*** 49,56 ****
bool withfunction;
! virtual void Reload();
! void SetFunction(const char *func);
! void ResetFunction();
virtual bool thrcall(void *data);
--- 49,56 ----
bool withfunction;
! virtual bool Reload();
! bool SetFunction(const char *func);
! bool ResetFunction();
virtual bool thrcall(void *data);
***************
*** 134,151 ****
#endif
! PyThreadState *state = PyLockSys();
! if(argc > 2)
! SetArgs(argc-2,argv+2);
! else
! SetArgs(0,NULL);
// init script module
if(argc >= 1) {
! if(!IsString(argv[0]))
! post("%s - script name argument is invalid",thisName());
! else {
char dir[1024];
! GetModulePath(GetString(argv[0]),dir,sizeof(dir));
// set script path
AddToPath(dir);
--- 134,147 ----
#endif
! if(argc > 2) args(argc-2,argv+2);
! PyThreadState *state = PyLockSys();
// init script module
if(argc >= 1) {
! const char *sn = GetAString(argv[0]);
! if(sn) {
char dir[1024];
! GetModulePath(sn,dir,sizeof(dir));
// set script path
AddToPath(dir);
***************
*** 164,186 ****
#endif
! ImportModule(GetString(argv[0]));
}
}
Register("_py");
! if(argc >= 2) {
! withfunction = true;
! // set function name
! if(!IsString(argv[1]))
! post("%s - function name argument is invalid",thisName());
! else {
! // Set function
! SetFunction(GetString(argv[1]));
! }
! }
! else
! withfunction = false;
PyUnlock(state);
--- 160,180 ----
#endif
! ImportModule(sn);
}
+ else
+ PyErr_SetString(PyExc_ValueError,"Invalid module name");
}
Register("_py");
! if(argc >= 2) {
! const char *fn = GetAString(argv[1]);
! if(fn)
! SetFunction(fn);
! else
! PyErr_SetString(PyExc_ValueError,"Invalid function name");
! }
! Report();
PyUnlock(state);
***************
*** 191,194 ****
--- 185,189 ----
PyThreadState *state = PyLockSys();
Unregister("_py");
+ Report();
PyUnlock(state);
}
***************
*** 218,257 ****
SetFunction(funname?GetString(funname):NULL);
PyUnlock(state);
}
- void pyobj::m_reload_(int argc,const t_atom *argv)
- {
- PyThreadState *state = PyLockSys();
- SetArgs(argc,argv);
- PyUnlock(state);
-
- m_reload();
- }
-
void pyobj::m_set(int argc,const t_atom *argv)
{
PyThreadState *state = PyLockSys();
! int ix = 0;
if(argc >= 2) {
! if(!IsString(argv[ix])) {
! post("%s - script name is not valid",thisName());
! return;
! }
! const char *sn = GetString(argv[ix]);
!
! if(!module || !strcmp(sn,PyModule_GetName(module))) {
! ImportModule(sn);
! Register("_py");
! }
! ++ix;
}
! if(!IsString(argv[ix]))
! post("%s - function name is not valid",thisName());
! else
! SetFunction(GetString(argv[ix]));
PyUnlock(state);
--- 213,248 ----
SetFunction(funname?GetString(funname):NULL);
+ Report();
PyUnlock(state);
}
void pyobj::m_set(int argc,const t_atom *argv)
{
PyThreadState *state = PyLockSys();
! // function name has precedence
if(argc >= 2) {
! const char *sn = GetAString(*argv);
! ++argv,--argc;
! if(sn) {
! if(!module || !strcmp(sn,PyModule_GetName(module))) {
! ImportModule(sn);
! Register("_py");
! }
! }
! else
! PyErr_SetString(PyExc_ValueError,"Invalid module name");
}
! if(argc) {
! const char *fn = GetAString(*argv);
! if(fn)
! SetFunction(fn);
! else
! PyErr_SetString(PyExc_ValueError,"Invalid function name");
! }
!
! Report();
PyUnlock(state);
***************
*** 288,328 ****
}
! void pyobj::ResetFunction()
{
! if(!module || !dict)
! {
post("%s - No module loaded",thisName());
! function = NULL;
! return;
! }
! function = funname?PyDict_GetItemString(dict,(char *)GetString(funname)):NULL; // borrowed!!!
! if(!function) {
! PyErr_Clear();
! if(funname) post("%s - Function %s could not be found",thisName(),GetString(funname));
! }
! else if(!PyFunction_Check(function)) {
! post("%s - Object %s is not a function",thisName(),GetString(funname));
! function = NULL;
! }
}
! void pyobj::SetFunction(const char *func)
{
if(func) {
funname = MakeSymbol(func);
! withfunction = true;
! ResetFunction();
}
else {
- withfunction = false;
function = NULL,funname = NULL;
}
}
! void pyobj::Reload()
{
ResetFunction();
}
--- 279,324 ----
}
! bool pyobj::ResetFunction()
{
! function = NULL;
!
! if(!module || !dict)
post("%s - No module loaded",thisName());
! else {
! if(funname) {
! function = PyDict_GetItemString(dict,(char *)GetString(funname)); // borrowed!!!
! if(!function)
! PyErr_SetString(PyExc_AttributeError,"Function not found");
! else if(!PyFunction_Check(function)) {
! function = NULL;
! PyErr_SetString(PyExc_TypeError,"Attribute is not a function");
! }
! }
! }
! // exception could be set here
! return function != NULL;
}
! bool pyobj::SetFunction(const char *func)
{
if(func) {
funname = MakeSymbol(func);
! withfunction = ResetFunction();
}
else {
function = NULL,funname = NULL;
+ withfunction = false;
}
+
+ // exception could be set here
+ return withfunction;
}
! bool pyobj::Reload()
{
ResetFunction();
+ return true;
}
***************
*** 336,348 ****
}
else {
! AtomList *rargs = GetPyArgs(ret);
! if(!rargs)
! PyErr_Print();
! else {
// call to outlet _outside_ the Mutex lock!
// otherwise (if not detached) deadlock will occur
! if(rargs->Count()) ToOutList(0,*rargs);
! delete rargs;
}
Py_DECREF(ret);
return true;
--- 332,344 ----
}
else {
! AtomListStatic<16> rargs;
! if(GetPyArgs(rargs,ret)) {
// call to outlet _outside_ the Mutex lock!
// otherwise (if not detached) deadlock will occur
! if(rargs.Count()) ToOutList(0,rargs);
}
+ else if(PyErr_Occurred())
+ PyErr_Print();
+
Py_DECREF(ret);
return true;
***************
*** 363,379 ****
}
else
! post("%s: no valid function defined",thisName());
}
else if(module) {
// no function defined as creation argument -> use message tag
! PyObject *func = PyObject_GetAttrString(module,const_cast<char *>(GetString(s)));
! if(func) {
! PyObject *pargs = MakePyArgs(sym_list,argc,argv);
! ret = gencall(func,pargs);
}
else
! PyErr_Print();
}
PyUnlock(state);
--- 359,379 ----
}
else
! PyErr_SetString(PyExc_RuntimeError,"No function set");
}
else if(module) {
// no function defined as creation argument -> use message tag
! if(s) {
! PyObject *func = PyObject_GetAttrString(module,const_cast<char *>(GetString(s)));
! if(func) {
! PyObject *pargs = MakePyArgs(sym_list,argc,argv);
! ret = gencall(func,pargs);
! }
}
else
! PyErr_SetString(PyExc_RuntimeError,"No function set");
}
+ Report();
+
PyUnlock(state);