]> SALOME platform Git repositories - modules/kernel.git/commitdiff
Salome HOME
CCAR: add a CORBA object PyScriptNode that can be created in a container
authorcaremoli <caremoli>
Tue, 25 Jan 2011 17:52:00 +0000 (17:52 +0000)
committercaremoli <caremoli>
Tue, 25 Jan 2011 17:52:00 +0000 (17:52 +0000)
and is able to execute python script code in the process of the container.
Creation : operation createPyScriptNode of Container interface
Execution : operation execute of PyScriptNode interface

idl/SALOME_Component.idl
idl/SALOME_PyNode.idl
src/Container/Container_i.cxx
src/Container/SALOME_Container.py
src/Container/SALOME_Container_i.hxx
src/Container/SALOME_PyNode.py
src/KERNEL_PY/salome_pynode.py

index e91c8b0463e4604c05257dee00d91819eeed31dd..a8b862ebf36ff1af85036108d7755d9e02da0e97 100644 (file)
@@ -217,6 +217,13 @@ module Engines
       \param code python code as text to load in the node
      */
     PyNode createPyNode(in string nodeName, in string code)  raises(SALOME::SALOME_Exception);
+
+    //! Create a PyScriptNode in the container
+    /*!
+      \param nodeName the name of the PyScriptNode
+      \param code python code as text to load in the node
+     */
+    PyScriptNode createPyScriptNode(in string nodeName, in string code)  raises(SALOME::SALOME_Exception);
   };
 
   /*! \brief Interface of the %component.
index da9164db6ff9e222f0c6fc2bd82cca75335014e3..01762e1666e28de725be44fc70a286031ae859a5 100644 (file)
@@ -36,6 +36,7 @@ This is a package of interfaces used for executing Python code on remote contain
 module Engines
 {
   typedef sequence<octet> pickledArgs;
+  typedef sequence<string> listofstring;
 
   interface PyNode : SALOME::GenericObj
   {
@@ -43,13 +44,26 @@ module Engines
     /*! \brief execute a python function defined in the node
 
       \param functionName the python function defined in the node to execute
-      \param inargs input argument values provided as a python pickle
-      \return output argument values as a python pickle
+      \param inargs input argument values (tuple,dict) provided as a python pickle
+      \return output argument values (tuple) as a python pickle
     */
     pickledArgs execute(in string functionName,in pickledArgs inargs) raises (SALOME::SALOME_Exception);
 
   } ;
 
+  interface PyScriptNode : SALOME::GenericObj
+  {
+
+    /*! \brief execute a python script defined in the node
+
+      \param outargsname output argument names 
+      \param inargs input argument values (dict) provided as a python pickle
+      \return output argument values (tuple) as a python pickle
+    */
+    pickledArgs execute(in listofstring outargsname, in pickledArgs inargs) raises (SALOME::SALOME_Exception);
+
+  } ;
+
 };
 
 #endif
index 3f8768718d38eb572e7e37077a29a4410f1677d2..ae0d323624e49b29c7b01e5283609e9f0a0e9366 100644 (file)
@@ -1621,6 +1621,54 @@ Engines::PyNode_ptr Engines_Container_i::createPyNode(const char* nodeName, cons
 
 }
 
+//=============================================================================
+/*! \brief create a PyScriptNode object to execute remote python code
+ * \param nodeName the name of the node
+ * \param code the python code to load
+ * \return the PyScriptNode
+ */
+//=============================================================================
+Engines::PyScriptNode_ptr Engines_Container_i::createPyScriptNode(const char* nodeName, const char* code)
+{
+    Engines::PyScriptNode_var node= Engines::PyScriptNode::_nil();
+
+    PyGILState_STATE gstate = PyGILState_Ensure();
+    PyObject *res = PyObject_CallMethod(_pyCont,
+      (char*)"create_pyscriptnode",
+      (char*)"ss",
+      nodeName,
+      code);
+    if(res==NULL)
+      {
+        //internal error
+        PyErr_Print();
+        PyGILState_Release(gstate);
+        SALOME::ExceptionStruct es;
+        es.type = SALOME::INTERNAL_ERROR;
+        es.text = "can not create a python node";
+        throw SALOME::SALOME_Exception(es);
+      }
+    long ierr=PyInt_AsLong(PyTuple_GetItem(res,0));
+    PyObject* result=PyTuple_GetItem(res,1);
+    std::string astr=PyString_AsString(result);
+    Py_DECREF(res);
+    PyGILState_Release(gstate);
+
+    if(ierr==0)
+      {
+        CORBA::Object_var obj = _orb->string_to_object(astr.c_str());
+        node = Engines::PyScriptNode::_narrow(obj);
+        return node._retn();
+      }
+    else
+      {
+        SALOME::ExceptionStruct es;
+        es.type = SALOME::INTERNAL_ERROR;
+        es.text = astr.c_str();
+        throw SALOME::SALOME_Exception(es);
+      }
+}
+
 //=============================================================================
 /* int checkifexecutable(const char *filename)
 *
index c830f8d96d5b72bf1538881a0b509ade60944fc6..fb74760cbd34fb4a8099f92c5ef7620c53e73492 100644 (file)
@@ -137,3 +137,15 @@ class SALOME_Container_i:
           exc_typ,exc_val,exc_fr=sys.exc_info()
           l=traceback.format_exception(exc_typ,exc_val,exc_fr)
           return 1,"".join(l)
+
+    def create_pyscriptnode(self,nodeName,code):
+        try:
+          node=SALOME_PyNode.PyScriptNode_i(nodeName,code,self._poa,self)
+          id_o = self._poa.activate_object(node)
+          comp_o = self._poa.id_to_reference(id_o)
+          comp_iors = self._orb.object_to_string(comp_o)
+          return 0,comp_iors
+        except:
+          exc_typ,exc_val,exc_fr=sys.exc_info()
+          l=traceback.format_exception(exc_typ,exc_val,exc_fr)
+          return 1,"".join(l)
index 80ddfa6ad64881c5781194a337ad14e0e8d7a048..11a5cbfe778642674ca5fe787abfc63159b867af 100644 (file)
@@ -105,6 +105,7 @@ public:
   virtual Engines::Salome_file_ptr createSalome_file(const char* origFileName);
   void copyFile(Engines::Container_ptr container, const char* remoteFile, const char* localFile);
   Engines::PyNode_ptr createPyNode(const char* nodeName, const char* code);
+  Engines::PyScriptNode_ptr createPyScriptNode(const char* nodeName, const char* code);
   // --- local C++ methods
 
   Engines::Component_ptr
index cf50f8ca6f5cbd3b1741d2c3758d7179dc14cafc..d0f8f527390ff443043991c8a419c984a8257cd1 100644 (file)
@@ -60,7 +60,7 @@ class PyNode_i (Engines__POA.PyNode,Generic):
     self.context["my_container"] = self.my_container
     exec ccode in self.context
 
-  def execute(self,funcName,argsin): 
+  def execute(self,funcName,argsin):
     """Execute the function funcName found in local context with pickled args (argsin)"""
     try:
       argsin,kws=cPickle.loads(argsin)
@@ -73,3 +73,33 @@ class PyNode_i (Engines__POA.PyNode,Generic):
       l=traceback.format_exception(exc_typ,exc_val,exc_fr)
       raise SALOME.SALOME_Exception(SALOME.ExceptionStruct(SALOME.BAD_PARAM,"".join(l),"PyNode: %s, function: %s" % (self.nodeName,funcName),0))
 
+class PyScriptNode_i (Engines__POA.PyScriptNode,Generic):
+  """The implementation of the PyScriptNode CORBA IDL that executes a script"""
+  def __init__(self, nodeName,code,poa,my_container):
+    """Initialize the node : compilation in the local context"""
+    Generic.__init__(self,poa)
+    self.nodeName=nodeName
+    self.code=code
+    self.my_container=my_container._container
+    linecache.cache[nodeName]=0,None,string.split(code,'\n'),nodeName
+    self.ccode=compile(code,nodeName,'exec')
+    self.context={}
+    self.context["my_container"] = self.my_container
+
+  def execute(self,outargsname,argsin):
+    """Execute the script stored in attribute ccode with pickled args (argsin)"""
+    try:
+      argsname,kws=cPickle.loads(argsin)
+      self.context.update(kws)
+      exec self.ccode in self.context
+      argsout=[]
+      for arg in outargsname:
+        if not self.context.has_key(arg):
+          raise KeyError("There is no variable %s in context" % arg)
+        argsout.append(self.context[arg])
+      argsout=cPickle.dumps(tuple(argsout),-1)
+      return argsout
+    except:
+      exc_typ,exc_val,exc_fr=sys.exc_info()
+      l=traceback.format_exception(exc_typ,exc_val,exc_fr)
+      raise SALOME.SALOME_Exception(SALOME.ExceptionStruct(SALOME.BAD_PARAM,"".join(l),"PyScriptNode: %s, outargsname: %s" % (self.nodeName,outargsname),0))
index b9ce2c0dddccb1925fefde0b6f36876ab16dcd3f..53ed531832fbb0fca28ef0b769a8c067611b6d76 100644 (file)
@@ -25,7 +25,7 @@
 """
  When imported this module adds to CORBA proxy (from PyNode type) automatic pickle and unpickle
  of arguments and results when calling execute method. It also converts the SALOME exception into a standard python
- exception 
+ exception
 """
 import omniORB
 import cPickle
@@ -53,6 +53,22 @@ class SmartPyNode(Engines._objref_PyNode):
       return self.execute(name,*args,**kws)
     return afunc
 
+class SmartPyScriptNode(Engines._objref_PyScriptNode):
+  def __init__(self):
+    Engines._objref_PyScriptNode.__init__(self)
+
+  def execute(self,outargsname,*args,**kws):
+    #the tuple args are ignored
+    try:
+      args=cPickle.dumps(((),kws),-1)
+      results=Engines._objref_PyScriptNode.execute(self,outargsname,args)
+      x=cPickle.loads(results)
+      return x
+    except SALOME.SALOME_Exception, e:
+      raise ValueError(e.details.text)
+
 #Register the new proxy for PyNode
 omniORB.registerObjref(Engines._objref_PyNode._NP_RepositoryId, SmartPyNode)
+#Register the new proxy for PyScriptNode
+omniORB.registerObjref(Engines._objref_PyScriptNode._NP_RepositoryId, SmartPyScriptNode)