[PD-cvs] externals/grill/py/source clmeth.cpp,1.16,1.17 main.cpp,1.32,1.33 main.h,1.37,1.38 modmeth.cpp,1.17,1.18 py.cpp,1.21,1.22 pyargs.cpp,1.14,1.15 pybuffer.cpp,1.5,1.6 pyext.cpp,1.30,1.31 pyext.h,1.20,1.21

Thomas Grill xovo at users.sourceforge.net
Thu Mar 31 05:54:13 CEST 2005


Update of /cvsroot/pure-data/externals/grill/py/source
In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv29671/source

Modified Files:
	clmeth.cpp main.cpp main.h modmeth.cpp py.cpp pyargs.cpp 
	pybuffer.cpp pyext.cpp pyext.h 
Log Message:
fixed reference count bug
cleaner error reporting
more optimizations
added generic numpy support (not working)
fixes for maxmsp


Index: clmeth.cpp
===================================================================
RCS file: /cvsroot/pure-data/externals/grill/py/source/clmeth.cpp,v
retrieving revision 1.16
retrieving revision 1.17
diff -C2 -d -r1.16 -r1.17
*** clmeth.cpp	13 Mar 2005 04:59:47 -0000	1.16
--- clmeth.cpp	31 Mar 2005 03:54:10 -0000	1.17
***************
*** 174,179 ****
  			val = PySequence_GetSlice(args,2,sz);  // new ref
  
! 		AtomList *lst = GetPyArgs(val);
! 		if(lst) {
  			int o = PyInt_AsLong(outl);
  			if(o >= 1 && o <= ext->Outlets()) {
--- 174,179 ----
  			val = PySequence_GetSlice(args,2,sz);  // new ref
  
!         AtomListStatic<16> lst;
! 		if(GetPyArgs(lst,val)) {
  			int o = PyInt_AsLong(outl);
  			if(o >= 1 && o <= ext->Outlets()) {
***************
*** 183,192 ****
  				// 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);
                  else
!                     ext->ToOutAtom(o-1,*lst->Atoms());
  			}
  			else
--- 183,192 ----
  				// 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);
                  else
!                     ext->ToOutAtom(o-1,*lst.Atoms());
  			}
  			else
***************
*** 197,201 ****
  		else 
  			post("py/pyext - No data to send");
- 		if(lst) delete lst;
  
  		if(!tp) Py_DECREF(val);
--- 197,200 ----
***************
*** 297,307 ****
  			val = PyTuple_GetSlice(args,1,sz);  // new ref
  
! 		AtomList *lst = GetPyArgs(val);
! 		if(lst) {
  			t_glist *gl = ext->thisCanvas(); //canvas_getcurrent();
  			t_class **cl = (t_pd *)gl;
! 			if(cl) {
! 				pd_forwardmess(cl,lst->Count(),lst->Atoms());
! 			}
  #ifdef FLEXT_DEBUG
  			else
--- 296,305 ----
  			val = PyTuple_GetSlice(args,1,sz);  // new ref
  
! 		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());
  #ifdef FLEXT_DEBUG
  			else
***************
*** 312,316 ****
  		else 
  			post("py/pyext - No data to send");
- 		if(lst) delete lst;
  
  		if(!tp) Py_DECREF(val);
--- 310,313 ----

Index: pyargs.cpp
===================================================================
RCS file: /cvsroot/pure-data/externals/grill/py/source/pyargs.cpp,v
retrieving revision 1.14
retrieving revision 1.15
diff -C2 -d -r1.14 -r1.15
*** pyargs.cpp	13 Mar 2005 04:59:47 -0000	1.14
--- pyargs.cpp	31 Mar 2005 03:54:11 -0000	1.15
***************
*** 85,92 ****
  }
  
! flext::AtomList *pybase::GetPyArgs(PyObject *pValue,PyObject **self)
  {
! 	if(pValue == NULL) return NULL; 
! 	AtomList *ret = NULL;
  
  	// analyze return value or tuple
--- 85,91 ----
  }
  
! bool pybase::GetPyArgs(AtomList &lst,PyObject *pValue,int offs,PyObject **self)
  {
! 	if(pValue == NULL) return false; 
  
  	// analyze return value or tuple
***************
*** 104,115 ****
  		tp = sequ;
  	}
!     else if(pValue == Py_None)
!         Py_DECREF(pValue);
!     else {
  		rargc = 1;
  		tp = atom;
  	}
  
! 	ret = new AtomList(rargc);
  
  	for(int ix = 0; ix < rargc; ++ix) {
--- 103,114 ----
  		tp = sequ;
  	}
!     else if(pValue != Py_None) {
  		rargc = 1;
  		tp = atom;
  	}
+ //    else
+ //        Py_DECREF(pValue);
  
! 	lst(offs+rargc);
  
  	for(int ix = 0; ix < rargc; ++ix) {
***************
*** 120,128 ****
              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));
  		else if(ix == 0 && self && PyInstance_Check(arg)) {
  			// assumed to be self ... that should be checked _somehow_ !!!
--- 119,128 ----
              arg = pValue;
  
!         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_ !!!
***************
*** 141,152 ****
  		}
  
! 		if(tp == sequ) Py_DECREF(arg);
  	}
  
! 	if(!ok) { 
! 		delete ret; 
! 		ret = NULL; 
! 	}
! 	return ret;
  }
- 
--- 141,148 ----
  		}
  
! 		if(tp == sequ) 
!             Py_DECREF(arg);
  	}
  
!     return ok;
  }

Index: pybuffer.cpp
===================================================================
RCS file: /cvsroot/pure-data/externals/grill/py/source/pybuffer.cpp,v
retrieving revision 1.5
retrieving revision 1.6
diff -C2 -d -r1.5 -r1.6
*** pybuffer.cpp	25 Mar 2005 04:54:16 -0000	1.5
--- pybuffer.cpp	31 Mar 2005 03:54:11 -0000	1.6
***************
*** 218,223 ****
          }
      }
!     else
!         Py_INCREF(ret = Py_None);
  	return ret;
  }
--- 218,225 ----
          }
      }
!     else {
!         Py_INCREF(Py_None);
!         ret = Py_None;
!     }
  	return ret;
  }
***************
*** 275,280 ****
                  ret = nobj;
          }
!         else
!             Py_INCREF(ret = Py_None);
      }
      else 
--- 277,284 ----
                  ret = nobj;
          }
!         else {
!             Py_INCREF(Py_None);
!             ret = Py_None;
!         }
      }
      else 

Index: main.cpp
===================================================================
RCS file: /cvsroot/pure-data/externals/grill/py/source/main.cpp,v
retrieving revision 1.32
retrieving revision 1.33
diff -C2 -d -r1.32 -r1.33
*** main.cpp	18 Mar 2005 04:58:20 -0000	1.32
--- main.cpp	31 Mar 2005 03:54:10 -0000	1.33
***************
*** 206,214 ****
  		    PyErr_Print(); // no method found
  	    else {
!             AtomList *l = GetPyArgs(pvar);
!             if(l) { 
!                 lst = *l; delete l; 
!             }
!             else
                  post("py/pyext - Argument list could not be created");
              Py_DECREF(pvar);
--- 206,210 ----
  		    PyErr_Print(); // no method found
  	    else {
!             if(!GetPyArgs(lst,pvar))
                  post("py/pyext - Argument list could not be created");
              Py_DECREF(pvar);
***************
*** 268,274 ****
  }
  
! void pybase::SetArgs(int argc,const t_atom *argv)
  {
  	// script arguments
  	char **sargv = new char *[argc+1];
  	for(int i = 0; i <= argc; ++i) {
--- 264,272 ----
  }
  
! 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) {
***************
*** 287,301 ****
  }
  
! void pybase::ImportModule(const char *name)
  {
! 	if(!name) return;
  
  	module = PyImport_ImportModule((char *)name);  // increases module_obj ref count by one
! 	if(!module) {
! 		PyErr_Print();
! 		dict = NULL;
! 	}
! 	else
! 		dict = PyModule_GetDict(module);
  }
  
--- 285,297 ----
  }
  
! bool pybase::ImportModule(const char *name)
  {
! 	if(!name) return false;
  
+     SetArgs();
  	module = PyImport_ImportModule((char *)name);  // increases module_obj ref count by one
!     dict = module?PyModule_GetDict(module):NULL;
! 
!     return module != NULL;
  }
  
***************
*** 316,325 ****
  }
  
! void pybase::ReloadModule()
  {
  	if(module) {
  		PyObject *newmod = PyImport_ReloadModule(module);
  		if(!newmod) {
- 			PyErr_Print();
  			// old module still exists?!
  //			dict = NULL;
--- 312,322 ----
  }
  
! bool pybase::ReloadModule()
  {
+     bool ok = false;
  	if(module) {
+         SetArgs();
  		PyObject *newmod = PyImport_ReloadModule(module);
  		if(!newmod) {
  			// old module still exists?!
  //			dict = NULL;
***************
*** 329,336 ****
  			module = newmod;
  			dict = PyModule_GetDict(module); // borrowed
  		}
  	}
! 	else 
  		post("py/pyext - No module to reload");
  }
  
--- 326,335 ----
  			module = newmod;
  			dict = PyModule_GetDict(module); // borrowed
+             ok = true;
  		}
  	}
!     else
  		post("py/pyext - No module to reload");
+     return ok;
  }
  

Index: pyext.h
===================================================================
RCS file: /cvsroot/pure-data/externals/grill/py/source/pyext.h,v
retrieving revision 1.20
retrieving revision 1.21
diff -C2 -d -r1.20 -r1.21
*** pyext.h	13 Mar 2005 04:59:47 -0000	1.20
--- pyext.h	31 Mar 2005 03:54:11 -0000	1.21
***************
*** 63,68 ****
  
  	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_dir_() { m__dir(pyobj); }
      void mg_dir_(AtomList &lst) { GetDir(pyobj,lst); }
--- 63,68 ----
  
  	void m_reload();
!     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); }
***************
*** 77,81 ****
      int siginlets,sigoutlets;
  
! 	virtual void Reload();
  	virtual bool DoInit();
  	virtual void DoExit();
--- 77,83 ----
      int siginlets,sigoutlets;
  
!     AtomListStatic<16> initargs;
! 
! 	virtual bool Reload();
  	virtual bool DoInit();
  	virtual void DoExit();
***************
*** 92,98 ****
  	void ClearBinding();
  	bool MakeInstance();
!     void InitInOut(int &inlets,int &outlets);
! 
! 	AtomList args;
  
  	static PyObject *class_obj,*class_dict;
--- 94,98 ----
  	void ClearBinding();
  	bool MakeInstance();
!     bool InitInOut(int &inlets,int &outlets);
  
  	static PyObject *class_obj,*class_dict;
***************
*** 125,130 ****
  	FLEXT_CALLBACK(m_doc_)
  
!     FLEXT_ATTRGET_V(args)
!     FLEXT_CALLSET_V(ms_args)
  
  	FLEXT_CALLBACK_S(m_get)
--- 125,130 ----
  	FLEXT_CALLBACK(m_doc_)
  
!     FLEXT_ATTRGET_V(initargs)
!     FLEXT_CALLSET_V(ms_initargs)
  
  	FLEXT_CALLBACK_S(m_get)

Index: modmeth.cpp
===================================================================
RCS file: /cvsroot/pure-data/externals/grill/py/source/modmeth.cpp,v
retrieving revision 1.17
retrieving revision 1.18
diff -C2 -d -r1.17 -r1.18
*** modmeth.cpp	13 Mar 2005 04:59:47 -0000	1.17
--- modmeth.cpp	31 Mar 2005 03:54:11 -0000	1.18
***************
*** 127,137 ****
  			val = PySequence_GetSlice(args,1,sz);  // new ref
  
! 		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
--- 127,137 ----
  			val = PySequence_GetSlice(args,1,sz);  // new ref
  
!         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);
  			else
! 				ok = Forward(recv,lst);
  
  #ifdef FLEXT_DEBUG
***************
*** 140,146 ****
  #endif
  		}
! 		else 
  			post("py/pyext - No data to send");
- 		if(lst) delete lst;
  
  		if(!tp) Py_DECREF(val);
--- 140,147 ----
  #endif
  		}
! 		else if(PyErr_Occurred())
!             PyErr_Print();
!         else
  			post("py/pyext - No data to send");
  
  		if(!tp) Py_DECREF(val);
***************
*** 184,188 ****
          if(value_getfloat(const_cast<t_symbol *>(sym),&f)) {
  		    post("py/pyext - Could not get value '%s'",GetString(sym));
!             Py_INCREF(ret = Py_None);
          }
          else
--- 185,190 ----
          if(value_getfloat(const_cast<t_symbol *>(sym),&f)) {
  		    post("py/pyext - Could not get value '%s'",GetString(sym));
!             Py_INCREF(Py_None);
!             ret = Py_None;
          }
          else
***************
*** 191,195 ****
      else {
          post("py/pyext - Syntax: _getvalue [name]");
!         Py_INCREF(ret = Py_None);
      }
      return ret;
--- 193,198 ----
      else {
          post("py/pyext - Syntax: _getvalue [name]");
!         Py_INCREF(Py_None);
!         ret = Py_None;
      }
      return ret;

Index: pyext.cpp
===================================================================
RCS file: /cvsroot/pure-data/externals/grill/py/source/pyext.cpp,v
retrieving revision 1.30
retrieving revision 1.31
diff -C2 -d -r1.30 -r1.31
*** pyext.cpp	14 Mar 2005 04:58:13 -0000	1.30
--- pyext.cpp	31 Mar 2005 03:54:11 -0000	1.31
***************
*** 36,40 ****
  	FLEXT_CADDATTR_GET(c,"dir+",mg_dir_);
  
!     FLEXT_CADDATTR_VAR(c,"args",args,ms_args);
  
  	FLEXT_CADDMETHOD_(c,0,"get",m_get);
--- 36,40 ----
  	FLEXT_CADDATTR_GET(c,"dir+",mg_dir_);
  
!     FLEXT_CADDATTR_VAR(c,"args",initargs,ms_initargs);
  
  	FLEXT_CADDMETHOD_(c,0,"get",m_get);
***************
*** 130,134 ****
      }
  
!     const t_atom *clname = NULL;
  
      PyThreadState *state = PyLockSys();
--- 130,134 ----
      }
  
!     const t_symbol *clname = NULL;
  
      PyThreadState *state = PyLockSys();
***************
*** 150,171 ****
          #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 {
  		    GetModulePath(GetString(scr),dir,sizeof(dir));
  		    // add to path
  		    AddToPath(dir);
  
! 			SetArgs(0,NULL);
  
  			ImportModule(GetString(scr));
  		}
  
          ++apre;
  
          // check for alias creation names
!         if(strrchr(thisName(),'.')) clname = &scr;
  	}
  
--- 150,170 ----
          #pragma message("Adding current dir to path is not implemented")
  #endif
!         const t_symbol *scr = GetASymbol(argv[apre]);
!         if(scr) {
  		    GetModulePath(GetString(scr),dir,sizeof(dir));
  		    // add to path
  		    AddToPath(dir);
  
! //			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;
  	}
  
***************
*** 173,186 ****
  
  	if(argc > apre || clname) {
!         if(!clname) clname = &argv[apre++];
      
  		// class name
! 		if(!IsString(*clname)) 
  			post("%s - class name argument is invalid",thisName());
  		else
! 			methname = GetSymbol(*clname);
  	}
  
! 	if(argc > apre) args(argc-apre,argv+apre);
  
  	PyUnlock(state);
--- 172,187 ----
  
  	if(argc > apre || clname) {
!         if(!clname) clname = GetASymbol(argv[apre++]);
      
  		// class name
! 		if(!clname) 
  			post("%s - class name argument is invalid",thisName());
  		else
! 			methname = clname;
  	}
  
! 	if(argc > apre) initargs(argc-apre,argv+apre);
! 
!     Report();
  
  	PyUnlock(state);
***************
*** 232,252 ****
      // 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;
  }
  
--- 233,257 ----
      // call init now, after _this has been set, which is
  	// important for eventual callbacks from __init__ to c
! 	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;
  }
  
***************
*** 270,273 ****
--- 275,279 ----
          }
          else
+             // _del has not been found - don't care
              PyErr_Clear();
  
***************
*** 281,285 ****
  }
  
! void pyext::InitInOut(int &inl,int &outl)
  {
      if(inl >= 0) {
--- 287,291 ----
  }
  
! bool pyext::InitInOut(int &inl,int &outl)
  {
      if(inl >= 0) {
***************
*** 294,299 ****
      }
  
-     DoInit(); // call __init__ constructor
      // __init__ can override the number of inlets and outlets
  
      if(inl < 0) {
--- 300,306 ----
      }
  
      // __init__ can override the number of inlets and outlets
+     if(!DoInit()) // call __init__ constructor
+         return false;
  
      if(inl < 0) {
***************
*** 331,334 ****
--- 338,343 ----
  			PyErr_Clear();
      }
+ 
+     return true;
  }
  
***************
*** 359,363 ****
  }
  
! void pyext::Reload()
  {
  	DoExit();
--- 368,372 ----
  }
  
! bool pyext::Reload()
  {
  	DoExit();
***************
*** 365,378 ****
  	// by here, the Python class destructor should have been called!
  
! 	SetArgs(0,NULL);
! 	ReloadModule();
  	
! 	MakeInstance();
  
!     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());
  }
  
--- 374,391 ----
  	// by here, the Python class destructor should have been called!
  
! //	SetArgs(0,NULL);
! 	bool ok = ReloadModule();
  	
! 	if(ok) ok = MakeInstance();
  
!     if(ok) {
!         int inl = -1,outl = -1;
!         ok = InitInOut(inl,outl);
  
!         if(inl != inlets || outl != outlets)
!             post("%s - Inlet and outlet count can't be changed by reload",thisName());
!     }
! 
!     return ok;
  }
  
***************
*** 391,401 ****
      SetThis();
  
! 	PyUnlock(state);
! }
  
! void pyext::m_reload_(int argc,const t_atom *argv)
! {
! 	args(argc,argv);
! 	m_reload();
  }
  
--- 404,410 ----
      SetThis();
  
!     Report();
  
! 	PyUnlock(state);
  }
  
***************
*** 405,428 ****
  
  	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) {
              // 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);
          }
!         else
!             post("%s - get: List could not be created",thisName());
          Py_DECREF(pvar);
      }
  
      PyUnlock(state);
  }
--- 414,430 ----
  
  	PyObject *pvar  = PyObject_GetAttrString(pyobj,const_cast<char *>(GetString(s))); /* fetch bound method */
! 	if(pvar) {
!         AtomListStatic<16> lst;
!         if(GetPyArgs(lst,pvar,1)) {
              // dump value to attribute outlet
!             SetSymbol(lst[0],s);
!             ToOutAnything(GetOutAttr(),sym_get,lst.Count(),lst.Atoms());
          }
! 
          Py_DECREF(pvar);
      }
  
+     Report();
+ 
      PyUnlock(state);
  }
***************
*** 438,451 ****
      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 {
              PyObject *pval = MakePyArgs(NULL,argc-1,argv+1,-1,false);
! 
!             if(!pval)
! 			    PyErr_Print();
! 		    else {
                  if(PySequence_Size(pval) == 1) {
                      // reduce lists of one element to element itself
--- 440,446 ----
      else {
          char *ch = const_cast<char *>(GetString(argv[0]));
!         if(PyObject_HasAttrString(pyobj,ch)) {
              PyObject *pval = MakePyArgs(NULL,argc-1,argv+1,-1,false);
!             if(pval) {
                  if(PySequence_Size(pval) == 1) {
                      // reduce lists of one element to element itself
***************
*** 462,465 ****
--- 457,462 ----
      }
  
+     Report();
+ 
      PyUnlock(state);
  }

Index: main.h
===================================================================
RCS file: /cvsroot/pure-data/externals/grill/py/source/main.h,v
retrieving revision 1.37
retrieving revision 1.38
diff -C2 -d -r1.37 -r1.38
*** main.h	14 Mar 2005 04:58:13 -0000	1.37
--- main.h	31 Mar 2005 03:54:11 -0000	1.38
***************
*** 53,57 ****
  
  	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 void lib_setup();
--- 53,57 ----
  
  	static PyObject *MakePyArgs(const t_symbol *s,int argc,const t_atom *argv,int inlet = -1,bool withself = false);
! 	static bool GetPyArgs(AtomList &lst,PyObject *pValue,int offs = 0,PyObject **self = NULL);
  
      static void lib_setup();
***************
*** 74,92 ****
      void GetDir(PyObject *obj,AtomList &lst);
  
  	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 UnimportModule();
! 	void ReloadModule();
  
  	void Register(const char *reg);
  	void Unregister(const char *reg);
  	void Reregister(const char *reg);
! 	virtual void Reload() = 0;
  
      void OpenEditor();
      void Respond(bool b);
  
  	static bool IsAnything(const t_symbol *s) { return s && s != sym_float && s != sym_int && s != sym_symbol && s != sym_list && s != sym_pointer; }
  
--- 74,96 ----
      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();
! 	bool ImportModule(const char *name);
  	void UnimportModule();
! 	bool ReloadModule();
  
  	void Register(const char *reg);
  	void Unregister(const char *reg);
  	void Reregister(const char *reg);
! 	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; }
  

Index: py.cpp
===================================================================
RCS file: /cvsroot/pure-data/externals/grill/py/source/py.cpp,v
retrieving revision 1.21
retrieving revision 1.22
diff -C2 -d -r1.21 -r1.22
*** py.cpp	14 Mar 2005 04:58:13 -0000	1.21
--- py.cpp	31 Mar 2005 03:54:11 -0000	1.22
***************
*** 31,35 ****
  
  	void m_reload();
! 	void m_reload_(int argc,const t_atom *argv);
  	void m_set(int argc,const t_atom *argv);
      void m_dir_() { m__dir(function); }
--- 31,35 ----
  
  	void m_reload();
!     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); }
***************
*** 49,56 ****
      bool withfunction;
  
! 	virtual void Reload();
  
! 	void SetFunction(const char *func);
! 	void ResetFunction();
  
      virtual bool thrcall(void *data);
--- 49,56 ----
      bool withfunction;
  
! 	virtual bool Reload();
  
! 	bool SetFunction(const char *func);
! 	bool ResetFunction();
  
      virtual bool thrcall(void *data);
***************
*** 134,151 ****
  #endif
  
! 	PyThreadState *state = PyLockSys();
  
! 	if(argc > 2) 
! 		SetArgs(argc-2,argv+2);
! 	else
! 		SetArgs(0,NULL);
  
  	// init script module
  	if(argc >= 1) {
! 		if(!IsString(argv[0])) 
! 			post("%s - script name argument is invalid",thisName());
!         else {
  		    char dir[1024];
! 		    GetModulePath(GetString(argv[0]),dir,sizeof(dir));
  		    // set script path
  		    AddToPath(dir);
--- 134,147 ----
  #endif
  
! 	if(argc > 2) args(argc-2,argv+2);
  
! 	PyThreadState *state = PyLockSys();
  
  	// init script module
  	if(argc >= 1) {
! 	    const char *sn = GetAString(argv[0]);
!         if(sn) {
  		    char dir[1024];
! 		    GetModulePath(sn,dir,sizeof(dir));
  		    // set script path
  		    AddToPath(dir);
***************
*** 164,186 ****
  #endif
  
! 			ImportModule(GetString(argv[0]));
          }
  	}
  
  	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;
  
  	PyUnlock(state);
--- 160,180 ----
  #endif
  
! 			ImportModule(sn);
          }
+         else
+             PyErr_SetString(PyExc_ValueError,"Invalid module name");
  	}
  
  	Register("_py");
  
!     if(argc >= 2) {
! 	    const char *fn = GetAString(argv[1]);
!         if(fn)
! 	        SetFunction(fn);
!         else
!             PyErr_SetString(PyExc_ValueError,"Invalid function name");
!     }
  
!     Report();
  
  	PyUnlock(state);
***************
*** 191,194 ****
--- 185,189 ----
  	PyThreadState *state = PyLockSys();
  	Unregister("_py");
+     Report();
  	PyUnlock(state);
  }
***************
*** 218,257 ****
  	SetFunction(funname?GetString(funname):NULL);
  
  	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;
  	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;
  	}
  
! 	if(!IsString(argv[ix])) 
! 		post("%s - function name is not valid",thisName());
! 	else
! 		SetFunction(GetString(argv[ix]));
  
  	PyUnlock(state);
--- 213,248 ----
  	SetFunction(funname?GetString(funname):NULL);
  
+     Report();
  	PyUnlock(state);
  }
  
  void pyobj::m_set(int argc,const t_atom *argv)
  {
  	PyThreadState *state = PyLockSys();
  
!     // function name has precedence
  	if(argc >= 2) {
! 	    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(argc) {
! 	    const char *fn = GetAString(*argv);
!         if(fn)
! 	        SetFunction(fn);
!         else
!             PyErr_SetString(PyExc_ValueError,"Invalid function name");
!     }
! 
!     Report();
  
  	PyUnlock(state);
***************
*** 288,328 ****
  }
  
! void pyobj::ResetFunction()
  {
! 	if(!module || !dict) 
! 	{ 
  		post("%s - No module loaded",thisName());
! 		function = NULL; 
! 		return; 
! 	}
  
! 	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;
! 	}
  }
  
! void pyobj::SetFunction(const char *func)
  {
  	if(func) {
  		funname = MakeSymbol(func);
!         withfunction = true;
! 		ResetFunction();
  	}
      else {
-         withfunction = false;
  		function = NULL,funname = NULL;
      }
  }
  
  
! void pyobj::Reload()
  {
  	ResetFunction();
  }
  
--- 279,324 ----
  }
  
! bool pyobj::ResetFunction()
  {
!     function = NULL;
!     
!     if(!module || !dict)
  		post("%s - No module loaded",thisName());
!     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");
!             }
! 	    }
!     }
  
!     // exception could be set here
!     return function != NULL;
  }
  
! bool pyobj::SetFunction(const char *func)
  {
  	if(func) {
  		funname = MakeSymbol(func);
!         withfunction = ResetFunction();
  	}
      else {
  		function = NULL,funname = NULL;
+         withfunction = false;
      }
+ 
+     // exception could be set here
+     return withfunction;
  }
  
  
! bool pyobj::Reload()
  {
  	ResetFunction();
+     return true;
  }
  
***************
*** 336,348 ****
      }
      else {
!         AtomList *rargs = GetPyArgs(ret);
! 		if(!rargs) 
!             PyErr_Print();
!         else {
              // call to outlet _outside_ the Mutex lock!
              // otherwise (if not detached) deadlock will occur
!             if(rargs->Count()) ToOutList(0,*rargs);
!             delete rargs;
          }
          Py_DECREF(ret);
          return true;
--- 332,344 ----
      }
      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);
          }
+         else if(PyErr_Occurred())
+             PyErr_Print();
+ 
          Py_DECREF(ret);
          return true;
***************
*** 363,379 ****
          }
  	    else
! 		    post("%s: no valid function defined",thisName());
      }
      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);
          }
          else
!             PyErr_Print();
      }
  
      PyUnlock(state);
  
--- 359,379 ----
          }
  	    else
! 		    PyErr_SetString(PyExc_RuntimeError,"No function set");
      }
      else if(module) {
          // no function defined as creation argument -> use message tag
!         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_SetString(PyExc_RuntimeError,"No function set");
      }
  
+     Report();
+ 
      PyUnlock(state);
  





More information about the Pd-cvs mailing list