Version: 8.3.0
SalomePythonNode.cxx
Go to the documentation of this file.
1 // Copyright (C) 2006-2016 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, or (at your option) any later version.
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 
20 #include "RuntimeSALOME.hxx"
22 #include "SalomePythonNode.hxx"
23 #include "PythonNode.hxx"
24 #include "PythonPorts.hxx"
25 #include "CORBANode.hxx"
26 #include "TypeCode.hxx"
27 
28 #include <iostream>
29 #include <sstream>
30 
31 using namespace YACS::ENGINE;
32 using namespace std;
33 
34 const char SalomePythonNode::PLACEMENT_VAR_NAME_IN_INTERP[]="__container__from__YACS__";
35 
36 SalomePythonNode::SalomePythonNode(const SalomePythonNode& other, ComposedNode *father):ServiceInlineNode(other,father),_pyfunc(0),_context(0)
37 {
38  //Not a bug : just because port point of view this is like PythonNode.
40  PyGILState_STATE gstate = PyGILState_Ensure();
41  _context=PyDict_New();
42  if( PyDict_SetItemString( _context, "__builtins__", getSALOMERuntime()->getBuiltins() ))
43  {
44  stringstream msg;
45  msg << "Not possible to set builtins" << __FILE__ << ":" << __LINE__;
46  PyGILState_Release(gstate);
47  throw Exception(msg.str());
48  }
49  PyGILState_Release(gstate);
50 }
51 
52 SalomePythonNode::SalomePythonNode(const std::string& name): ServiceInlineNode(name),_pyfunc(0)
53 {
54 
55  //Not a bug : just because port point of view this is like PythonNode.
57  PyGILState_STATE gstate = PyGILState_Ensure();
58  _context=PyDict_New();
59  if( PyDict_SetItemString( _context, "__builtins__", getSALOMERuntime()->getBuiltins() ))
60  {
61  stringstream msg;
62  msg << "Not possible to set builtins" << __FILE__ << ":" << __LINE__;
63  PyGILState_Release(gstate);
64  throw Exception(msg.str());
65  }
66  PyGILState_Release(gstate);
67 }
68 
70 {
72  cerr << "---------------SalomePythonNode::load function---------------" << endl;
73  list<OutputPort *>::iterator iter;
74  string value2Export=((SalomePythonComponent*)_component)->getStringValueToExportInInterp(this);
75  PyObject* ob=PyString_FromString(value2Export.c_str());
76  PyDict_SetItemString(_context,PLACEMENT_VAR_NAME_IN_INTERP,ob);
77  for(iter = _setOfOutputPort.begin(); iter != _setOfOutputPort.end(); iter++)
78  {
79  OutputPyPort *p=(OutputPyPort *)*iter;
80  cerr << "port name: " << p->getName() << endl;
81  cerr << "port kind: " << p->edGetType()->kind() << endl;
82  }
83  cerr << _script << endl;
84  PyGILState_STATE gstate = PyGILState_Ensure();
85  PyObject *res=PyRun_String(_script.c_str(),Py_file_input,_context,_context);
86  if(res == NULL)
87  {
88  PyErr_Print();
89  PyGILState_Release(gstate);
90  throw Exception("Error during execution");
91  return;
92  }
93  Py_DECREF(res);
94  _pyfunc=PyDict_GetItemString(_context,_method.c_str());
95  if(_pyfunc == NULL)
96  {
97  PyErr_Print();
98  PyGILState_Release(gstate);
99  throw Exception("Error during execution");
100  }
101  cerr << "---------------End SalomePythonNode::load function---------------" << endl;
102  PyGILState_Release(gstate);
103 }
104 
106 {
107  cerr << "++++++++++++++ SalomePythonNode::execute: " << getName() << " ++++++++++++++++++++" << endl;
108  int pos=0;
109  PyObject* ob;
110  if(!_pyfunc)throw Exception("SalomePythonNode badly loaded");
111  PyGILState_STATE gstate = PyGILState_Ensure();
112 
113  cerr << "---------------SalomePythonNode::inputs---------------" << endl;
114  PyObject* args = PyTuple_New(getNumberOfInputPorts()) ;
115  list<InputPort *>::iterator iter2;
116  for(iter2 = _setOfInputPort.begin(); iter2 != _setOfInputPort.end(); iter2++)
117  {
118  InputPyPort *p=(InputPyPort *)*iter2;
119  cerr << "port name: " << p->getName() << endl;
120  cerr << "port kind: " << p->edGetType()->kind() << endl;
121  ob=p->getPyObj();
122  PyObject_Print(ob,stderr,Py_PRINT_RAW);
123  cerr << endl;
124  cerr << "ob refcnt: " << ob->ob_refcnt << endl;
125  Py_INCREF(ob);
126  PyTuple_SetItem(args,pos,ob);
127  cerr << "ob refcnt: " << ob->ob_refcnt << endl;
128  pos++;
129  }
130  cerr << "---------------End SalomePythonNode::inputs---------------" << endl;
131 
132  cerr << "----------------SalomePythonNode::calculation---------------" << endl;
133  PyObject_Print(_pyfunc,stderr,Py_PRINT_RAW);
134  cerr << endl;
135  PyObject_Print(args,stderr,Py_PRINT_RAW);
136  cerr << endl;
137  PyObject* result = PyObject_CallObject( _pyfunc , args ) ;
138  Py_DECREF(args);
139  if(result == NULL)
140  {
141  PyErr_Print();
142  PyGILState_Release(gstate);
143  throw Exception("Error during execution");
144  }
145  cerr << "----------------End SalomePythonNode::calculation---------------" << endl;
146 
147  cerr << "-----------------SalomePythonNode::outputs-----------------" << endl;
148  int nres=1;
149  if(result == Py_None)
150  nres=0;
151  else if(PyTuple_Check(result))
152  nres=PyTuple_Size(result);
153 
154  if(getNumberOfOutputPorts() != nres)
155  {
156  Py_DECREF(result);
157  PyGILState_Release(gstate);
158  throw Exception("Number of output arguments : Mismatch between definition and execution");
159  }
160 
161  pos=0;
162  PyObject_Print(result,stderr,Py_PRINT_RAW);
163  cerr << endl;
164  list<OutputPort *>::iterator iter;
165  try
166  {
167  for(iter = _setOfOutputPort.begin(); iter != _setOfOutputPort.end(); iter++)
168  {
169  OutputPyPort *p=(OutputPyPort *)*iter;
170  cerr << "port name: " << p->getName() << endl;
171  cerr << "port kind: " << p->edGetType()->kind() << endl;
172  cerr << "port pos : " << pos << endl;
173  if(PyTuple_Check(result))ob=PyTuple_GetItem(result,pos) ;
174  else ob=result;
175  cerr << "ob refcnt: " << ob->ob_refcnt << endl;
176  PyObject_Print(ob,stderr,Py_PRINT_RAW);
177  cerr << endl;
178  p->put(ob);
179  pos++;
180  }
181  }
182  catch(ConversionException)
183  {
184  Py_DECREF(result);
185  PyGILState_Release(gstate);
186  throw;
187  }
188  cerr << "-----------------End SalomePythonNode::outputs-----------------" << endl;
189 
190  Py_DECREF(result);
191  PyGILState_Release(gstate);
192  cerr << "++++++++++++++ End SalomePythonNode::execute: " << getName() << " ++++++++++++++++++++" << endl;
193 }
194 
195 std::string SalomePythonNode::getKind() const
196 {
197  static const char LOC_KIND[]="";
198  return LOC_KIND;
199 }
200 
201 Node *SalomePythonNode::simpleClone(ComposedNode *father, bool editionOnly) const
202 {
203  return new SalomePythonNode(*this,father);
204 }
205 
206 ServiceNode *SalomePythonNode::createNode(const std::string &name)
207 {
208  ServiceNode* node=new SalomePythonNode(name);
209  node->setComponent(_component);
210  return node;
211 }
212 
215 {
217  n->setScript(_script);
218  n->setMethod(_method);
219  list<InputPort *>::iterator iter;
220  for(iter = _setOfInputPort.begin(); iter != _setOfInputPort.end(); iter++)
221  {
222  InputPyPort *p=(InputPyPort *)*iter;
223  n->edAddInputPort(p->getName(),p->edGetType());
224  }
225  list<OutputPort *>::iterator iter2;
226  for(iter2 = _setOfOutputPort.begin(); iter2 != _setOfOutputPort.end(); iter2++)
227  {
228  OutputPyPort *p=(OutputPyPort *)*iter2;
229  n->edAddOutputPort(p->getName(),p->edGetType());
230  }
231  return n;
232 }