]> SALOME platform Git repositories - modules/yacs.git/blob - src/runtime/PythonNode.cxx
Salome HOME
e4d7c596f9d043eadae388c2050ee37c46069aee
[modules/yacs.git] / src / runtime / PythonNode.cxx
1 //  Copyright (C) 2006-2008  CEA/DEN, EDF R&D
2 //
3 //  This library is free software; you can redistribute it and/or
4 //  modify it under the terms of the GNU Lesser General Public
5 //  License as published by the Free Software Foundation; either
6 //  version 2.1 of the License.
7 //
8 //  This library is distributed in the hope that it will be useful,
9 //  but WITHOUT ANY WARRANTY; without even the implied warranty of
10 //  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
11 //  Lesser General Public License for more details.
12 //
13 //  You should have received a copy of the GNU Lesser General Public
14 //  License along with this library; if not, write to the Free Software
15 //  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
16 //
17 //  See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
18 //
19 #include "RuntimeSALOME.hxx"
20 #include "PythonNode.hxx"
21 #include "PythonPorts.hxx"
22
23 #include "PyStdout.hxx"
24 #include <iostream>
25 #include <sstream>
26
27 //#define _DEVDEBUG_
28 #include "YacsTrace.hxx"
29
30 using namespace YACS::ENGINE;
31 using namespace std;
32
33 const char PythonNode::IMPL_NAME[]="Python";
34 const char PythonNode::KIND[]="Python";
35
36 PythonNode::PythonNode(const PythonNode& other, ComposedNode *father):InlineNode(other,father)
37 {
38   _implementation=IMPL_NAME;
39   PyGILState_STATE gstate=PyGILState_Ensure();
40   _context=PyDict_New();
41   PyGILState_Release(gstate);
42 }
43
44 PythonNode::PythonNode(const std::string& name):InlineNode(name)
45 {
46   _implementation=IMPL_NAME;
47   PyGILState_STATE gstate = PyGILState_Ensure();
48   _context=PyDict_New();
49   PyGILState_Release(gstate);
50 }
51
52 PythonNode::~PythonNode()
53 {
54   PyGILState_STATE gstate = PyGILState_Ensure();
55   DEBTRACE( "_context refcnt: " << _context->ob_refcnt );
56   Py_DECREF(_context);
57   PyGILState_Release(gstate);
58 }
59
60 void PythonNode::load()
61 {
62 }
63
64 void PythonNode::execute()
65 {
66   DEBTRACE( "++++++++++++++ PyNode::execute: " << getName() << " ++++++++++++++++++++" );
67   PyGILState_STATE gstate = PyGILState_Ensure();
68   if( PyDict_SetItemString( _context, "__builtins__", getSALOMERuntime()->getBuiltins() ))
69     {
70       stringstream msg;
71       msg << "Impossible to set builtins" << __FILE__ << ":" << __LINE__;
72       PyGILState_Release(gstate);
73       _errorDetails=msg.str();
74       throw Exception(msg.str());
75     }
76
77   DEBTRACE( "---------------PyNode::inputs---------------" );
78   list<InputPort *>::iterator iter2;
79   for(iter2 = _setOfInputPort.begin(); iter2 != _setOfInputPort.end(); iter2++)
80     {
81       InputPyPort *p=(InputPyPort *)*iter2;
82       DEBTRACE( "port name: " << p->getName() );
83       DEBTRACE( "port kind: " << p->edGetType()->kind() );
84       PyObject* ob=p->getPyObj();
85       DEBTRACE( "ob refcnt: " << ob->ob_refcnt );
86 #ifdef _DEVDEBUG_
87       PyObject_Print(ob,stderr,Py_PRINT_RAW);
88       cerr << endl;
89 #endif
90       int ier=PyDict_SetItemString(_context,p->getName().c_str(),ob);
91       DEBTRACE( "after PyDict_SetItemString:ob refcnt: " << ob->ob_refcnt );
92     }
93   
94   DEBTRACE( "---------------End PyNode::inputs---------------" );
95   
96   //calculation
97   DEBTRACE( "----------------PyNode::calculation---------------" );
98   DEBTRACE(  _script );
99   DEBTRACE( "_context refcnt: " << _context->ob_refcnt );
100   PyObject *res=PyRun_String(_script.c_str(),Py_file_input,_context,_context);
101   DEBTRACE( "_context refcnt: " << _context->ob_refcnt );
102   fflush(stdout);
103   fflush(stderr);
104   if(res == NULL)
105     {
106       _errorDetails="";
107       PyObject* new_stderr = newPyStdOut(_errorDetails);
108       PySys_SetObject("stderr", new_stderr);
109       PyErr_Print();
110       PySys_SetObject("stderr", PySys_GetObject("__stderr__"));
111       Py_DECREF(new_stderr);
112
113       PyGILState_Release(gstate);
114       throw Exception("Error during execution");
115     }
116   Py_DECREF(res);
117   
118   DEBTRACE( "-----------------PyNode::outputs-----------------" );
119   list<OutputPort *>::iterator iter;
120   try
121     {
122       for(iter = _setOfOutputPort.begin(); iter != _setOfOutputPort.end(); iter++)
123         {
124           OutputPyPort *p=(OutputPyPort *)*iter;
125           DEBTRACE( "port name: " << p->getName() );
126           DEBTRACE( "port kind: " << p->edGetType()->kind() );
127           PyObject *ob=PyDict_GetItemString(_context,p->getName().c_str());
128           if(ob==NULL){
129              PyGILState_Release(gstate);
130              std::string msg="Error during execution: there is no variable ";
131              msg=msg+p->getName()+" in node context";
132              _errorDetails=msg;
133              throw Exception(msg);
134           }
135           DEBTRACE( "PyNode::outputs::ob refcnt: " << ob->ob_refcnt );
136 #ifdef _DEVDEBUG_
137           PyObject_Print(ob,stderr,Py_PRINT_RAW);
138           cerr << endl;
139 #endif
140           p->put(ob);
141         }
142     }
143   catch(ConversionException& ex)
144     {
145       PyGILState_Release(gstate);
146       _errorDetails=ex.what();
147       throw;
148     }
149
150   DEBTRACE( "-----------------End PyNode::outputs-----------------" );
151   PyGILState_Release(gstate);
152   DEBTRACE( "++++++++++++++ End PyNode::execute: " << getName() << " ++++++++++++++++++++" );
153 }
154
155 Node *PythonNode::simpleClone(ComposedNode *father, bool editionOnly) const
156 {
157   return new PythonNode(*this,father);
158 }
159
160 //! Create a new node of same type with a given name
161 PythonNode* PythonNode::cloneNode(const std::string& name)
162 {
163   PythonNode* n=new PythonNode(name);
164   n->setScript(_script);
165   list<InputPort *>::iterator iter;
166   for(iter = _setOfInputPort.begin(); iter != _setOfInputPort.end(); iter++)
167     {
168       InputPyPort *p=(InputPyPort *)*iter;
169       DEBTRACE( "port name: " << p->getName() );
170       DEBTRACE( "port kind: " << p->edGetType()->kind() );
171       n->edAddInputPort(p->getName(),p->edGetType());
172     }
173   list<OutputPort *>::iterator iter2;
174   for(iter2 = _setOfOutputPort.begin(); iter2 != _setOfOutputPort.end(); iter2++)
175     {
176       OutputPyPort *p=(OutputPyPort *)*iter2;
177       DEBTRACE( "port name: " << p->getName() );
178       DEBTRACE( "port kind: " << p->edGetType()->kind() );
179       n->edAddOutputPort(p->getName(),p->edGetType());
180     }
181   return n;
182 }
183
184 PyFuncNode::PyFuncNode(const PyFuncNode& other, ComposedNode *father):InlineFuncNode(other,father),_pyfunc(0)
185 {
186   _implementation = PythonNode::IMPL_NAME;
187   PyGILState_STATE gstate = PyGILState_Ensure();
188   _context=PyDict_New();
189   DEBTRACE( "_context refcnt: " << _context->ob_refcnt );
190   if( PyDict_SetItemString( _context, "__builtins__", getSALOMERuntime()->getBuiltins() ))
191     {
192       stringstream msg;
193       msg << "Not possible to set builtins" << __FILE__ << ":" << __LINE__;
194       _errorDetails=msg.str();
195       PyGILState_Release(gstate);
196       throw Exception(msg.str());
197     }
198   PyGILState_Release(gstate);
199 }
200
201 PyFuncNode::PyFuncNode(const std::string& name): InlineFuncNode(name),_pyfunc(0)
202 {
203
204   _implementation = PythonNode::IMPL_NAME;
205   DEBTRACE( "PyFuncNode::PyFuncNode " << name );
206   PyGILState_STATE gstate = PyGILState_Ensure();
207   _context=PyDict_New();
208   DEBTRACE( "_context refcnt: " << _context->ob_refcnt );
209   if( PyDict_SetItemString( _context, "__builtins__", getSALOMERuntime()->getBuiltins() ))
210     {
211       stringstream msg;
212       msg << "Not possible to set builtins" << __FILE__ << ":" << __LINE__;
213       _errorDetails=msg.str();
214       PyGILState_Release(gstate);
215       throw Exception(msg.str());
216     }
217   PyGILState_Release(gstate);
218 }
219
220 PyFuncNode::~PyFuncNode()
221 {
222   DEBTRACE( getName() );
223   PyGILState_STATE gstate = PyGILState_Ensure();
224   DEBTRACE( "_context refcnt: " << _context->ob_refcnt );
225   if(_pyfunc)DEBTRACE( "_pyfunc refcnt: " << _pyfunc->ob_refcnt );
226   Py_DECREF(_context);
227   PyGILState_Release(gstate);
228 }
229
230 void PyFuncNode::load()
231 {
232   DEBTRACE( "---------------PyFuncNode::load function " << getName() << " ---------------" );
233   DEBTRACE(  _script );
234 #ifdef _DEVDEBUG_
235   list<OutputPort *>::iterator iter;
236   for(iter = _setOfOutputPort.begin(); iter != _setOfOutputPort.end(); iter++)
237     {
238       OutputPyPort *p=(OutputPyPort *)*iter;
239       DEBTRACE( "port name: " << p->getName() );
240       DEBTRACE( "port kind: " << p->edGetType()->kind() );
241     }
242 #endif
243   PyGILState_STATE gstate = PyGILState_Ensure();
244   DEBTRACE( "_context refcnt: " << _context->ob_refcnt );
245   PyObject *res=PyRun_String(_script.c_str(),Py_file_input,_context,_context);
246   DEBTRACE( "_context refcnt: " << _context->ob_refcnt );
247   if(res == NULL)
248     {
249       _errorDetails="";
250       PyObject* new_stderr = newPyStdOut(_errorDetails);
251       PySys_SetObject("stderr", new_stderr);
252       PyErr_Print();
253       PySys_SetObject("stderr", PySys_GetObject("__stderr__"));
254       Py_DECREF(new_stderr);
255
256       PyGILState_Release(gstate);
257       throw Exception("Error during execution");
258       return;
259     }
260   Py_DECREF(res);
261   _pyfunc=PyDict_GetItemString(_context,_fname.c_str());
262   DEBTRACE( "_pyfunc refcnt: " << _pyfunc->ob_refcnt );
263   if(_pyfunc == NULL)
264     {
265       _errorDetails="";
266       PyObject* new_stderr = newPyStdOut(_errorDetails);
267       PySys_SetObject("stderr", new_stderr);
268       PyErr_Print();
269       PySys_SetObject("stderr", PySys_GetObject("__stderr__"));
270       Py_DECREF(new_stderr);
271
272       PyGILState_Release(gstate);
273       throw Exception("Error during execution");
274     }
275   DEBTRACE( "---------------End PyFuncNode::load function---------------" );
276   PyGILState_Release(gstate);
277 }
278
279 void PyFuncNode::execute()
280 {
281   DEBTRACE( "++++++++++++++ PyFuncNode::execute: " << getName() << " ++++++++++++++++++++" );
282   int pos=0;
283   PyObject* ob;
284   if(!_pyfunc)throw Exception("PyFuncNode badly loaded");
285   PyGILState_STATE gstate = PyGILState_Ensure();
286
287   DEBTRACE( "---------------PyFuncNode::inputs---------------" );
288   PyObject* args = PyTuple_New(getNumberOfInputPorts()) ;
289   list<InputPort *>::iterator iter2;
290   for(iter2 = _setOfInputPort.begin(); iter2 != _setOfInputPort.end(); iter2++)
291     {
292       InputPyPort *p=(InputPyPort *)*iter2;
293       DEBTRACE( "port name: " << p->getName() );
294       DEBTRACE( "port kind: " << p->edGetType()->kind() );
295       ob=p->getPyObj();
296 #ifdef _DEVDEBUG_
297       PyObject_Print(ob,stderr,Py_PRINT_RAW);
298       cerr << endl;
299 #endif
300       DEBTRACE( "ob refcnt: " << ob->ob_refcnt );
301       Py_INCREF(ob);
302       PyTuple_SetItem(args,pos,ob);
303       DEBTRACE( "ob refcnt: " << ob->ob_refcnt );
304       pos++;
305     }
306   DEBTRACE( "---------------End PyFuncNode::inputs---------------" );
307
308   DEBTRACE( "----------------PyFuncNode::calculation---------------" );
309 #ifdef _DEVDEBUG_
310   PyObject_Print(_pyfunc,stderr,Py_PRINT_RAW);
311   cerr << endl;
312   PyObject_Print(args,stderr,Py_PRINT_RAW);
313   cerr << endl;
314 #endif
315   DEBTRACE( "_pyfunc refcnt: " << _pyfunc->ob_refcnt );
316   PyObject* result = PyObject_CallObject( _pyfunc , args ) ;
317   DEBTRACE( "_pyfunc refcnt: " << _pyfunc->ob_refcnt );
318   Py_DECREF(args);
319   fflush(stdout);
320   fflush(stderr);
321   if(result == NULL)
322     {
323       _errorDetails="";
324       PyObject* new_stderr = newPyStdOut(_errorDetails);
325       PySys_SetObject("stderr", new_stderr);
326       PyErr_Print();
327       PySys_SetObject("stderr", PySys_GetObject("__stderr__"));
328       Py_DECREF(new_stderr);
329
330       PyGILState_Release(gstate);
331       throw Exception("Error during execution");
332     }
333   DEBTRACE( "----------------End PyFuncNode::calculation---------------" );
334
335   DEBTRACE( "-----------------PyFuncNode::outputs-----------------" );
336   int nres=1;
337   if(result == Py_None)
338     nres=0;
339   else if(PyTuple_Check(result))
340     nres=PyTuple_Size(result);
341
342   if(getNumberOfOutputPorts() != nres)
343     {
344       std::string msg="Number of output arguments : Mismatch between definition and execution";
345       Py_DECREF(result);
346       PyGILState_Release(gstate);
347       _errorDetails=msg;
348       throw Exception(msg);
349     }
350
351   pos=0;
352 #ifdef _DEVDEBUG_
353   PyObject_Print(result,stderr,Py_PRINT_RAW);
354   cerr << endl;
355 #endif
356   list<OutputPort *>::iterator iter;
357   try
358     {
359       for(iter = _setOfOutputPort.begin(); iter != _setOfOutputPort.end(); iter++)
360         {
361           OutputPyPort *p=(OutputPyPort *)*iter;
362           DEBTRACE( "port name: " << p->getName() );
363           DEBTRACE( "port kind: " << p->edGetType()->kind() );
364           DEBTRACE( "port pos : " << pos );
365           if(PyTuple_Check(result))ob=PyTuple_GetItem(result,pos) ;
366           else ob=result;
367           DEBTRACE( "ob refcnt: " << ob->ob_refcnt );
368 #ifdef _DEVDEBUG_
369           PyObject_Print(ob,stderr,Py_PRINT_RAW);
370           cerr << endl;
371 #endif
372           p->put(ob);
373           pos++;
374         }
375     }
376   catch(ConversionException& ex)
377     {
378       Py_DECREF(result);
379       PyGILState_Release(gstate);
380       _errorDetails=ex.what();
381       throw;
382     }
383   DEBTRACE( "-----------------End PyFuncNode::outputs-----------------" );
384
385   Py_DECREF(result);
386   PyGILState_Release(gstate);
387   DEBTRACE( "++++++++++++++ End PyFuncNode::execute: " << getName() << " ++++++++++++++++++++" );
388 }
389
390 Node *PyFuncNode::simpleClone(ComposedNode *father, bool editionOnly) const
391 {
392   return new PyFuncNode(*this,father);
393 }
394
395 //! Create a new node of same type with a given name
396 PyFuncNode* PyFuncNode::cloneNode(const std::string& name)
397 {
398   PyFuncNode* n=new PyFuncNode(name);
399   n->setScript(_script);
400   n->setFname(_fname);
401   list<InputPort *>::iterator iter;
402   for(iter = _setOfInputPort.begin(); iter != _setOfInputPort.end(); iter++)
403     {
404       InputPyPort *p=(InputPyPort *)*iter;
405       n->edAddInputPort(p->getName(),p->edGetType());
406     }
407   list<OutputPort *>::iterator iter2;
408   for(iter2 = _setOfOutputPort.begin(); iter2 != _setOfOutputPort.end(); iter2++)
409     {
410       OutputPyPort *p=(OutputPyPort *)*iter2;
411       n->edAddOutputPort(p->getName(),p->edGetType());
412     }
413   return n;
414 }