aboutsummaryrefslogtreecommitdiff
path: root/externals/grill/py
diff options
context:
space:
mode:
authorThomas Grill <xovo@users.sourceforge.net>2005-03-31 03:54:11 +0000
committerThomas Grill <xovo@users.sourceforge.net>2005-03-31 03:54:11 +0000
commit64d57eae96b65b3d618d8b3e8d68111da80f283a (patch)
tree886f24cf54d210509fa85ebd8c5dfbd3864a9bdb /externals/grill/py
parent6c94eab605e5ec018654541bf2bf410b7db17788 (diff)
fixed reference count bug
cleaner error reporting more optimizations added generic numpy support (not working) fixes for maxmsp svn path=/trunk/; revision=2655
Diffstat (limited to 'externals/grill/py')
-rw-r--r--externals/grill/py/pd/script-1.pd4
-rw-r--r--externals/grill/py/source/clmeth.cpp25
-rw-r--r--externals/grill/py/source/main.cpp33
-rw-r--r--externals/grill/py/source/main.h14
-rw-r--r--externals/grill/py/source/modmeth.cpp21
-rw-r--r--externals/grill/py/source/py.cpp170
-rw-r--r--externals/grill/py/source/pyargs.cpp34
-rw-r--r--externals/grill/py/source/pybuffer.cpp12
-rw-r--r--externals/grill/py/source/pyext.cpp137
-rw-r--r--externals/grill/py/source/pyext.h16
10 files changed, 234 insertions, 232 deletions
diff --git a/externals/grill/py/pd/script-1.pd b/externals/grill/py/pd/script-1.pd
index 27b63d43..328b096d 100644
--- a/externals/grill/py/pd/script-1.pd
+++ b/externals/grill/py/pd/script-1.pd
@@ -1,4 +1,4 @@
-#N canvas 297 17 692 534 12;
+#N canvas 297 17 696 538 12;
#X obj 39 278 print;
#X obj 345 251 print;
#X msg 499 149 freakhole;
@@ -38,6 +38,7 @@ file.;
#X msg 509 178 a b c;
#X text 556 181 too many args;
#X text 505 372 just trigger without arguments;
+#X msg 386 371 set ret4;
#X connect 2 0 25 1;
#X connect 3 0 21 1;
#X connect 4 0 21 1;
@@ -60,3 +61,4 @@ file.;
#X connect 26 0 21 0;
#X connect 28 0 21 0;
#X connect 32 0 25 1;
+#X connect 35 0 23 0;
diff --git a/externals/grill/py/source/clmeth.cpp b/externals/grill/py/source/clmeth.cpp
index cfd8604a..4b403cf8 100644
--- a/externals/grill/py/source/clmeth.cpp
+++ b/externals/grill/py/source/clmeth.cpp
@@ -173,8 +173,8 @@ PyObject *pyext::pyext_outlet(PyObject *,PyObject *args)
if(!tp)
val = PySequence_GetSlice(args,2,sz); // new ref
- AtomList *lst = GetPyArgs(val);
- if(lst) {
+ AtomListStatic<16> lst;
+ if(GetPyArgs(lst,val)) {
int o = PyInt_AsLong(outl);
if(o >= 1 && o <= ext->Outlets()) {
// offset outlet by signal outlets
@@ -182,12 +182,12 @@ PyObject *pyext::pyext_outlet(PyObject *,PyObject *args)
// 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);
+ 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());
+ ext->ToOutAtom(o-1,*lst.Atoms());
}
else
post("pyext: outlet index out of range");
@@ -196,7 +196,6 @@ PyObject *pyext::pyext_outlet(PyObject *,PyObject *args)
}
else
post("py/pyext - No data to send");
- if(lst) delete lst;
if(!tp) Py_DECREF(val);
}
@@ -296,13 +295,12 @@ PyObject *pyext::pyext_tocanvas(PyObject *,PyObject *args)
if(!tp)
val = PyTuple_GetSlice(args,1,sz); // new ref
- AtomList *lst = GetPyArgs(val);
- if(lst) {
+ 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());
- }
+ if(cl)
+ pd_forwardmess(cl,lst.Count(),lst.Atoms());
#ifdef FLEXT_DEBUG
else
post("pyext - no parent canvas?!");
@@ -311,7 +309,6 @@ PyObject *pyext::pyext_tocanvas(PyObject *,PyObject *args)
}
else
post("py/pyext - No data to send");
- if(lst) delete lst;
if(!tp) Py_DECREF(val);
}
diff --git a/externals/grill/py/source/main.cpp b/externals/grill/py/source/main.cpp
index 3b0aa869..608ecdd7 100644
--- a/externals/grill/py/source/main.cpp
+++ b/externals/grill/py/source/main.cpp
@@ -205,11 +205,7 @@ void pybase::GetDir(PyObject *obj,AtomList &lst)
if(!pvar)
PyErr_Print(); // no method found
else {
- AtomList *l = GetPyArgs(pvar);
- if(l) {
- lst = *l; delete l;
- }
- else
+ if(!GetPyArgs(lst,pvar))
post("py/pyext - Argument list could not be created");
Py_DECREF(pvar);
}
@@ -267,9 +263,11 @@ void pybase::OpenEditor()
// this should once open the editor....
}
-void pybase::SetArgs(int argc,const t_atom *argv)
+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) {
sargv[i] = new char[256];
@@ -286,17 +284,15 @@ void pybase::SetArgs(int argc,const t_atom *argv)
delete[] sargv;
}
-void pybase::ImportModule(const char *name)
+bool pybase::ImportModule(const char *name)
{
- if(!name) return;
+ if(!name) return false;
+ SetArgs();
module = PyImport_ImportModule((char *)name); // increases module_obj ref count by one
- if(!module) {
- PyErr_Print();
- dict = NULL;
- }
- else
- dict = PyModule_GetDict(module);
+ dict = module?PyModule_GetDict(module):NULL;
+
+ return module != NULL;
}
void pybase::UnimportModule()
@@ -315,12 +311,13 @@ void pybase::UnimportModule()
dict = NULL;
}
-void pybase::ReloadModule()
+bool pybase::ReloadModule()
{
+ bool ok = false;
if(module) {
+ SetArgs();
PyObject *newmod = PyImport_ReloadModule(module);
if(!newmod) {
- PyErr_Print();
// old module still exists?!
// dict = NULL;
}
@@ -328,10 +325,12 @@ void pybase::ReloadModule()
Py_XDECREF(module);
module = newmod;
dict = PyModule_GetDict(module); // borrowed
+ ok = true;
}
}
- else
+ else
post("py/pyext - No module to reload");
+ return ok;
}
void pybase::GetModulePath(const char *mod,char *dir,int len)
diff --git a/externals/grill/py/source/main.h b/externals/grill/py/source/main.h
index f9df5807..538e577d 100644
--- a/externals/grill/py/source/main.h
+++ b/externals/grill/py/source/main.h
@@ -52,7 +52,7 @@ public:
void Exit();
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 bool GetPyArgs(AtomList &lst,PyObject *pValue,int offs = 0,PyObject **self = NULL);
static void lib_setup();
@@ -73,21 +73,25 @@ protected:
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(int argc,const t_atom *argv);
- void ImportModule(const char *name);
+ void SetArgs();
+ bool ImportModule(const char *name);
void UnimportModule();
- void ReloadModule();
+ bool ReloadModule();
void Register(const char *reg);
void Unregister(const char *reg);
void Reregister(const char *reg);
- virtual void Reload() = 0;
+ 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; }
enum retval { nothing,atom,sequ };
diff --git a/externals/grill/py/source/modmeth.cpp b/externals/grill/py/source/modmeth.cpp
index bbbe64b1..983176bf 100644
--- a/externals/grill/py/source/modmeth.cpp
+++ b/externals/grill/py/source/modmeth.cpp
@@ -126,22 +126,23 @@ PyObject *pybase::py_send(PyObject *,PyObject *args)
if(!tp)
val = PySequence_GetSlice(args,1,sz); // new ref
- AtomList *lst = GetPyArgs(val);
- if(lst) {
+ 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);
+ if(lst.Count() && IsSymbol(lst[0]))
+ ok = Forward(recv,GetSymbol(lst[0]),lst.Count()-1,lst.Atoms()+1);
else
- ok = Forward(recv,*lst);
+ ok = Forward(recv,lst);
#ifdef FLEXT_DEBUG
if(!ok)
post("py/pyext - Receiver doesn't exist");
#endif
}
- else
+ else if(PyErr_Occurred())
+ PyErr_Print();
+ else
post("py/pyext - No data to send");
- if(lst) delete lst;
if(!tp) Py_DECREF(val);
}
@@ -183,14 +184,16 @@ PyObject *pybase::py_getvalue(PyObject *self,PyObject *args)
float f;
if(value_getfloat(const_cast<t_symbol *>(sym),&f)) {
post("py/pyext - Could not get value '%s'",GetString(sym));
- Py_INCREF(ret = Py_None);
+ Py_INCREF(Py_None);
+ ret = Py_None;
}
else
ret = PyFloat_FromDouble(f);
}
else {
post("py/pyext - Syntax: _getvalue [name]");
- Py_INCREF(ret = Py_None);
+ Py_INCREF(Py_None);
+ ret = Py_None;
}
return ret;
}
diff --git a/externals/grill/py/source/py.cpp b/externals/grill/py/source/py.cpp
index eb1d2390..4f46a9ea 100644
--- a/externals/grill/py/source/py.cpp
+++ b/externals/grill/py/source/py.cpp
@@ -30,7 +30,7 @@ protected:
void m_help();
void m_reload();
- void m_reload_(int argc,const t_atom *argv);
+ 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); }
void m_doc_() { m__doc(function); }
@@ -48,10 +48,10 @@ protected:
PyObject *function;
bool withfunction;
- virtual void Reload();
+ virtual bool Reload();
- void SetFunction(const char *func);
- void ResetFunction();
+ bool SetFunction(const char *func);
+ bool ResetFunction();
virtual bool thrcall(void *data);
virtual void DumpOut(const t_symbol *sym,int argc,const t_atom *argv);
@@ -133,20 +133,16 @@ pyobj::pyobj(int argc,const t_atom *argv):
FLEXT_CALLMETHOD(threadworker);
#endif
- PyThreadState *state = PyLockSys();
+ if(argc > 2) args(argc-2,argv+2);
- if(argc > 2)
- SetArgs(argc-2,argv+2);
- else
- SetArgs(0,NULL);
+ PyThreadState *state = PyLockSys();
// init script module
if(argc >= 1) {
- if(!IsString(argv[0]))
- post("%s - script name argument is invalid",thisName());
- else {
+ const char *sn = GetAString(argv[0]);
+ if(sn) {
char dir[1024];
- GetModulePath(GetString(argv[0]),dir,sizeof(dir));
+ GetModulePath(sn,dir,sizeof(dir));
// set script path
AddToPath(dir);
@@ -163,25 +159,23 @@ pyobj::pyobj(int argc,const t_atom *argv):
#pragma message("Adding current dir to path is not implemented")
#endif
- ImportModule(GetString(argv[0]));
+ ImportModule(sn);
}
+ else
+ PyErr_SetString(PyExc_ValueError,"Invalid module name");
}
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;
+ if(argc >= 2) {
+ const char *fn = GetAString(argv[1]);
+ if(fn)
+ SetFunction(fn);
+ else
+ PyErr_SetString(PyExc_ValueError,"Invalid function name");
+ }
+
+ Report();
PyUnlock(state);
}
@@ -190,6 +184,7 @@ pyobj::~pyobj()
{
PyThreadState *state = PyLockSys();
Unregister("_py");
+ Report();
PyUnlock(state);
}
@@ -217,42 +212,38 @@ void pyobj::m_reload()
Register("_py");
SetFunction(funname?GetString(funname):NULL);
+ Report();
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;
+ // function name has precedence
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;
+ 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(!IsString(argv[ix]))
- post("%s - function name is not valid",thisName());
- else
- SetFunction(GetString(argv[ix]));
+ if(argc) {
+ const char *fn = GetAString(*argv);
+ if(fn)
+ SetFunction(fn);
+ else
+ PyErr_SetString(PyExc_ValueError,"Invalid function name");
+ }
+
+ Report();
PyUnlock(state);
}
@@ -287,43 +278,48 @@ void pyobj::m_help()
post("");
}
-void pyobj::ResetFunction()
+bool pyobj::ResetFunction()
{
- if(!module || !dict)
- {
+ function = NULL;
+
+ if(!module || !dict)
post("%s - No module loaded",thisName());
- function = NULL;
- return;
- }
+ 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");
+ }
+ }
+ }
- 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;
- }
+ // exception could be set here
+ return function != NULL;
}
-void pyobj::SetFunction(const char *func)
+bool pyobj::SetFunction(const char *func)
{
if(func) {
funname = MakeSymbol(func);
- withfunction = true;
- ResetFunction();
+ withfunction = ResetFunction();
}
else {
- withfunction = false;
function = NULL,funname = NULL;
+ withfunction = false;
}
+
+ // exception could be set here
+ return withfunction;
}
-void pyobj::Reload()
+bool pyobj::Reload()
{
ResetFunction();
+ return true;
}
bool pyobj::callpy(PyObject *fun,PyObject *args)
@@ -335,15 +331,15 @@ bool pyobj::callpy(PyObject *fun,PyObject *args)
return false;
}
else {
- AtomList *rargs = GetPyArgs(ret);
- if(!rargs)
- PyErr_Print();
- 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);
- delete rargs;
+ if(rargs.Count()) ToOutList(0,rargs);
}
+ else if(PyErr_Occurred())
+ PyErr_Print();
+
Py_DECREF(ret);
return true;
}
@@ -362,19 +358,23 @@ void pyobj::callwork(const t_symbol *s,int argc,const t_atom *argv)
ret = gencall(function,pargs);
}
else
- post("%s: no valid function defined",thisName());
+ PyErr_SetString(PyExc_RuntimeError,"No function set");
}
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);
+ 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_Print();
+ PyErr_SetString(PyExc_RuntimeError,"No function set");
}
+ Report();
+
PyUnlock(state);
Respond(ret);
diff --git a/externals/grill/py/source/pyargs.cpp b/externals/grill/py/source/pyargs.cpp
index 56b0123a..5e328975 100644
--- a/externals/grill/py/source/pyargs.cpp
+++ b/externals/grill/py/source/pyargs.cpp
@@ -84,10 +84,9 @@ PyObject *pybase::MakePyArgs(const t_symbol *s,int argc,const t_atom *argv,int i
return pArgs;
}
-flext::AtomList *pybase::GetPyArgs(PyObject *pValue,PyObject **self)
+bool pybase::GetPyArgs(AtomList &lst,PyObject *pValue,int offs,PyObject **self)
{
- if(pValue == NULL) return NULL;
- AtomList *ret = NULL;
+ if(pValue == NULL) return false;
// analyze return value or tuple
@@ -103,14 +102,14 @@ flext::AtomList *pybase::GetPyArgs(PyObject *pValue,PyObject **self)
rargc = PySequence_Size(pValue);
tp = sequ;
}
- else if(pValue == Py_None)
- Py_DECREF(pValue);
- else {
+ else if(pValue != Py_None) {
rargc = 1;
tp = atom;
}
+// else
+// Py_DECREF(pValue);
- ret = new AtomList(rargc);
+ lst(offs+rargc);
for(int ix = 0; ix < rargc; ++ix) {
PyObject *arg;
@@ -119,11 +118,12 @@ flext::AtomList *pybase::GetPyArgs(PyObject *pValue,PyObject **self)
else
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));
+ 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_ !!!
Py_INCREF(arg);
@@ -140,13 +140,9 @@ flext::AtomList *pybase::GetPyArgs(PyObject *pValue,PyObject **self)
ok = false;
}
- if(tp == sequ) Py_DECREF(arg);
+ if(tp == sequ)
+ Py_DECREF(arg);
}
- if(!ok) {
- delete ret;
- ret = NULL;
- }
- return ret;
+ return ok;
}
-
diff --git a/externals/grill/py/source/pybuffer.cpp b/externals/grill/py/source/pybuffer.cpp
index 8f22acf1..42e23557 100644
--- a/externals/grill/py/source/pybuffer.cpp
+++ b/externals/grill/py/source/pybuffer.cpp
@@ -217,8 +217,10 @@ static PyObject *buffer_item(pySamplebuffer *self, int i)
}
}
}
- else
- Py_INCREF(ret = Py_None);
+ else {
+ Py_INCREF(Py_None);
+ ret = Py_None;
+ }
return ret;
}
@@ -274,8 +276,10 @@ static PyObject *buffer_slice(pySamplebuffer *self,int ilow = 0,int ihigh = 1<<(
else
ret = nobj;
}
- else
- Py_INCREF(ret = Py_None);
+ else {
+ Py_INCREF(Py_None);
+ ret = Py_None;
+ }
}
else
#endif
diff --git a/externals/grill/py/source/pyext.cpp b/externals/grill/py/source/pyext.cpp
index 2d772d15..7d234956 100644
--- a/externals/grill/py/source/pyext.cpp
+++ b/externals/grill/py/source/pyext.cpp
@@ -35,7 +35,7 @@ void pyext::Setup(t_classid c)
FLEXT_CADDMETHOD_(c,0,"dir+",m_dir_);
FLEXT_CADDATTR_GET(c,"dir+",mg_dir_);
- FLEXT_CADDATTR_VAR(c,"args",args,ms_args);
+ FLEXT_CADDATTR_VAR(c,"args",initargs,ms_initargs);
FLEXT_CADDMETHOD_(c,0,"get",m_get);
FLEXT_CADDMETHOD_(c,0,"set",m_set);
@@ -129,7 +129,7 @@ pyext::pyext(int argc,const t_atom *argv,bool sig):
apre += 2;
}
- const t_atom *clname = NULL;
+ const t_symbol *clname = NULL;
PyThreadState *state = PyLockSys();
@@ -149,39 +149,40 @@ pyext::pyext(int argc,const t_atom *argv,bool sig):
#else
#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 {
+ const t_symbol *scr = GetASymbol(argv[apre]);
+ if(scr) {
GetModulePath(GetString(scr),dir,sizeof(dir));
// add to path
AddToPath(dir);
- SetArgs(0,NULL);
+// 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;
+ if(strrchr(thisName(),'.')) clname = scr;
}
Register("_pyext");
if(argc > apre || clname) {
- if(!clname) clname = &argv[apre++];
+ if(!clname) clname = GetASymbol(argv[apre++]);
// class name
- if(!IsString(*clname))
+ if(!clname)
post("%s - class name argument is invalid",thisName());
else
- methname = GetSymbol(*clname);
+ methname = clname;
}
- if(argc > apre) args(argc-apre,argv+apre);
+ if(argc > apre) initargs(argc-apre,argv+apre);
+
+ Report();
PyUnlock(state);
}
@@ -231,23 +232,27 @@ bool pyext::DoInit()
// 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;
+ 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;
}
void pyext::DoExit()
@@ -269,6 +274,7 @@ void pyext::DoExit()
Py_DECREF(objdel);
}
else
+ // _del has not been found - don't care
PyErr_Clear();
gcrun = pyobj->ob_refcnt > 1;
@@ -280,7 +286,7 @@ void pyext::DoExit()
}
}
-void pyext::InitInOut(int &inl,int &outl)
+bool pyext::InitInOut(int &inl,int &outl)
{
if(inl >= 0) {
// set number of inlets
@@ -293,8 +299,9 @@ void pyext::InitInOut(int &inl,int &outl)
FLEXT_ASSERT(!ret);
}
- DoInit(); // call __init__ constructor
// __init__ can override the number of inlets and outlets
+ if(!DoInit()) // call __init__ constructor
+ return false;
if(inl < 0) {
// get number of inlets
@@ -330,6 +337,8 @@ void pyext::InitInOut(int &inl,int &outl)
else
PyErr_Clear();
}
+
+ return true;
}
bool pyext::MakeInstance()
@@ -358,22 +367,26 @@ bool pyext::MakeInstance()
return false;
}
-void pyext::Reload()
+bool pyext::Reload()
{
DoExit();
// by here, the Python class destructor should have been called!
- SetArgs(0,NULL);
- ReloadModule();
+// SetArgs(0,NULL);
+ bool ok = ReloadModule();
- MakeInstance();
+ if(ok) ok = MakeInstance();
+
+ if(ok) {
+ int inl = -1,outl = -1;
+ ok = InitInOut(inl,outl);
- 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());
+ }
- if(inl != inlets || outl != outlets)
- post("%s - Inlet and outlet count can't be changed by reload",thisName());
+ return ok;
}
@@ -390,13 +403,9 @@ void pyext::m_reload()
SetThis();
- PyUnlock(state);
-}
+ Report();
-void pyext::m_reload_(int argc,const t_atom *argv)
-{
- args(argc,argv);
- m_reload();
+ PyUnlock(state);
}
void pyext::m_get(const t_symbol *s)
@@ -404,26 +413,19 @@ void pyext::m_get(const t_symbol *s)
PyThreadState *state = PyLockSys();
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) {
+ if(pvar) {
+ AtomListStatic<16> lst;
+ if(GetPyArgs(lst,pvar,1)) {
// 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);
+ SetSymbol(lst[0],s);
+ ToOutAnything(GetOutAttr(),sym_get,lst.Count(),lst.Atoms());
}
- else
- post("%s - get: List could not be created",thisName());
+
Py_DECREF(pvar);
}
+ Report();
+
PyUnlock(state);
}
@@ -437,16 +439,9 @@ void pyext::m_set(int argc,const t_atom *argv)
post("%s - set: variables with leading _ are reserved and can't be set",thisName());
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 {
+ if(PyObject_HasAttrString(pyobj,ch)) {
PyObject *pval = MakePyArgs(NULL,argc-1,argv+1,-1,false);
-
- if(!pval)
- PyErr_Print();
- else {
+ if(pval) {
if(PySequence_Size(pval) == 1) {
// reduce lists of one element to element itself
@@ -461,6 +456,8 @@ void pyext::m_set(int argc,const t_atom *argv)
}
}
+ Report();
+
PyUnlock(state);
}
diff --git a/externals/grill/py/source/pyext.h b/externals/grill/py/source/pyext.h
index 3c6a86b5..4dd97983 100644
--- a/externals/grill/py/source/pyext.h
+++ b/externals/grill/py/source/pyext.h
@@ -62,8 +62,8 @@ protected:
void m_help();
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_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); }
void m_doc_() { m__doc(((PyInstanceObject *)pyobj)->in_class->cl_dict); }
@@ -76,7 +76,9 @@ protected:
int inlets,outlets;
int siginlets,sigoutlets;
- virtual void Reload();
+ AtomListStatic<16> initargs;
+
+ virtual bool Reload();
virtual bool DoInit();
virtual void DoExit();
@@ -91,9 +93,7 @@ private:
void ClearBinding();
bool MakeInstance();
- void InitInOut(int &inlets,int &outlets);
-
- AtomList args;
+ bool InitInOut(int &inlets,int &outlets);
static PyObject *class_obj,*class_dict;
static PyMethodDef attr_tbl[],meth_tbl[];
@@ -124,8 +124,8 @@ private:
FLEXT_CALLGET_V(mg_dir_)
FLEXT_CALLBACK(m_doc_)
- FLEXT_ATTRGET_V(args)
- FLEXT_CALLSET_V(ms_args)
+ FLEXT_ATTRGET_V(initargs)
+ FLEXT_CALLSET_V(ms_initargs)
FLEXT_CALLBACK_S(m_get)
FLEXT_CALLBACK_V(m_set)