[pytango] 271/483: green pytango feature

Sandor Bodo-Merle sbodomerle-guest at moszumanska.debian.org
Thu Sep 28 19:14:49 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 07464f01cca7212e2d3e8df8a8eb63903259ca4e
Author: tiagocoutinho <tiagocoutinho at 4e9c00fd-8f2e-0410-aa12-93ce3db5e235>
Date:   Wed Jul 17 14:44:09 2013 +0000

    green pytango feature
    
    git-svn-id: http://svn.code.sf.net/p/tango-cs/code/bindings/PyTango/trunk@23143 4e9c00fd-8f2e-0410-aa12-93ce3db5e235
---
 doc/client/miscellaneous.rst        |   8 +-
 doc/client/other.rst                |   5 +-
 doc/utilities.rst                   |   4 +
 src/boost/cpp/base_types.cpp        |   6 +
 src/boost/cpp/defs.h                |   6 +
 src/boost/cpp/device_proxy.cpp      |   8 +-
 src/boost/python/__init__.py        |   6 +-
 src/boost/python/attribute_proxy.py |  71 +++++++-
 src/boost/python/base_types.py      |  10 ++
 src/boost/python/connection.py      |  25 ++-
 src/boost/python/device_proxy.py    | 311 ++++++++++++++++++++++++++++++++----
 src/boost/python/group.py           |   4 +-
 src/boost/python/tango_futures.py   |  61 +++++++
 src/boost/python/tango_gevent.py    |  37 +++++
 src/boost/python/tango_green.py     | 140 ++++++++++++++++
 src/boost/python/utils.py           |  39 ++++-
 16 files changed, 695 insertions(+), 46 deletions(-)

diff --git a/doc/client/miscellaneous.rst b/doc/client/miscellaneous.rst
index 55cd8c2..e8f5b9c 100644
--- a/doc/client/miscellaneous.rst
+++ b/doc/client/miscellaneous.rst
@@ -1,6 +1,11 @@
+.. currentmodule:: PyTango
 
+Green creation of PyTango objects
+---------------------------------
 
-.. currentmodule:: PyTango
+.. autofunction:: get_device_proxy
+
+.. autofunction:: get_attribute_proxy
 
 API util
 --------
@@ -15,6 +20,7 @@ See also `Event configuration information`_
 
 Attribute
 ~~~~~~~~~
+
 .. autoclass:: PyTango.AttributeAlarmInfo
     :members:
 
diff --git a/doc/client/other.rst b/doc/client/other.rst
index 910e026..d8b7fe8 100644
--- a/doc/client/other.rst
+++ b/doc/client/other.rst
@@ -50,6 +50,9 @@ Enumerations
 
 .. autoclass:: PyTango.DispLevel
 
+.. autoclass:: PyTango.GreenMode
+
+
 Other classes
 ~~~~~~~~~~~~~
 
@@ -57,4 +60,4 @@ Other classes
     :members:
     
 .. autoclass:: PyTango.TimeVal
-    :members:
\ No newline at end of file
+    :members:
diff --git a/doc/utilities.rst b/doc/utilities.rst
index 962e8dd..5412ca9 100644
--- a/doc/utilities.rst
+++ b/doc/utilities.rst
@@ -12,6 +12,10 @@ The Utilities API
     :members:
     :undoc-members:
 
+.. autofunction:: PyTango.utils.get_green_mode
+
+.. autofunction:: PyTango.utils.set_green_mode
+
 .. autofunction:: PyTango.utils.is_scalar_type
     
 .. autofunction:: PyTango.utils.is_array_type
diff --git a/src/boost/cpp/base_types.cpp b/src/boost/cpp/base_types.cpp
index b2fd009..66e05b4 100644
--- a/src/boost/cpp/base_types.cpp
+++ b/src/boost/cpp/base_types.cpp
@@ -188,6 +188,12 @@ void export_base_types()
         .value("Nothing", PyTango::ExtractAsNothing)
     ;
 
+    enum_<PyTango::GreenMode>("GreenMode")
+        .value("Synchronous", PyTango::GreenModeSynchronous)
+        .value("Futures", PyTango::GreenModeFutures)
+        .value("Gevent", PyTango::GreenModeGevent)
+    ;
+
     enum_<PyTango::ImageFormat>("_ImageFormat")
         .value("RawImage", PyTango::RawImage)
         .value("JpegImage", PyTango::JpegImage)
diff --git a/src/boost/cpp/defs.h b/src/boost/cpp/defs.h
index 8e1e5e2..c73ccb1 100644
--- a/src/boost/cpp/defs.h
+++ b/src/boost/cpp/defs.h
@@ -64,4 +64,10 @@ namespace PyTango
         RawImage,
         JpegImage
     };
+
+    enum GreenMode {
+        GreenModeSynchronous,
+        GreenModeFutures,
+        GreenModeGevent
+    };
 }
diff --git a/src/boost/cpp/device_proxy.cpp b/src/boost/cpp/device_proxy.cpp
index bc5c099..8ab73e3 100644
--- a/src/boost/cpp/device_proxy.cpp
+++ b/src/boost/cpp/device_proxy.cpp
@@ -553,21 +553,21 @@ void export_device_proxy()
             &PyDeviceProxy::read_attribute,
             ( arg_("self"), arg_("attr_name"), arg_("extract_as")=PyTango::ExtractAsNumpy ) )
 
-        .def("read_attributes",
+        .def("_read_attributes",
             &PyDeviceProxy::read_attributes,
             ( arg_("self"), arg_("attr_names"), arg_("extract_as")=PyTango::ExtractAsNumpy ) )
 
-        .def("write_attribute",
+        .def("_write_attribute",
             (void (*)(Tango::DeviceProxy&, const string &, bopy::object ))
             &PyDeviceProxy::write_attribute,
             ( arg_("self"), arg_("attr_name"), arg_("value") ) )
 
-        .def("write_attribute",
+        .def("_write_attribute",
             (void (*)(Tango::DeviceProxy&, const Tango::AttributeInfo &, bopy::object ))
             &PyDeviceProxy::write_attribute,
             ( arg_("self"), arg_("attr_info"), arg_("value") ) )
 
-        .def("write_attributes",
+        .def("_write_attributes",
             &PyDeviceProxy::write_attributes,
             ( arg_("self"), arg_("name_val") ) )
 
diff --git a/src/boost/python/__init__.py b/src/boost/python/__init__.py
index 64e8aee..08ccd5f 100644
--- a/src/boost/python/__init__.py
+++ b/src/boost/python/__init__.py
@@ -143,7 +143,7 @@ from ._PyTango import (AccessControlType, ApiUtil, ArchiveEventInfo,
     DeviceImpl, DeviceInfo, DeviceUnlocked, Device_2Impl,
     Device_3Impl, Device_4Impl, DispLevel, EncodedAttribute, ErrSeverity,
     EventData, EventSystemFailed, EventType,
-    Except, ExtractAs, FMT_UNKNOWN, GroupAttrReply, GroupAttrReplyList,
+    Except, ExtractAs, GreenMode, FMT_UNKNOWN, GroupAttrReply, GroupAttrReplyList,
     GroupCmdReply, GroupCmdReplyList, GroupReply, GroupReplyList,
     IMAGE, ImageAttr, KeepAliveCmdCode, Level, LockCmdCode, LockerInfo,
     LockerLanguage, LogLevel, LogTarget, Logger, Logging, MessBoxType,
@@ -176,7 +176,7 @@ from .log4tango import TangoStream, LogIt, DebugIt, InfoIt, WarnIt, \
 from .device_server import ChangeEventProp, PeriodicEventProp, \
     ArchiveEventProp, AttributeAlarm, EventProperties, AttributeConfig, \
     AttributeConfig_2, AttributeConfig_3, MultiAttrProp
-from .attribute_proxy import AttributeProxy
+from .attribute_proxy import AttributeProxy, get_attribute_proxy
 from .group import Group
 from .pyutil import Util
 from .device_class import DeviceClass
@@ -186,6 +186,8 @@ from .globals import get_class, get_classes, get_cpp_class, get_cpp_classes, \
 from .utils import is_scalar_type, is_array_type, is_numerical_type, \
     is_int_type, is_float_type, obj_2_str, seqStr_2_obj
 from .utils import server_run
+from .utils import set_green_mode, get_green_mode
+from .device_proxy import get_device_proxy
 from .tango_numpy import NumpyType, numpy_type, numpy_spectrum, numpy_image
 
 from .pytango_init import init as __init
diff --git a/src/boost/python/attribute_proxy.py b/src/boost/python/attribute_proxy.py
index 66fd972..1e6d59d 100644
--- a/src/boost/python/attribute_proxy.py
+++ b/src/boost/python/attribute_proxy.py
@@ -29,16 +29,77 @@ To access these members use directly :mod:`PyTango` module and NOT
 PyTango.attribute_proxy.
 """
 
-__all__ = [ "AttributeProxy", "attribute_proxy_init"]
+__all__ = [ "AttributeProxy", "attribute_proxy_init", "get_attribute_proxy" ]
             
 __docformat__ = "restructuredtext"
 
+import collections
+
 from ._PyTango import StdStringVector, DbData, DbDatum, DeviceProxy
 from ._PyTango import __AttributeProxy as _AttributeProxy
 from .utils import seq_2_StdStringVector, seq_2_DbData, DbData_2_dict, \
-    is_pure_str, is_non_str_seq
-import collections
+    is_pure_str, is_non_str_seq, get_green_mode
+from .tango_green import result, submit, green
+
 
+def get_attribute_proxy(*args, **kwargs):
+    """
+    get_attribute_proxy(self, full_attr_name, green_mode=None, wait=True, timeout=True) -> AttributeProxy
+    get_attribute_proxy(self, device_proxy, attr_name, green_mode=None, wait=True, timeout=True) -> AttributeProxy
+
+    Returns a new :class:`~PyTango.AttributeProxy`.
+    There is no difference between using this function and the direct 
+    :class:`~PyTango.AttributeProxy` constructor if you use the default kwargs.
+     
+    The added value of this function becomes evident when you choose a green_mode
+    to be *Futures* or *Gevent*. The AttributeProxy constructor internally makes some
+    network calls which makes it *slow*. By using one of the *green modes* as 
+    green_mode you are allowing other python code to be executed in a cooperative way.
+
+    :param full_attr_name: the full name of the attribute
+    :type full_attr_name: str
+    :param device_proxy: the :class:`~PyTango.DeviceProxy`
+    :type device_proxy: DeviceProxy
+    :param attr_name: attribute name for the given device proxy
+    :type attr_name: str
+    :param green_mode: determines the mode of execution of the device (including
+                      the way it is created). Defaults to the current global
+                      green_mode (check :func:`~PyTango.utils.get_green_mode` and
+                      :func:`~PyTango.utils.set_green_mode`)
+    :type green_mode: :obj:`~PyTango.GreenMode`
+    :param wait: whether or not to wait for result. If green_mode
+                 Ignored when green_mode is Synchronous (always waits).
+    :type wait: bool
+    :param timeout: The number of seconds to wait for the result.
+                    If None, then there is no limit on the wait time.
+                    Ignored when green_mode is Synchronous or wait is False.
+    :type timeout: float
+    :returns:
+        if green_mode is Synchronous or wait is True:
+            :class:`~PyTango.AttributeProxy`
+        else if green_mode is Futures:
+            :class:`concurrent.futures.Future`
+        else if green_mode is Gevent:
+            :class:`gevent.event.AsynchResult`
+    :throws:
+        * a *DevFailed* if green_mode is Synchronous or wait is True 
+          and there is an error creating the attribute.
+        * a *concurrent.futures.TimeoutError* if green_mode is Futures,
+          wait is False, timeout is not None and the time to create the attribute
+          has expired.                            
+        * a *gevent.timeout.Timeout* if green_mode is Gevent, wait is False,
+          timeout is not None and the time to create the attribute has expired.
+    
+    New in PyTango 8.1.0
+    """
+    # we cannot use the green wrapper because it consumes the green_mode and we
+    # want to forward it to the DeviceProxy constructor
+    green_mode = kwargs.get('green_mode', get_green_mode())
+    wait = kwargs.pop('wait', True)
+    timeout = kwargs.pop('timeout', None)
+    
+    d = submit(green_mode, AttributeProxy, *args, **kwargs)
+    return result(d, green_mode, wait=wait, timeout=timeout)
 
 def __AttributeProxy__get_property(self, propname, value=None):
     """
@@ -239,10 +300,12 @@ class AttributeProxy(object):
         python reimplementation of the AttributeProxy found on the C++ API.
     """
     def __init__(self, *args, **kwds):
+        green_mode = kwds.pop('green_mode', get_green_mode())
         self.__attr_proxy = _AttributeProxy(*args, **kwds)
         # get_device_proxy() returns a different python object each time
         # we don't want a different object, so we save the current one.
-        self.__dev_proxy = self.__attr_proxy.get_device_proxy()
+        self.__dev_proxy = dp = self.__attr_proxy.get_device_proxy()
+        dp.set_green_mode(green_mode)
 
     def get_device_proxy(self):
         """
diff --git a/src/boost/python/base_types.py b/src/boost/python/base_types.py
index 909a0f4..ca4b24d 100644
--- a/src/boost/python/base_types.py
+++ b/src/boost/python/base_types.py
@@ -594,6 +594,16 @@ def __doc_base_types():
         - OPERATOR
         - EXPERT
     """ )
+
+    document_enum("GreenMode", """
+    An enumeration representing the GreenMode
+    
+        - Synchronous
+        - Futures
+        - Gevent
+    
+    New in PyTango 8.1.0
+    """ )
     
     ArchiveEventInfo.__doc__ = """
     A structure containing available archiving event information for an attribute
diff --git a/src/boost/python/connection.py b/src/boost/python/connection.py
index 0245c0b..3f51b5c 100644
--- a/src/boost/python/connection.py
+++ b/src/boost/python/connection.py
@@ -36,6 +36,7 @@ from ._PyTango import Connection, DeviceData, __CallBackAutoDie, CmdArgType, \
     DeviceProxy, Database, ExtractAs
 from .utils import document_method as __document_method
 from .utils import document_static_method as __document_static_method
+from .tango_green import green
 
 
 def __CallBackAutoDie__cmd_ended_aux(self, fn):
@@ -79,7 +80,7 @@ def __get_command_inout_param(self, cmd_name, cmd_param=None):
 
 def __Connection__command_inout(self, name, *args, **kwds):
     """
-    command_inout( self, cmd_name, cmd_param=None) -> any
+    command_inout( self, cmd_name, cmd_param=None, green_mode=None, wait=True, timeout=None) -> any
 
             Execute a command on a device.
             
@@ -88,9 +89,26 @@ def __Connection__command_inout(self, name, *args, **kwds):
                 - cmd_param : (any) It should be a value of the type expected by the
                               command or a DeviceData object with this value inserted.
                               It can be ommited if the command should not get any argument.
+                - green_mode : (GreenMode) Defaults to the current DeviceProxy GreenMode.
+                               (see :meth:`~PyTango.DeviceProxy.get_green_mode` and
+                               :meth:`~PyTango.DeviceProxy.set_green_mode`).
+                - wait       : (bool) whether or not to wait for result. If green_mode
+                               is *Synchronous*, this parameter is ignored as it always
+                               waits for the result.
+                               Ignored when green_mode is Synchronous (always waits).
+                - timeout    : (float) The number of seconds to wait for the result.
+                               If None, then there is no limit on the wait time.
+                               Ignored when green_mode is Synchronous or wait is False.
         Return     : The result of the command. The type depends on the command. It may be None.
 
         Throws     : ConnectionFailed, CommunicationFailed, DeviceUnlocked, DevFailed from device 
+                     TimeoutError (green_mode == Futures) If the future didn't finish executing before the given timeout.
+                     Timeout (green_mode == Gevent) If the async result didn't finish executing before the given timeout.
+
+    .. versionadded:: 8.1.0
+        *green_mode* parameter.
+        *wait* parameter.
+        *timeout* parameter.
     """
     r = Connection.command_inout_raw(self, name, *args, **kwds)
     if isinstance(r, DeviceData):
@@ -100,6 +118,7 @@ def __Connection__command_inout(self, name, *args, **kwds):
             return None
     else:
         return r
+__Connection__command_inout.__name__ = "command_inout"
 
 def __Connection__command_inout_raw(self, cmd_name, cmd_param = None):
     """
@@ -198,6 +217,7 @@ def __Connection__command_inout_asynch(self, cmd_name, *args):
             return self.__command_inout_asynch_id(cmd_name, argin, forget)
     else:
         raise TypeError("Wrong number of attributes!")
+__Connection__command_inout_asynch.__name__ = "command_inout_asynch"
 
 def __Connection__command_inout_reply(self, idx, timeout=None):
     """
@@ -244,11 +264,12 @@ def __Connection__command_inout_reply(self, idx, timeout=None):
             return None
     else:
         return r
+__Connection__command_inout_reply.__name__ = "command_inout_reply"
     
 def __init_Connection():
     Connection.defaultCommandExtractAs = ExtractAs.Numpy
     Connection.command_inout_raw = __Connection__command_inout_raw
-    Connection.command_inout = __Connection__command_inout
+    Connection.command_inout = green(__Connection__command_inout)
     Connection.command_inout_asynch = __Connection__command_inout_asynch
     Connection.command_inout_reply = __Connection__command_inout_reply
     
diff --git a/src/boost/python/device_proxy.py b/src/boost/python/device_proxy.py
index 677a821..2afad96 100644
--- a/src/boost/python/device_proxy.py
+++ b/src/boost/python/device_proxy.py
@@ -27,21 +27,92 @@ This is an internal PyTango module.
 
 from __future__ import with_statement
 
-__all__ = ["device_proxy_init"]
+__all__ = ["device_proxy_init", "get_device_proxy"]
 
 __docformat__ = "restructuredtext"
 
+
+import collections
+import numbers
 import threading
 
 from ._PyTango import StdStringVector, DbData, DbDatum, AttributeInfo, \
     AttributeInfoEx, AttributeInfoList, AttributeInfoListEx, DeviceProxy, \
     __CallBackAutoDie, __CallBackPushEvent, EventType, DevFailed, Except, \
-    ExtractAs
+    ExtractAs, GreenMode
+
 from .utils import is_pure_str, is_non_str_seq, is_integer, \
     seq_2_StdStringVector, StdStringVector_2_seq, seq_2_DbData, DbData_2_dict
+    
 from .utils import document_method as __document_method
-import collections
-import numbers
+from .utils import get_green_mode
+
+from .tango_green import result, submit, green
+
+
+def get_device_proxy(*args, **kwargs):
+    """get_device_proxy(self, dev_name, green_mode=None, wait=True, timeout=True) -> DeviceProxy
+    get_device_proxy(self, dev_name, need_check_acc, green_mode=None, wait=True, timeout=True) -> DeviceProxy
+
+    Returns a new :class:`~PyTango.DeviceProxy`.
+    There is no difference between using this function and the direct 
+    :class:`~PyTango.DeviceProxy` constructor if you use the default kwargs.
+     
+    The added value of this function becomes evident when you choose a green_mode
+    to be *Futures* or *Gevent*. The DeviceProxy constructor internally makes some
+    network calls which makes it *slow*. By using one of the *green modes* as 
+    green_mode you are allowing other python code to be executed in a cooperative way.
+
+    .. note::
+        The timeout parameter has no relation with the tango device client side
+        timeout (gettable by :meth:`~PyTango.DeviceProxy.get_timeout_millis` and 
+        settable through :meth:`~PyTango.DeviceProxy.set_timeout_millis`)
+
+    :param dev_name: the device name or alias
+    :type dev_name: str
+    :param need_check_acc: in first version of the function it defaults to True.
+                           Determines if at creation time of DeviceProxy it should check
+                           for channel access (rarely used)
+    :type need_check_acc: bool
+    :param green_mode: determines the mode of execution of the device (including
+                      the way it is created). Defaults to the current global
+                      green_mode (check :func:`~PyTango.utils.get_green_mode` and
+                      :func:`~PyTango.utils.set_green_mode`)
+    :type green_mode: :obj:`~PyTango.GreenMode`
+    :param wait: whether or not to wait for result. If green_mode
+                 Ignored when green_mode is Synchronous (always waits).
+    :type wait: bool
+    :param timeout: The number of seconds to wait for the result.
+                    If None, then there is no limit on the wait time.
+                    Ignored when green_mode is Synchronous or wait is False.
+    :type timeout: float
+    :returns:
+        if green_mode is Synchronous or wait is True:
+            :class:`~PyTango.DeviceProxy`
+        else if green_mode is Futures:
+            :class:`concurrent.futures.Future`
+        else if green_mode is Gevent:
+            :class:`gevent.event.AsynchResult`
+    :throws:
+        * a *DevFailed* if green_mode is Synchronous or wait is True 
+          and there is an error creating the device.
+        * a *concurrent.futures.TimeoutError* if green_mode is Futures,
+          wait is False, timeout is not None and the time to create the device
+          has expired.                            
+        * a *gevent.timeout.Timeout* if green_mode is Gevent, wait is False,
+          timeout is not None and the time to create the device has expired.
+    
+    New in PyTango 8.1.0
+    """
+    # we cannot use the green wrapper because it consumes the green_mode and we
+    # want to forward it to the DeviceProxy constructor
+    green_mode = kwargs.get('green_mode', get_green_mode())
+    wait = kwargs.pop('wait', True)
+    timeout = kwargs.pop('timeout', None)
+    
+    d = submit(green_mode, DeviceProxy, *args, **kwargs)
+    return result(d, green_mode, wait=wait, timeout=timeout)
+
 
 class __TangoInfo(object):
     """Helper class for when DeviceProxy.info() is not available"""
@@ -63,6 +134,44 @@ def __check_read_attribute(dev_attr):
         raise DevFailed(*dev_attr.get_err_stack())
     return dev_attr
 
+def __DeviceProxy__init__(self, *args, **kwargs):
+    self.__dict__['_green_mode'] = kwargs.pop('green_mode', get_green_mode())
+    self.__dict__['_executors'] = executors = {}
+    executors[GreenMode.Futures] = kwargs.pop('executor', None)
+    executors[GreenMode.Gevent] = kwargs.pop('threadpool', None)
+    return DeviceProxy.__init_orig__(self, *args, **kwargs)
+
+def __DeviceProxy__get_green_mode(self):
+    """Returns the green mode in use by this DeviceProxy.
+    It returns None if it is using the global PyTango green mode
+    (see :func:`PyTango.utils.get_green_mode`).
+    
+    :returns: the green mode in use by this DeviceProxy.
+    :rtype: GreenMode
+
+    .. seealso::
+        :func:`PyTango.utils.get_green_mode`
+        :func:`PyTango.utils.set_green_mode`
+
+    New in PyTango 8.1.0
+    """
+    return self._green_mode
+
+def __DeviceProxy__set_green_mode(self, green_mode=None):
+    """Sets the green mode to be used by this DeviceProxy
+    Setting it to None means use the global PyTango green mode
+    (see :func:`PyTango.utils.get_green_mode`).
+    
+    :param green_mode: the new green mode
+    :type green_mode: GreenMode
+
+    New in PyTango 8.1.0
+    """
+    if green_mode is None:
+        green_mode = get_green_mode()
+    self._green_mode = green_mode
+
+
 def __DeviceProxy__refresh_cmd_cache(self):
     cmd_list = self.command_list_query()
     cmd_cache = {}
@@ -154,6 +263,12 @@ def __DeviceProxy__contains(self, key):
 def __DeviceProxy__read_attribute(self, value, extract_as=ExtractAs.Numpy):
     return __check_read_attribute(self._read_attribute(value, extract_as))
 
+#def __DeviceProxy__read_attribute(self, value, extract_as=ExtractAs.Numpy,
+#                                  green_mode=None, wait=True, timeout=None):
+#    green_mode, submit = submitable(green_mode)
+#    result = submit(__DeviceProxy__read_attribute_raw, self, value, extract_as=extract_as)
+#    return get_result(result, green_mode, wait=wait, timeout=timeout)
+
 def __DeviceProxy__read_attributes_asynch(self, attr_names, cb=None, extract_as=ExtractAs.Numpy):
     """
     read_attributes_asynch( self, attr_names) -> int
@@ -859,26 +974,44 @@ def __DeviceProxy__str(self):
     info = self._get_info_()
     return "%s(%s)" % (info.dev_class, self.dev_name())
 
+def __DeviceProxy__read_attributes(self, *args, **kwargs):
+    return self._read_attributes(*args, **kwargs)
+
+def __DeviceProxy__write_attribute(self, *args, **kwargs):
+    return self._write_attribute(*args, **kwargs)
+
+def __DeviceProxy__write_attributes(self, *args, **kwargs):
+    return self._write_attributes(*args, **kwargs)
+
 def __init_DeviceProxy():
+    DeviceProxy.__init_orig__ = DeviceProxy.__init__
+    DeviceProxy.__init__ = __DeviceProxy__init__
+
+    DeviceProxy.get_green_mode = __DeviceProxy__get_green_mode
+    DeviceProxy.set_green_mode = __DeviceProxy__set_green_mode
+
     DeviceProxy.__getattr__ = __DeviceProxy__getattr
     DeviceProxy.__setattr__ = __DeviceProxy__setattr
     DeviceProxy.__getitem__ = __DeviceProxy__getitem
     DeviceProxy.__setitem__ = __DeviceProxy__setitem
     DeviceProxy.__contains__ = __DeviceProxy__contains
-
+    
     DeviceProxy._getAttributeNames = __DeviceProxy__getAttributeNames
 
     DeviceProxy.__refresh_cmd_cache = __DeviceProxy__refresh_cmd_cache
     DeviceProxy.__refresh_attr_cache = __DeviceProxy__refresh_attr_cache
 
-    DeviceProxy.read_attribute = __DeviceProxy__read_attribute
+    DeviceProxy.read_attribute = green(__DeviceProxy__read_attribute)
+    DeviceProxy.read_attributes = green(__DeviceProxy__read_attributes)
     DeviceProxy.read_attributes_asynch = __DeviceProxy__read_attributes_asynch
     DeviceProxy.read_attribute_asynch = __DeviceProxy__read_attribute_asynch
     DeviceProxy.read_attribute_reply = __DeviceProxy__read_attribute_reply
     DeviceProxy.write_attributes_asynch = __DeviceProxy__write_attributes_asynch
     DeviceProxy.write_attribute_asynch = __DeviceProxy__write_attribute_asynch
     DeviceProxy.write_attribute_reply = DeviceProxy.write_attributes_reply
-    DeviceProxy.write_read_attribute = __DeviceProxy__write_read_attribute
+    DeviceProxy.write_read_attribute = green(__DeviceProxy__write_read_attribute)
+    DeviceProxy.write_attribute = green(__DeviceProxy__write_attribute)
+    DeviceProxy.write_attributes = green(__DeviceProxy__write_attributes)
 
     DeviceProxy.get_property = __DeviceProxy__get_property
     DeviceProxy.put_property = __DeviceProxy__put_property
@@ -904,7 +1037,7 @@ def __doc_DeviceProxy():
     def document_method(method_name, desc, append=True):
         return __document_method(DeviceProxy, method_name, desc, append)
 
-    DeviceProxy.__doc__ = """
+    DeviceProxy.__doc__ = """\
     DeviceProxy is the high level Tango object which provides the client with
     an easy-to-use interface to TANGO devices. DeviceProxy provides interfaces
     to all TANGO Device interfaces.The DeviceProxy manages timeouts, stateless
@@ -913,6 +1046,51 @@ def __doc_DeviceProxy():
 
     Example :
        dev = PyTango.DeviceProxy("sys/tg_test/1")
+
+    DeviceProxy(dev_name, green_mode=None, wait=True, timeout=True) -> DeviceProxy
+    DeviceProxy(self, dev_name, need_check_acc, green_mode=None, wait=True, timeout=True) -> DeviceProxy
+
+    Creates a new :class:`~PyTango.DeviceProxy`.
+     
+    :param dev_name: the device name or alias
+    :type dev_name: str
+    :param need_check_acc: in first version of the function it defaults to True.
+                           Determines if at creation time of DeviceProxy it should check
+                           for channel access (rarely used)
+    :type need_check_acc: bool
+    :param green_mode: determines the mode of execution of the device (including.
+                      the way it is created). Defaults to the current global
+                      green_mode (check :func:`~PyTango.utils.get_green_mode` and
+                      :func:`~PyTango.utils.set_green_mode`)
+    :type green_mode: :obj:`~PyTango.GreenMode`
+    :param wait: whether or not to wait for result. If green_mode
+                 Ignored when green_mode is Synchronous (always waits).
+    :type wait: bool
+    :param timeout: The number of seconds to wait for the result.
+                    If None, then there is no limit on the wait time.
+                    Ignored when green_mode is Synchronous or wait is False.
+    :type timeout: float
+    :returns:
+        if green_mode is Synchronous or wait is True:
+            :class:`~PyTango.DeviceProxy`
+        elif green_mode is Futures:
+            :class:`concurrent.futures.Future`
+        elif green_mode is Gevent:
+            :class:`gevent.event.AsynchResult`
+    :throws:
+        * :class:`~PyTango.DevFailed` if green_mode is Synchronous or wait is True 
+          and there is an error creating the device.
+        * :class:`concurrent.futures.TimeoutError` if green_mode is Futures,
+          wait is False, timeout is not None and the time to create the device
+          has expired.                            
+        * :class:`gevent.timeout.Timeout` if green_mode is Gevent, wait is False,
+          timeout is not None and the time to create the device has expired.
+
+    .. versionadded:: 8.1.0
+        *green_mode* parameter.
+        *wait* parameter.
+        *timeout* parameter.
+
     """
 
 #-------------------------------------
@@ -1165,16 +1343,29 @@ def __doc_DeviceProxy():
     # set_attribute_config -> in code
 
     document_method("read_attribute", """
-    read_attribute(self, attr_name, extract_as=ExtractAs.Numpy) -> DeviceAttribute
+    read_attribute(self, attr_name, extract_as=ExtractAs.Numpy, green_mode=None, wait=True, timeout=None) -> DeviceAttribute
 
             Read a single attribute.
 
         Parameters :
             - attr_name  : (str) The name of the attribute to read.
             - extract_as : (ExtractAs) Defaults to numpy.
+            - green_mode : (GreenMode) Defaults to the current DeviceProxy GreenMode.
+                           (see :meth:`~PyTango.DeviceProxy.get_green_mode` and
+                           :meth:`~PyTango.DeviceProxy.set_green_mode`).
+            - wait       : (bool) whether or not to wait for result. If green_mode
+                           is *Synchronous*, this parameter is ignored as it always
+                           waits for the result.
+                           Ignored when green_mode is Synchronous (always waits).
+            - timeout    : (float) The number of seconds to wait for the result.
+                           If None, then there is no limit on the wait time.
+                           Ignored when green_mode is Synchronous or wait is False.
+
         Return     : (DeviceAttribute)
         
         Throws     : ConnectionFailed, CommunicationFailed, DevFailed from device
+                     TimeoutError (green_mode == Futures) If the future didn't finish executing before the given timeout.
+                     Timeout (green_mode == Gevent) If the async result didn't finish executing before the given timeout.
             
     .. versionchanged:: 7.1.4
         For DevEncoded attributes, before it was returning a DeviceAttribute.value
@@ -1189,50 +1380,107 @@ def __doc_DeviceProxy():
         in which case it returns **(format<str>, data<str>)**. Carefull, if
         using python >= 3 data<str> is decoded using default python 
         *utf-8* encoding. This means that PyTango assumes tango DS was written
-        encapsulating string into *utf-8* which is the default python enconding.
+        encapsulating string into *utf-8* which is the default python encoding.
+
+    .. versionadded:: 8.1.0
+        *green_mode* parameter.
+        *wait* parameter.
+        *timeout* parameter.
     """ )
 
     document_method("read_attributes", """
-        read_attributes(self, attr_names, extract_as=ExtractAs.Numpy) -> sequence<DeviceAttribute>
+    read_attributes(self, attr_names, extract_as=ExtractAs.Numpy, green_mode=None, wait=True, timeout=None) -> sequence<DeviceAttribute>
 
-                Read the list of specified attributes.
+            Read the list of specified attributes.
 
-            Parameters :
-                    - attr_names : (sequence<str>) A list of attributes to read.
-                    - extract_as : (ExtractAs) Defaults to numpy.
-            Return     : (sequence<DeviceAttribute>)
+        Parameters :
+                - attr_names : (sequence<str>) A list of attributes to read.
+                - extract_as : (ExtractAs) Defaults to numpy.
+                - green_mode : (GreenMode) Defaults to the current DeviceProxy GreenMode.
+                               (see :meth:`~PyTango.DeviceProxy.get_green_mode` and
+                               :meth:`~PyTango.DeviceProxy.set_green_mode`).
+                - wait       : (bool) whether or not to wait for result. If green_mode
+                               is *Synchronous*, this parameter is ignored as it always
+                               waits for the result.
+                               Ignored when green_mode is Synchronous (always waits).
+                - timeout    : (float) The number of seconds to wait for the result.
+                               If None, then there is no limit on the wait time.
+                               Ignored when green_mode is Synchronous or wait is False.
+
+        Return     : (sequence<DeviceAttribute>)
+
+        Throws     : ConnectionFailed, CommunicationFailed, DevFailed from device
+                     TimeoutError (green_mode == Futures) If the future didn't finish executing before the given timeout.
+                     Timeout (green_mode == Gevent) If the async result didn't finish executing before the given timeout.
 
-            Throws     : ConnectionFailed, CommunicationFailed, DevFailed from device
+    .. versionadded:: 8.1.0
+        *green_mode* parameter.
+        *wait* parameter.
+        *timeout* parameter.
     """ )
 
     document_method("write_attribute", """
-        write_attribute(self, attr_name, value) -> None
-        write_attribute(self, attr_info, value) -> None
+    write_attribute(self, attr_name, value, green_mode=None, wait=True, timeout=None) -> None
+    write_attribute(self, attr_info, value, green_mode=None, wait=True, timeout=None) -> None
 
-                Write a single attribute.
+            Write a single attribute.
 
-            Parameters :
-                    - attr_name : (str) The name of the attribute to write.
-                    - attr_info : (AttributeInfo)
-                    - value : The value. For non SCALAR attributes it may be any sequence of sequences.
-
-            Throws     : ConnectionFailed, CommunicationFailed, DeviceUnlocked, DevFailed from device
+        Parameters :
+                - attr_name : (str) The name of the attribute to write.
+                - attr_info : (AttributeInfo)
+                - value : The value. For non SCALAR attributes it may be any sequence of sequences.
+                - green_mode : (GreenMode) Defaults to the current DeviceProxy GreenMode.
+                               (see :meth:`~PyTango.DeviceProxy.get_green_mode` and
+                               :meth:`~PyTango.DeviceProxy.set_green_mode`).
+                - wait       : (bool) whether or not to wait for result. If green_mode
+                               is *Synchronous*, this parameter is ignored as it always
+                               waits for the result.
+                               Ignored when green_mode is Synchronous (always waits).
+                - timeout    : (float) The number of seconds to wait for the result.
+                               If None, then there is no limit on the wait time.
+                               Ignored when green_mode is Synchronous or wait is False.
+
+        Throws     : ConnectionFailed, CommunicationFailed, DeviceUnlocked, DevFailed from device
+                     TimeoutError (green_mode == Futures) If the future didn't finish executing before the given timeout.
+                     Timeout (green_mode == Gevent) If the async result didn't finish executing before the given timeout.
+
+    .. versionadded:: 8.1.0
+        *green_mode* parameter.
+        *wait* parameter.
+        *timeout* parameter.
     """ )
 
     document_method("write_attributes", """
-    write_attributes(self, name_val) -> None
+    write_attributes(self, name_val, green_mode=None, wait=True, timeout=None) -> None
 
             Write the specified attributes.
 
         Parameters :
                 - name_val: A list of pairs (attr_name, value). See write_attribute
+                - green_mode : (GreenMode) Defaults to the current DeviceProxy GreenMode.
+                               (see :meth:`~PyTango.DeviceProxy.get_green_mode` and
+                               :meth:`~PyTango.DeviceProxy.set_green_mode`).
+                - wait       : (bool) whether or not to wait for result. If green_mode
+                               is *Synchronous*, this parameter is ignored as it always
+                               waits for the result.
+                               Ignored when green_mode is Synchronous (always waits).
+                - timeout    : (float) The number of seconds to wait for the result.
+                               If None, then there is no limit on the wait time.
+                               Ignored when green_mode is Synchronous or wait is False.
 
         Throws     : ConnectionFailed, CommunicationFailed, DeviceUnlocked,
                      DevFailed or NamedDevFailedList from device
+                     TimeoutError (green_mode == Futures) If the future didn't finish executing before the given timeout.
+                     Timeout (green_mode == Gevent) If the async result didn't finish executing before the given timeout.
+
+    .. versionadded:: 8.1.0
+        *green_mode* parameter.
+        *wait* parameter.
+        *timeout* parameter.
     """ )
 
     document_method("write_read_attribute", """
-    write_read_attribute(self, attr_name, value, extract_as=ExtractAs.Numpy) -> DeviceAttribute
+    write_read_attribute(self, attr_name, value, extract_as=ExtractAs.Numpy, green_mode=None, wait=True, timeout=None) -> DeviceAttribute
 
             Write then read a single attribute in a single network call.
             By default (serialisation by device), the execution of this call in
@@ -1243,8 +1491,15 @@ def __doc_DeviceProxy():
 
         Throws     : ConnectionFailed, CommunicationFailed, DeviceUnlocked,
                      DevFailed from device, WrongData
+                     TimeoutError (green_mode == Futures) If the future didn't finish executing before the given timeout.
+                     Timeout (green_mode == Gevent) If the async result didn't finish executing before the given timeout.
 
         New in PyTango 7.0.0
+
+    .. versionadded:: 8.1.0
+        *green_mode* parameter.
+        *wait* parameter.
+        *timeout* parameter.
     """ )
 
 #-------------------------------------
diff --git a/src/boost/python/group.py b/src/boost/python/group.py
index c121e9b..265702f 100644
--- a/src/boost/python/group.py
+++ b/src/boost/python/group.py
@@ -177,8 +177,8 @@ def __init_proxy_Group():
     for fname in proxy_methods:
         proxy_call_define(fname)
     
-    #Group.add.im_func.__doc__ = _RealGroup.add.__doc__
-    #Group.get_group.im_func.__doc__ = _RealGroup.get_group.__doc__
+    #Group.add.__func__.__doc__ = _RealGroup.add.__doc__
+    #Group.get_group.__func__.__doc__ = _RealGroup.get_group.__doc__
     #Group.__doc__ = _RealGroup.__doc__
 
 
diff --git a/src/boost/python/tango_futures.py b/src/boost/python/tango_futures.py
new file mode 100644
index 0000000..7afbfd8
--- /dev/null
+++ b/src/boost/python/tango_futures.py
@@ -0,0 +1,61 @@
+################################################################################
+##
+## This file is part of PyTango, a python binding for Tango
+## 
+## http://www.tango-controls.org/static/PyTango/latest/doc/html/index.html
+##
+## Copyright 2011 CELLS / ALBA Synchrotron, Bellaterra, Spain
+## 
+## PyTango is free software: you can redistribute it and/or modify
+## it under the terms of the GNU Lesser General Public License as published by
+## the Free Software Foundation, either version 3 of the License, or
+## (at your option) any later version.
+## 
+## PyTango is distributed in the hope that it will be useful,
+## but WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+## GNU Lesser General Public License for more details.
+## 
+## You should have received a copy of the GNU Lesser General Public License
+## along with PyTango.  If not, see <http://www.gnu.org/licenses/>.
+##
+################################################################################
+
+__all__ = ["uses_future", "get_global_executor", "submit", "spawn"] 
+
+__use_future = None
+__global_executor = None
+MAX_WORKERS = 8
+MODE = 'thread'
+
+def uses_future():
+    global __use_future
+    if __use_future is None:
+        try:
+            import concurrent.futures
+            __use_future = True
+        except ImportError:
+            __use_future = False
+    return __use_future
+
+def __get_executor_class():
+    import concurrent.futures
+    ret = None
+    if MODE == 'thread':
+        ret = concurrent.futures.ThreadPoolExecutor
+    else:
+        ret = concurrent.futures.ProcessPoolExecutor
+    return ret
+
+def get_global_executor():
+    global __global_executor
+    if __global_executor is None:
+        klass = __get_executor_class()
+        if klass is not None:
+            __global_executor = klass(max_workers=MAX_WORKERS)
+    return __global_executor
+
+def submit(fn, *args, **kwargs):
+    return get_global_executor().submit(fn, *args, **kwargs)
+
+spawn = submit
diff --git a/src/boost/python/tango_gevent.py b/src/boost/python/tango_gevent.py
new file mode 100644
index 0000000..72789f6
--- /dev/null
+++ b/src/boost/python/tango_gevent.py
@@ -0,0 +1,37 @@
+################################################################################
+##
+## This file is part of PyTango, a python binding for Tango
+## 
+## http://www.tango-controls.org/static/PyTango/latest/doc/html/index.html
+##
+## Copyright 2011 CELLS / ALBA Synchrotron, Bellaterra, Spain
+## 
+## PyTango is free software: you can redistribute it and/or modify
+## it under the terms of the GNU Lesser General Public License as published by
+## the Free Software Foundation, either version 3 of the License, or
+## (at your option) any later version.
+## 
+## PyTango is distributed in the hope that it will be useful,
+## but WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+## GNU Lesser General Public License for more details.
+## 
+## You should have received a copy of the GNU Lesser General Public License
+## along with PyTango.  If not, see <http://www.gnu.org/licenses/>.
+##
+################################################################################
+
+__all__ = ["get_global_threadpool", "get_global_executor", "submit", "spawn"] 
+
+__docformat__ = "restructuredtext"
+
+def get_global_threadpool():
+    import gevent
+    return gevent.get_hub().threadpool
+
+get_global_executor = get_global_threadpool
+
+def spawn(fn, *args, **kwargs):
+    return get_global_threadpool().spawn(fn, *args, **kwargs)
+
+submit = spawn
diff --git a/src/boost/python/tango_green.py b/src/boost/python/tango_green.py
new file mode 100644
index 0000000..29e7909
--- /dev/null
+++ b/src/boost/python/tango_green.py
@@ -0,0 +1,140 @@
+################################################################################
+##
+## This file is part of PyTango, a python binding for Tango
+## 
+## http://www.tango-controls.org/static/PyTango/latest/doc/html/index.html
+##
+## Copyright 2011 CELLS / ALBA Synchrotron, Bellaterra, Spain
+## 
+## PyTango is free software: you can redistribute it and/or modify
+## it under the terms of the GNU Lesser General Public License as published by
+## the Free Software Foundation, either version 3 of the License, or
+## (at your option) any later version.
+## 
+## PyTango is distributed in the hope that it will be useful,
+## but WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+## GNU Lesser General Public License for more details.
+## 
+## You should have received a copy of the GNU Lesser General Public License
+## along with PyTango.  If not, see <http://www.gnu.org/licenses/>.
+##
+################################################################################
+
+__all__ = ["get_executor", "submit", "spawn",
+           "get_synch_executor", "synch_submit",
+           "get_gevent_executor", "gevent_submit",
+           "get_futures_executor", "futures_submit"
+           "result", "submitable", "green"] 
+
+__docformat__ = "restructuredtext"
+
+from functools import wraps
+
+from ._PyTango import GreenMode
+from .tango_gevent import get_global_executor as get_gevent_executor
+from .tango_gevent import submit as gevent_submit
+from .tango_futures import get_global_executor as get_futures_executor
+from .tango_futures import submit as futures_submit
+from .utils import get_green_mode
+
+class SynchExecutor(object):
+    def submit(self, fn, *args, **kwargs):
+        return fn(*args, **kwargs)
+
+__synch_executor = SynchExecutor()
+
+def get_synch_executor():
+    return __synch_executor
+
+def synch_submit(fn, *args, **kwargs):
+    return get_synch_executor().submit(fn, *args, **kwargs)
+
+__executor_map = {
+    GreenMode.Synchronous: get_synch_executor,
+    GreenMode.Futures:     get_futures_executor,
+    GreenMode.Gevent:      get_gevent_executor,
+}
+
+__submit_map = {
+    GreenMode.Synchronous: synch_submit,
+    GreenMode.Futures:     futures_submit,
+    GreenMode.Gevent:      gevent_submit,
+}
+
+def get_executor(mode):
+    return __executor_map[mode]()
+
+def get_submitter(mode):
+    executor = get_executor(mode)
+    if mode == GreenMode.Gevent:
+        return executor.spawn
+    return executor.submit
+
+def submit(mode, fn, *args, **kwargs):
+    return get_submitter(mode)(fn, *args, **kwargs)
+
+spawn = submit
+
+def result(value, green_mode, wait=True, timeout=None):
+    if wait and not green_mode is GreenMode.Synchronous:
+        if green_mode == GreenMode.Futures:
+            return value.result(timeout=timeout)
+        elif green_mode == GreenMode.Gevent:
+            return value.get(timeout=timeout)
+    return value
+
+def submitable(obj, green_mode=None):
+    """Returns a proper submit callable for the given object.
+
+    If the object has *_executors* and *_green_mode* members it returns a submit
+    callable for the executor corresponding to the green_mode.
+    Otherwise it returns the global submit callable for the given green_mode
+
+    :returns: green_mode, submit callable"""
+    # determine the efective green_mode
+    if green_mode is None:
+        if hasattr(obj, "_green_mode"):
+            green_mode = obj._green_mode
+        else:
+            green_mode = get_green_mode()
+    
+    if green_mode == GreenMode.Synchronous:
+        return green_mode, synch_submit
+    
+    has_executors = hasattr(obj, "_executors")
+    s_func = __submit_map[green_mode]
+    if green_mode == GreenMode.Futures:
+        if has_executors:
+            executor = obj._executors.get(GreenMode.Futures)
+            if executor:
+                s_func = executor.submit
+    elif green_mode == GreenMode.Gevent:
+        if has_executors:
+            executor = obj._executors.get(GreenMode.Gevent)
+            if executor:
+                s_func = executor.spawn
+    else:
+        raise TypeError("Undefined green_mode '%s' for %s" % (str(green_mode)), str(obj))
+    return green_mode, s_func
+
+def green(fn):
+    """make a method green. Can be used as a decorator"""
+
+    @wraps(fn)
+    def greener(self, *args, **kwargs):
+        # first take out all green parameters
+        green_mode = kwargs.pop('green_mode', None)
+        wait = kwargs.pop('wait', True)
+        timeout = kwargs.pop('timeout', None)
+
+        # get the proper submitable for the given green_mode
+        green_mode, submit = submitable(self, green_mode)
+
+        # submit the method
+        ret = submit(fn, self, *args, **kwargs)
+        
+        # return the proper result        
+        return result(ret, green_mode, wait=wait, timeout=timeout)
+    return greener     
+
diff --git a/src/boost/python/utils.py b/src/boost/python/utils.py
index c47c8e1..6676c57 100644
--- a/src/boost/python/utils.py
+++ b/src/boost/python/utils.py
@@ -28,7 +28,8 @@ This is an internal PyTango module.
 from __future__ import with_statement
 from __future__ import print_function
 
-__all__ = [ "is_pure_str", "is_seq", "is_non_str_seq", "is_integer",
+__all__ = [ "get_green_mode", "set_green_mode",
+            "is_pure_str", "is_seq", "is_non_str_seq", "is_integer",
             "is_number", "is_scalar_type", "is_array_type", "is_numerical_type",
             "is_int_type", "is_float_type", "is_bool_type", "is_bin_type",
             "is_str_type", "obj_2_str", "seqStr_2_obj",
@@ -47,10 +48,13 @@ import numbers
 import functools
 import inspect
 import traceback
+import threading
 
 from ._PyTango import StdStringVector, StdDoubleVector, \
     DbData, DbDevInfos, DbDevExportInfos, CmdArgType, AttrDataFormat, \
-    EventData, AttrConfEventData, DataReadyEventData, DevFailed, constants
+    EventData, AttrConfEventData, DataReadyEventData, DevFailed, constants, \
+    GreenMode
+
 
 _scalar_int_types = (CmdArgType.DevShort, CmdArgType.DevUShort,
     CmdArgType.DevInt, CmdArgType.DevLong, CmdArgType.DevULong,
@@ -101,6 +105,31 @@ _scalar_to_array_type = {
     CmdArgType.ConstDevString : CmdArgType.DevVarStringArray,
 }
 
+__current_green_mode = GreenMode.Synchronous
+
+def set_green_mode(green_mode=None):
+    """Sets the global default PyTango green mode.
+
+    Advice: Use only in your final application. Don't use this in a python library
+    in order not to interfere with the beavior of other libraries and/or 
+    application where your library is being.
+
+    :param green_mode: the new global default PyTango green mode
+    :type green_mode: GreenMode
+    """
+    global __current_green_mode
+    if green_mode is None:
+        green_mode = GreenMode.Synchronous
+    __current_green_mode = green_mode
+
+def get_green_mode():
+    """Returns the current global default PyTango green mode.
+
+    :returns: the current global default PyTango green mode
+    :rtype: GreenMode
+    """
+    return __current_green_mode
+
 __device_classes = None
 
 def get_tango_device_classes():
@@ -596,6 +625,12 @@ def document_method(klass, method_name, d, add=True):
             func.__doc__ = "%s\n%s" % (d, cpp_doc)
             return
     func.__doc__ = d
+    
+    if func.__name__ != method_name:
+        try:
+            func.__name__ = method_name
+        except AttributeError:
+            pass
 
 def document_static_method(klass, method_name, d, add=True):
     meth, func = __get_meth_func(klass, method_name)

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