[pytango] 436/483: Fix SF bug #698: PyTango.Util discrepancy

Sandor Bodo-Merle sbodomerle-guest at moszumanska.debian.org
Thu Sep 28 19:15:09 UTC 2017


This is an automated email from the git hooks/post-receive script.

sbodomerle-guest pushed a commit to annotated tag bliss_8.10
in repository pytango.

commit 3618411bfc5ff25e0d8b871c975b842fd71bc2b3
Author: coutinho <coutinho at esrf.fr>
Date:   Wed Dec 17 10:35:43 2014 +0100

    Fix SF bug #698: PyTango.Util discrepancy
---
 src/boost/cpp/server/tango_util.cpp |  47 ++++---
 src/boost/python/pyutil.py          | 251 ++++++++++++++++++------------------
 2 files changed, 152 insertions(+), 146 deletions(-)

diff --git a/src/boost/cpp/server/tango_util.cpp b/src/boost/cpp/server/tango_util.cpp
index b8a0aa1..157afc2 100644
--- a/src/boost/cpp/server/tango_util.cpp
+++ b/src/boost/cpp/server/tango_util.cpp
@@ -67,7 +67,7 @@ namespace PyUtil
         AutoPythonAllowThreads guard;
         instance.server_run();
     }
-    
+
     inline Tango::Util* init(boost::python::object &obj)
     {
         PyObject *obj_ptr = obj.ptr();
@@ -87,12 +87,18 @@ namespace PyUtil
                 str item = str(handle<>(item_ptr));
                 argv[i] = extract<char *>(item);
             }
-            res = Tango::Util::init(argc, argv);
+	    res = Tango::Util::init(argc, argv);
         } catch (...) {
             delete [] argv;
             throw;
         }
         delete [] argv;
+
+	if (PyEval_ThreadsInitialized() == 0)
+	{
+	    PyEval_InitThreads();
+	}
+
         return res;
     }
 
@@ -117,7 +123,7 @@ namespace PyUtil
                             to_python_indirect<
                                 Tango::DeviceImpl*,
                                 detail::make_reference_holder>()(*it)));
-            
+
             py_dev_list.append(py_value);
         }
         return py_dev_list;
@@ -134,7 +140,7 @@ namespace PyUtil
 
         return py_value;
     }
-    
+
     inline object get_device_list(Tango::Util &self, const string &name)
     {
         boost::python::list py_dev_list;
@@ -150,7 +156,7 @@ namespace PyUtil
         }
         return py_dev_list;
     }
-    
+
     inline bool event_loop()
     {
         AutoPythonGIL guard;
@@ -160,7 +166,7 @@ namespace PyUtil
         bool ret = boost::python::extract<bool>(py_ret);
         return ret;
     }
-    
+
     inline void server_set_event_loop(Tango::Util& self,
                                       boost::python::object& py_event_loop)
     {
@@ -176,12 +182,12 @@ namespace PyUtil
             self.server_set_event_loop(event_loop);
         }
     }
-    
+
     void set_use_db(bool use_db)
     {
         Tango::Util::_UseDb = use_db;
     }
-    
+
     boost::python::str get_dserver_ior(Tango::Util& self, Tango::DServer* dserver)
     {
         Tango::Device_var d = dserver->_this();
@@ -199,7 +205,7 @@ namespace PyUtil
         delete [] ior;
         return ret;
     }
-    
+
     void orb_run(Tango::Util& self)
     {
         AutoPythonAllowThreads guard;
@@ -217,16 +223,16 @@ namespace PyUtil
         boost::python::str ret = self.get_version_str().c_str();
         return ret;
     }
-}
 
-void init_python()
-{
-    if (PyEval_ThreadsInitialized() == 0)
+    static boost::shared_ptr<Tango::Util>
+    makeUtil(boost::python::object& args)
     {
-        PyEval_InitThreads();
+        Tango::Util* util = PyUtil::init(args);
+        return boost::shared_ptr<Tango::Util>(util);
     }
 }
 
+
 BOOST_PYTHON_FUNCTION_OVERLOADS (server_init_overload, PyUtil::server_init, 1, 2)
 
 void export_util()
@@ -235,8 +241,9 @@ void export_util()
         .def("create_thread", &Tango::Interceptors::create_thread)
         .def("delete_thread", &Tango::Interceptors::delete_thread)
     ;
-    
-    class_<Tango::Util, boost::noncopyable>("_Util", no_init)
+
+    class_<Tango::Util, boost::noncopyable>("Util", no_init)
+        .def("__init__", boost::python::make_constructor(PyUtil::makeUtil))
         .def("init", PyUtil::init,
             return_value_policy<reference_existing_object>())
         .staticmethod("init")
@@ -279,13 +286,13 @@ void export_util()
         .def("set_polling_threads_pool_size", &Tango::Util::set_polling_threads_pool_size)
         .def("get_polling_threads_pool_size", &Tango::Util::get_polling_threads_pool_size)
         .def("is_svr_starting", &Tango::Util::is_svr_starting)
-        .def("is_svr_shutting_down", &Tango::Util::is_svr_shutting_down)        
-        .def("is_device_restarting", &Tango::Util::is_device_restarting)        
+        .def("is_svr_shutting_down", &Tango::Util::is_svr_shutting_down)
+        .def("is_device_restarting", &Tango::Util::is_device_restarting)
         .def("get_sub_dev_diag", &Tango::Util::get_sub_dev_diag,
             return_internal_reference<>())
         .def("connect_db", &Tango::Util::connect_db)
         .def("reset_filedatabase", &Tango::Util::reset_filedatabase)
-        .def("get_database", &Tango::Util::get_database, 
+        .def("get_database", &Tango::Util::get_database,
             return_internal_reference<>())
         .def("unregister_server", &Tango::Util::unregister_server)
         .def("get_device_list_by_class", &PyUtil::get_device_list_by_class)
@@ -295,8 +302,6 @@ void export_util()
         .def("set_interceptors", &Tango::Util::set_interceptors)
         .def_readonly("_UseDb", &Tango::Util::_UseDb)
         .def_readonly("_FileDb", &Tango::Util::_FileDb)
-        .def("init_python", init_python)
-        .staticmethod("init_python")
         .def("set_use_db", &PyUtil::set_use_db)
         .staticmethod("set_use_db")
         .def("get_dserver_ior", &PyUtil::get_dserver_ior)
diff --git a/src/boost/python/pyutil.py b/src/boost/python/pyutil.py
index 23ac8a8..0a8415a 100644
--- a/src/boost/python/pyutil.py
+++ b/src/boost/python/pyutil.py
@@ -20,7 +20,7 @@ __docformat__ = "restructuredtext"
 import os
 import copy
 
-from ._PyTango import _Util, Except, DevFailed, DbDevInfo
+from ._PyTango import Util, Except, DevFailed, DbDevInfo
 from .utils import document_method as __document_method
 #from utils import document_static_method as __document_static_method
 from .globals import class_list, cpp_class_list, get_constructed_classes
@@ -52,22 +52,22 @@ def __Util__get_class_list(self):
 def __Util__create_device(self, klass_name, device_name, alias=None, cb=None):
     """
         create_device(self, klass_name, device_name, alias=None, cb=None) -> None
-        
+
             Creates a new device of the given class in the database, creates a new
             DeviceImpl for it and calls init_device (just like it is done for
             existing devices when the DS starts up)
-    
-            An optional parameter callback is called AFTER the device is 
+
+            An optional parameter callback is called AFTER the device is
             registered in the database and BEFORE the init_device for the
             newly created device is called
-            
+
             Throws PyTango.DevFailed:
                 - the device name exists already or
                 - the given class is not registered for this DS.
                 - the cb is not a callable
-            
+
         New in PyTango 7.1.2
-        
+
         Parameters :
             - klass_name : (str) the device class name
             - device_name : (str) the device name
@@ -77,17 +77,17 @@ def __Util__create_device(self, klass_name, device_name, alias=None, cb=None):
                    device is called. Typically you may want to put device and/or attribute
                    properties in the database here. The callback must receive a parameter:
                    device name (str). Default value is None meaning no callback
-        
+
         Return     : None"""
     if cb is not None and not isinstance(cb, collections.Callable):
         Except.throw_exception("PyAPI_InvalidParameter",
             "The optional cb parameter must be a python callable",
             "Util.create_device")
-    
+
     db = self.get_database()
 
     device_name = __simplify_device_name(device_name)
-    
+
     device_exists = True
     try:
         db.import_device(device_name)
@@ -96,7 +96,7 @@ def __Util__create_device(self, klass_name, device_name, alias=None, cb=None):
 
     # 1 - Make sure device name doesn't exist already in the database
     if device_exists:
-        Except.throw_exception("PyAPI_DeviceAlreadyDefined", 
+        Except.throw_exception("PyAPI_DeviceAlreadyDefined",
             "The device %s is already defined in the database" % device_name,
             "Util.create_device")
 
@@ -109,28 +109,28 @@ def __Util__create_device(self, klass_name, device_name, alias=None, cb=None):
             klass = k
             break
     if klass is None:
-        Except.throw_exception("PyAPI_UnknownDeviceClass", 
+        Except.throw_exception("PyAPI_UnknownDeviceClass",
             "The device class %s could not be found" % klass_name,
             "Util.create_device")
-            
+
     # 3 - Create entry in the database (with alias if necessary)
     dev_info = DbDevInfo()
     dev_info.name = device_name
     dev_info._class = klass_name
     dev_info.server = self.get_ds_name()
-    
+
     db.add_device(dev_info)
-    
+
     if alias is not None:
         db.put_device_alias(device_name, alias)
 
     # from this point on, if anything wrong happens we need to clean the database
     try:
-        # 4 - run the callback which tipically is used to initialize 
+        # 4 - run the callback which tipically is used to initialize
         #     device and/or attribute properties in the database
         if cb is not None:
             cb(device_name)
-            
+
         # 5 - Initialize device object on this server
         k.device_factory([device_name])
     except:
@@ -144,22 +144,22 @@ def __Util__create_device(self, klass_name, device_name, alias=None, cb=None):
 def __Util__delete_device(self, klass_name, device_name):
     """
         delete_device(self, klass_name, device_name) -> None
-        
+
             Deletes an existing device from the database and from this running
             server
-    
+
             Throws PyTango.DevFailed:
                 - the device name doesn't exist in the database
                 - the device name doesn't exist in this DS.
-        
+
         New in PyTango 7.1.2
-        
+
         Parameters :
             - klass_name : (str) the device class name
             - device_name : (str) the device name
-        
+
         Return     : None"""
-        
+
     db = self.get_database()
     device_name = __simplify_device_name(device_name)
     device_exists = True
@@ -170,10 +170,10 @@ def __Util__delete_device(self, klass_name, device_name):
 
     # 1 - Make sure device name exists in the database
     if not device_exists:
-        Except.throw_exception("PyAPI_DeviceNotDefined", 
+        Except.throw_exception("PyAPI_DeviceNotDefined",
             "The device %s is not defined in the database" % device_name,
             "Util.delete_device")
-    
+
     # 2 - Make sure device name is defined in this server
     class_device_name = "%s::%s" % (klass_name, device_name)
     ds = self.get_dserver_device()
@@ -186,94 +186,95 @@ def __Util__delete_device(self, klass_name, device_name):
             device_exists =True
             break
     if not device_exists:
-        Except.throw_exception("PyAPI_DeviceNotDefinedInServer", 
+        Except.throw_exception("PyAPI_DeviceNotDefinedInServer",
             "The device %s is not defined in this server" % class_device_name,
             "Util.delete_device")
-    
+
     db.delete_device(device_name)
-    
+
     dimpl = self.get_device_by_name(device_name)
-    
+
     dc = dimpl.get_device_class()
     dc.device_destroyer(device_name)
 
-def __Util__server_set_event_loop(self, event_loop):
-    self._server_event_loop = event_loop
-    self._server_set_event_loop()
+def __Util__init__(self, args):
+    args = copy.copy(args)
+    args[0] = os.path.splitext(args[0])[0]
+    Util.__init_orig__(self, args)
+
+def __Util__add_TgClass(self, klass_device_class, klass_device,
+                        device_class_name=None):
+    """Register a new python tango class. Example::
+
+           util.add_TgClass(MotorClass, Motor)
+           util.add_TgClass(MotorClass, Motor, 'Motor') # equivalent to previous line
 
-class Util(_Util):
+       .. deprecated:: 7.1.2
+           Use :meth:`PyTango.Util.add_class` instead."""
+    if device_class_name is None:
+        device_class_name = klass_device.__name__
+    class_list.append((klass_device_class, klass_device, device_class_name))
+
+
+def __Util__add_Cpp_TgClass(self, device_class_name, tango_device_class_name):
+    """Register a new C++ tango class.
+
+       If there is a shared library file called MotorClass.so which
+       contains a MotorClass class and a _create_MotorClass_class method. Example::
+
+           util.add_Cpp_TgClass('MotorClass', 'Motor')
+
+       .. note:: the parameter 'device_class_name' must match the shared
+                 library name.
+
+       .. deprecated:: 7.1.2
+           Use :meth:`PyTango.Util.add_class` instead."""
+    cpp_class_list.append((device_class_name, tango_device_class_name))
+
+def __Util__add_class(self, *args, **kwargs):
     """
-        This class is a used to store TANGO device server process data and to
-        provide the user with a set of utilities method.
-
-        This class is implemented using the singleton design pattern.
-        Therefore a device server process can have only one instance of this
-        class and its constructor is not public. Example::
-            
-            util = PyTango.Util.instance()
-            print(util.get_host_name())"""
-
-    def __init__(self, args):
-        args = copy.copy(args)
-        args[0] = os.path.splitext(args[0])[0]
-        _Util.init(args)
-        _Util.init_python()
-
-    def add_TgClass(self, klass_device_class, klass_device, device_class_name=None):
-        """Register a new python tango class. Example::
-           
-               util.add_TgClass(MotorClass, Motor)
-               util.add_TgClass(MotorClass, Motor, 'Motor') # equivalent to previous line
-           
-           .. deprecated:: 7.1.2
-               Use :meth:`PyTango.Util.add_class` instead."""
-               
-        if device_class_name is None:
-            device_class_name = klass_device.__name__
-        class_list.append((klass_device_class, klass_device, device_class_name))
-
-
-    def add_Cpp_TgClass(self, device_class_name, tango_device_class_name):
-        """Register a new C++ tango class.
-           
-           If there is a shared library file called MotorClass.so which
-           contains a MotorClass class and a _create_MotorClass_class method. Example::
-           
-               util.add_Cpp_TgClass('MotorClass', 'Motor')
-               
-           .. note:: the parameter 'device_class_name' must match the shared
-                     library name.
-                    
-           .. deprecated:: 7.1.2
-               Use :meth:`PyTango.Util.add_class` instead."""
-        cpp_class_list.append((device_class_name, tango_device_class_name))
-
-    def add_class(self, *args, **kwargs):
-        """
-            add_class(self, args, language="python") -> None
-            
-                Register a new tango class ('python' or 'c++').
-           
-                If language is 'python' then args must be the same as 
-                :meth:`PyTango.Util.add_TgClass`. Otherwise, args should be the ones
-                in :meth:`PyTango.Util.add_Cpp_TgClass`. Example::
-                
-                    util.add_class(MotorClass, Motor)
-                    util.add_class('CounterClass', 'Counter', language='c++')
-           
-            New in PyTango 7.1.2"""
-        language = kwargs.get("language", "python")
-        f = self.add_TgClass
-        if language != "python":
-            f = f = self.add_Cpp_TgClass
-        return f(*args)
+        add_class(self, class<DeviceClass>, class<DeviceImpl>, language="python") -> None
+
+            Register a new tango class ('python' or 'c++').
+
+            If language is 'python' then args must be the same as
+            :meth:`PyTango.Util.add_TgClass`. Otherwise, args should be the ones
+            in :meth:`PyTango.Util.add_Cpp_TgClass`. Example::
+
+                util.add_class(MotorClass, Motor)
+                util.add_class('CounterClass', 'Counter', language='c++')
+
+        New in PyTango 7.1.2"""
+    language = kwargs.get("language", "python")
+    f = self.add_TgClass
+    if language != "python":
+        f = f = self.add_Cpp_TgClass
+    return f(*args)
 
 def __init_Util():
-    _Util.get_class_list = __Util__get_class_list
-    _Util.create_device = __Util__create_device
-    _Util.delete_device = __Util__delete_device
+    Util.__init_orig__ = Util.__init__
+    Util.__init__ = __Util__init__
+    Util.add_TgClass = __Util__add_TgClass
+    Util.add_Cpp_TgClass = __Util__add_Cpp_TgClass
+    Util.add_class = __Util__add_class
+    Util.get_class_list = __Util__get_class_list
+    Util.create_device = __Util__create_device
+    Util.delete_device = __Util__delete_device
 
 def __doc_Util():
+
+    Util.__doc__ = """\
+    This class is a used to store TANGO device server process data and to
+    provide the user with a set of utilities method.
+
+    This class is implemented using the singleton design pattern.
+    Therefore a device server process can have only one instance of this
+    class and its constructor is not public. Example::
+
+        util = PyTango.Util.instance()
+            print(util.get_host_name())
+    """
+
     def document_method(method_name, desc, append=True):
         return __document_method(Util, method_name, desc, append)
 
@@ -584,7 +585,7 @@ def __doc_Util():
 
         New in PyTango 8.0.0
     """ )
-            
+
     document_method("get_sub_dev_diag", """
     get_sub_dev_diag(self) -> SubDevDiag
 
@@ -592,7 +593,7 @@ def __doc_Util():
 
         Parameters : None
         Return     : (SubDevDiag) the sub device manager
-        
+
         New in PyTango 7.0.0
     """ )
 
@@ -603,7 +604,7 @@ def __doc_Util():
 
         Parameters : None
         Return     : None
-        
+
         New in PyTango 7.0.0
     """ )
 
@@ -614,7 +615,7 @@ def __doc_Util():
 
         Parameters : None
         Return     : (Database) the database
-        
+
         New in PyTango 7.0.0
     """ )
 
@@ -622,30 +623,30 @@ def __doc_Util():
     unregister_server(self) -> None
 
             Unregister a device server process from the TANGO database.
-            If the database call fails, a message is displayed on the screen 
+            If the database call fails, a message is displayed on the screen
             and the process is aborted
 
         Parameters : None
         Return     : None
-        
+
         New in PyTango 7.0.0
     """ )
-    
+
     document_method("get_device_list_by_class", """
     get_device_list_by_class(self, class_name) -> sequence<DeviceImpl>
 
             Get the list of device references for a given TANGO class.
             Return the list of references for all devices served by one implementation
             of the TANGO device pattern implemented in the process.
-            
+
         Parameters :
             - class_name : (str) The TANGO device class name
-            
+
         Return     : (sequence<DeviceImpl>) The device reference list
-        
+
         New in PyTango 7.0.0
     """ )
-    
+
     document_method("get_device_by_name", """
     get_device_by_name(self, dev_name) -> DeviceImpl
 
@@ -654,10 +655,10 @@ def __doc_Util():
         Parameters :
             - dev_name : (str) The TANGO device name
         Return     : (DeviceImpl) The device reference
-        
+
         New in PyTango 7.0.0
     """ )
-    
+
     document_method("get_dserver_device", """
     get_dserver_device(self) -> DServer
 
@@ -665,33 +666,33 @@ def __doc_Util():
 
         Parameters : None
         Return     : (DServer) A reference to the dserver device
-        
+
         New in PyTango 7.0.0
     """ )
-    
+
     document_method("get_device_list", """
     get_device_list(self) -> sequence<DeviceImpl>
 
             Get device list from name.
             It is possible to use a wild card ('*') in the name parameter
             (e.g. "*", "/tango/tangotest/n*", ...)
-            
+
         Parameters : None
         Return     : (sequence<DeviceImpl>) the list of device objects
-        
+
         New in PyTango 7.0.0
     """ )
-    
+
     document_method("server_set_event_loop", """
     server_set_event_loop(self, event_loop) -> None
-    
+
         This method registers an event loop function in a Tango server.
         This function will be called by the process main thread in an infinite loop
         The process will not use the classical ORB blocking event loop.
         It is the user responsability to code this function in a way that it implements
-        some kind of blocking in order not to load the computer CPU. The following 
+        some kind of blocking in order not to load the computer CPU. The following
         piece of code is an example of how you can use this feature::
-        
+
             _LOOP_NB = 1
             def looping():
                 global _LOOP_NB
@@ -699,10 +700,10 @@ def __doc_Util():
                 time.sleep(0.1)
                 _LOOP_NB += 1
                 return _LOOP_NB > 100
-            
+
             def main():
                 py = PyTango.Util(sys.argv)
-                
+
                 # ...
 
                 U = PyTango.Util.instance()
@@ -712,11 +713,11 @@ def __doc_Util():
 
         Parameters : None
         Return     : None
-        
+
         New in PyTango 8.1.0
     """ )
 
-            
+
 #    document_static_method("init_python", """
 #    init_python() -> None
 #

-- 
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/debian-science/packages/pytango.git



More information about the debian-science-commits mailing list