Version: 9.16.0
SalomePythonNode.cxx
Go to the documentation of this file.
1// Copyright (C) 2006-2026 CEA, EDF
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
31using namespace YACS::ENGINE;
32using namespace std;
33
34const char SalomePythonNode::PLACEMENT_VAR_NAME_IN_INTERP[]="__container__from__YACS__";
35
36SalomePythonNode::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
52SalomePythonNode::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=PyBytes_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 }
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
195std::string SalomePythonNode::getKind() const
196{
197 static const char LOC_KIND[]="";
198 return LOC_KIND;
199}
200
201Node *SalomePythonNode::simpleClone(ComposedNode *father, bool editionOnly) const
202{
203 return new SalomePythonNode(*this,father);
204}
205
207{
208 ServiceNode* node=new SalomePythonNode(name);
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}
Base class for all composed nodes.
std::string getName() const
std::list< InputPort * > _setOfInputPort
std::list< OutputPort * > _setOfOutputPort
Class for Python Ports.
Definition: PythonPorts.hxx:74
Base class for all nodes.
Definition: Node.hxx:70
const std::string & getName() const
Definition: Node.hxx:125
std::string _implementation
Definition: Node.hxx:97
static const char IMPL_NAME[]
Definition: PythonNode.hxx:123
ServiceNode * createNode(const std::string &name)
static const char PLACEMENT_VAR_NAME_IN_INTERP[]
std::string getKind() const
Return the service node kind.
SalomePythonNode * cloneNode(const std::string &name)
Create a new node of same type with a given name.
SalomePythonNode(const SalomePythonNode &other, ComposedNode *father)
virtual void load()
Load the component associated to the node.
Node * simpleClone(ComposedNode *father, bool editionOnly) const
Class for calculation node associated with a component service.
Definition: ServiceNode.hxx:35
virtual void load()
Load the component associated to the node.
Definition: ServiceNode.cxx:90
ComponentInstance * _component
Definition: ServiceNode.hxx:60
virtual void setComponent(ComponentInstance *compo)
Associate an existing component instance to this service node AND check the consistency regarding the...
Proc * p
Definition: driver.cxx:216
YACSRUNTIMESALOME_EXPORT RuntimeSALOME * getSALOMERuntime()