1 // Copyright (C) 2006-2023 CEA, EDF
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 static void RegisterReleasePyObj(PyObject* data, const char *method1)
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*)method1, (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 releasePyObj(PyObject* data)
76 RegisterReleasePyObj(data,"Destroy");
79 void registerPyObj(PyObject* data)
81 RegisterReleasePyObj(data,"Register");
84 InputPyPort::InputPyPort(const std::string& name, Node *node, TypeCode * type)
85 : InputPort(name, node, type)
86 , DataPort(name, node, type)
94 InputPyPort::~InputPyPort()
96 PyGILState_STATE gstate = PyGILState_Ensure();
97 DEBTRACE( "_data refcnt: " << (_data ? _data->ob_refcnt : -1) );
98 DEBTRACE( "_initData refcnt: " << (_initData ? _initData->ob_refcnt : -1));
99 // Release or not release : all GenericObj are deleted when the input port is deleted
102 Py_XDECREF(_initData);
103 PyGILState_Release(gstate);
106 InputPyPort::InputPyPort(const InputPyPort& other, Node *newHelder):InputPort(other,newHelder),DataPort(other,newHelder),Port(other,newHelder)
108 _initData=other._initData;
109 Py_XINCREF(_initData);
112 _isEmpty=other._isEmpty;
115 bool InputPyPort::edIsManuallyInitialized() const
117 return _initData!=nullptr;
120 void InputPyPort::edRemoveManInit()
122 Py_XDECREF(_initData);
128 InputPort::edRemoveManInit();
131 void InputPyPort::put(const void *data)
133 put((PyObject *)data);
136 void InputPyPort::releaseDataUnsafe()
143 void InputPyPort::releaseData()
145 InterpreterUnlocker l;
146 InputPyPort::releaseDataUnsafe();
149 void InputPyPort::put(PyObject *data)
151 InterpreterUnlocker l;
152 InputPyPort::releaseDataUnsafe();
156 registerPyObj(_data);
158 DEBTRACE( "_data refcnt: " << _data->ob_refcnt );
161 InputPort *InputPyPort::clone(Node *newHelder) const
163 return new InputPyPort(*this,newHelder);
166 PyObject * InputPyPort::getPyObj() const
171 void *InputPyPort::get() const
173 return (void*) _data;
176 std::string InputPyPort::getAsString()
179 //protect _data against modification or delete in another thread
180 PyObject* data=_data;
182 ret = convertPyObjectToString(data);
187 std::string InputPyPort::getHumanRepr()
191 PyObject *ret(PyObject_Str(_data));
195 char *val(PyBytes_AsString(ret));
202 bool InputPyPort::isEmpty()
207 //! Save the current data value for further reinitialization of the port
211 void InputPyPort::exSaveInit()
213 // Interpreter lock seems necessary when deleting lists in Python 2.7
214 PyGILState_STATE gstate = PyGILState_Ensure();
215 Py_XDECREF(_initData);
217 Py_INCREF(_initData);
218 PyGILState_Release(gstate);
219 DEBTRACE( "_initData.ob refcnt: " << (_initData ? _initData->ob_refcnt : -1));
220 DEBTRACE( "_data.ob refcnt: " << _data->ob_refcnt );
223 //! Restore the saved data value to current data value
225 * If no data has been saved (_initData == 0) don't restore
227 void InputPyPort::exRestoreInit()
229 if(!_initData)return;
234 DEBTRACE( "_initData.ob refcnt: " << _initData->ob_refcnt );
235 DEBTRACE( "_data.ob refcnt: " << _data->ob_refcnt );
238 std::string InputPyPort::dump()
241 return "<value>None</value>";
243 InterpreterUnlocker l;
244 return convertPyObjectXml(edGetType(), _data);
247 std::string InputPyPort::valToStr()
249 int isString = PyBytes_Check(getPyObj());
250 //DEBTRACE("isString=" << isString);
251 PyObject *strPyObj = PyObject_Str(getPyObj());
252 //DEBTRACE(PyString_Size(strPyObj));
253 string val = PyBytes_AsString(strPyObj);
255 val = "\"" + val + "\"";
261 void InputPyPort::valFromStr(std::string valstr)
266 OutputPyPort::OutputPyPort(const std::string& name, Node *node, TypeCode * type)
267 : OutputPort(name, node, type), DataPort(name, node, type), Port(node)
272 OutputPyPort::~OutputPyPort()
274 PyGILState_STATE gstate = PyGILState_Ensure();
275 DEBTRACE( "_data refcnt: " << _data->ob_refcnt );
276 // Release or not release : all GenericObj are deleted when the output port is deleted
279 PyGILState_Release(gstate);
282 OutputPyPort::OutputPyPort(const OutputPyPort& other, Node *newHelder):OutputPort(other,newHelder),DataPort(other,newHelder),Port(other,newHelder),
288 void OutputPyPort::put(const void *data)
290 put((PyObject *)data);
293 void OutputPyPort::putWithoutForward(PyObject *data)
295 DEBTRACE( "OutputPyPort::put.ob refcnt: " << data->ob_refcnt );
297 PyObject_Print(data,stderr,Py_PRINT_RAW);
304 //no registerPyObj : we steal the output reference of the node
307 void OutputPyPort::put(PyObject *data)
309 putWithoutForward(data);
310 DEBTRACE( "OutputPyPort::put.ob refcnt: " << data->ob_refcnt );
311 OutputPort::put(data);
314 OutputPort *OutputPyPort::clone(Node *newHelder) const
316 return new OutputPyPort(*this,newHelder);
319 PyObject * OutputPyPort::get() const
324 PyObject * OutputPyPort::getPyObj() const
329 std::string OutputPyPort::getAsString()
332 //protect _data against modification or delete in another thread
333 PyObject* data=_data;
335 ret = convertPyObjectToString(data);
340 std::string OutputPyPort::dump()
342 InterpreterUnlocker l;
343 string xmldump = convertPyObjectXml(edGetType(), _data);
347 std::string OutputPyPort::valToStr()
349 PyObject *strPyObj = PyObject_Str(getPyObj());
350 string val = PyBytes_AsString(strPyObj);
355 void OutputPyPort::valFromStr(std::string valstr)