[pytango] 409/483: avoid inheriting from DeviceClass.\nMake use of original DeviceClass class wrapped from c++

Sandor Bodo-Merle sbodomerle-guest at moszumanska.debian.org
Thu Sep 28 19:15:06 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 c45cb91e3edf310e0b65121e73c8cb73ff2f7a7c
Author: tiagocoutinho <tiagocoutinho at 4e9c00fd-8f2e-0410-aa12-93ce3db5e235>
Date:   Tue Sep 30 11:18:28 2014 +0000

    avoid inheriting from DeviceClass.\nMake use of original DeviceClass class wrapped from c++
    
    git-svn-id: http://svn.code.sf.net/p/tango-cs/code/bindings/PyTango/trunk@26593 4e9c00fd-8f2e-0410-aa12-93ce3db5e235
---
 src/boost/cpp/server/device_class.cpp |  77 ++--
 src/boost/python/device_class.py      | 736 +++++++++++++++++-----------------
 2 files changed, 407 insertions(+), 406 deletions(-)

diff --git a/src/boost/cpp/server/device_class.cpp b/src/boost/cpp/server/device_class.cpp
index 63e4324..58d9c7b 100644
--- a/src/boost/cpp/server/device_class.cpp
+++ b/src/boost/cpp/server/device_class.cpp
@@ -70,18 +70,18 @@ void CppDeviceClass::create_command(const std::string &cmd_name,
 }
 
 void CppDeviceClass::create_attribute(vector<Tango::Attr *> &att_list,
-                                    const std::string &attr_name,
-                                    Tango::CmdArgType attr_type,
-                                    Tango::AttrDataFormat attr_format,
-                                    Tango::AttrWriteType attr_write,
-                                    long dim_x, long dim_y,
-                                    Tango::DispLevel display_level,
-                                    long polling_period,
-                                    bool memorized, bool hw_memorized,
-                                    const std::string &read_method_name,
-                                    const std::string &write_method_name,
-                                    const std::string &is_allowed_name,
-                                    Tango::UserDefaultAttrProp *att_prop)
+				      const std::string &attr_name,
+				      Tango::CmdArgType attr_type,
+				      Tango::AttrDataFormat attr_format,
+				      Tango::AttrWriteType attr_write,
+				      long dim_x, long dim_y,
+				      Tango::DispLevel display_level,
+				      long polling_period,
+				      bool memorized, bool hw_memorized,
+				      const std::string &read_method_name,
+				      const std::string &write_method_name,
+				      const std::string &is_allowed_name,
+				      Tango::UserDefaultAttrProp *att_prop)
 {
     //
     // Create the attribute objet according to attribute format
@@ -102,13 +102,15 @@ void CppDeviceClass::create_attribute(vector<Tango::Attr *> &att_list,
             break;
 
         case Tango::SPECTRUM:
-            spec_attr_ptr = new PySpecAttr(attr_name.c_str(), attr_type, attr_write, dim_x);
+            spec_attr_ptr = new PySpecAttr(attr_name.c_str(), attr_type,
+					   attr_write, dim_x);
             py_attr_ptr = spec_attr_ptr;
             attr_ptr = spec_attr_ptr;
             break;
 
         case Tango::IMAGE:
-            ima_attr_ptr = new PyImaAttr(attr_name.c_str(), attr_type, attr_write, dim_x, dim_y);
+            ima_attr_ptr = new PyImaAttr(attr_name.c_str(), attr_type, 
+					 attr_write, dim_x, dim_y);
             py_attr_ptr = ima_attr_ptr;
             attr_ptr = ima_attr_ptr;
             break;
@@ -178,7 +180,7 @@ void CppDeviceClassWrap::attribute_factory(std::vector<Tango::Attr *> &att_list)
 
     try
     {
-        boost::python::call_method<void>(m_self, "_DeviceClass__attribute_factory",
+        boost::python::call_method<void>(m_self, "_attribute_factory",
                                          py_att_list);
     }
     catch(boost::python::error_already_set &eas)
@@ -189,7 +191,7 @@ void CppDeviceClassWrap::attribute_factory(std::vector<Tango::Attr *> &att_list)
 
 void CppDeviceClassWrap::command_factory()
 {
-    CALL_DEVCLASS_METHOD(_DeviceClass__command_factory)
+    CALL_DEVCLASS_METHOD(_command_factory)
 }
 
 void CppDeviceClassWrap::device_name_factory(std::vector<std::string> &dev_list)
@@ -281,7 +283,8 @@ namespace PyDeviceClass
     {
         boost::python::list py_cmd_list;
         vector<Tango::Command *> cmd_list = self.get_command_list();
-        for(vector<Tango::Command *>::iterator it = cmd_list.begin(); it != cmd_list.end(); ++it)
+        for(vector<Tango::Command *>::iterator it = cmd_list.begin(); 
+	    it != cmd_list.end(); ++it)
         {
             object py_value = object(
                         handle<>(
@@ -292,37 +295,25 @@ namespace PyDeviceClass
         }
         return py_cmd_list;
     }
-        
-    /*
-    void add_device(CppDeviceClass &self, auto_ptr<Tango::DeviceImpl> dev)
+   
+    void register_signal(CppDeviceClass &self, long signo)
     {
-        self.add_device(dev.get());
-        dev.release();
+	self.register_signal(signo);
     }
 
-    void add_device(CppDeviceClass &self, auto_ptr<Tango::Device_4Impl> dev)
+#if (defined __linux)
+    
+    void register_signal(CppDeviceClass &self, long signo, bool own_handler)
     {
-        self.add_device(dev.get());
-        dev.release();
+	self.register_signal(signo, own_handler);
     }
 
-    void (*add_device1)(CppDeviceClass &, auto_ptr<Tango::DeviceImpl>) = &add_device;
-    void (*add_device2)(CppDeviceClass &, auto_ptr<Tango::Device_4Impl>) = &add_device;
-    */
-    
+#endif
 }
 
 BOOST_PYTHON_MEMBER_FUNCTION_OVERLOADS (export_device_overload,
                                         CppDeviceClass::export_device, 1, 2)
 
-#if !(defined __linux)
-BOOST_PYTHON_MEMBER_FUNCTION_OVERLOADS (register_signal_overload,
-                                        Tango::DeviceClass::register_signal, 1, 1)
-#else
-BOOST_PYTHON_MEMBER_FUNCTION_OVERLOADS (register_signal_overload,
-                                        Tango::DeviceClass::register_signal, 1, 2)
-#endif
-
 
 void export_device_class()
 {
@@ -335,18 +326,20 @@ void export_device_class()
     void (Tango::DeviceClass::*add_wiz_class_prop__)(string &,string &,string &) =
         &Tango::DeviceClass::add_wiz_class_prop;
 
-    class_<CppDeviceClass, auto_ptr<CppDeviceClassWrap>, boost::noncopyable>("_DeviceClass",
+    class_<CppDeviceClass, auto_ptr<CppDeviceClassWrap>, boost::noncopyable>("DeviceClass",
         init<const std::string &>())
 
         .def("device_factory", &CppDeviceClassWrap::device_factory)
         .def("device_name_factory", &CppDeviceClassWrap::device_name_factory)
         .def("export_device", &CppDeviceClass::export_device,
             export_device_overload())
-        //.def("_add_device", PyDeviceClass::add_device1)
-        //.def("_add_device", PyDeviceClass::add_device2)
         .def("_add_device", &CppDeviceClass::add_device)
-        .def("register_signal",&Tango::DeviceClass::register_signal,
-            register_signal_overload())
+        .def("register_signal", 
+	     (void (*) (CppDeviceClass &, long)) &PyDeviceClass::register_signal)
+#if defined __linux
+        .def("register_signal", 
+	     (void (*) (CppDeviceClass &, long, bool)) &PyDeviceClass::register_signal)
+#endif
         .def("unregister_signal", &Tango::DeviceClass::unregister_signal)
         .def("signal_handler", &Tango::DeviceClass::signal_handler,
             &CppDeviceClassWrap::default_signal_handler)
diff --git a/src/boost/python/device_class.py b/src/boost/python/device_class.py
index f35eef4..ff71336 100644
--- a/src/boost/python/device_class.py
+++ b/src/boost/python/device_class.py
@@ -21,7 +21,7 @@ __docformat__ = "restructuredtext"
 
 import collections
 
-from ._PyTango import Except, DevFailed, _DeviceClass, CmdArgType, \
+from ._PyTango import Except, DevFailed, DeviceClass, CmdArgType, \
     DispLevel, UserDefaultAttrProp
 from .pyutil import Util
 
@@ -261,393 +261,401 @@ class PropUtil:
         return obj_2_str(argin, argout_type)
 
 
-class DeviceClass(_DeviceClass):
-    """Base class for all TANGO device-class class.
-       A TANGO device-class class is a class where is stored all
-       data/method common to all devices of a TANGO device class"""
+def __DeviceClass__init__(self, name):
+    DeviceClass.__init_orig__(self, name)
+    self.dyn_att_added_methods = []
+    try:
+        pu = self.prop_util = PropUtil()
+        self.py_dev_list = []
+        pu.set_default_property_values(self, self.class_property_list,
+                                       self.device_property_list)
+        pu.get_class_properties(self, self.class_property_list)
+        for prop_name in self.class_property_list:
+            if not hasattr(self, prop_name):
+                setattr(self, prop_name, pu.get_property_values(prop_name,
+                        self.class_property_list))
+    except DevFailed as df:
+        print("PyDS: %s: A Tango error occured in the constructor:" % name)
+        Except.print_exception(df)
+    except Exception as e:
+        print("PyDS: %s: An error occured in the constructor:" % name)
+        print(str(e))
+
+def __DeviceClass__str__(self):
+    return '%s(%s)' % (self.__class__.__name__, self.get_name())
+
+def __DeviceClass__repr__(self):
+    return '%s(%s)' % (self.__class__.__name__, self.get_name())    
+
+def __throw_create_attribute_exception(msg):
+    """
+    Helper method to throw DevFailed exception when inside
+    create_attribute
+    """
+    Except.throw_exception("PyDs_WrongAttributeDefinition", msg,
+                           "create_attribute()")
+
+def __throw_create_command_exception(msg):
+    """
+    Helper method to throw DevFailed exception when inside
+    create_command
+    """
+    Except.throw_exception("PyDs_WrongCommandDefinition", msg,
+                           "create_command()")
+
+def __DeviceClass__attribute_factory(self, attr_list):
+    """for internal usage only"""
+    for attr_name, attr_info in self.attr_list.items():
+        if isinstance(attr_info, AttrData):
+            attr_data = attr_info
+        else:
+            attr_data = AttrData(attr_name, self.get_name(), attr_info)
+        self._create_attribute(attr_list, attr_data.attr_name,
+                               attr_data.attr_type,
+                               attr_data.attr_format,
+                               attr_data.attr_write,
+                               attr_data.dim_x, attr_data.dim_y,
+                               attr_data.display_level,
+                               attr_data.polling_period,
+                               attr_data.memorized,
+                               attr_data.hw_memorized,
+                               attr_data.read_method_name,
+                               attr_data.write_method_name,
+                               attr_data.is_allowed_name,
+                               attr_data.att_prop)
+
+def __DeviceClass__command_factory(self):
+    """for internal usage only"""
+    name = self.get_name()
+    class_info = get_class(name)
+    deviceimpl_class = class_info[1]
+
+    if not hasattr(deviceimpl_class, "init_device"):
+        msg = "Wrong definition of class %s\n" \
+              "The init_device() method does not exist!" % name
+        Except.throw_exception("PyDs_WrongCommandDefinition", msg, "command_factory()")
+
+    for cmd_name, cmd_info in self.cmd_list.items():
+        __create_command(self, deviceimpl_class, cmd_name, cmd_info)
+
+def __create_command(self, deviceimpl_class, cmd_name, cmd_info):
+    """for internal usage only"""
+    name = self.get_name()
+
+    # check for well defined command info
+
+    # check parameter
+    if not isinstance(cmd_info, collections.Sequence):
+        msg = "Wrong data type for value for describing command %s in " \
+              "class %s\nMust be a sequence with 2 or 3 elements" % (cmd_name, name)
+        __throw_create_command_exception(msg)
+
+    if len(cmd_info) < 2 or len(cmd_info) > 3:
+        msg = "Wrong number of argument for describing command %s in " \
+              "class %s\nMust be a sequence with 2 or 3 elements" % (cmd_name, name)
+        __throw_create_command_exception(msg)
+
+    param_info, result_info = cmd_info[0], cmd_info[1]
+
+    if not isinstance(param_info, collections.Sequence):
+        msg = "Wrong data type in command argument for command %s in " \
+              "class %s\nCommand parameter (first element) must be a sequence" % (cmd_name, name)
+        __throw_create_command_exception(msg)
+
+    if len(param_info) < 1 or len(param_info) > 2:
+        msg = "Wrong data type in command argument for command %s in " \
+              "class %s\nSequence describing command parameters must contain " \
+              "1 or 2 elements"
+        __throw_create_command_exception(msg)
+
+    param_type = CmdArgType.DevVoid
+    try:
+        param_type = CmdArgType(param_info[0])
+    except:
+        msg = "Wrong data type in command argument for command %s in " \
+              "class %s\nCommand parameter type (first element in first " \
+              "sequence) must be a PyTango.CmdArgType"
+        __throw_create_command_exception(msg)
+
+    param_desc = ""
+    if len(param_info) > 1:
+        param_desc = param_info[1]
+        if not is_pure_str(param_desc):
+            msg = "Wrong data type in command parameter for command %s in " \
+                  "class %s\nCommand parameter description (second element " \
+                  "in first sequence), when given, must be a string"
+            __throw_create_command_exception(msg)
+
+    # Check result
+    if not isinstance(result_info, collections.Sequence):
+        msg = "Wrong data type in command result for command %s in " \
+              "class %s\nCommand result (second element) must be a sequence" % (cmd_name, name)
+        __throw_create_command_exception(msg)
+
+    if len(result_info) < 1 or len(result_info) > 2:
+        msg = "Wrong data type in command result for command %s in " \
+              "class %s\nSequence describing command result must contain " \
+              "1 or 2 elements" % (cmd_name, name)
+        __throw_create_command_exception(msg)
+
+    result_type = CmdArgType.DevVoid
+    try:
+        result_type = CmdArgType(result_info[0])
+    except:
+        msg = "Wrong data type in command result for command %s in " \
+              "class %s\nCommand result type (first element in second " \
+              "sequence) must be a PyTango.CmdArgType" % (cmd_name, name)
+        __throw_create_command_exception(msg)
+
+    result_desc = ""
+    if len(result_info) > 1:
+        result_desc = result_info[1]
+        if not is_pure_str(result_desc):
+            msg = "Wrong data type in command result for command %s in " \
+                  "class %s\nCommand parameter description (second element " \
+                  "in second sequence), when given, must be a string" % (cmd_name, name)
+            __throw_create_command_exception(msg)
+
+    # If it is defined, get addictional dictionnary used for optional parameters
+    display_level, default_command, polling_period = DispLevel.OPERATOR, False, -1
+
+    if len(cmd_info) == 3:
+        extra_info = cmd_info[2]
+        if not isinstance(extra_info, collections.Mapping):
+            msg = "Wrong data type in command information for command %s in " \
+                  "class %s\nCommand information (third element in sequence), " \
+                  "when given, must be a dictionary" % (cmd_name, name)
+            __throw_create_command_exception(msg)
+
+        if len(extra_info) > 3:
+            msg = "Wrong data type in command information for command %s in " \
+                  "class %s\nThe optional dictionary can not have more than " \
+                  "three elements" % (cmd_name, name)
+            __throw_create_command_exception(msg)
+
+        for info_name, info_value in extra_info.items():
+            info_name_lower = info_name.lower()
+            if info_name_lower == "display level":
+                try:
+                    display_level = DispLevel(info_value)
+                except:
+                    msg = "Wrong data type in command information for command %s in " \
+                          "class %s\nCommand information for display level is not a " \
+                          "PyTango.DispLevel" % (cmd_name, name)
+                    __throw_create_command_exception(msg)
+            elif info_name_lower == "default command":
+                if not is_pure_str(info_value):
+                    msg = "Wrong data type in command information for command %s in " \
+                          "class %s\nCommand information for default command is not a " \
+                          "string" % (cmd_name, name)
+                    __throw_create_command_exception(msg)
+                v = info_value.lower()
+                default_command = v == 'true'
+            elif info_name_lower == "polling period":
+                try:
+                    polling_period = int(info_value)
+                except:
+                    msg = "Wrong data type in command information for command %s in " \
+                          "class %s\nCommand information for polling period is not an " \
+                          "integer" % (cmd_name, name)
+                    __throw_create_command_exception(msg)
+            else:
+                msg = "Wrong data type in command information for command %s in " \
+                      "class %s\nCommand information has unknown key " \
+                      "%s" % (cmd_name, name, info_name)
+                __throw_create_command_exception(msg)
+
+    # check that the method to be executed exists
+    try:
+        cmd = getattr(deviceimpl_class, cmd_name)
+        if not isinstance(cmd, collections.Callable):
+            msg = "Wrong definition of command %s in " \
+                  "class %s\nThe object exists in class but is not " \
+                  "a method!" % (cmd_name, name)
+            __throw_create_command_exception(msg)
+    except AttributeError:
+        msg = "Wrong definition of command %s in " \
+              "class %s\nThe command method does not exist!" % (cmd_name, name)
+        __throw_create_command_exception(msg)
+
+    is_allowed_name = "is_%s_allowed" % cmd_name
+    try:
+        is_allowed = getattr(deviceimpl_class, is_allowed_name)
+        if not isinstance(is_allowed, collections.Callable):
+            msg = "Wrong definition of command %s in " \
+                  "class %s\nThe object '%s' exists in class but is " \
+                  "not a method!" % (cmd_name, name, is_allowed_name)
+            __throw_create_command_exception(msg)
+    except:
+        is_allowed_name = ""
 
-    class_property_list = {}
-    device_property_list = {}
-    cmd_list = {}
-    attr_list = {}
+    self._create_command(cmd_name, param_type, result_type,
+                         param_desc, result_desc,
+                         display_level, default_command,
+                         polling_period, is_allowed_name)
 
-    def __init__(self, name):
-        _DeviceClass.__init__(self, name)
-        self.dyn_att_added_methods = []
-        try:
-            pu = self.prop_util = PropUtil()
-            self.py_dev_list = []
-            pu.set_default_property_values(self, self.class_property_list,
-                                           self.device_property_list)
-            pu.get_class_properties(self, self.class_property_list)
-            for prop_name in self.class_property_list:
-                if not hasattr(self, prop_name):
-                    setattr(self, prop_name, pu.get_property_values(prop_name,
-                            self.class_property_list))
-        except DevFailed as df:
-            print("PyDS: %s: A Tango error occured in the constructor:" % name)
-            Except.print_exception(df)
-        except Exception as e:
-            print("PyDS: %s: An error occured in the constructor:" % name)
-            print(str(e))
-            
-    def __str__(self):
-        return '%s(%s)' % (self.__class__.__name__, self.get_name())
-    
-    def __repr__(self):
-        return '%s(%s)' % (self.__class__.__name__, self.get_name())    
-    
-    def __throw_create_attribute_exception(self, msg):
-        """Helper method to throw DevFailed exception when inside create_attribute"""
-        Except.throw_exception("PyDs_WrongAttributeDefinition", msg, "create_attribute()")
+def __DeviceClass__new_device(self, klass, dev_class, dev_name):
+    return klass(dev_class, dev_name)
 
-    def __throw_create_command_exception(self, msg):
-        """Helper method to throw DevFailed exception when inside create_command"""
-        Except.throw_exception("PyDs_WrongCommandDefinition", msg, "create_command()")
+def __DeviceClass__device_factory(self, device_list):
+    """for internal usage only"""
 
-    def __attribute_factory(self, attr_list):
-        """for internal usage only"""
+    klass = self.__class__
+    klass_name = klass.__name__
+    info, klass = get_class_by_class(klass), get_constructed_class_by_class(klass)
 
-        for attr_name, attr_info in self.attr_list.items():
-            if isinstance(attr_info, AttrData):
-                attr_data = attr_info
-            else:
-                attr_data = AttrData(attr_name, self.get_name(), attr_info)
-            self.__create_attribute(attr_list, attr_data)
+    if info is None:
+        raise RuntimeError("Device class '%s' is not registered" % klass_name)
 
-    def __create_attribute(self, attr_list, attr_data):
-        """for internal usage only"""
-        self._create_attribute(attr_list, attr_data.attr_name,
-                               attr_data.attr_type, attr_data.attr_format,
-                               attr_data.attr_write, attr_data.dim_x,
-                               attr_data.dim_y, attr_data.display_level,
-                               attr_data.polling_period, attr_data.memorized,
-                               attr_data.hw_memorized,
-                               attr_data.read_method_name,
-                               attr_data.write_method_name,
-                               attr_data.is_allowed_name, attr_data.att_prop)
-
-    def __create_user_default_attr_prop(self, attr_name, extra_info):
-        """for internal usage only"""
-        p = UserDefaultAttrProp()
-        for k, v in extra_info.items():
-            k_lower = k.lower()
-            method_name = "set_%s" % k_lower.replace(' ','_')
-            if hasattr(p, method_name):
-                method = getattr(p, method_name)
-                method(str(v))
-            elif k == 'delta_time':
-                p.set_delta_t(str(v))
-            elif not k_lower in ('display level', 'polling period', 'memorized'):
-                name = self.get_name()
-                msg = "Wrong definition of attribute %s in " \
-                      "class %s\nThe object extra information '%s' " \
-                      "is not recognized!" % (attr_name, name, k)
-                self.__throw_create_attribute_exception(msg)
-        return p
-
-    def __command_factory(self):
-        """for internal usage only"""
-        name = self.get_name()
-        class_info = get_class(name)
-        deviceimpl_class = class_info[1]
-
-        if not hasattr(deviceimpl_class, "init_device"):
-            msg = "Wrong definition of class %s\n" \
-                  "The init_device() method does not exist!" % name
-            Except.throw_exception("PyDs_WrongCommandDefinition", msg, "command_factory()")
-
-        for cmd_name, cmd_info in self.cmd_list.items():
-            self.__create_command(deviceimpl_class, cmd_name, cmd_info)
-
-    def __create_command(self, deviceimpl_class, cmd_name, cmd_info):
-        """for internal usage only"""
-        name = self.get_name()
-
-        # check for well defined command info
-
-        # check parameter
-        if not isinstance(cmd_info, collections.Sequence):
-            msg = "Wrong data type for value for describing command %s in " \
-                  "class %s\nMust be a sequence with 2 or 3 elements" % (cmd_name, name)
-            self.__throw_create_command_exception(msg)
-
-        if len(cmd_info) < 2 or len(cmd_info) > 3:
-            msg = "Wrong number of argument for describing command %s in " \
-                  "class %s\nMust be a sequence with 2 or 3 elements" % (cmd_name, name)
-            self.__throw_create_command_exception(msg)
-
-        param_info, result_info = cmd_info[0], cmd_info[1]
-
-        if not isinstance(param_info, collections.Sequence):
-            msg = "Wrong data type in command argument for command %s in " \
-                  "class %s\nCommand parameter (first element) must be a sequence" % (cmd_name, name)
-            self.__throw_create_command_exception(msg)
-
-        if len(param_info) < 1 or len(param_info) > 2:
-            msg = "Wrong data type in command argument for command %s in " \
-                  "class %s\nSequence describing command parameters must contain " \
-                  "1 or 2 elements"
-            self.__throw_create_command_exception(msg)
-
-        param_type = CmdArgType.DevVoid
-        try:
-            param_type = CmdArgType(param_info[0])
-        except:
-            msg = "Wrong data type in command argument for command %s in " \
-                  "class %s\nCommand parameter type (first element in first " \
-                  "sequence) must be a PyTango.CmdArgType"
-            self.__throw_create_command_exception(msg)
-
-        param_desc = ""
-        if len(param_info) > 1:
-            param_desc = param_info[1]
-            if not is_pure_str(param_desc):
-                msg = "Wrong data type in command parameter for command %s in " \
-                      "class %s\nCommand parameter description (second element " \
-                      "in first sequence), when given, must be a string"
-                self.__throw_create_command_exception(msg)
-
-        # Check result
-        if not isinstance(result_info, collections.Sequence):
-            msg = "Wrong data type in command result for command %s in " \
-                  "class %s\nCommand result (second element) must be a sequence" % (cmd_name, name)
-            self.__throw_create_command_exception(msg)
+    if klass is None:
+        raise RuntimeError("Device class '%s' as not been constructed" % klass_name)
 
-        if len(result_info) < 1 or len(result_info) > 2:
-            msg = "Wrong data type in command result for command %s in " \
-                  "class %s\nSequence describing command result must contain " \
-                  "1 or 2 elements" % (cmd_name, name)
-            self.__throw_create_command_exception(msg)
+    deviceClassClass, deviceImplClass, deviceImplName = info
+    deviceImplClass._device_class_instance = klass
 
-        result_type = CmdArgType.DevVoid
-        try:
-            result_type = CmdArgType(result_info[0])
-        except:
-            msg = "Wrong data type in command result for command %s in " \
-                  "class %s\nCommand result type (first element in second " \
-                  "sequence) must be a PyTango.CmdArgType" % (cmd_name, name)
-            self.__throw_create_command_exception(msg)
-
-        result_desc = ""
-        if len(result_info) > 1:
-            result_desc = result_info[1]
-            if not is_pure_str(result_desc):
-                msg = "Wrong data type in command result for command %s in " \
-                      "class %s\nCommand parameter description (second element " \
-                      "in second sequence), when given, must be a string" % (cmd_name, name)
-                self.__throw_create_command_exception(msg)
-
-        # If it is defined, get addictional dictionnary used for optional parameters
-        display_level, default_command, polling_period = DispLevel.OPERATOR, False, -1
-
-        if len(cmd_info) == 3:
-            extra_info = cmd_info[2]
-            if not isinstance(extra_info, collections.Mapping):
-                msg = "Wrong data type in command information for command %s in " \
-                      "class %s\nCommand information (third element in sequence), " \
-                      "when given, must be a dictionary" % (cmd_name, name)
-                self.__throw_create_command_exception(msg)
+    tmp_dev_list = []
+    for dev_name in device_list:
+        device = self._new_device(deviceImplClass, klass, dev_name)
+        self._add_device(device)
+        tmp_dev_list.append(device)
 
-            if len(extra_info) > 3:
-                msg = "Wrong data type in command information for command %s in " \
-                      "class %s\nThe optional dictionary can not have more than " \
-                      "three elements" % (cmd_name, name)
-                self.__throw_create_command_exception(msg)
-
-            for info_name, info_value in extra_info.items():
-                info_name_lower = info_name.lower()
-                if info_name_lower == "display level":
-                    try:
-                        display_level = DispLevel(info_value)
-                    except:
-                        msg = "Wrong data type in command information for command %s in " \
-                              "class %s\nCommand information for display level is not a " \
-                              "PyTango.DispLevel" % (cmd_name, name)
-                        self.__throw_create_command_exception(msg)
-                elif info_name_lower == "default command":
-                    if not is_pure_str(info_value):
-                        msg = "Wrong data type in command information for command %s in " \
-                              "class %s\nCommand information for default command is not a " \
-                              "string" % (cmd_name, name)
-                        self.__throw_create_command_exception(msg)
-                    v = info_value.lower()
-                    default_command = v == 'true'
-                elif info_name_lower == "polling period":
-                    try:
-                        polling_period = int(info_value)
-                    except:
-                        msg = "Wrong data type in command information for command %s in " \
-                              "class %s\nCommand information for polling period is not an " \
-                              "integer" % (cmd_name, name)
-                        self.__throw_create_command_exception(msg)
-                else:
-                    msg = "Wrong data type in command information for command %s in " \
-                          "class %s\nCommand information has unknown key " \
-                          "%s" % (cmd_name, name, info_name)
-                    self.__throw_create_command_exception(msg)
+    self.dyn_attr(tmp_dev_list)
 
-        # check that the method to be executed exists
-        try:
-            cmd = getattr(deviceimpl_class, cmd_name)
-            if not isinstance(cmd, collections.Callable):
-                msg = "Wrong definition of command %s in " \
-                      "class %s\nThe object exists in class but is not " \
-                      "a method!" % (cmd_name, name)
-                self.__throw_create_command_exception(msg)
-        except AttributeError:
-            msg = "Wrong definition of command %s in " \
-                  "class %s\nThe command method does not exist!" % (cmd_name, name)
-            self.__throw_create_command_exception(msg)
+    for dev in tmp_dev_list:
+        if Util._UseDb and not Util._FileDb:
+            self.export_device(dev)
+        else:
+            self.export_device(dev, dev.get_name())
+    self.py_dev_list += tmp_dev_list
 
-        is_allowed_name = "is_%s_allowed" % cmd_name
-        try:
-            is_allowed = getattr(deviceimpl_class, is_allowed_name)
-            if not isinstance(is_allowed, collections.Callable):
-                msg = "Wrong definition of command %s in " \
-                      "class %s\nThe object '%s' exists in class but is " \
-                      "not a method!" % (cmd_name, name, is_allowed_name)
-                self.__throw_create_command_exception(msg)
-        except:
-            is_allowed_name = ""
-
-        self._create_command(cmd_name, param_type, result_type,
-                             param_desc, result_desc,
-                             display_level, default_command,
-                             polling_period, is_allowed_name)
-
-    def device_factory(self, device_list):
-        """for internal usage only"""
-       
-        klass = self.__class__
-        klass_name = klass.__name__
-        info, klass = get_class_by_class(klass), get_constructed_class_by_class(klass)
-        
-        if info is None:
-            raise RuntimeError("Device class '%s' is not registered" % klass_name)
+def __DeviceClass__create_device(self, device_name, alias=None, cb=None):
+    """
+        create_device(self, device_name, alias=None, cb=None) -> None
 
-        if klass is None:
-            raise RuntimeError("Device class '%s' as not been constructed" % klass_name)
-        
-        deviceClassClass, deviceImplClass, deviceImplName = info
-        deviceImplClass._device_class_instance = klass
+            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 
+            registered in the database and BEFORE the init_device for the
+            newly created device is called
 
-        tmp_dev_list = []
-        for dev_name in device_list:
-            device = deviceImplClass(klass, dev_name)
-            self._add_device(device)
-            tmp_dev_list.append(device)
+        Throws PyTango.DevFailed:
+            - the device name exists already or
+            - the given class is not registered for this DS.
+            - the cb is not a callable
 
-        self.dyn_attr(tmp_dev_list)
+        New in PyTango 7.1.2
 
-        for dev in tmp_dev_list:
-            if Util._UseDb and not Util._FileDb:
-                self.export_device(dev)
-            else:
-                self.export_device(dev, dev.get_name())
-        self.py_dev_list += tmp_dev_list
+        Parameters :
+            - device_name : (str) the device name
+            - alias : (str) optional alias. Default value is None meaning do not create device alias
+            - cb : (callable) a callback that is called AFTER the device is registered
+                   in the database and BEFORE the init_device for the newly created
+                   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"""
+    util = Util.instance()
+    util.create_device(self.get_name(), device_name, alias=alias, cb=cb)
+
+def __DeviceClass__delete_device(self, device_name):
+    """
+        delete_device(self, klass_name, device_name) -> None
+
+            Deletes an existing device from the database and from this running
+            server
 
-    def create_device(self, device_name, alias=None, cb=None):
-        """
-            create_device(self, 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 
-                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 :
-                - device_name : (str) the device name
-                - alias : (str) optional alias. Default value is None meaning do not create device alias
-                - cb : (callable) a callback that is called AFTER the device is registered
-                       in the database and BEFORE the init_device for the newly created
-                       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"""
-        util = Util.instance()
-        util.create_device(self.get_name(), device_name, alias=alias, cb=cb)
-
-    def delete_device(self, 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"""
-        util = Util.instance()
-        util.delete_device(self.get_name(), device_name)
-        
-    def dyn_attr(self,device_list):
-        """
-            dyn_attr(self,device_list) -> None
+                - the device name doesn't exist in the database
+                - the device name doesn't exist in this DS.
 
-                Default implementation does not do anything
-                Overwrite in order to provide dynamic attributes
+        New in PyTango 7.1.2
 
-            Parameters :
-                - device_list : (seq<DeviceImpl>) sequence of devices of this class
-
-            Return     : None"""
-        pass
-
-    def device_destroyer(self,name):
-        """for internal usage only"""
-        name = name.lower()
-        for d in self.py_dev_list:
-            dname = d.get_name().lower()
-            if dname == name:
-                dev_cl = d.get_device_class()
-                # the internal C++ device_destroyer isn't case sensitive so we
-                # use the internal DeviceImpl name to make sure the DeviceClass
-                # finds it
-                dev_cl._device_destroyer(d.get_name())
-                self.py_dev_list.remove(d)
-                return
-        err_mess = "Device " + name + " not in Tango class device list!"
-        Except.throw_exception("PyAPI_CantDestroyDevice",err_mess,"DeviceClass.device_destroyer")
-    
-    def device_name_factory(self, dev_name_list):
-        """
-            device_name_factory(self, dev_name_list) ->  None
-                
-                Create device(s) name list (for no database device server).
-                This method can be re-defined in DeviceClass sub-class for
-                device server started without database. Its rule is to
-                initialise class device name. The default method does nothing.
-            
-            Parameters :
-                - dev_name_list : (seq<str>) sequence of devices to be filled
+        Parameters :
+            - klass_name : (str) the device class name
+            - device_name : (str) the device name
+
+        Return     : None"""
+    util = Util.instance()
+    util.delete_device(self.get_name(), device_name)
+
+def __DeviceClass__dyn_attr(self,device_list):
+    """
+        dyn_attr(self,device_list) -> None
+
+            Default implementation does not do anything
+            Overwrite in order to provide dynamic attributes
+
+        Parameters :
+            - device_list : (seq<DeviceImpl>) sequence of devices of this class
+
+        Return     : None"""
+    pass
+
+def __DeviceClass__device_destroyer(self,name):
+    """for internal usage only"""
+    name = name.lower()
+    for d in self.py_dev_list:
+        dname = d.get_name().lower()
+        if dname == name:
+            dev_cl = d.get_device_class()
+            # the internal C++ device_destroyer isn't case sensitive so we
+            # use the internal DeviceImpl name to make sure the DeviceClass
+            # finds it
+            dev_cl._device_destroyer(d.get_name())
+            self.py_dev_list.remove(d)
+            return
+    err_mess = "Device " + name + " not in Tango class device list!"
+    Except.throw_exception("PyAPI_CantDestroyDevice",err_mess,"DeviceClass.device_destroyer")
+
+
+def __DeviceClass__device_name_factory(self, dev_name_list):
+    """
+        device_name_factory(self, dev_name_list) ->  None
+
+            Create device(s) name list (for no database device server).
+            This method can be re-defined in DeviceClass sub-class for
+            device server started without database. Its rule is to
+            initialise class device name. The default method does nothing.
+
+        Parameters :
+            - dev_name_list : (seq<str>) sequence of devices to be filled
+
+        Return     : None"""
+    pass
 
-            Return     : None"""
-        pass
     
 def __init_DeviceClass():
-    pass
+    DeviceClass.class_property_list = {}
+    DeviceClass.device_property_list = {}
+    DeviceClass.cmd_list = {}
+    DeviceClass.attr_list = {}
+    DeviceClass.__init_orig__ = DeviceClass.__init__
+    DeviceClass.__init__ = __DeviceClass__init__
+    DeviceClass.__str__ = __DeviceClass__str__
+    DeviceClass.__repr__ = __DeviceClass__repr__
+    DeviceClass._attribute_factory = __DeviceClass__attribute_factory
+    DeviceClass._command_factory = __DeviceClass__command_factory
+    DeviceClass._new_device = __DeviceClass__new_device
+    
+    DeviceClass.device_factory = __DeviceClass__device_factory
+    DeviceClass.create_device = __DeviceClass__create_device
+    DeviceClass.delete_device = __DeviceClass__delete_device
+    DeviceClass.dyn_attr = __DeviceClass__dyn_attr
+    DeviceClass.device_destroyer = __DeviceClass__device_destroyer
+    DeviceClass.device_name_factory = __DeviceClass__device_name_factory
+
 
 def __doc_DeviceClass():
+
+    DeviceClass.__doc__ = """
+    Base class for all TANGO device-class class.
+    A TANGO device-class class is a class where is stored all
+    data/method common to all devices of a TANGO device class
+    """
+    
     def document_method(method_name, desc, append=True):
         return __document_method(DeviceClass, method_name, desc, append)
 

-- 
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