aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorThomas Grill <xovo@users.sourceforge.net>2005-09-21 10:52:33 +0000
committerThomas Grill <xovo@users.sourceforge.net>2005-09-21 10:52:33 +0000
commit2b91966061ead3c4aa260033e95cfc4adb396496 (patch)
treecd8b0d9196dd9f49a389427ad56349d22bde2476
parent45da6684cbe9bd2fe199b0fd75a40f1c219b6341 (diff)
__str__ method for pyext, to enable print self calls
python-like dotted module.function syntax multiply inlets for py (hot and cold inlets) enable symbol binding for all callables (not only functions and methods) enable optimization of Python code in reease build _isthreaded is now a data member instead of a method compiler flag to exclude DSP objects some ASSERTs for explicitly created pyext classes (should be runtime checks i guess) cleaned up float vs. int pyext tags more safety for calls where association python-pd has already been removed open editor for module file on "edit" message (or click) let _inlets and _outlets default to 0 svn path=/trunk/; revision=3610
-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