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;
59 _context=PyDict_New();
60 if( PyDict_SetItemString( _context, "__builtins__", getSALOMERuntime()->getBuiltins() ))
63 msg << "Impossible to set builtins" << __FILE__ << ":" << __LINE__;
64 _errorDetails=msg.str();
65 throw Exception(msg.str());
70 PythonNode::PythonNode(const std::string& name):InlineNode(name)
72 _implementation=IMPL_NAME;
75 _context=PyDict_New();
76 if( PyDict_SetItemString( _context, "__builtins__", getSALOMERuntime()->getBuiltins() ))
79 msg << "Impossible to set builtins" << __FILE__ << ":" << __LINE__;
80 _errorDetails=msg.str();
81 throw Exception(msg.str());
86 PythonNode::~PythonNode()
89 DEBTRACE( "_context refcnt: " << _context->ob_refcnt );
93 void PythonNode::checkBasicConsistency() const throw(YACS::Exception)
95 DEBTRACE("checkBasicConsistency");
96 InlineNode::checkBasicConsistency();
100 res=Py_CompileString(_script.c_str(),getName().c_str(),Py_file_input);
103 std::string error="";
104 PyObject* new_stderr = newPyStdOut(error);
105 PySys_SetObject((char*)"stderr", new_stderr);
107 PySys_SetObject((char*)"stderr", PySys_GetObject((char*)"__stderr__"));
108 Py_DECREF(new_stderr);
109 throw Exception(error);
116 void PythonNode::load()
118 DEBTRACE( "---------------PyNode::load function---------------" );
125 void PythonNode::loadLocal()
127 DEBTRACE( "---------------PyNode::loadLocal function---------------" );
131 void PythonNode::loadRemote()
133 DEBTRACE( "---------------PyNode::loadRemote function---------------" );
134 bool isContAlreadyStarted(false);
137 isContAlreadyStarted=_container->isAlreadyStarted(this);
138 if(!isContAlreadyStarted)
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 !");
176 bool isInitializeRequested(false);
179 if(containerCast0 || !isContAlreadyStarted)
181 _pynode = objContainer->createPyScriptNode(getName().c_str(),getScript().c_str());
185 Engines::PyScriptNode_var dftPyScript(objContainer->getDefaultPyScriptNode());
186 if(CORBA::is_nil(dftPyScript))
188 isInitializeRequested=true;
189 _pynode = objContainer->createPyScriptNode(getName().c_str(),getScript().c_str());
192 _pynode = dftPyScript;
195 catch( const SALOME::SALOME_Exception& ex )
197 std::string msg="Exception on remote python node creation ";
199 msg += ex.details.text.in();
201 throw Exception(msg);
204 if(CORBA::is_nil(_pynode))
205 throw Exception("In PythonNode the ref in NULL ! ");
210 const char picklizeScript[]="import cPickle\n"
211 "def pickleForDistPyth2009(kws):\n"
212 " return cPickle.dumps(((),kws),-1)\n"
214 "def unPickleForDistPyth2009(st):\n"
215 " args=cPickle.loads(st)\n"
217 PyObject *res=PyRun_String(picklizeScript,Py_file_input,_context,_context);
221 PyObject* new_stderr = newPyStdOut(_errorDetails);
222 PySys_SetObject((char*)"stderr", new_stderr);
224 PySys_SetObject((char*)"stderr", PySys_GetObject((char*)"__stderr__"));
225 Py_DECREF(new_stderr);
226 throw Exception("Error during load");
230 _pyfuncSer=PyDict_GetItemString(_context,"pickleForDistPyth2009");
231 _pyfuncUnser=PyDict_GetItemString(_context,"unPickleForDistPyth2009");
232 if(_pyfuncSer == NULL)
235 PyObject* new_stderr = newPyStdOut(_errorDetails);
236 PySys_SetObject((char*)"stderr", new_stderr);
238 PySys_SetObject((char*)"stderr", PySys_GetObject((char*)"__stderr__"));
239 Py_DECREF(new_stderr);
240 throw Exception("Error during load");
242 if(_pyfuncUnser == NULL)
245 PyObject* new_stderr = newPyStdOut(_errorDetails);
246 PySys_SetObject((char*)"stderr", new_stderr);
248 PySys_SetObject((char*)"stderr", PySys_GetObject((char*)"__stderr__"));
249 Py_DECREF(new_stderr);
250 throw Exception("Error during load");
252 if(isInitializeRequested)
253 {//This one is called only once at initialization in the container if an init-script is specified.
256 std::string zeInitScriptKey(_container->getProperty(HomogeneousPoolContainer::INITIALIZE_SCRIPT_KEY));
257 if(!zeInitScriptKey.empty())
258 _pynode->executeAnotherPieceOfCode(zeInitScriptKey.c_str());
260 catch( const SALOME::SALOME_Exception& ex )
262 std::string msg="Exception on PythonNode::loadRemote python invocation of initializisation py script !";
264 msg += ex.details.text.in();
266 throw Exception(msg);
269 DEBTRACE( "---------------End PyNode::loadRemote function---------------" );
273 void PythonNode::execute()
281 void PythonNode::executeRemote()
283 DEBTRACE( "++++++++++++++ PyNode::executeRemote: " << getName() << " ++++++++++++++++++++" );
285 throw Exception("DistributedPythonNode badly loaded");
286 Engines::pickledArgs_var serializationInputCorba(new Engines::pickledArgs);
289 PyObject *args(0),*ob(0);
290 //===========================================================================
291 // Get inputs in input ports, build a Python dict and pickle it
292 //===========================================================================
294 std::list<InputPort *>::iterator iter2;
296 for(iter2 = _setOfInputPort.begin(); iter2 != _setOfInputPort.end(); ++iter2)
298 InputPyPort *p=(InputPyPort *)*iter2;
300 PyDict_SetItemString(args,p->getName().c_str(),ob);
304 PyObject_Print(args,stderr,Py_PRINT_RAW);
307 PyObject *serializationInput(PyObject_CallFunctionObjArgs(_pyfuncSer,args,NULL));
309 //The pickled string may contain NULL characters so use PyString_AsStringAndSize
310 char *serializationInputC(0);
312 if (PyString_AsStringAndSize(serializationInput, &serializationInputC, &len))
313 throw Exception("DistributedPythonNode problem in python pickle");
314 serializationInputCorba->length(len);
315 for(int i=0; i < len ; i++)
316 serializationInputCorba[i]=serializationInputC[i];
317 Py_DECREF(serializationInput);
320 //get the list of output argument names
321 std::list<OutputPort *>::iterator iter;
322 Engines::listofstring myseq;
323 myseq.length(getNumberOfOutputPorts());
325 for(iter = _setOfOutputPort.begin(); iter != _setOfOutputPort.end(); ++iter)
327 OutputPyPort *p=(OutputPyPort *)*iter;
328 myseq[pos]=p->getName().c_str();
329 DEBTRACE( "port name: " << p->getName() );
330 DEBTRACE( "port kind: " << p->edGetType()->kind() );
331 DEBTRACE( "port pos : " << pos );
334 //===========================================================================
335 // Execute in remote Python node
336 //===========================================================================
337 DEBTRACE( "-----------------starting remote python invocation-----------------" );
338 Engines::pickledArgs_var resultCorba;
341 //pass outargsname and dict serialized
342 resultCorba=_pynode->execute(myseq,serializationInputCorba);
344 catch( const SALOME::SALOME_Exception& ex )
346 std::string msg="Exception on remote python invocation";
348 msg += ex.details.text.in();
350 throw Exception(msg);
352 DEBTRACE( "-----------------end of remote python invocation-----------------" );
353 //===========================================================================
354 // Get results, unpickle and put them in output ports
355 //===========================================================================
356 char *resultCorbaC=new char[resultCorba->length()+1];
357 resultCorbaC[resultCorba->length()]='\0';
358 for(int i=0;i<resultCorba->length();i++)
359 resultCorbaC[i]=resultCorba[i];
363 PyObject *args(0),*ob(0);
364 PyObject* resultPython=PyString_FromStringAndSize(resultCorbaC,resultCorba->length());
365 delete [] resultCorbaC;
366 args = PyTuple_New(1);
367 PyTuple_SetItem(args,0,resultPython);
368 PyObject *finalResult=PyObject_CallObject(_pyfuncUnser,args);
371 if (finalResult == NULL)
373 std::stringstream msg;
374 msg << "Conversion with pickle of output ports failed !";
375 msg << " : " << __FILE__ << ":" << __LINE__;
376 _errorDetails=msg.str();
377 throw YACS::ENGINE::ConversionException(msg.str());
380 DEBTRACE( "-----------------PythonNode::outputs-----------------" );
382 if(finalResult == Py_None)
384 else if(PyTuple_Check(finalResult))
385 nres=PyTuple_Size(finalResult);
387 if(getNumberOfOutputPorts() != nres)
389 std::string msg="Number of output arguments : Mismatch between definition and execution";
390 Py_DECREF(finalResult);
392 throw Exception(msg);
398 for(iter = _setOfOutputPort.begin(); iter != _setOfOutputPort.end(); ++iter)
400 OutputPyPort *p=(OutputPyPort *)*iter;
401 DEBTRACE( "port name: " << p->getName() );
402 DEBTRACE( "port kind: " << p->edGetType()->kind() );
403 DEBTRACE( "port pos : " << pos );
404 if(PyTuple_Check(finalResult))
405 ob=PyTuple_GetItem(finalResult,pos) ;
408 DEBTRACE( "ob refcnt: " << ob->ob_refcnt );
412 Py_DECREF(finalResult);
414 catch(ConversionException& ex)
416 Py_DECREF(finalResult);
417 _errorDetails=ex.what();
421 DEBTRACE( "++++++++++++++ ENDOF PyNode::executeRemote: " << getName() << " ++++++++++++++++++++" );
424 void PythonNode::executeLocal()
426 DEBTRACE( "++++++++++++++ PyNode::executeLocal: " << getName() << " ++++++++++++++++++++" );
430 DEBTRACE( "---------------PyNode::inputs---------------" );
431 list<InputPort *>::iterator iter2;
432 for(iter2 = _setOfInputPort.begin(); iter2 != _setOfInputPort.end(); iter2++)
434 InputPyPort *p=(InputPyPort *)*iter2;
435 DEBTRACE( "port name: " << p->getName() );
436 DEBTRACE( "port kind: " << p->edGetType()->kind() );
437 PyObject* ob=p->getPyObj();
438 DEBTRACE( "ob refcnt: " << ob->ob_refcnt );
440 PyObject_Print(ob,stderr,Py_PRINT_RAW);
443 int ier=PyDict_SetItemString(_context,p->getName().c_str(),ob);
444 DEBTRACE( "after PyDict_SetItemString:ob refcnt: " << ob->ob_refcnt );
447 DEBTRACE( "---------------End PyNode::inputs---------------" );
450 DEBTRACE( "----------------PyNode::calculation---------------" );
452 DEBTRACE( "_context refcnt: " << _context->ob_refcnt );
454 std::ostringstream stream;
455 stream << "/tmp/PythonNode_";
458 PyObject* code=Py_CompileString(_script.c_str(), stream.str().c_str(), Py_file_input);
462 PyObject* new_stderr = newPyStdOut(_errorDetails);
463 PySys_SetObject((char*)"stderr", new_stderr);
465 PySys_SetObject((char*)"stderr", PySys_GetObject((char*)"__stderr__"));
466 Py_DECREF(new_stderr);
467 throw Exception("Error during execution");
469 PyObject *res = PyEval_EvalCode((PyCodeObject *)code, _context, _context);
473 DEBTRACE( "_context refcnt: " << _context->ob_refcnt );
476 if(PyErr_Occurred ())
479 PyObject* new_stderr = newPyStdOut(_errorDetails);
480 PySys_SetObject((char*)"stderr", new_stderr);
481 ofstream errorfile(stream.str().c_str());
482 if (errorfile.is_open())
484 errorfile << _script;
488 PySys_SetObject((char*)"stderr", PySys_GetObject((char*)"__stderr__"));
489 Py_DECREF(new_stderr);
490 throw Exception("Error during execution");
493 DEBTRACE( "-----------------PyNode::outputs-----------------" );
494 list<OutputPort *>::iterator iter;
497 for(iter = _setOfOutputPort.begin(); iter != _setOfOutputPort.end(); iter++)
499 OutputPyPort *p=(OutputPyPort *)*iter;
500 DEBTRACE( "port name: " << p->getName() );
501 DEBTRACE( "port kind: " << p->edGetType()->kind() );
502 PyObject *ob=PyDict_GetItemString(_context,p->getName().c_str());
505 std::string msg="Error during execution: there is no variable ";
506 msg=msg+p->getName()+" in node context";
508 throw Exception(msg);
510 DEBTRACE( "PyNode::outputs::ob refcnt: " << ob->ob_refcnt );
512 PyObject_Print(ob,stderr,Py_PRINT_RAW);
518 catch(ConversionException& ex)
520 _errorDetails=ex.what();
524 DEBTRACE( "-----------------End PyNode::outputs-----------------" );
526 DEBTRACE( "++++++++++++++ End PyNode::execute: " << getName() << " ++++++++++++++++++++" );
529 std::string PythonNode::getContainerLog()
531 if(_mode=="local")return "";
536 Engines::Container_var objContainer=((SalomeContainer*)_container)->getContainerPtr(this);
537 CORBA::String_var logname = objContainer->logfilename();
540 std::string::size_type pos = msg.find(":");
541 msg=msg.substr(pos+1);
545 msg = "Container no longer reachable";
550 void PythonNode::shutdown(int level)
552 DEBTRACE("PythonNode::shutdown " << level);
553 if(_mode=="local")return;
556 if(!CORBA::is_nil(_pynode)) _pynode->UnRegister();
557 _pynode=Engines::PyScriptNode::_nil();
558 _container->shutdown(level);
562 Node *PythonNode::simpleClone(ComposedNode *father, bool editionOnly) const
564 return new PythonNode(*this,father);
567 //! Create a new node of same type with a given name
568 PythonNode* PythonNode::cloneNode(const std::string& name)
570 PythonNode* n=new PythonNode(name);
571 n->setScript(_script);
572 list<InputPort *>::iterator iter;
573 for(iter = _setOfInputPort.begin(); iter != _setOfInputPort.end(); iter++)
575 InputPyPort *p=(InputPyPort *)*iter;
576 DEBTRACE( "port name: " << p->getName() );
577 DEBTRACE( "port kind: " << p->edGetType()->kind() );
578 n->edAddInputPort(p->getName(),p->edGetType());
580 list<OutputPort *>::iterator iter2;
581 for(iter2 = _setOfOutputPort.begin(); iter2 != _setOfOutputPort.end(); iter2++)
583 OutputPyPort *p=(OutputPyPort *)*iter2;
584 DEBTRACE( "port name: " << p->getName() );
585 DEBTRACE( "port kind: " << p->edGetType()->kind() );
586 n->edAddOutputPort(p->getName(),p->edGetType());
591 PyFuncNode::PyFuncNode(const PyFuncNode& other, ComposedNode *father):InlineFuncNode(other,father),_pyfunc(0)
593 _implementation = PythonNode::IMPL_NAME;
596 _context=PyDict_New();
597 DEBTRACE( "_context refcnt: " << _context->ob_refcnt );
598 if( PyDict_SetItemString( _context, "__builtins__", getSALOMERuntime()->getBuiltins() ))
601 msg << "Not possible to set builtins" << __FILE__ << ":" << __LINE__;
602 _errorDetails=msg.str();
603 throw Exception(msg.str());
608 PyFuncNode::PyFuncNode(const std::string& name): InlineFuncNode(name),_pyfunc(0)
611 _implementation = PythonNode::IMPL_NAME;
612 DEBTRACE( "PyFuncNode::PyFuncNode " << name );
615 _context=PyDict_New();
616 DEBTRACE( "_context refcnt: " << _context->ob_refcnt );
617 if( PyDict_SetItemString( _context, "__builtins__", getSALOMERuntime()->getBuiltins() ))
620 msg << "Not possible to set builtins" << __FILE__ << ":" << __LINE__;
621 _errorDetails=msg.str();
622 throw Exception(msg.str());
627 PyFuncNode::~PyFuncNode()
629 DEBTRACE( getName() );
632 DEBTRACE( "_context refcnt: " << _context->ob_refcnt );
633 if(_pyfunc)DEBTRACE( "_pyfunc refcnt: " << _pyfunc->ob_refcnt );
636 if(!CORBA::is_nil(_pynode))
638 _pynode->UnRegister();
642 void PyFuncNode::checkBasicConsistency() const throw(YACS::Exception)
644 DEBTRACE("checkBasicConsistency");
645 InlineFuncNode::checkBasicConsistency();
649 res=Py_CompileString(_script.c_str(),getName().c_str(),Py_file_input);
652 std::string error="";
653 PyObject* new_stderr = newPyStdOut(error);
654 PySys_SetObject((char*)"stderr", new_stderr);
656 PySys_SetObject((char*)"stderr", PySys_GetObject((char*)"__stderr__"));
657 Py_DECREF(new_stderr);
658 throw Exception(error);
665 void PyFuncNode::load()
667 DEBTRACE( "---------------PyfuncNode::load function---------------" );
674 void PyFuncNode::loadRemote()
676 DEBTRACE( "---------------PyfuncNode::loadRemote function---------------" );
677 bool isContAlreadyStarted(false);
680 isContAlreadyStarted=_container->isAlreadyStarted(this);
681 if(!isContAlreadyStarted)
685 _container->start(this);
689 _errorDetails=e.what();
696 std::string what("PyFuncNode::loadRemote : a load operation requested on \"");
697 what+=_name; what+="\" with no container specified.";
699 throw Exception(what);
702 Engines::Container_var objContainer=Engines::Container::_nil();
704 throw Exception("No container specified !");
705 SalomeContainer *containerCast0(dynamic_cast<SalomeContainer *>(_container));
706 SalomeHPContainer *containerCast1(dynamic_cast<SalomeHPContainer *>(_container));
708 objContainer=containerCast0->getContainerPtr(this);
709 else if(containerCast1)
711 YACS::BASES::AutoCppPtr<SalomeContainerTmpForHP> tmpCont(SalomeContainerTmpForHP::BuildFrom(containerCast1,this));
712 objContainer=tmpCont->getContainerPtr(this);
715 throw Exception("Unrecognized type of container ! Salome one is expected ! In PythonNode !");
716 if(CORBA::is_nil(objContainer))
717 throw Exception("Container corba pointer is NULL ! In PythonNode !");
721 if(containerCast0 || !isContAlreadyStarted)
723 _pynode = objContainer->createPyNode(getName().c_str(),getScript().c_str());
727 Engines::PyNode_var dftPyScript(objContainer->getDefaultPyNode());
728 if(CORBA::is_nil(dftPyScript))
729 _pynode = objContainer->createPyNode(getName().c_str(),getScript().c_str());
731 _pynode = dftPyScript;
734 catch( const SALOME::SALOME_Exception& ex )
736 std::string msg="Exception on remote python node creation ";
738 msg += ex.details.text.in();
740 throw Exception(msg);
743 if(CORBA::is_nil(_pynode))
744 throw Exception("In PyFuncNode the ref in NULL ! ");
748 const char picklizeScript[]="import cPickle\n"
749 "def pickleForDistPyth2009(*args,**kws):\n"
750 " return cPickle.dumps((args,kws),-1)\n"
752 "def unPickleForDistPyth2009(st):\n"
753 " args=cPickle.loads(st)\n"
755 PyObject *res=PyRun_String(picklizeScript,Py_file_input,_context,_context);
759 PyObject* new_stderr = newPyStdOut(_errorDetails);
760 PySys_SetObject((char*)"stderr", new_stderr);
762 PySys_SetObject((char*)"stderr", PySys_GetObject((char*)"__stderr__"));
763 Py_DECREF(new_stderr);
764 throw Exception("Error during load");
768 _pyfuncSer=PyDict_GetItemString(_context,"pickleForDistPyth2009");
769 _pyfuncUnser=PyDict_GetItemString(_context,"unPickleForDistPyth2009");
770 if(_pyfuncSer == NULL)
773 PyObject* new_stderr = newPyStdOut(_errorDetails);
774 PySys_SetObject((char*)"stderr", new_stderr);
776 PySys_SetObject((char*)"stderr", PySys_GetObject((char*)"__stderr__"));
777 Py_DECREF(new_stderr);
778 throw Exception("Error during load");
780 if(_pyfuncUnser == NULL)
783 PyObject* new_stderr = newPyStdOut(_errorDetails);
784 PySys_SetObject((char*)"stderr", new_stderr);
786 PySys_SetObject((char*)"stderr", PySys_GetObject((char*)"__stderr__"));
787 Py_DECREF(new_stderr);
788 throw Exception("Error during load");
790 DEBTRACE( "---------------End PyfuncNode::loadRemote function---------------" );
794 void PyFuncNode::loadLocal()
796 DEBTRACE( "---------------PyFuncNode::load function " << getName() << " ---------------" );
800 list<OutputPort *>::iterator iter;
801 for(iter = _setOfOutputPort.begin(); iter != _setOfOutputPort.end(); iter++)
803 OutputPyPort *p=(OutputPyPort *)*iter;
804 DEBTRACE( "port name: " << p->getName() );
805 DEBTRACE( "port kind: " << p->edGetType()->kind() );
811 DEBTRACE( "_context refcnt: " << _context->ob_refcnt );
813 std::ostringstream stream;
814 stream << "/tmp/PythonNode_";
817 PyObject* code=Py_CompileString(_script.c_str(), stream.str().c_str(), Py_file_input);
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);
826 throw Exception("Error during execution");
828 PyObject *res = PyEval_EvalCode((PyCodeObject *)code, _context, _context);
832 DEBTRACE( "_context refcnt: " << _context->ob_refcnt );
833 if(PyErr_Occurred ())
836 PyObject* new_stderr = newPyStdOut(_errorDetails);
837 PySys_SetObject((char*)"stderr", new_stderr);
838 ofstream errorfile(stream.str().c_str());
839 if (errorfile.is_open())
841 errorfile << _script;
845 PySys_SetObject((char*)"stderr", PySys_GetObject((char*)"__stderr__"));
846 Py_DECREF(new_stderr);
847 throw Exception("Error during execution");
850 _pyfunc=PyDict_GetItemString(_context,_fname.c_str());
851 DEBTRACE( "_pyfunc refcnt: " << _pyfunc->ob_refcnt );
855 PyObject* new_stderr = newPyStdOut(_errorDetails);
856 PySys_SetObject((char*)"stderr", new_stderr);
858 PySys_SetObject((char*)"stderr", PySys_GetObject((char*)"__stderr__"));
859 Py_DECREF(new_stderr);
860 throw Exception("Error during execution");
862 DEBTRACE( "---------------End PyFuncNode::load function---------------" );
866 void PyFuncNode::execute()
874 void PyFuncNode::executeRemote()
876 DEBTRACE( "++++++++++++++ PyFuncNode::executeRemote: " << getName() << " ++++++++++++++++++++" );
878 throw Exception("DistributedPythonNode badly loaded");
879 Engines::pickledArgs_var serializationInputCorba(new Engines::pickledArgs);;
883 //===========================================================================
884 // Get inputs in input ports, build a Python tuple and pickle it
885 //===========================================================================
886 PyObject *args(PyTuple_New(getNumberOfInputPorts()));
888 for(std::list<InputPort *>::iterator iter2 = _setOfInputPort.begin(); iter2 != _setOfInputPort.end(); iter2++,pos++)
890 InputPyPort *p=(InputPyPort *)*iter2;
893 PyTuple_SetItem(args,pos,ob);
896 PyObject_Print(args,stderr,Py_PRINT_RAW);
899 PyObject *serializationInput=PyObject_CallObject(_pyfuncSer,args);
901 //The pickled string may contain NULL characters so use PyString_AsStringAndSize
902 char *serializationInputC(0);
904 if (PyString_AsStringAndSize(serializationInput, &serializationInputC, &len))
905 throw Exception("DistributedPythonNode problem in python pickle");
907 serializationInputCorba->length(len);
908 for(int i=0; i < len ; i++)
909 serializationInputCorba[i]=serializationInputC[i];
910 Py_DECREF(serializationInput);
913 //===========================================================================
914 // Execute in remote Python node
915 //===========================================================================
916 DEBTRACE( "-----------------starting remote python invocation-----------------" );
917 Engines::pickledArgs_var resultCorba;
920 resultCorba=_pynode->execute(getFname().c_str(),serializationInputCorba);
922 catch( const SALOME::SALOME_Exception& ex )
924 std::string msg="Exception on remote python invocation";
926 msg += ex.details.text.in();
928 throw Exception(msg);
930 DEBTRACE( "-----------------end of remote python invocation-----------------" );
931 //===========================================================================
932 // Get results, unpickle and put them in output ports
933 //===========================================================================
934 char *resultCorbaC=new char[resultCorba->length()+1];
935 resultCorbaC[resultCorba->length()]='\0';
936 for(int i=0;i<resultCorba->length();i++)
937 resultCorbaC[i]=resultCorba[i];
942 PyObject *resultPython(PyString_FromStringAndSize(resultCorbaC,resultCorba->length()));
943 delete [] resultCorbaC;
944 PyObject *args(PyTuple_New(1)),*ob(0);
945 PyTuple_SetItem(args,0,resultPython);
946 PyObject *finalResult=PyObject_CallObject(_pyfuncUnser,args);
949 DEBTRACE( "-----------------PythonNode::outputs-----------------" );
951 if(finalResult == Py_None)
953 else if(PyTuple_Check(finalResult))
954 nres=PyTuple_Size(finalResult);
956 if(getNumberOfOutputPorts() != nres)
958 std::string msg="Number of output arguments : Mismatch between definition and execution";
959 Py_DECREF(finalResult);
961 throw Exception(msg);
967 for(std::list<OutputPort *>::iterator iter = _setOfOutputPort.begin(); iter != _setOfOutputPort.end(); iter++, pos++)
969 OutputPyPort *p=(OutputPyPort *)*iter;
970 DEBTRACE( "port name: " << p->getName() );
971 DEBTRACE( "port kind: " << p->edGetType()->kind() );
972 DEBTRACE( "port pos : " << pos );
973 if(PyTuple_Check(finalResult))
974 ob=PyTuple_GetItem(finalResult,pos) ;
977 DEBTRACE( "ob refcnt: " << ob->ob_refcnt );
980 Py_DECREF(finalResult);
982 catch(ConversionException& ex)
984 Py_DECREF(finalResult);
985 _errorDetails=ex.what();
990 DEBTRACE( "++++++++++++++ ENDOF PyFuncNode::executeRemote: " << getName() << " ++++++++++++++++++++" );
993 void PyFuncNode::executeLocal()
995 DEBTRACE( "++++++++++++++ PyFuncNode::execute: " << getName() << " ++++++++++++++++++++" );
999 if(!_pyfunc)throw Exception("PyFuncNode badly loaded");
1002 DEBTRACE( "---------------PyFuncNode::inputs---------------" );
1003 PyObject* args = PyTuple_New(getNumberOfInputPorts()) ;
1004 list<InputPort *>::iterator iter2;
1005 for(iter2 = _setOfInputPort.begin(); iter2 != _setOfInputPort.end(); iter2++)
1007 InputPyPort *p=(InputPyPort *)*iter2;
1008 DEBTRACE( "port name: " << p->getName() );
1009 DEBTRACE( "port kind: " << p->edGetType()->kind() );
1012 PyObject_Print(ob,stderr,Py_PRINT_RAW);
1015 DEBTRACE( "ob refcnt: " << ob->ob_refcnt );
1017 PyTuple_SetItem(args,pos,ob);
1018 DEBTRACE( "ob refcnt: " << ob->ob_refcnt );
1021 DEBTRACE( "---------------End PyFuncNode::inputs---------------" );
1023 DEBTRACE( "----------------PyFuncNode::calculation---------------" );
1025 PyObject_Print(_pyfunc,stderr,Py_PRINT_RAW);
1027 PyObject_Print(args,stderr,Py_PRINT_RAW);
1030 DEBTRACE( "_pyfunc refcnt: " << _pyfunc->ob_refcnt );
1031 PyObject* result = PyObject_CallObject( _pyfunc , args ) ;
1032 DEBTRACE( "_pyfunc refcnt: " << _pyfunc->ob_refcnt );
1039 PyObject* new_stderr = newPyStdOut(_errorDetails);
1040 PySys_SetObject((char*)"stderr", new_stderr);
1041 std::ostringstream stream;
1042 stream << "/tmp/PythonNode_";
1044 ofstream errorfile(stream.str().c_str());
1045 if (errorfile.is_open())
1047 errorfile << _script;
1051 PySys_SetObject((char*)"stderr", PySys_GetObject((char*)"__stderr__"));
1052 Py_DECREF(new_stderr);
1053 throw Exception("Error during execution");
1055 DEBTRACE( "----------------End PyFuncNode::calculation---------------" );
1057 DEBTRACE( "-----------------PyFuncNode::outputs-----------------" );
1059 if(result == Py_None)
1061 else if(PyTuple_Check(result))
1062 nres=PyTuple_Size(result);
1064 if(getNumberOfOutputPorts() != nres)
1066 std::string msg="Number of output arguments : Mismatch between definition and execution";
1069 throw Exception(msg);
1074 PyObject_Print(result,stderr,Py_PRINT_RAW);
1077 list<OutputPort *>::iterator iter;
1080 for(iter = _setOfOutputPort.begin(); iter != _setOfOutputPort.end(); iter++)
1082 OutputPyPort *p=(OutputPyPort *)*iter;
1083 DEBTRACE( "port name: " << p->getName() );
1084 DEBTRACE( "port kind: " << p->edGetType()->kind() );
1085 DEBTRACE( "port pos : " << pos );
1086 if(PyTuple_Check(result))ob=PyTuple_GetItem(result,pos) ;
1088 DEBTRACE( "ob refcnt: " << ob->ob_refcnt );
1090 PyObject_Print(ob,stderr,Py_PRINT_RAW);
1097 catch(ConversionException& ex)
1100 _errorDetails=ex.what();
1103 DEBTRACE( "-----------------End PyFuncNode::outputs-----------------" );
1106 DEBTRACE( "++++++++++++++ End PyFuncNode::execute: " << getName() << " ++++++++++++++++++++" );
1109 Node *PyFuncNode::simpleClone(ComposedNode *father, bool editionOnly) const
1111 return new PyFuncNode(*this,father);
1114 //! Create a new node of same type with a given name
1115 PyFuncNode* PyFuncNode::cloneNode(const std::string& name)
1117 PyFuncNode* n=new PyFuncNode(name);
1118 n->setScript(_script);
1119 n->setFname(_fname);
1120 list<InputPort *>::iterator iter;
1121 for(iter = _setOfInputPort.begin(); iter != _setOfInputPort.end(); iter++)
1123 InputPyPort *p=(InputPyPort *)*iter;
1124 n->edAddInputPort(p->getName(),p->edGetType());
1126 list<OutputPort *>::iterator iter2;
1127 for(iter2 = _setOfOutputPort.begin(); iter2 != _setOfOutputPort.end(); iter2++)
1129 OutputPyPort *p=(OutputPyPort *)*iter2;
1130 n->edAddOutputPort(p->getName(),p->edGetType());
1135 std::string PyFuncNode::getContainerLog()
1137 if(_mode=="local")return "";
1142 Engines::Container_var objContainer=((SalomeContainer*)_container)->getContainerPtr(this);
1143 CORBA::String_var logname = objContainer->logfilename();
1146 std::string::size_type pos = msg.find(":");
1147 msg=msg.substr(pos+1);
1151 msg = "Container no longer reachable";
1156 void PyFuncNode::shutdown(int level)
1158 DEBTRACE("PyFuncNode::shutdown " << level);
1159 if(_mode=="local")return;
1162 if(!CORBA::is_nil(_pynode)) _pynode->UnRegister();
1163 _pynode=Engines::PyNode::_nil();
1164 _container->shutdown(level);