1 // Copyright (C) 2006-2022 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 "PythonPorts.hxx"
21 #include "TypeConversions.hxx"
22 #include "TypeCode.hxx"
24 #include "ConversionException.hxx"
30 #include "YacsTrace.hxx"
32 using namespace YACS::ENGINE;
35 void releasePyObj(PyObject* data)
39 DEBTRACE( "data refcnt: " << data->ob_refcnt );
40 if (PyObject_HasAttrString(data, (char*)"_is_a"))
42 PyObject *result = PyObject_CallMethod(data, (char*)"_is_a", (char*)"s",(char*)"IDL:SALOME/GenericObj:1.0");
43 if(result && PyLong_Check(result))
45 if(PyLong_AS_LONG(result))
47 PyObject* o=PyObject_CallMethod(data, (char*)"Destroy", (char*)"");
57 throw ConversionException("Corba object does not exist: you have perhaps forgotten to call Register on a GenericObj");
69 throw ConversionException("Corba object does not exist: you have perhaps forgotten to call Register on a GenericObj");
74 void registerPyObj(PyObject* data)
76 if (PyObject_HasAttrString(data, (char*)"_is_a"))
78 PyObject *result = PyObject_CallMethod(data, (char*)"_is_a", (char*)"s",(char*)"IDL:SALOME/GenericObj:1.0");
79 if(result && PyLong_Check(result))
81 if(PyLong_AS_LONG(result))
83 PyObject* o= PyObject_CallMethod(data, (char*)"Register", (char*)"") ;
93 throw ConversionException("Corba object does not exist: you have perhaps forgotten to call Register on a GenericObj");
105 throw ConversionException("Corba object does not exist: you have perhaps forgotten to call Register on a GenericObj");
110 InputPyPort::InputPyPort(const std::string& name, Node *node, TypeCode * type)
111 : InputPort(name, node, type)
112 , DataPort(name, node, type)
120 InputPyPort::~InputPyPort()
122 PyGILState_STATE gstate = PyGILState_Ensure();
123 DEBTRACE( "_data refcnt: " << (_data ? _data->ob_refcnt : -1) );
124 DEBTRACE( "_initData refcnt: " << (_initData ? _initData->ob_refcnt : -1));
125 // Release or not release : all GenericObj are deleted when the input port is deleted
128 Py_XDECREF(_initData);
129 PyGILState_Release(gstate);
132 InputPyPort::InputPyPort(const InputPyPort& other, Node *newHelder):InputPort(other,newHelder),DataPort(other,newHelder),Port(other,newHelder)
134 _initData=other._initData;
135 Py_XINCREF(_initData);
138 _isEmpty=other._isEmpty;
141 bool InputPyPort::edIsManuallyInitialized() const
143 return _initData!=nullptr;
146 void InputPyPort::edRemoveManInit()
148 Py_XDECREF(_initData);
154 InputPort::edRemoveManInit();
157 void InputPyPort::put(const void *data)
159 put((PyObject *)data);
162 void InputPyPort::releaseDataUnsafe()
169 void InputPyPort::releaseData()
171 InterpreterUnlocker l;
172 InputPyPort::releaseDataUnsafe();
175 void InputPyPort::put(PyObject *data)
177 InterpreterUnlocker l;
178 InputPyPort::releaseDataUnsafe();
182 registerPyObj(_data);
184 DEBTRACE( "_data refcnt: " << _data->ob_refcnt );
187 InputPort *InputPyPort::clone(Node *newHelder) const
189 return new InputPyPort(*this,newHelder);
192 PyObject * InputPyPort::getPyObj() const
197 void *InputPyPort::get() const
199 return (void*) _data;
202 std::string InputPyPort::getAsString()
205 //protect _data against modification or delete in another thread
206 PyObject* data=_data;
208 ret = convertPyObjectToString(data);
213 std::string InputPyPort::getHumanRepr()
217 PyObject *ret(PyObject_Str(_data));
221 char *val(PyBytes_AsString(ret));
228 bool InputPyPort::isEmpty()
233 //! Save the current data value for further reinitialization of the port
237 void InputPyPort::exSaveInit()
239 // Interpreter lock seems necessary when deleting lists in Python 2.7
240 PyGILState_STATE gstate = PyGILState_Ensure();
241 Py_XDECREF(_initData);
243 Py_INCREF(_initData);
244 PyGILState_Release(gstate);
245 DEBTRACE( "_initData.ob refcnt: " << (_initData ? _initData->ob_refcnt : -1));
246 DEBTRACE( "_data.ob refcnt: " << _data->ob_refcnt );
249 //! Restore the saved data value to current data value
251 * If no data has been saved (_initData == 0) don't restore
253 void InputPyPort::exRestoreInit()
255 if(!_initData)return;
260 DEBTRACE( "_initData.ob refcnt: " << _initData->ob_refcnt );
261 DEBTRACE( "_data.ob refcnt: " << _data->ob_refcnt );
264 std::string InputPyPort::dump()
267 return "<value>None</value>";
269 InterpreterUnlocker l;
270 return convertPyObjectXml(edGetType(), _data);
273 std::string InputPyPort::valToStr()
275 int isString = PyBytes_Check(getPyObj());
276 //DEBTRACE("isString=" << isString);
277 PyObject *strPyObj = PyObject_Str(getPyObj());
278 //DEBTRACE(PyString_Size(strPyObj));
279 string val = PyBytes_AsString(strPyObj);
281 val = "\"" + val + "\"";
287 void InputPyPort::valFromStr(std::string valstr)
292 OutputPyPort::OutputPyPort(const std::string& name, Node *node, TypeCode * type)
293 : OutputPort(name, node, type), DataPort(name, node, type), Port(node)
298 OutputPyPort::~OutputPyPort()
300 PyGILState_STATE gstate = PyGILState_Ensure();
301 DEBTRACE( "_data refcnt: " << _data->ob_refcnt );
302 // Release or not release : all GenericObj are deleted when the output port is deleted
305 PyGILState_Release(gstate);
308 OutputPyPort::OutputPyPort(const OutputPyPort& other, Node *newHelder):OutputPort(other,newHelder),DataPort(other,newHelder),Port(other,newHelder),
314 void OutputPyPort::put(const void *data)
316 put((PyObject *)data);
319 void OutputPyPort::putWithoutForward(PyObject *data)
321 DEBTRACE( "OutputPyPort::put.ob refcnt: " << data->ob_refcnt );
323 PyObject_Print(data,stderr,Py_PRINT_RAW);
330 //no registerPyObj : we steal the output reference of the node
333 void OutputPyPort::put(PyObject *data)
335 putWithoutForward(data);
336 DEBTRACE( "OutputPyPort::put.ob refcnt: " << data->ob_refcnt );
337 OutputPort::put(data);
340 OutputPort *OutputPyPort::clone(Node *newHelder) const
342 return new OutputPyPort(*this,newHelder);
345 PyObject * OutputPyPort::get() const
350 PyObject * OutputPyPort::getPyObj() const
355 std::string OutputPyPort::getAsString()
358 //protect _data against modification or delete in another thread
359 PyObject* data=_data;
361 ret = convertPyObjectToString(data);
366 std::string OutputPyPort::dump()
368 InterpreterUnlocker l;
369 string xmldump = convertPyObjectXml(edGetType(), _data);
373 std::string OutputPyPort::valToStr()
375 PyObject *strPyObj = PyObject_Str(getPyObj());
376 string val = PyBytes_AsString(strPyObj);
381 void OutputPyPort::valFromStr(std::string valstr)