aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--externals/grill/py/readme.txt5
-rw-r--r--externals/grill/py/source/bound.cpp18
-rw-r--r--externals/grill/py/source/clmeth.cpp105
-rw-r--r--externals/grill/py/source/pybase.cpp3
-rw-r--r--externals/grill/py/source/pyext.h4
5 files changed, 93 insertions, 42 deletions
diff --git a/externals/grill/py/readme.txt b/externals/grill/py/readme.txt
index 7c782c82..34be0a14 100644
--- a/externals/grill/py/readme.txt
+++ b/externals/grill/py/readme.txt
@@ -102,6 +102,11 @@ Version history:
- FIX: much better detached method handling (one thread for all object instances!)
- ADD: open module file in editor on "edit" message (or shift-click (PD) or double click (Max))
- FIX: _inlets and _outlets default to 0 if not given
+- ADD: enable optimization of Python code in reease build
+- CHG: _isthreaded is now a data member instead of a method
+- FIX: more safety for calls where association python-pd has already been removed
+- ADD: __str__ method for pyext, to enable print self calls
+- CHG: enable symbol binding for all callables (not only functions and methods)
0.2.0:
- ADD: handling of Python threads
diff --git a/externals/grill/py/source/bound.cpp b/externals/grill/py/source/bound.cpp
index 4c57f65f..3e7bc386 100644
--- a/externals/grill/py/source/bound.cpp
+++ b/externals/grill/py/source/bound.cpp
@@ -46,7 +46,7 @@ public:
if(PyMethod_Check(b))
return true;
else
- // both are functions
+ // both are non-method callables
return a < b;
}
};
@@ -88,12 +88,15 @@ PyObject *pyext::pyext_bind(PyObject *,PyObject *args)
PyObject *self,*meth,*name;
if(!PyArg_ParseTuple(args, "OOO:pyext_bind", &self,&name,&meth)) // borrowed references
post("py/pyext - Wrong arguments!");
- else if(!PyInstance_Check(self) || !(PyMethod_Check(meth) || PyFunction_Check(meth))) {
+ else if(!PyInstance_Check(self) || !PyCallable_Check(meth)) {
post("py/pyext - Wrong argument types!");
}
else {
pyext *th = GetThis(self);
- FLEXT_ASSERT(th);
+ if(!th) {
+ PyErr_SetString(PyExc_RuntimeError,"pyext - _bind: instance not associated with pd object");
+ return NULL;
+ }
const t_symbol *recv = pyObject_AsSymbol(name);
@@ -130,12 +133,15 @@ PyObject *pyext::pyext_unbind(PyObject *,PyObject *args)
PyObject *self,*meth,*name;
if(!PyArg_ParseTuple(args, "OOO:pyext_bind", &self,&name,&meth)) // borrowed references
post("py/pyext - Wrong arguments!");
- else if(!PyInstance_Check(self) || !(PyMethod_Check(meth) || PyFunction_Check(meth))) {
+ else if(!PyInstance_Check(self) || !PyCallable_Check(meth)) {
post("py/pyext - Wrong argument types!");
}
else {
pyext *th = GetThis(self);
- FLEXT_ASSERT(th);
+ if(!th) {
+ PyErr_SetString(PyExc_RuntimeError,"pyext - _unbind: instance not associated with pd object");
+ return NULL;
+ }
const t_symbol *recv = pyObject_AsSymbol(name);
@@ -175,7 +181,7 @@ void pyext::ClearBinding()
if(!pyobj) return;
pyext *th = GetThis(pyobj);
- FLEXT_ASSERT(th);
+ if(!th) return;
void *data = NULL;
const t_symbol *sym = NULL;
diff --git a/externals/grill/py/source/clmeth.cpp b/externals/grill/py/source/clmeth.cpp
index 30474eff..c8d38f81 100644
--- a/externals/grill/py/source/clmeth.cpp
+++ b/externals/grill/py/source/clmeth.cpp
@@ -17,6 +17,7 @@ PyMethodDef pyext::meth_tbl[] =
{"__init__", pyext::pyext__init__, METH_VARARGS, "Constructor"},
{"__del__", pyext::pyext__del__, METH_VARARGS, "Destructor"},
*/
+ {"__str__", pyext::pyext__str__, METH_VARARGS, "stringify"},
{"_outlet", pyext::pyext_outlet, METH_VARARGS,"Send message to outlet"},
#if FLEXT_SYS == FLEXT_SYS_PD
{"_tocanvas", pyext::pyext_tocanvas, METH_VARARGS,"Send message to canvas" },
@@ -28,8 +29,6 @@ PyMethodDef pyext::meth_tbl[] =
{ "_detach", pyext::pyext_detach, METH_VARARGS,"Set detach flag for called methods" },
{ "_stop", pyext::pyext_stop, METH_VARARGS,"Stop running threads" },
#endif
- { "_isthreaded", pyext::pyext_isthreaded, METH_O,"Query whether threading is enabled" },
-
{ "_invec", pyext::pyext_invec, METH_VARARGS,"Get input vector" },
{ "_outvec", pyext::pyext_outvec, METH_VARARGS,"Get output vector" },
{NULL, NULL, 0, NULL} /* Sentinel */
@@ -53,11 +52,12 @@ const char *pyext::pyext_doc =
#endif
"_bind(self,name,func): Bind a python function to a symbol\n"
"_unbind(self,name,func): Unbind a python function from a symbol\n"
+ "_isthreaded: Query whether threading is enabled\n"
#ifdef FLEXT_THREADS
"_detach(self,int): Define whether a called Python method has its own thread\n"
"_stop(self): Stop running threads\n"
+ "_shouldexit: Query whether threads should terminate\n"
#endif
- "_isthreaded(self): Query whether threading is enabled\n"
;
/*
@@ -78,10 +78,22 @@ PyObject* pyext::pyext__del__(PyObject *,PyObject *args)
}
*/
+PyObject* pyext::pyext__str__(PyObject *,PyObject *args)
+{
+ PyObject *self;
+ if(!PyArg_ParseTuple(args, "O:pyext__str__",&self)) {
+ // handle error
+ ERRINTERNAL();
+ return NULL;
+ }
+
+ return PyString_FromFormat("<pyext object %p>",self);
+}
+
PyObject* pyext::pyext_setattr(PyObject *,PyObject *args)
{
PyObject *self,*name,*val;
- if(!PyArg_ParseTuple(args, "OOO:test_foo", &self,&name,&val)) {
+ if(!PyArg_ParseTuple(args, "OOO:pyext_setattr", &self,&name,&val)) {
// handle error
ERRINTERNAL();
return NULL;
@@ -111,28 +123,38 @@ PyObject* pyext::pyext_setattr(PyObject *,PyObject *args)
PyObject* pyext::pyext_getattr(PyObject *,PyObject *args)
{
PyObject *self,*name,*ret = NULL;
- if(!PyArg_ParseTuple(args, "OO:test_foo", &self,&name)) {
+ if(!PyArg_ParseTuple(args, "OO:pyext_getattr", &self,&name)) {
// handle error
ERRINTERNAL();
}
-#ifdef FLEXT_THREADS
if(PyString_Check(name)) {
char* sname = PyString_AS_STRING(name);
if(sname) {
+#ifdef FLEXT_THREADS
if(!strcmp(sname,"_shouldexit")) {
pyext *ext = GetThis(self);
if(ext)
ret = PyLong_FromLong(ext->shouldexit?1:0);
else {
+ // return true for _shouldexit if association has been removed
Py_INCREF(Py_True);
ret = Py_True;
}
}
-// post("pyext::getattr %s",sname);
+ else
+#endif
+ if(!strcmp(sname,"_isthreaded")) {
+ #ifdef FLEXT_THREADS
+ Py_INCREF(Py_True);
+ ret = Py_True;
+ #else
+ Py_INCREF(Py_False);
+ ret = Py_False;
+ #endif
+ }
}
}
-#endif
if(!ret) {
#if PY_VERSION_HEX >= 0x02020000
@@ -165,7 +187,10 @@ PyObject *pyext::pyext_outlet(PyObject *,PyObject *args)
(outl = PyTuple_GET_ITEM(args,1)) != NULL && PyInt_Check(outl)
) {
pyext *ext = GetThis(self);
- FLEXT_ASSERT(ext);
+ if(!ext) {
+ PyErr_SetString(PyExc_RuntimeError,"pyext - _outlet: instance not associated with pd object");
+ return NULL;
+ }
PyObject *val;
#if 0
@@ -230,7 +255,11 @@ PyObject *pyext::pyext_detach(PyObject *,PyObject *args)
}
else {
pyext *ext = GetThis(self);
- FLEXT_ASSERT(ext);
+ if(!ext) {
+ PyErr_SetString(PyExc_RuntimeError,"pyext - _detach: instance not associated with pd object");
+ return NULL;
+ }
+
ext->detach = val;
}
@@ -254,7 +283,11 @@ PyObject *pyext::pyext_stop(PyObject *,PyObject *args)
}
else {
pyext *ext = GetThis(self);
- FLEXT_ASSERT(ext);
+ if(!ext) {
+ PyErr_SetString(PyExc_RuntimeError,"pyext - _stop: instance not associated with pd object");
+ return NULL;
+ }
+
int cnt;
t_atom at;
if(val >= 0) cnt = 1,flext::SetInt(at,val);
@@ -268,17 +301,6 @@ PyObject *pyext::pyext_stop(PyObject *,PyObject *args)
#endif
-//! Query whether threading is enabled
-PyObject *pyext::pyext_isthreaded(PyObject *,PyObject *)
-{
- return PyInt_FromLong(
-#ifdef FLEXT_THREADED
- 1
-#else
- 0
-#endif
- );
-}
#if FLEXT_SYS == FLEXT_SYS_PD
//! Send message to canvas
@@ -295,7 +317,11 @@ PyObject *pyext::pyext_tocanvas(PyObject *,PyObject *args)
(self = PyTuple_GET_ITEM(args,0)) != NULL && PyInstance_Check(self)
) {
pyext *ext = GetThis(self);
- FLEXT_ASSERT(ext);
+ if(!ext) {
+ PyErr_SetString(PyExc_RuntimeError,"pyext - _tocanvas: instance not associated with pd object");
+ return NULL;
+ }
+
PyObject *val;
bool tp =
@@ -310,10 +336,13 @@ PyObject *pyext::pyext_tocanvas(PyObject *,PyObject *args)
flext::AtomListStatic<16> lst;
const t_symbol *sym = GetPyArgs(lst,val);
if(sym) {
- t_glist *gl = ext->thisCanvas(); //canvas_getcurrent();
- t_class **cl = (t_pd *)gl;
- if(cl)
- pd_forwardmess(cl,lst.Count(),lst.Atoms());
+ t_glist *gl = ext->thisCanvas();
+ if(gl) {
+ // \TODO find a flext-based non-locking method
+ sys_lock();
+ pd_forwardmess((t_class **)gl,lst.Count(),lst.Atoms());
+ sys_unlock();
+ }
#ifdef FLEXT_DEBUG
else
post("pyext - no parent canvas?!");
@@ -351,9 +380,14 @@ PyObject *pyext::pyext_invec(PyObject *,PyObject *args)
}
else {
pyext *ext = GetThis(self);
- FLEXT_ASSERT(ext);
- PyObject *b = ext->GetSig(val,true);
- if(b) return b;
+ if(ext) {
+ PyObject *b = ext->GetSig(val,true);
+ if(b) return b;
+ }
+ else {
+ PyErr_SetString(PyExc_RuntimeError,"pyext - _invec: instance not associated with pd object");
+ return NULL;
+ }
}
Py_INCREF(Py_None);
@@ -375,9 +409,14 @@ PyObject *pyext::pyext_outvec(PyObject *,PyObject *args)
}
else {
pyext *ext = GetThis(self);
- FLEXT_ASSERT(ext);
- PyObject *b = ext->GetSig(val,false);
- if(b) return b;
+ if(ext) {
+ PyObject *b = ext->GetSig(val,false);
+ if(b) return b;
+ }
+ else {
+ PyErr_SetString(PyExc_RuntimeError,"pyext - _outvec: instance not associated with pd object");
+ return NULL;
+ }
}
Py_INCREF(Py_None);
diff --git a/externals/grill/py/source/pybase.cpp b/externals/grill/py/source/pybase.cpp
index b7a112e9..09fd8687 100644
--- a/externals/grill/py/source/pybase.cpp
+++ b/externals/grill/py/source/pybase.cpp
@@ -101,7 +101,10 @@ void pybase::lib_setup()
Py_Initialize();
#ifdef FLEXT_DEBUG
+ Py_DebugFlag = 1;
// Py_VerboseFlag = 1;
+#else
+ Py_OptimizeFlag = 1;
#endif
#ifdef FLEXT_THREADS
diff --git a/externals/grill/py/source/pyext.h b/externals/grill/py/source/pyext.h
index 4a4e79f1..672fe5f1 100644
--- a/externals/grill/py/source/pyext.h
+++ b/externals/grill/py/source/pyext.h
@@ -22,9 +22,7 @@ class pyext
public:
pyext(int argc,const t_atom *argv,bool sig = false);
- static PyObject *pyext__doc__(PyObject *,PyObject *args);
- static PyObject *pyext__init__(PyObject *,PyObject *args);
- static PyObject *pyext__del__(PyObject *,PyObject *args);
+ static PyObject *pyext__str__(PyObject *,PyObject *args);
static PyObject *pyext_outlet(PyObject *,PyObject *args);
#if FLEXT_SYS == FLEXT_SYS_PD