aboutsummaryrefslogtreecommitdiff
path: root/externals/grill/py/source
diff options
context:
space:
mode:
authorThomas Grill <xovo@users.sourceforge.net>2004-06-21 14:08:57 +0000
committerThomas Grill <xovo@users.sourceforge.net>2004-06-21 14:08:57 +0000
commite728a5bc3db296b4b67c2d3e5b56558c42c566a8 (patch)
tree180656eeb13352bc2cee7fb759e2ff74332069d2 /externals/grill/py/source
parentcefab503b7db648244a4244ef255d15609e2c205 (diff)
""
svn path=/trunk/; revision=1826
Diffstat (limited to 'externals/grill/py/source')
-rw-r--r--externals/grill/py/source/bound.cpp10
-rw-r--r--externals/grill/py/source/clmeth.cpp4
-rw-r--r--externals/grill/py/source/main.cpp159
-rw-r--r--externals/grill/py/source/main.h26
-rw-r--r--externals/grill/py/source/modmeth.cpp10
-rw-r--r--externals/grill/py/source/py.cpp4
-rw-r--r--externals/grill/py/source/pyargs.cpp12
-rw-r--r--externals/grill/py/source/pyext.cpp115
-rw-r--r--externals/grill/py/source/pyext.h5
9 files changed, 164 insertions, 181 deletions
diff --git a/externals/grill/py/source/bound.cpp b/externals/grill/py/source/bound.cpp
index 928d7b67..9578e4c0 100644
--- a/externals/grill/py/source/bound.cpp
+++ b/externals/grill/py/source/bound.cpp
@@ -13,10 +13,12 @@ WARRANTIES, see the file, "license.txt," in this distribution.
#include <set>
+typedef std::set<PyObject *> FuncSet;
+
struct bounddata
{
PyObject *self;
- std::set<PyObject *> funcs;
+ FuncSet funcs;
};
bool pyext::boundmeth(flext_base *,t_symbol *sym,int argc,t_atom *argv,void *data)
@@ -25,10 +27,10 @@ bool pyext::boundmeth(flext_base *,t_symbol *sym,int argc,t_atom *argv,void *dat
PY_LOCK
- PyObject *args = MakePyArgs(sym,AtomList(argc,argv),-1,obj->self != NULL);
+ PyObject *args = MakePyArgs(sym,argc,argv,-1,obj->self != NULL);
// call all functions bound by this symbol
- for(std::set<PyObject *>::iterator it = obj->funcs.begin(); it != obj->funcs.end(); ++it) {
+ for(FuncSet::iterator it = obj->funcs.begin(); it != obj->funcs.end(); ++it) {
PyObject *ret = PyObject_CallObject(*it,args);
if(!ret) {
PyErr_Print();
@@ -135,7 +137,7 @@ V pyext::ClearBinding()
while(GetThis(pyobj)->UnbindMethod(sym,NULL,&data)) {
bounddata *bdt = (bounddata *)data;
if(bdt) {
- for(std::set<PyObject *>::iterator it = bdt->funcs.begin(); it != bdt->funcs.end(); ++it) {
+ for(FuncSet::iterator it = bdt->funcs.begin(); it != bdt->funcs.end(); ++it) {
PyObject *func = *it;
if(PyMethod_Check(func)) Py_DECREF(func);
}
diff --git a/externals/grill/py/source/clmeth.cpp b/externals/grill/py/source/clmeth.cpp
index a17c010a..d3b909ff 100644
--- a/externals/grill/py/source/clmeth.cpp
+++ b/externals/grill/py/source/clmeth.cpp
@@ -161,8 +161,10 @@ PyObject *pyext::pyext_outlet(PyObject *,PyObject *args)
// deadlock would occur if this was another py/pyext object!
if(lst->Count() && IsSymbol((*lst)[0]))
ext->ToQueueAnything(o-1,GetSymbol((*lst)[0]),lst->Count()-1,lst->Atoms()+1);
+// ext->ToOutAnything(o-1,GetSymbol((*lst)[0]),lst->Count()-1,lst->Atoms()+1);
else
ext->ToQueueList(o-1,*lst);
+// ext->ToOutList(o-1,*lst);
}
else
post("pyext: outlet index out of range");
@@ -230,7 +232,7 @@ PyObject *pyext::pyext_stop(PyObject *,PyObject *args)
//! Query whether threading is enabled
PyObject *pyext::pyext_isthreaded(PyObject *,PyObject *)
{
- return Py_BuildValue("i",
+ return PyInt_FromLong(
#ifdef FLEXT_THREADED
1
#else
diff --git a/externals/grill/py/source/main.cpp b/externals/grill/py/source/main.cpp
index e552bc5a..0434f682 100644
--- a/externals/grill/py/source/main.cpp
+++ b/externals/grill/py/source/main.cpp
@@ -10,82 +10,83 @@ WARRANTIES, see the file, "license.txt," in this distribution.
#include "main.h"
+
+static PyMethodDef StdOut_Methods[] =
+{
+ { "write", py::StdOut_Write, 1 },
+ { NULL, NULL, }
+};
+
V py::lib_setup()
{
post("");
post("py/pyext %s - python script objects, (C)2002-2004 Thomas Grill",PY__VERSION);
post("");
+ // -------------------------------------------------------------
+
+ Py_Initialize();
+
+#if 0 //def FLEXT_DEBUG
+ Py_DebugFlag = 1;
+ Py_VerboseFlag = 1;
+#endif
+
+#ifdef FLEXT_THREADS
+ // enable thread support and acquire the global thread lock
+ PyEval_InitThreads();
+
+ // get thread state
+ pythrmain = PyThreadState_Get();
+ // get main interpreter state
+ pystate = pythrmain->interp;
+
+ // add thread state of main thread to map
+ pythrmap[GetThreadId()] = pythrmain;
+#endif
+
+ // register/initialize pyext module only once!
+ module_obj = Py_InitModule(PYEXT_MODULE, func_tbl);
+ module_dict = PyModule_GetDict(module_obj); // borrowed reference
+
+ PyModule_AddStringConstant(module_obj,"__doc__",(C *)py_doc);
+
+ // redirect stdout
+ PyObject* py_out = Py_InitModule("stdout", StdOut_Methods);
+ PySys_SetObject("stdout", py_out);
+
+#ifdef FLEXT_THREADS
+ // release global lock
+ PyEval_ReleaseLock();
+#endif
+
+ // -------------------------------------------------------------
+
FLEXT_SETUP(pyobj);
FLEXT_SETUP(pyext);
-
- pyref = 0;
}
FLEXT_LIB_SETUP(py,py::lib_setup)
-PyInterpreterState *py::pystate = NULL;
#ifdef FLEXT_THREADS
-std::map<flext::thrid_t,PyThreadState *> py::pythrmap;
+PyInterpreterState *py::pystate = NULL;
+PyThreadState *py::pythrmain = NULL;
+PyThrMap py::pythrmap;
#endif
-I py::pyref = 0;
PyObject *py::module_obj = NULL;
PyObject *py::module_dict = NULL;
-static PyMethodDef StdOut_Methods[] =
-{
- { "write", py::StdOut_Write, 1 },
- { NULL, NULL, }
-};
-
-
py::py():
module(NULL),
detach(false),shouldexit(false),thrcount(0),
stoptick(0)
{
- Lock();
-
- if(!(pyref++)) {
- Py_Initialize();
-
- #ifdef FLEXT_THREADS
- // enable thread support and acquire the global thread lock
- PyEval_InitThreads();
-
- // get thread state
- PyThreadState *pythrmain = PyThreadState_Get();
- // get main interpreter state
- pystate = pythrmain->interp;
-
- // release global lock
- PyEval_ReleaseLock();
-
- // add thread state of main thread to map
- pythrmap[GetThreadId()] = pythrmain;
- #endif
-
- // register/initialize pyext module only once!
- module_obj = Py_InitModule(PYEXT_MODULE, func_tbl);
- module_dict = PyModule_GetDict(module_obj);
-
- PyModule_AddStringConstant(module_obj,"__doc__",(C *)py_doc);
-
- // redirect stdout
- PyObject* py_out = Py_InitModule("stdout", StdOut_Methods);
- PySys_SetObject("stdout", py_out);
- }
- else {
- PY_LOCK
- Py_INCREF(module_obj);
- Py_INCREF(module_dict);
- PY_UNLOCK
- }
-
- Unlock();
+ PY_LOCK
+ Py_INCREF(module_obj);
+ PY_UNLOCK
FLEXT_ADDTIMER(stoptmr,tick);
}
@@ -104,38 +105,7 @@ py::~py()
post("%s - Okay, all threads have terminated",thisName());
}
- Lock();
-
- if(!(--pyref)) {
- // no more py/pyext objects left... shut down Python
-
- module_obj = NULL;
- module_dict = NULL;
-
- Py_XDECREF(module);
-
- PyEval_AcquireLock();
-
-#ifdef FLEXT_THREADS
- PyThreadState_Swap(pythrmap[GetThreadId()]);
-#endif
-
-#if 0 //def FLEXT_DEBUG
- // need not necessarily do that....
- Py_Finalize();
-#endif
-
-#ifdef FLEXT_THREADS
- // reset thread state map
- pythrmap.clear();
-#endif
- }
- else {
- Py_DECREF(module_obj);
- Py_DECREF(module_dict);
- }
-
- Unlock();
+ Py_XDECREF(module_obj);
}
@@ -229,16 +199,31 @@ V py::ImportModule(const C *name)
{
if(!name) return;
- module = PyImport_ImportModule((C *)name);
+ module = PyImport_ImportModule((C *)name); // increases module_obj ref count by one
if (!module) {
+
PyErr_Print();
dict = NULL;
}
else
- dict = PyModule_GetDict(module); // borrowed
-
+ dict = PyModule_GetDict(module);
}
+V py::UnimportModule()
+{
+ if(!module) return;
+
+ assert(dict && module_obj && module_dict);
+
+ Py_DECREF(module);
+
+ // reference count to module is not 0 here, altough probably the last instance was unloaded
+ // Python retains one reference to the module all the time
+ // we don't care
+
+ module = NULL;
+ dict = NULL;
+}
V py::ReloadModule()
{
@@ -262,7 +247,7 @@ V py::ReloadModule()
V py::GetModulePath(const C *mod,C *dir,I len)
{
#if FLEXT_SYS == FLEXT_SYS_PD
- // uarghh... pd doesn't show it's path for extra modules
+ // uarghh... pd doesn't show its path for extra modules
C *name;
I fd = open_via_path("",mod,".py",dir,&name,len,0);
diff --git a/externals/grill/py/source/main.h b/externals/grill/py/source/main.h
index d6ca52cb..2e8419d3 100644
--- a/externals/grill/py/source/main.h
+++ b/externals/grill/py/source/main.h
@@ -50,6 +50,8 @@ WARRANTIES, see the file, "license.txt," in this distribution.
#include "main.h"
+typedef std::map<flext::thrid_t,PyThreadState *> PyThrMap;
+
class py:
public flext_base
{
@@ -60,7 +62,7 @@ public:
~py();
static V lib_setup();
- static PyObject *MakePyArgs(const t_symbol *s,const AtomList &args,I inlet = -1,BL withself = false);
+ static PyObject *MakePyArgs(const t_symbol *s,int argc,const t_atom *argv,I inlet = -1,BL withself = false);
static AtomList *GetPyArgs(PyObject *pValue,PyObject **self = NULL);
protected:
@@ -74,7 +76,6 @@ protected:
PyObject *module,*dict; // inherited user class module and associated dictionary
- static I pyref;
static const C *py_doc;
V GetDir(PyObject *obj,AtomList &lst);
@@ -83,6 +84,7 @@ protected:
V AddToPath(const C *dir);
V SetArgs(I argc,const t_atom *argv);
V ImportModule(const C *name);
+ V UnimportModule();
V ReloadModule();
V Register(const C *reg);
@@ -124,16 +126,17 @@ protected:
V tick(V *);
public:
- static PyInterpreterState *pystate;
#ifdef FLEXT_THREADS
- static std::map<flext::thrid_t,PyThreadState *> pythrmap;
+ static PyInterpreterState *pystate;
+ static PyThreadState *pythrmain;
+ static PyThrMap pythrmap;
ThrMutex mutex;
- V Lock() { mutex.Unlock(); }
- V Unlock() { mutex.Unlock(); }
+ inline V Lock() { mutex.Unlock(); }
+ inline V Unlock() { mutex.Unlock(); }
#else
- V Lock() {}
- V Unlock() {}
+ inline V Lock() {}
+ inline V Unlock() {}
#endif
static PyObject* StdOut_Write(PyObject* Self, PyObject* Args);
@@ -152,11 +155,14 @@ protected:
#ifdef FLEXT_THREADS
+// if thread is not found in the thread map, the state of the system thread is used
+// we have yet to see if this has bad side-effects
+
#define PY_LOCK \
{ \
PyEval_AcquireLock(); \
- PyThreadState *__st = pythrmap[GetThreadId()]; \
- FLEXT_ASSERT(__st != NULL); \
+ PyThrMap::iterator it = pythrmap.find(GetThreadId()); \
+ PyThreadState *__st = it != pythrmap.end()?it->second:pythrmain; \
PyThreadState *__oldst = PyThreadState_Swap(__st);
#define PY_UNLOCK \
diff --git a/externals/grill/py/source/modmeth.cpp b/externals/grill/py/source/modmeth.cpp
index f7dae309..b3a98c98 100644
--- a/externals/grill/py/source/modmeth.cpp
+++ b/externals/grill/py/source/modmeth.cpp
@@ -142,11 +142,15 @@ PyObject *py::py_send(PyObject *,PyObject *args)
AtomList *lst = GetPyArgs(val);
if(lst) {
- if(!Forward(recv,*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
+ if(!ok)
post("py/pyext - Receiver doesn't exist");
-#else
- {}
#endif
}
else
diff --git a/externals/grill/py/source/py.cpp b/externals/grill/py/source/py.cpp
index e7524ce1..8b14a485 100644
--- a/externals/grill/py/source/py.cpp
+++ b/externals/grill/py/source/py.cpp
@@ -2,7 +2,7 @@
py/pyext - python script object for PD and Max/MSP
-Copyright (c) 2002-2004 Thomas Grill (xovo@gmx.net)
+Copyright (c)2002-2004 Thomas Grill (xovo@gmx.net)
For information on usage and redistribution, and for a DISCLAIMER OF ALL
WARRANTIES, see the file, "license.txt," in this distribution.
@@ -297,7 +297,7 @@ BL pyobj::work(const t_symbol *s,I argc,const t_atom *argv)
PY_LOCK
if(function) {
- PyObject *pArgs = MakePyArgs(s,AtomList(argc,argv));
+ PyObject *pArgs = MakePyArgs(s,argc,argv);
PyObject *pValue = PyObject_CallObject(function, pArgs);
rargs = GetPyArgs(pValue);
diff --git a/externals/grill/py/source/pyargs.cpp b/externals/grill/py/source/pyargs.cpp
index 8fe68cbd..1b204273 100644
--- a/externals/grill/py/source/pyargs.cpp
+++ b/externals/grill/py/source/pyargs.cpp
@@ -27,7 +27,7 @@ static PyObject *MakePyAtom(const t_atom &at)
return NULL;
}
-PyObject *py::MakePyArgs(const t_symbol *s,const AtomList &args,I inlet,BL withself)
+PyObject *py::MakePyArgs(const t_symbol *s,int argc,const t_atom *argv,I inlet,BL withself)
{
PyObject *pArgs;
@@ -41,7 +41,7 @@ PyObject *py::MakePyArgs(const t_symbol *s,const AtomList &args,I inlet,BL withs
*/
{
BL any = IsAnything(s);
- pArgs = PyTuple_New(args.Count()+(any?1:0)+(inlet >= 0?1:0));
+ pArgs = PyTuple_New(argc+(any?1:0)+(inlet >= 0?1:0));
I pix = 0;
@@ -54,8 +54,8 @@ PyObject *py::MakePyArgs(const t_symbol *s,const AtomList &args,I inlet,BL withs
I ix;
PyObject *tmp;
- if(!withself || args.Count() < (any?1:2)) tmp = pArgs,ix = pix;
- else tmp = PyTuple_New(args.Count()+(any?1:0)),ix = 0;
+ if(!withself || argc < (any?1:2)) tmp = pArgs,ix = pix;
+ else tmp = PyTuple_New(argc+(any?1:0)),ix = 0;
if(any) {
PyObject *pValue = PyString_FromString(GetString(s));
@@ -64,8 +64,8 @@ PyObject *py::MakePyArgs(const t_symbol *s,const AtomList &args,I inlet,BL withs
PyTuple_SetItem(tmp, ix++, pValue);
}
- for(I i = 0; i < args.Count(); ++i) {
- PyObject *pValue = MakePyAtom(args[i]);
+ for(I i = 0; i < argc; ++i) {
+ PyObject *pValue = MakePyAtom(argv[i]);
if(!pValue) {
post("py/pyext: cannot convert argument %i",any?i+1:i);
continue;
diff --git a/externals/grill/py/source/pyext.cpp b/externals/grill/py/source/pyext.cpp
index 7dd4d805..66428054 100644
--- a/externals/grill/py/source/pyext.cpp
+++ b/externals/grill/py/source/pyext.cpp
@@ -34,6 +34,43 @@ V pyext::Setup(t_classid c)
FLEXT_CADDMETHOD_(c,0,"set",m_set);
FLEXT_CADDATTR_VAR1(c,"respond",respond);
+
+
+ // ----------------------------------------------------
+
+ // register/initialize pyext base class along with module
+ class_dict = PyDict_New();
+ PyObject *className = PyString_FromString(PYEXT_CLASS);
+ PyMethodDef *def;
+
+ // add setattr/getattr to class
+ for(def = attr_tbl; def->ml_name; def++) {
+ PyObject *func = PyCFunction_New(def, NULL);
+ PyDict_SetItemString(class_dict, def->ml_name, func);
+ Py_DECREF(func);
+ }
+
+ class_obj = PyClass_New(NULL, class_dict, className);
+ Py_DECREF(className);
+
+ // add methods to class
+ for (def = meth_tbl; def->ml_name != NULL; def++) {
+ PyObject *func = PyCFunction_New(def, NULL);
+ PyObject *method = PyMethod_New(func, NULL, class_obj); // increases class_obj ref count by 1
+ PyDict_SetItemString(class_dict, def->ml_name, method);
+ Py_DECREF(func);
+ Py_DECREF(method);
+ }
+
+#if PY_VERSION_HEX >= 0x02020000
+ // not absolutely necessary, existent in python 2.2 upwards
+ // make pyext functions available in class scope
+ PyDict_Merge(class_dict,module_dict,0);
+#endif
+ // after merge so that it's not in class_dict as well...
+ PyDict_SetItemString(module_dict, PYEXT_CLASS,class_obj); // increases class_obj ref count by 1
+
+ PyDict_SetItemString(class_dict,"__doc__",PyString_FromString(pyext_doc));
}
pyext *pyext::GetThis(PyObject *self)
@@ -60,7 +97,6 @@ static short patcher_myvol(t_patcher *x)
#endif
-I pyext::pyextref = 0;
PyObject *pyext::class_obj = NULL;
PyObject *pyext::class_dict = NULL;
@@ -71,53 +107,14 @@ pyext::pyext(I argc,const t_atom *argv):
{
int apre = 0;
- PY_LOCK
-
- if(!pyextref++) {
- // register/initialize pyext base class along with module
- class_dict = PyDict_New();
- PyObject *className = PyString_FromString(PYEXT_CLASS);
- PyMethodDef *def;
-
- // add setattr/getattr to class
- for(def = attr_tbl; def->ml_name; def++) {
- PyObject *func = PyCFunction_New(def, NULL);
- PyDict_SetItemString(class_dict, def->ml_name, func);
- Py_DECREF(func);
- }
-
- class_obj = PyClass_New(NULL, class_dict, className);
- PyDict_SetItemString(module_dict, PYEXT_CLASS,class_obj);
- Py_DECREF(className);
-
- // add methods to class
- for (def = meth_tbl; def->ml_name != NULL; def++) {
- PyObject *func = PyCFunction_New(def, NULL);
- PyObject *method = PyMethod_New(func, NULL, class_obj);
- PyDict_SetItemString(class_dict, def->ml_name, method);
- Py_DECREF(func);
- Py_DECREF(method);
- }
-
-#if PY_VERSION_HEX >= 0x02020000
- // not absolutely necessary, existent in python 2.2 upwards
- // make pyext functions available in class scope
- PyDict_Merge(class_dict,module_dict,0);
-#endif
-
- PyDict_SetItemString(class_dict,"__doc__",PyString_FromString(pyext_doc));
- }
- else {
- Py_INCREF(class_obj);
- Py_INCREF(class_dict);
- }
-
if(argc >= apre+2 && CanbeInt(argv[apre]) && CanbeInt(argv[apre+1])) {
inlets = GetAInt(argv[apre]);
outlets = GetAInt(argv[apre+1]);
apre += 2;
}
+ PY_LOCK
+
// init script module
if(argc > apre) {
char dir[1024];
@@ -151,7 +148,7 @@ pyext::pyext(I argc,const t_atom *argv):
++apre;
}
- Register("_pyext");
+ Register("_pyext");
// t_symbol *sobj = NULL;
if(argc > apre) {
@@ -168,7 +165,7 @@ pyext::pyext(I argc,const t_atom *argv):
if(argc > apre) args(argc-apre,argv+apre);
if(methname) {
- SetClssMeth();
+ MakeInstance();
if(inlets < 0 && outlets < 0) {
// now get number of inlets and outlets
@@ -222,22 +219,15 @@ pyext::~pyext()
PY_LOCK
ClearBinding();
-
Unregister("_pyext");
+ UnimportModule();
- Py_XDECREF(pyobj);
- Py_XDECREF(class_obj);
- Py_XDECREF(class_dict);
-
- if(!--pyextref) {
- class_obj = NULL;
- class_dict = NULL;
- }
+ Py_XDECREF(pyobj); // opposite of SetClssMeth
PY_UNLOCK
}
-BL pyext::SetClssMeth() //I argc,t_atom *argv)
+BL pyext::MakeInstance()
{
// pyobj should already have been decref'd / cleared before getting here!!
@@ -250,7 +240,6 @@ BL pyext::SetClssMeth() //I argc,t_atom *argv)
// make instance, but don't call __init__
pyobj = PyInstance_NewRaw(pref,NULL);
- Py_DECREF(pref);
if(pyobj == NULL)
PyErr_Print();
else {
@@ -260,8 +249,9 @@ BL pyext::SetClssMeth() //I argc,t_atom *argv)
// call init now, after _this has been set, which is
// important for eventual callbacks from __init__ to c
- PyObject *pargs = MakePyArgs(NULL,args,-1,true);
- if (pargs == NULL) PyErr_Print();
+ PyObject *pargs = MakePyArgs(NULL,args.Count(),args.Atoms(),-1,true);
+ if (pargs == NULL)
+ PyErr_Print();
PyObject *init;
init = PyObject_GetAttrString(pyobj,"__init__"); // get ref
@@ -300,7 +290,7 @@ V pyext::Reload()
SetArgs(0,NULL);
ReloadModule();
- SetClssMeth();
+ MakeInstance();
}
@@ -367,7 +357,7 @@ void pyext::m_set(int argc,const t_atom *argv)
post("%s - set: Python variable %s not found",thisName(),ch);
}
else {
- PyObject *pval = MakePyArgs(NULL,AtomList(argc-1,argv+1),-1,false);
+ PyObject *pval = MakePyArgs(NULL,argc-1,argv+1,-1,false);
if(!pval)
PyErr_Print();
@@ -438,17 +428,13 @@ PyObject *pyext::call(const C *meth,I inlet,const t_symbol *s,I argc,const t_ato
PyErr_Clear(); // no method found
}
else {
- PyObject *pargs = MakePyArgs(s,AtomList(argc,argv),inlet?inlet:-1,true);
+ PyObject *pargs = MakePyArgs(s,argc,argv,inlet?inlet:-1,true);
if(!pargs)
PyErr_Print();
else {
ret = PyEval_CallObject(pmeth, pargs);
if (ret == NULL) // function not found resp. arguments not matching
-#ifdef FLEXT_DEBUG
PyErr_Print();
-#else
- PyErr_Clear();
-#endif
Py_DECREF(pargs);
}
@@ -470,7 +456,6 @@ V pyext::work_wrapper(V *data)
// --- make new Python thread ---
// get the global lock
PyEval_AcquireLock();
- // get a reference to the PyInterpreterState
// create a thread state object for this thread
PyThreadState *newthr = PyThreadState_New(pystate);
// free the lock
diff --git a/externals/grill/py/source/pyext.h b/externals/grill/py/source/pyext.h
index 976ef0a6..d05ea7e5 100644
--- a/externals/grill/py/source/pyext.h
+++ b/externals/grill/py/source/pyext.h
@@ -51,7 +51,7 @@ protected:
V ms_args(const AtomList &a) { m_reload_(a.Count(),a.Atoms()); }
V m_dir_() { m__dir(pyobj); }
V mg_dir_(AtomList &lst) { GetDir(pyobj,lst); }
- V m_doc_() { m__doc(pyobj); }
+ V m_doc_() { m__doc(((PyInstanceObject *)pyobj)->in_class->cl_dict); }
virtual V m_help();
V m_get(const t_symbol *s);
@@ -66,13 +66,12 @@ private:
static pyext *GetThis(PyObject *self);
V ClearBinding();
- BL SetClssMeth(); //I argc,t_atom *argv);
+ BL MakeInstance();
AtomList args;
virtual V Reload();
- static I pyextref;
static PyObject *class_obj,*class_dict;
static PyMethodDef attr_tbl[],meth_tbl[];
static const C *pyext_doc;