1 // Copyright (C) 2006-2014 CEA/DEN, EDF R&D
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, or (at your option) any later version.
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.
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
17 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
20 #include "RuntimeSALOME.hxx"
21 #include "PythonNode.hxx"
22 #include "PythonPorts.hxx"
23 #include "TypeCode.hxx"
24 #include "AutoGIL.hxx"
25 #include "Container.hxx"
26 #include "SalomeContainer.hxx"
27 #include "SalomeHPContainer.hxx"
28 #include "SalomeContainerTmpForHP.hxx"
29 #include "ConversionException.hxx"
31 #include "PyStdout.hxx"
38 #define getpid _getpid
41 #if PY_VERSION_HEX < 0x02050000
42 typedef int Py_ssize_t;
46 #include "YacsTrace.hxx"
48 using namespace YACS::ENGINE;
51 const char PythonNode::IMPL_NAME[]="Python";
52 const char PythonNode::KIND[]="Python";
54 PythonNode::PythonNode(const PythonNode& other, ComposedNode *father):InlineNode(other,father)
56 _implementation=IMPL_NAME;
57 PyGILState_STATE gstate=PyGILState_Ensure();
58 _context=PyDict_New();
59 if( PyDict_SetItemString( _context, "__builtins__", getSALOMERuntime()->getBuiltins() ))
62 msg << "Impossible to set builtins" << __FILE__ << ":" << __LINE__;
63 PyGILState_Release(gstate);
64 _errorDetails=msg.str();
65 throw Exception(msg.str());
67 PyGILState_Release(gstate);
70 PythonNode::PythonNode(const std::string& name):InlineNode(name)
72 _implementation=IMPL_NAME;
73 PyGILState_STATE gstate = PyGILState_Ensure();
74 _context=PyDict_New();
75 if( PyDict_SetItemString( _context, "__builtins__", getSALOMERuntime()->getBuiltins() ))
78 msg << "Impossible to set builtins" << __FILE__ << ":" << __LINE__;
79 PyGILState_Release(gstate);
80 _errorDetails=msg.str();
81 throw Exception(msg.str());
83 PyGILState_Release(gstate);
86 PythonNode::~PythonNode()
88 PyGILState_STATE gstate = PyGILState_Ensure();
89 DEBTRACE( "_context refcnt: " << _context->ob_refcnt );
91 PyGILState_Release(gstate);
94 void PythonNode::checkBasicConsistency() const throw(YACS::Exception)
96 DEBTRACE("checkBasicConsistency");
97 InlineNode::checkBasicConsistency();
99 PyGILState_STATE gstate = PyGILState_Ensure();
101 res=Py_CompileString(_script.c_str(),getName().c_str(),Py_file_input);
104 std::string error="";
105 PyObject* new_stderr = newPyStdOut(error);
106 PySys_SetObject((char*)"stderr", new_stderr);
108 PySys_SetObject((char*)"stderr", PySys_GetObject((char*)"__stderr__"));
109 Py_DECREF(new_stderr);
110 PyGILState_Release(gstate);
111 throw Exception(error);
115 PyGILState_Release(gstate);
118 void PythonNode::load()
120 DEBTRACE( "---------------PyNode::load function---------------" );
127 void PythonNode::loadLocal()
129 DEBTRACE( "---------------PyNode::loadLocal function---------------" );
133 void PythonNode::loadRemote()
135 DEBTRACE( "---------------PyNode::loadRemote function---------------" );
138 if(!_container->isAlreadyStarted(this))
142 _container->start(this);
146 _errorDetails=e.what();
153 std::string what("PyNode::loadRemote : a load operation requested on \"");
154 what+=_name; what+="\" with no container specified.";
156 throw Exception(what);
160 Engines::Container_var objContainer=Engines::Container::_nil();
162 throw Exception("No container specified !");
163 SalomeContainer *containerCast0(dynamic_cast<SalomeContainer *>(_container));
164 SalomeHPContainer *containerCast1(dynamic_cast<SalomeHPContainer *>(_container));
166 objContainer=containerCast0->getContainerPtr(this);
167 else if(containerCast1)
169 YACS::BASES::AutoCppPtr<SalomeContainerTmpForHP> tmpCont(SalomeContainerTmpForHP::BuildFrom(containerCast1,this));
170 objContainer=tmpCont->getContainerPtr(this);
173 throw Exception("Unrecognized type of container ! Salome one is expected for PythonNode !");
174 if(CORBA::is_nil(objContainer))
175 throw Exception("Container corba pointer is NULL for PythonNode !");
179 _pynode = objContainer->createPyScriptNode(getName().c_str(),getScript().c_str());
181 catch( const SALOME::SALOME_Exception& ex )
183 std::string msg="Exception on remote python node creation ";
185 msg += ex.details.text.in();
187 throw Exception(msg);
190 PyGILState_STATE gstate = PyGILState_Ensure();
191 const char picklizeScript[]="import cPickle\n"
192 "def pickleForDistPyth2009(kws):\n"
193 " return cPickle.dumps(((),kws),-1)\n"
195 "def unPickleForDistPyth2009(st):\n"
196 " args=cPickle.loads(st)\n"
198 PyObject *res=PyRun_String(picklizeScript,Py_file_input,_context,_context);
202 PyObject* new_stderr = newPyStdOut(_errorDetails);
203 PySys_SetObject((char*)"stderr", new_stderr);
205 PySys_SetObject((char*)"stderr", PySys_GetObject((char*)"__stderr__"));
206 Py_DECREF(new_stderr);
208 PyGILState_Release(gstate);
209 throw Exception("Error during load");
213 _pyfuncSer=PyDict_GetItemString(_context,"pickleForDistPyth2009");
214 _pyfuncUnser=PyDict_GetItemString(_context,"unPickleForDistPyth2009");
215 if(_pyfuncSer == NULL)
218 PyObject* new_stderr = newPyStdOut(_errorDetails);
219 PySys_SetObject((char*)"stderr", new_stderr);
221 PySys_SetObject((char*)"stderr", PySys_GetObject((char*)"__stderr__"));
222 Py_DECREF(new_stderr);
224 PyGILState_Release(gstate);
225 throw Exception("Error during load");
227 if(_pyfuncUnser == NULL)
230 PyObject* new_stderr = newPyStdOut(_errorDetails);
231 PySys_SetObject((char*)"stderr", new_stderr);
233 PySys_SetObject((char*)"stderr", PySys_GetObject((char*)"__stderr__"));
234 Py_DECREF(new_stderr);
236 PyGILState_Release(gstate);
237 throw Exception("Error during load");
239 DEBTRACE( "---------------End PyNode::loadRemote function---------------" );
240 PyGILState_Release(gstate);
244 void PythonNode::execute()
252 void PythonNode::executeRemote()
254 DEBTRACE( "++++++++++++++ PyNode::executeRemote: " << getName() << " ++++++++++++++++++++" );
256 throw Exception("DistributedPythonNode badly loaded");
257 PyGILState_STATE gstate = PyGILState_Ensure();
259 //===========================================================================
260 // Get inputs in input ports, build a Python dict and pickle it
261 //===========================================================================
263 PyObject* args = PyDict_New();
264 std::list<InputPort *>::iterator iter2;
266 for(iter2 = _setOfInputPort.begin(); iter2 != _setOfInputPort.end(); ++iter2)
268 InputPyPort *p=(InputPyPort *)*iter2;
270 PyDict_SetItemString(args,p->getName().c_str(),ob);
274 PyObject_Print(args,stderr,Py_PRINT_RAW);
277 PyObject *serializationInput=PyObject_CallFunctionObjArgs(_pyfuncSer,args,NULL);
278 //The pickled string may contain NULL characters so use PyString_AsStringAndSize
279 char* serializationInputC;
281 if (PyString_AsStringAndSize(serializationInput, &serializationInputC, &len))
283 PyGILState_Release(gstate);
284 throw Exception("DistributedPythonNode problem in python pickle");
286 PyGILState_Release(gstate);
288 Engines::pickledArgs_var serializationInputCorba=new Engines::pickledArgs;
289 serializationInputCorba->length(len);
290 for(int i=0; i < len ; i++)
291 serializationInputCorba[i]=serializationInputC[i];
293 //get the list of output argument names
294 std::list<OutputPort *>::iterator iter;
295 Engines::listofstring myseq;
296 myseq.length(getNumberOfOutputPorts());
298 for(iter = _setOfOutputPort.begin(); iter != _setOfOutputPort.end(); ++iter)
300 OutputPyPort *p=(OutputPyPort *)*iter;
301 myseq[pos]=p->getName().c_str();
302 DEBTRACE( "port name: " << p->getName() );
303 DEBTRACE( "port kind: " << p->edGetType()->kind() );
304 DEBTRACE( "port pos : " << pos );
307 //===========================================================================
308 // Execute in remote Python node
309 //===========================================================================
310 DEBTRACE( "-----------------starting remote python invocation-----------------" );
311 Engines::pickledArgs_var resultCorba;
314 //pass outargsname and dict serialized
315 resultCorba=_pynode->execute(myseq,serializationInputCorba);
317 catch( const SALOME::SALOME_Exception& ex )
319 std::string msg="Exception on remote python invocation";
321 msg += ex.details.text.in();
323 throw Exception(msg);
325 DEBTRACE( "-----------------end of remote python invocation-----------------" );
326 //===========================================================================
327 // Get results, unpickle and put them in output ports
328 //===========================================================================
329 char *resultCorbaC=new char[resultCorba->length()+1];
330 resultCorbaC[resultCorba->length()]='\0';
331 for(int i=0;i<resultCorba->length();i++)
332 resultCorbaC[i]=resultCorba[i];
334 gstate = PyGILState_Ensure();
336 PyObject* resultPython=PyString_FromStringAndSize(resultCorbaC,resultCorba->length());
337 delete [] resultCorbaC;
338 args = PyTuple_New(1);
339 PyTuple_SetItem(args,0,resultPython);
340 PyObject *finalResult=PyObject_CallObject(_pyfuncUnser,args);
343 if (finalResult == NULL)
345 std::stringstream msg;
346 msg << "Conversion with pickle of output ports failed !";
347 msg << " : " << __FILE__ << ":" << __LINE__;
348 PyGILState_Release(gstate);
349 _errorDetails=msg.str();
350 throw YACS::ENGINE::ConversionException(msg.str());
353 DEBTRACE( "-----------------PythonNode::outputs-----------------" );
355 if(finalResult == Py_None)
357 else if(PyTuple_Check(finalResult))
358 nres=PyTuple_Size(finalResult);
360 if(getNumberOfOutputPorts() != nres)
362 std::string msg="Number of output arguments : Mismatch between definition and execution";
363 Py_DECREF(finalResult);
364 PyGILState_Release(gstate);
366 throw Exception(msg);
372 for(iter = _setOfOutputPort.begin(); iter != _setOfOutputPort.end(); ++iter)
374 OutputPyPort *p=(OutputPyPort *)*iter;
375 DEBTRACE( "port name: " << p->getName() );
376 DEBTRACE( "port kind: " << p->edGetType()->kind() );
377 DEBTRACE( "port pos : " << pos );
378 if(PyTuple_Check(finalResult))
379 ob=PyTuple_GetItem(finalResult,pos) ;
382 DEBTRACE( "ob refcnt: " << ob->ob_refcnt );
386 Py_DECREF(finalResult);
388 catch(ConversionException& ex)
390 Py_DECREF(finalResult);
391 PyGILState_Release(gstate);
392 _errorDetails=ex.what();
396 PyGILState_Release(gstate);
398 DEBTRACE( "++++++++++++++ ENDOF PyNode::executeRemote: " << getName() << " ++++++++++++++++++++" );
401 void PythonNode::executeLocal()
403 DEBTRACE( "++++++++++++++ PyNode::executeLocal: " << getName() << " ++++++++++++++++++++" );
404 PyGILState_STATE gstate = PyGILState_Ensure();
406 DEBTRACE( "---------------PyNode::inputs---------------" );
407 list<InputPort *>::iterator iter2;
408 for(iter2 = _setOfInputPort.begin(); iter2 != _setOfInputPort.end(); iter2++)
410 InputPyPort *p=(InputPyPort *)*iter2;
411 DEBTRACE( "port name: " << p->getName() );
412 DEBTRACE( "port kind: " << p->edGetType()->kind() );
413 PyObject* ob=p->getPyObj();
414 DEBTRACE( "ob refcnt: " << ob->ob_refcnt );
416 PyObject_Print(ob,stderr,Py_PRINT_RAW);
419 int ier=PyDict_SetItemString(_context,p->getName().c_str(),ob);
420 DEBTRACE( "after PyDict_SetItemString:ob refcnt: " << ob->ob_refcnt );
423 DEBTRACE( "---------------End PyNode::inputs---------------" );
426 DEBTRACE( "----------------PyNode::calculation---------------" );
428 DEBTRACE( "_context refcnt: " << _context->ob_refcnt );
430 std::ostringstream stream;
431 stream << "/tmp/PythonNode_";
434 PyObject* code=Py_CompileString(_script.c_str(), stream.str().c_str(), Py_file_input);
438 PyObject* new_stderr = newPyStdOut(_errorDetails);
439 PySys_SetObject((char*)"stderr", new_stderr);
441 PySys_SetObject((char*)"stderr", PySys_GetObject((char*)"__stderr__"));
442 Py_DECREF(new_stderr);
443 PyGILState_Release(gstate);
444 throw Exception("Error during execution");
446 PyObject *res = PyEval_EvalCode((PyCodeObject *)code, _context, _context);
450 DEBTRACE( "_context refcnt: " << _context->ob_refcnt );
453 if(PyErr_Occurred ())
456 PyObject* new_stderr = newPyStdOut(_errorDetails);
457 PySys_SetObject((char*)"stderr", new_stderr);
458 ofstream errorfile(stream.str().c_str());
459 if (errorfile.is_open())
461 errorfile << _script;
465 PySys_SetObject((char*)"stderr", PySys_GetObject((char*)"__stderr__"));
466 Py_DECREF(new_stderr);
468 PyGILState_Release(gstate);
469 throw Exception("Error during execution");
472 DEBTRACE( "-----------------PyNode::outputs-----------------" );
473 list<OutputPort *>::iterator iter;
476 for(iter = _setOfOutputPort.begin(); iter != _setOfOutputPort.end(); iter++)
478 OutputPyPort *p=(OutputPyPort *)*iter;
479 DEBTRACE( "port name: " << p->getName() );
480 DEBTRACE( "port kind: " << p->edGetType()->kind() );
481 PyObject *ob=PyDict_GetItemString(_context,p->getName().c_str());
483 PyGILState_Release(gstate);
484 std::string msg="Error during execution: there is no variable ";
485 msg=msg+p->getName()+" in node context";
487 throw Exception(msg);
489 DEBTRACE( "PyNode::outputs::ob refcnt: " << ob->ob_refcnt );
491 PyObject_Print(ob,stderr,Py_PRINT_RAW);
497 catch(ConversionException& ex)
499 PyGILState_Release(gstate);
500 _errorDetails=ex.what();
504 DEBTRACE( "-----------------End PyNode::outputs-----------------" );
505 PyGILState_Release(gstate);
506 DEBTRACE( "++++++++++++++ End PyNode::execute: " << getName() << " ++++++++++++++++++++" );
509 std::string PythonNode::getContainerLog()
511 if(_mode=="local")return "";
516 Engines::Container_var objContainer=((SalomeContainer*)_container)->getContainerPtr(this);
517 CORBA::String_var logname = objContainer->logfilename();
520 std::string::size_type pos = msg.find(":");
521 msg=msg.substr(pos+1);
525 msg = "Container no longer reachable";
530 void PythonNode::shutdown(int level)
532 DEBTRACE("PythonNode::shutdown " << level);
533 if(_mode=="local")return;
536 if(!CORBA::is_nil(_pynode)) _pynode->UnRegister();
537 _pynode=Engines::PyScriptNode::_nil();
538 _container->shutdown(level);
542 Node *PythonNode::simpleClone(ComposedNode *father, bool editionOnly) const
544 return new PythonNode(*this,father);
547 //! Create a new node of same type with a given name
548 PythonNode* PythonNode::cloneNode(const std::string& name)
550 PythonNode* n=new PythonNode(name);
551 n->setScript(_script);
552 list<InputPort *>::iterator iter;
553 for(iter = _setOfInputPort.begin(); iter != _setOfInputPort.end(); iter++)
555 InputPyPort *p=(InputPyPort *)*iter;
556 DEBTRACE( "port name: " << p->getName() );
557 DEBTRACE( "port kind: " << p->edGetType()->kind() );
558 n->edAddInputPort(p->getName(),p->edGetType());
560 list<OutputPort *>::iterator iter2;
561 for(iter2 = _setOfOutputPort.begin(); iter2 != _setOfOutputPort.end(); iter2++)
563 OutputPyPort *p=(OutputPyPort *)*iter2;
564 DEBTRACE( "port name: " << p->getName() );
565 DEBTRACE( "port kind: " << p->edGetType()->kind() );
566 n->edAddOutputPort(p->getName(),p->edGetType());
571 PyFuncNode::PyFuncNode(const PyFuncNode& other, ComposedNode *father):InlineFuncNode(other,father),_pyfunc(0)
573 _implementation = PythonNode::IMPL_NAME;
574 PyGILState_STATE gstate = PyGILState_Ensure();
575 _context=PyDict_New();
576 DEBTRACE( "_context refcnt: " << _context->ob_refcnt );
577 if( PyDict_SetItemString( _context, "__builtins__", getSALOMERuntime()->getBuiltins() ))
580 msg << "Not possible to set builtins" << __FILE__ << ":" << __LINE__;
581 _errorDetails=msg.str();
582 PyGILState_Release(gstate);
583 throw Exception(msg.str());
585 PyGILState_Release(gstate);
588 PyFuncNode::PyFuncNode(const std::string& name): InlineFuncNode(name),_pyfunc(0)
591 _implementation = PythonNode::IMPL_NAME;
592 DEBTRACE( "PyFuncNode::PyFuncNode " << name );
593 PyGILState_STATE gstate = PyGILState_Ensure();
594 _context=PyDict_New();
595 DEBTRACE( "_context refcnt: " << _context->ob_refcnt );
596 if( PyDict_SetItemString( _context, "__builtins__", getSALOMERuntime()->getBuiltins() ))
599 msg << "Not possible to set builtins" << __FILE__ << ":" << __LINE__;
600 _errorDetails=msg.str();
601 PyGILState_Release(gstate);
602 throw Exception(msg.str());
604 PyGILState_Release(gstate);
607 PyFuncNode::~PyFuncNode()
609 DEBTRACE( getName() );
610 PyGILState_STATE gstate = PyGILState_Ensure();
611 DEBTRACE( "_context refcnt: " << _context->ob_refcnt );
612 if(_pyfunc)DEBTRACE( "_pyfunc refcnt: " << _pyfunc->ob_refcnt );
614 PyGILState_Release(gstate);
615 if(!CORBA::is_nil(_pynode))
617 _pynode->UnRegister();
621 void PyFuncNode::checkBasicConsistency() const throw(YACS::Exception)
623 DEBTRACE("checkBasicConsistency");
624 InlineFuncNode::checkBasicConsistency();
626 PyGILState_STATE gstate = PyGILState_Ensure();
628 res=Py_CompileString(_script.c_str(),getName().c_str(),Py_file_input);
631 std::string error="";
632 PyObject* new_stderr = newPyStdOut(error);
633 PySys_SetObject((char*)"stderr", new_stderr);
635 PySys_SetObject((char*)"stderr", PySys_GetObject((char*)"__stderr__"));
636 Py_DECREF(new_stderr);
637 PyGILState_Release(gstate);
638 throw Exception(error);
642 PyGILState_Release(gstate);
645 void PyFuncNode::load()
647 DEBTRACE( "---------------PyfuncNode::load function---------------" );
654 void PyFuncNode::loadRemote()
656 DEBTRACE( "---------------PyfuncNode::loadRemote function---------------" );
659 if(!_container->isAlreadyStarted(this))
663 _container->start(this);
667 _errorDetails=e.what();
674 std::string what("PyFuncNode::loadRemote : a load operation requested on \"");
675 what+=_name; what+="\" with no container specified.";
677 throw Exception(what);
680 Engines::Container_var objContainer=Engines::Container::_nil();
682 throw Exception("No container specified !");
683 SalomeContainer *containerCast0(dynamic_cast<SalomeContainer *>(_container));
684 SalomeHPContainer *containerCast1(dynamic_cast<SalomeHPContainer *>(_container));
686 objContainer=containerCast0->getContainerPtr(this);
687 else if(containerCast1)
689 YACS::BASES::AutoCppPtr<SalomeContainerTmpForHP> tmpCont(SalomeContainerTmpForHP::BuildFrom(containerCast1,this));
690 objContainer=tmpCont->getContainerPtr(this);
693 throw Exception("Unrecognized type of container ! Salome one is expected ! In PythonNode !");
694 if(CORBA::is_nil(objContainer))
695 throw Exception("Container corba pointer is NULL ! In PythonNode !");
699 _pynode = objContainer->createPyNode(getName().c_str(),getScript().c_str());
701 catch( const SALOME::SALOME_Exception& ex )
703 std::string msg="Exception on remote python node creation ";
705 msg += ex.details.text.in();
707 throw Exception(msg);
712 const char picklizeScript[]="import cPickle\n"
713 "def pickleForDistPyth2009(*args,**kws):\n"
714 " return cPickle.dumps((args,kws),-1)\n"
716 "def unPickleForDistPyth2009(st):\n"
717 " args=cPickle.loads(st)\n"
719 PyObject *res=PyRun_String(picklizeScript,Py_file_input,_context,_context);
723 PyObject* new_stderr = newPyStdOut(_errorDetails);
724 PySys_SetObject((char*)"stderr", new_stderr);
726 PySys_SetObject((char*)"stderr", PySys_GetObject((char*)"__stderr__"));
727 Py_DECREF(new_stderr);
728 throw Exception("Error during load");
732 _pyfuncSer=PyDict_GetItemString(_context,"pickleForDistPyth2009");
733 _pyfuncUnser=PyDict_GetItemString(_context,"unPickleForDistPyth2009");
734 if(_pyfuncSer == NULL)
737 PyObject* new_stderr = newPyStdOut(_errorDetails);
738 PySys_SetObject((char*)"stderr", new_stderr);
740 PySys_SetObject((char*)"stderr", PySys_GetObject((char*)"__stderr__"));
741 Py_DECREF(new_stderr);
742 throw Exception("Error during load");
744 if(_pyfuncUnser == NULL)
747 PyObject* new_stderr = newPyStdOut(_errorDetails);
748 PySys_SetObject((char*)"stderr", new_stderr);
750 PySys_SetObject((char*)"stderr", PySys_GetObject((char*)"__stderr__"));
751 Py_DECREF(new_stderr);
752 throw Exception("Error during load");
754 DEBTRACE( "---------------End PyfuncNode::loadRemote function---------------" );
758 void PyFuncNode::loadLocal()
760 DEBTRACE( "---------------PyFuncNode::load function " << getName() << " ---------------" );
764 list<OutputPort *>::iterator iter;
765 for(iter = _setOfOutputPort.begin(); iter != _setOfOutputPort.end(); iter++)
767 OutputPyPort *p=(OutputPyPort *)*iter;
768 DEBTRACE( "port name: " << p->getName() );
769 DEBTRACE( "port kind: " << p->edGetType()->kind() );
773 PyGILState_STATE gstate = PyGILState_Ensure();
774 DEBTRACE( "_context refcnt: " << _context->ob_refcnt );
776 std::ostringstream stream;
777 stream << "/tmp/PythonNode_";
780 PyObject* code=Py_CompileString(_script.c_str(), stream.str().c_str(), Py_file_input);
784 PyObject* new_stderr = newPyStdOut(_errorDetails);
785 PySys_SetObject((char*)"stderr", new_stderr);
787 PySys_SetObject((char*)"stderr", PySys_GetObject((char*)"__stderr__"));
788 Py_DECREF(new_stderr);
789 PyGILState_Release(gstate);
790 throw Exception("Error during execution");
792 PyObject *res = PyEval_EvalCode((PyCodeObject *)code, _context, _context);
796 DEBTRACE( "_context refcnt: " << _context->ob_refcnt );
797 if(PyErr_Occurred ())
800 PyObject* new_stderr = newPyStdOut(_errorDetails);
801 PySys_SetObject((char*)"stderr", new_stderr);
802 ofstream errorfile(stream.str().c_str());
803 if (errorfile.is_open())
805 errorfile << _script;
809 PySys_SetObject((char*)"stderr", PySys_GetObject((char*)"__stderr__"));
810 Py_DECREF(new_stderr);
812 PyGILState_Release(gstate);
813 throw Exception("Error during execution");
816 _pyfunc=PyDict_GetItemString(_context,_fname.c_str());
817 DEBTRACE( "_pyfunc refcnt: " << _pyfunc->ob_refcnt );
821 PyObject* new_stderr = newPyStdOut(_errorDetails);
822 PySys_SetObject((char*)"stderr", new_stderr);
824 PySys_SetObject((char*)"stderr", PySys_GetObject((char*)"__stderr__"));
825 Py_DECREF(new_stderr);
827 PyGILState_Release(gstate);
828 throw Exception("Error during execution");
830 DEBTRACE( "---------------End PyFuncNode::load function---------------" );
831 PyGILState_Release(gstate);
834 void PyFuncNode::execute()
842 void PyFuncNode::executeRemote()
844 DEBTRACE( "++++++++++++++ PyFuncNode::executeRemote: " << getName() << " ++++++++++++++++++++" );
846 throw Exception("DistributedPythonNode badly loaded");
848 char *serializationInputC(0);
849 PyObject *args(0),*ob(0);
854 //===========================================================================
855 // Get inputs in input ports, build a Python tuple and pickle it
856 //===========================================================================
857 args = PyTuple_New(getNumberOfInputPorts());
858 std::list<InputPort *>::iterator iter2;
859 for(iter2 = _setOfInputPort.begin(); iter2 != _setOfInputPort.end(); ++iter2)
861 InputPyPort *p=(InputPyPort *)*iter2;
864 PyTuple_SetItem(args,pos,ob);
868 PyObject_Print(args,stderr,Py_PRINT_RAW);
871 PyObject *serializationInput=PyObject_CallObject(_pyfuncSer,args);
872 //The pickled string may contain NULL characters so use PyString_AsStringAndSize
873 if (PyString_AsStringAndSize(serializationInput, &serializationInputC, &len))
874 throw Exception("DistributedPythonNode problem in python pickle");
877 Engines::pickledArgs_var serializationInputCorba=new Engines::pickledArgs;
878 serializationInputCorba->length(len);
879 for(int i=0; i < len ; i++)
880 serializationInputCorba[i]=serializationInputC[i];
882 //===========================================================================
883 // Execute in remote Python node
884 //===========================================================================
885 DEBTRACE( "-----------------starting remote python invocation-----------------" );
886 Engines::pickledArgs_var resultCorba;
889 resultCorba=_pynode->execute(getFname().c_str(),serializationInputCorba);
891 catch( const SALOME::SALOME_Exception& ex )
893 std::string msg="Exception on remote python invocation";
895 msg += ex.details.text.in();
897 throw Exception(msg);
899 DEBTRACE( "-----------------end of remote python invocation-----------------" );
900 //===========================================================================
901 // Get results, unpickle and put them in output ports
902 //===========================================================================
903 char *resultCorbaC=new char[resultCorba->length()+1];
904 resultCorbaC[resultCorba->length()]='\0';
905 for(int i=0;i<resultCorba->length();i++)
906 resultCorbaC[i]=resultCorba[i];
911 PyObject* resultPython=PyString_FromStringAndSize(resultCorbaC,resultCorba->length());
912 delete [] resultCorbaC;
913 args = PyTuple_New(1);
914 PyTuple_SetItem(args,0,resultPython);
915 PyObject *finalResult=PyObject_CallObject(_pyfuncUnser,args);
918 DEBTRACE( "-----------------PythonNode::outputs-----------------" );
920 if(finalResult == Py_None)
922 else if(PyTuple_Check(finalResult))
923 nres=PyTuple_Size(finalResult);
925 if(getNumberOfOutputPorts() != nres)
927 std::string msg="Number of output arguments : Mismatch between definition and execution";
928 Py_DECREF(finalResult);
930 throw Exception(msg);
934 std::list<OutputPort *>::iterator iter;
937 for(iter = _setOfOutputPort.begin(); iter != _setOfOutputPort.end(); ++iter)
939 OutputPyPort *p=(OutputPyPort *)*iter;
940 DEBTRACE( "port name: " << p->getName() );
941 DEBTRACE( "port kind: " << p->edGetType()->kind() );
942 DEBTRACE( "port pos : " << pos );
943 if(PyTuple_Check(finalResult))
944 ob=PyTuple_GetItem(finalResult,pos) ;
947 DEBTRACE( "ob refcnt: " << ob->ob_refcnt );
951 Py_DECREF(finalResult);
953 catch(ConversionException& ex)
955 Py_DECREF(finalResult);
956 _errorDetails=ex.what();
961 DEBTRACE( "++++++++++++++ ENDOF PyFuncNode::executeRemote: " << getName() << " ++++++++++++++++++++" );
964 void PyFuncNode::executeLocal()
966 DEBTRACE( "++++++++++++++ PyFuncNode::execute: " << getName() << " ++++++++++++++++++++" );
970 if(!_pyfunc)throw Exception("PyFuncNode badly loaded");
971 PyGILState_STATE gstate = PyGILState_Ensure();
973 DEBTRACE( "---------------PyFuncNode::inputs---------------" );
974 PyObject* args = PyTuple_New(getNumberOfInputPorts()) ;
975 list<InputPort *>::iterator iter2;
976 for(iter2 = _setOfInputPort.begin(); iter2 != _setOfInputPort.end(); iter2++)
978 InputPyPort *p=(InputPyPort *)*iter2;
979 DEBTRACE( "port name: " << p->getName() );
980 DEBTRACE( "port kind: " << p->edGetType()->kind() );
983 PyObject_Print(ob,stderr,Py_PRINT_RAW);
986 DEBTRACE( "ob refcnt: " << ob->ob_refcnt );
988 PyTuple_SetItem(args,pos,ob);
989 DEBTRACE( "ob refcnt: " << ob->ob_refcnt );
992 DEBTRACE( "---------------End PyFuncNode::inputs---------------" );
994 DEBTRACE( "----------------PyFuncNode::calculation---------------" );
996 PyObject_Print(_pyfunc,stderr,Py_PRINT_RAW);
998 PyObject_Print(args,stderr,Py_PRINT_RAW);
1001 DEBTRACE( "_pyfunc refcnt: " << _pyfunc->ob_refcnt );
1002 PyObject* result = PyObject_CallObject( _pyfunc , args ) ;
1003 DEBTRACE( "_pyfunc refcnt: " << _pyfunc->ob_refcnt );
1010 PyObject* new_stderr = newPyStdOut(_errorDetails);
1011 PySys_SetObject((char*)"stderr", new_stderr);
1012 std::ostringstream stream;
1013 stream << "/tmp/PythonNode_";
1015 ofstream errorfile(stream.str().c_str());
1016 if (errorfile.is_open())
1018 errorfile << _script;
1022 PySys_SetObject((char*)"stderr", PySys_GetObject((char*)"__stderr__"));
1023 Py_DECREF(new_stderr);
1025 PyGILState_Release(gstate);
1026 throw Exception("Error during execution");
1028 DEBTRACE( "----------------End PyFuncNode::calculation---------------" );
1030 DEBTRACE( "-----------------PyFuncNode::outputs-----------------" );
1032 if(result == Py_None)
1034 else if(PyTuple_Check(result))
1035 nres=PyTuple_Size(result);
1037 if(getNumberOfOutputPorts() != nres)
1039 std::string msg="Number of output arguments : Mismatch between definition and execution";
1041 PyGILState_Release(gstate);
1043 throw Exception(msg);
1048 PyObject_Print(result,stderr,Py_PRINT_RAW);
1051 list<OutputPort *>::iterator iter;
1054 for(iter = _setOfOutputPort.begin(); iter != _setOfOutputPort.end(); iter++)
1056 OutputPyPort *p=(OutputPyPort *)*iter;
1057 DEBTRACE( "port name: " << p->getName() );
1058 DEBTRACE( "port kind: " << p->edGetType()->kind() );
1059 DEBTRACE( "port pos : " << pos );
1060 if(PyTuple_Check(result))ob=PyTuple_GetItem(result,pos) ;
1062 DEBTRACE( "ob refcnt: " << ob->ob_refcnt );
1064 PyObject_Print(ob,stderr,Py_PRINT_RAW);
1071 catch(ConversionException& ex)
1074 PyGILState_Release(gstate);
1075 _errorDetails=ex.what();
1078 DEBTRACE( "-----------------End PyFuncNode::outputs-----------------" );
1081 PyGILState_Release(gstate);
1082 DEBTRACE( "++++++++++++++ End PyFuncNode::execute: " << getName() << " ++++++++++++++++++++" );
1085 Node *PyFuncNode::simpleClone(ComposedNode *father, bool editionOnly) const
1087 return new PyFuncNode(*this,father);
1090 //! Create a new node of same type with a given name
1091 PyFuncNode* PyFuncNode::cloneNode(const std::string& name)
1093 PyFuncNode* n=new PyFuncNode(name);
1094 n->setScript(_script);
1095 n->setFname(_fname);
1096 list<InputPort *>::iterator iter;
1097 for(iter = _setOfInputPort.begin(); iter != _setOfInputPort.end(); iter++)
1099 InputPyPort *p=(InputPyPort *)*iter;
1100 n->edAddInputPort(p->getName(),p->edGetType());
1102 list<OutputPort *>::iterator iter2;
1103 for(iter2 = _setOfOutputPort.begin(); iter2 != _setOfOutputPort.end(); iter2++)
1105 OutputPyPort *p=(OutputPyPort *)*iter2;
1106 n->edAddOutputPort(p->getName(),p->edGetType());
1111 std::string PyFuncNode::getContainerLog()
1113 if(_mode=="local")return "";
1118 Engines::Container_var objContainer=((SalomeContainer*)_container)->getContainerPtr(this);
1119 CORBA::String_var logname = objContainer->logfilename();
1122 std::string::size_type pos = msg.find(":");
1123 msg=msg.substr(pos+1);
1127 msg = "Container no longer reachable";
1132 void PyFuncNode::shutdown(int level)
1134 DEBTRACE("PyFuncNode::shutdown " << level);
1135 if(_mode=="local")return;
1138 if(!CORBA::is_nil(_pynode)) _pynode->UnRegister();
1139 _pynode=Engines::PyNode::_nil();
1140 _container->shutdown(level);