Update of /cvsroot/pure-data/externals/grill/py/source In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv27303/source
Modified Files: bound.cpp clmeth.cpp main.cpp main.h modmeth.cpp py.cpp pyargs.cpp pyext.cpp pyext.h Log Message: ""
Index: clmeth.cpp =================================================================== RCS file: /cvsroot/pure-data/externals/grill/py/source/clmeth.cpp,v retrieving revision 1.7 retrieving revision 1.8 diff -C2 -d -r1.7 -r1.8 *** clmeth.cpp 26 Mar 2004 03:27:49 -0000 1.7 --- clmeth.cpp 21 Jun 2004 14:04:15 -0000 1.8 *************** *** 162,167 **** --- 162,169 ---- 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 *************** *** 231,235 **** PyObject *pyext::pyext_isthreaded(PyObject *,PyObject *) { ! return Py_BuildValue("i", #ifdef FLEXT_THREADED 1 --- 233,237 ---- PyObject *pyext::pyext_isthreaded(PyObject *,PyObject *) { ! return PyInt_FromLong( #ifdef FLEXT_THREADED 1
Index: pyargs.cpp =================================================================== RCS file: /cvsroot/pure-data/externals/grill/py/source/pyargs.cpp,v retrieving revision 1.5 retrieving revision 1.6 diff -C2 -d -r1.5 -r1.6 *** pyargs.cpp 14 Jan 2004 03:38:02 -0000 1.5 --- pyargs.cpp 21 Jun 2004 14:04:15 -0000 1.6 *************** *** 28,32 **** }
! PyObject *py::MakePyArgs(const t_symbol *s,const AtomList &args,I inlet,BL withself) { PyObject *pArgs; --- 28,32 ---- }
! PyObject *py::MakePyArgs(const t_symbol *s,int argc,const t_atom *argv,I inlet,BL withself) { PyObject *pArgs; *************** *** 42,46 **** { BL any = IsAnything(s); ! pArgs = PyTuple_New(args.Count()+(any?1:0)+(inlet >= 0?1:0));
I pix = 0; --- 42,46 ---- { BL any = IsAnything(s); ! pArgs = PyTuple_New(argc+(any?1:0)+(inlet >= 0?1:0));
I pix = 0; *************** *** 55,60 **** 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(any) { --- 55,60 ---- I ix; PyObject *tmp; ! if(!withself || argc < (any?1:2)) tmp = pArgs,ix = pix; ! else tmp = PyTuple_New(argc+(any?1:0)),ix = 0;
if(any) { *************** *** 65,70 **** }
! for(I i = 0; i < args.Count(); ++i) { ! PyObject *pValue = MakePyAtom(args[i]); if(!pValue) { post("py/pyext: cannot convert argument %i",any?i+1:i); --- 65,70 ---- }
! 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);
Index: main.cpp =================================================================== RCS file: /cvsroot/pure-data/externals/grill/py/source/main.cpp,v retrieving revision 1.12 retrieving revision 1.13 diff -C2 -d -r1.12 -r1.13 *** main.cpp 26 Mar 2004 03:27:49 -0000 1.12 --- main.cpp 21 Jun 2004 14:04:15 -0000 1.13 *************** *** 11,14 **** --- 11,21 ---- #include "main.h"
+ + static PyMethodDef StdOut_Methods[] = + { + { "write", py::StdOut_Write, 1 }, + { NULL, NULL, } + }; + V py::lib_setup() { *************** *** 17,46 **** post("");
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; #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), --- 24,83 ---- 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); }
FLEXT_LIB_SETUP(py,py::lib_setup)
#ifdef FLEXT_THREADS ! PyInterpreterState *py::pystate = NULL; ! PyThreadState *py::pythrmain = NULL; ! PyThrMap py::pythrmap; #endif
PyObject *py::module_obj = NULL; PyObject *py::module_dict = NULL;
py::py(): module(NULL), *************** *** 48,90 **** 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();
FLEXT_ADDTIMER(stoptmr,tick); --- 85,91 ---- stoptick(0) { ! PY_LOCK ! Py_INCREF(module_obj); ! PY_UNLOCK
FLEXT_ADDTIMER(stoptmr,tick); *************** *** 105,140 **** } ! 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(); }
--- 106,110 ---- } ! Py_XDECREF(module_obj); }
*************** *** 230,243 **** if(!name) return;
! module = PyImport_ImportModule((C *)name); if (!module) { PyErr_Print(); dict = NULL; } else ! dict = PyModule_GetDict(module); // borrowed ! }
V py::ReloadModule() --- 200,228 ---- if(!name) return;
! module = PyImport_ImportModule((C *)name); // increases module_obj ref count by one if (!module) { + PyErr_Print(); dict = NULL; } else ! 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() *************** *** 263,267 **** { #if FLEXT_SYS == FLEXT_SYS_PD ! // uarghh... pd doesn't show it's path for extra modules
C *name; --- 248,252 ---- { #if FLEXT_SYS == FLEXT_SYS_PD ! // uarghh... pd doesn't show its path for extra modules
C *name;
Index: pyext.h =================================================================== RCS file: /cvsroot/pure-data/externals/grill/py/source/pyext.h,v retrieving revision 1.13 retrieving revision 1.14 diff -C2 -d -r1.13 -r1.14 *** pyext.h 20 Jan 2004 03:38:46 -0000 1.13 --- pyext.h 21 Jun 2004 14:04:15 -0000 1.14 *************** *** 52,56 **** V m_dir_() { m__dir(pyobj); } V mg_dir_(AtomList &lst) { GetDir(pyobj,lst); } ! V m_doc_() { m__doc(pyobj); } virtual V m_help();
--- 52,56 ---- V m_dir_() { m__dir(pyobj); } V mg_dir_(AtomList &lst) { GetDir(pyobj,lst); } ! V m_doc_() { m__doc(((PyInstanceObject *)pyobj)->in_class->cl_dict); } virtual V m_help();
*************** *** 67,71 **** static pyext *GetThis(PyObject *self); V ClearBinding(); ! BL SetClssMeth(); //I argc,t_atom *argv);
AtomList args; --- 67,71 ---- static pyext *GetThis(PyObject *self); V ClearBinding(); ! BL MakeInstance();
AtomList args; *************** *** 73,77 **** virtual V Reload();
- static I pyextref; static PyObject *class_obj,*class_dict; static PyMethodDef attr_tbl[],meth_tbl[]; --- 73,76 ----
Index: modmeth.cpp =================================================================== RCS file: /cvsroot/pure-data/externals/grill/py/source/modmeth.cpp,v retrieving revision 1.8 retrieving revision 1.9 diff -C2 -d -r1.8 -r1.9 *** modmeth.cpp 22 Jan 2004 03:38:37 -0000 1.8 --- modmeth.cpp 21 Jun 2004 14:04:15 -0000 1.9 *************** *** 143,151 **** AtomList *lst = GetPyArgs(val); if(lst) { ! if(!Forward(recv,*lst)) #ifdef FLEXT_DEBUG post("py/pyext - Receiver doesn't exist"); - #else - {} #endif } --- 143,155 ---- 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 + if(!ok) post("py/pyext - Receiver doesn't exist"); #endif }
Index: bound.cpp =================================================================== RCS file: /cvsroot/pure-data/externals/grill/py/source/bound.cpp,v retrieving revision 1.8 retrieving revision 1.9 diff -C2 -d -r1.8 -r1.9 *** bound.cpp 26 Feb 2004 03:32:48 -0000 1.8 --- bound.cpp 21 Jun 2004 14:04:15 -0000 1.9 *************** *** 14,21 **** #include <set>
struct bounddata { PyObject *self; ! std::set<PyObject *> funcs; };
--- 14,23 ---- #include <set>
+ typedef std::set<PyObject *> FuncSet; + struct bounddata { PyObject *self; ! FuncSet funcs; };
*************** *** 26,33 **** PY_LOCK
! PyObject *args = MakePyArgs(sym,AtomList(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) { PyObject *ret = PyObject_CallObject(*it,args); if(!ret) { --- 28,35 ---- PY_LOCK
! PyObject *args = MakePyArgs(sym,argc,argv,-1,obj->self != NULL);
// call all functions bound by this symbol ! for(FuncSet::iterator it = obj->funcs.begin(); it != obj->funcs.end(); ++it) { PyObject *ret = PyObject_CallObject(*it,args); if(!ret) { *************** *** 136,140 **** bounddata *bdt = (bounddata *)data; if(bdt) { ! for(std::set<PyObject *>::iterator it = bdt->funcs.begin(); it != bdt->funcs.end(); ++it) { PyObject *func = *it; if(PyMethod_Check(func)) Py_DECREF(func); --- 138,142 ---- bounddata *bdt = (bounddata *)data; if(bdt) { ! for(FuncSet::iterator it = bdt->funcs.begin(); it != bdt->funcs.end(); ++it) { PyObject *func = *it; if(PyMethod_Check(func)) Py_DECREF(func);
Index: main.h =================================================================== RCS file: /cvsroot/pure-data/externals/grill/py/source/main.h,v retrieving revision 1.18 retrieving revision 1.19 diff -C2 -d -r1.18 -r1.19 *** main.h 26 Mar 2004 03:27:49 -0000 1.18 --- main.h 21 Jun 2004 14:04:15 -0000 1.19 *************** *** 51,54 **** --- 51,56 ---- #include "main.h"
+ typedef std::map<flext::thrid_t,PyThreadState *> PyThrMap; + class py: public flext_base *************** *** 61,65 **** static V lib_setup();
! static PyObject *MakePyArgs(const t_symbol *s,const AtomList &args,I inlet = -1,BL withself = false); static AtomList *GetPyArgs(PyObject *pValue,PyObject **self = NULL);
--- 63,67 ---- static V lib_setup();
! 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);
*************** *** 75,79 **** PyObject *module,*dict; // inherited user class module and associated dictionary
- static I pyref; static const C *py_doc;
--- 77,80 ---- *************** *** 84,87 **** --- 85,89 ---- V SetArgs(I argc,const t_atom *argv); V ImportModule(const C *name); + V UnimportModule(); V ReloadModule();
*************** *** 125,138 ****
public: - static PyInterpreterState *pystate;
#ifdef FLEXT_THREADS ! static std::map<flext::thrid_t,PyThreadState *> pythrmap; ThrMutex mutex; ! V Lock() { mutex.Unlock(); } ! V Unlock() { mutex.Unlock(); } #else ! V Lock() {} ! V Unlock() {} #endif
--- 127,141 ----
public:
#ifdef FLEXT_THREADS ! static PyInterpreterState *pystate; ! static PyThreadState *pythrmain; ! static PyThrMap pythrmap; ThrMutex mutex; ! inline V Lock() { mutex.Unlock(); } ! inline V Unlock() { mutex.Unlock(); } #else ! inline V Lock() {} ! inline V Unlock() {} #endif
*************** *** 153,161 **** #ifdef FLEXT_THREADS
#define PY_LOCK \ { \ PyEval_AcquireLock(); \ ! PyThreadState *__st = pythrmap[GetThreadId()]; \ ! FLEXT_ASSERT(__st != NULL); \ PyThreadState *__oldst = PyThreadState_Swap(__st);
--- 156,167 ---- #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(); \ ! PyThrMap::iterator it = pythrmap.find(GetThreadId()); \ ! PyThreadState *__st = it != pythrmap.end()?it->second:pythrmain; \ PyThreadState *__oldst = PyThreadState_Swap(__st);
Index: pyext.cpp =================================================================== RCS file: /cvsroot/pure-data/externals/grill/py/source/pyext.cpp,v retrieving revision 1.15 retrieving revision 1.16 diff -C2 -d -r1.15 -r1.16 *** pyext.cpp 22 Jan 2004 03:38:37 -0000 1.15 --- pyext.cpp 21 Jun 2004 14:04:15 -0000 1.16 *************** *** 35,38 **** --- 35,75 ----
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)); }
*************** *** 61,65 ****
- I pyext::pyextref = 0; PyObject *pyext::class_obj = NULL; PyObject *pyext::class_dict = NULL; --- 98,101 ---- *************** *** 72,116 **** 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]); --- 108,111 ---- *************** *** 119,122 **** --- 114,119 ---- }
+ PY_LOCK + // init script module if(argc > apre) { *************** *** 152,156 **** }
! Register("_pyext");
// t_symbol *sobj = NULL; --- 149,153 ---- }
! Register("_pyext");
// t_symbol *sobj = NULL; *************** *** 169,173 ****
if(methname) { ! SetClssMeth();
if(inlets < 0 && outlets < 0) { --- 166,170 ----
if(methname) { ! MakeInstance();
if(inlets < 0 && outlets < 0) { *************** *** 223,242 ****
ClearBinding(); - Unregister("_pyext");
! Py_XDECREF(pyobj); ! Py_XDECREF(class_obj); ! Py_XDECREF(class_dict); ! ! if(!--pyextref) { ! class_obj = NULL; ! class_dict = NULL; ! }
PY_UNLOCK }
! BL pyext::SetClssMeth() //I argc,t_atom *argv) { // pyobj should already have been decref'd / cleared before getting here!! --- 220,232 ----
ClearBinding(); Unregister("_pyext"); + UnimportModule();
! Py_XDECREF(pyobj); // opposite of SetClssMeth
PY_UNLOCK }
! BL pyext::MakeInstance() { // pyobj should already have been decref'd / cleared before getting here!! *************** *** 251,255 **** pyobj = PyInstance_NewRaw(pref,NULL);
- Py_DECREF(pref); if(pyobj == NULL) PyErr_Print(); --- 241,244 ---- *************** *** 261,266 **** // 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 *init; --- 250,256 ---- // 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 == NULL) ! PyErr_Print();
PyObject *init; *************** *** 301,305 **** ReloadModule(); ! SetClssMeth(); }
--- 291,295 ---- ReloadModule(); ! MakeInstance(); }
*************** *** 368,372 **** } else { ! PyObject *pval = MakePyArgs(NULL,AtomList(argc-1,argv+1),-1,false);
if(!pval) --- 358,362 ---- } else { ! PyObject *pval = MakePyArgs(NULL,argc-1,argv+1,-1,false);
if(!pval) *************** *** 439,443 **** } else { ! PyObject *pargs = MakePyArgs(s,AtomList(argc,argv),inlet?inlet:-1,true); if(!pargs) PyErr_Print(); --- 429,433 ---- } else { ! PyObject *pargs = MakePyArgs(s,argc,argv,inlet?inlet:-1,true); if(!pargs) PyErr_Print(); *************** *** 445,453 **** 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); --- 435,439 ---- *************** *** 471,475 **** // 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); --- 457,460 ----
Index: py.cpp =================================================================== RCS file: /cvsroot/pure-data/externals/grill/py/source/py.cpp,v retrieving revision 1.11 retrieving revision 1.12 diff -C2 -d -r1.11 -r1.12 *** py.cpp 20 Mar 2004 03:28:45 -0000 1.11 --- py.cpp 21 Jun 2004 14:04:15 -0000 1.12 *************** *** 3,7 **** py/pyext - python script object for PD and Max/MSP
! 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. --- 3,7 ---- py/pyext - python script object for PD and Max/MSP
! 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. *************** *** 298,302 ****
if(function) { ! PyObject *pArgs = MakePyArgs(s,AtomList(argc,argv)); PyObject *pValue = PyObject_CallObject(function, pArgs);
--- 298,302 ----
if(function) { ! PyObject *pArgs = MakePyArgs(s,argc,argv); PyObject *pValue = PyObject_CallObject(function, pArgs);