[pytango] 126/483: merge with branch Release_8_0_0_py3k
Sandor Bodo-Merle
sbodomerle-guest at moszumanska.debian.org
Thu Sep 28 19:14:32 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 b76d672d958b942c9bc57ce4f80e12d487815eed
Author: tiagocoutinho <tiagocoutinho at 4e9c00fd-8f2e-0410-aa12-93ce3db5e235>
Date: Tue Sep 4 08:03:56 2012 +0000
merge with branch Release_8_0_0_py3k
git-svn-id: http://svn.code.sf.net/p/tango-cs/code/bindings/PyTango/trunk@21071 4e9c00fd-8f2e-0410-aa12-93ce3db5e235
---
PyTango/__init__.py | 58 +-
PyTango/api_util.py | 8 +-
PyTango/attr_data.py | 11 +-
PyTango/attribute_proxy.py | 40 +-
PyTango/base_types.py | 26 +-
PyTango/callback.py | 6 +-
PyTango/connection.py | 33 +-
PyTango/db.py | 116 ++--
PyTango/device_attribute.py | 34 +-
PyTango/device_class.py | 105 ++--
PyTango/device_data.py | 8 +-
PyTango/device_proxy.py | 155 +++---
PyTango/device_server.py | 56 +-
PyTango/encoded_attribute.py | 55 +-
PyTango/exception.py | 10 +-
PyTango/globals.py | 4 +-
PyTango/group.py | 598 +++++++++++++++++++--
PyTango/group_element.py | 20 +-
PyTango/group_reply.py | 11 +-
PyTango/group_reply_list.py | 13 +-
PyTango/ipython/__init__.py | 22 +-
PyTango/ipython/common.py | 14 +-
.../{ipython_00_10/ipy_cli.py => eventlogger.py} | 30 +-
PyTango/ipython/ipython_00_10/__init__.py | 4 +-
PyTango/ipython/ipython_00_10/ipy_install.py | 14 +-
PyTango/ipython/ipython_00_10/ipy_qt.py | 2 +-
PyTango/ipython/ipython_00_10/ipython_00_10.py | 121 ++---
PyTango/ipython/ipython_00_11/__init__.py | 4 +-
PyTango/ipython/ipython_00_11/ipy_install.py | 15 +-
PyTango/ipython/ipython_00_11/ipython_00_11.py | 216 +++++---
PyTango/ipython/ipython_00_12/__init__.py | 2 +-
PyTango/ipython/ipython_00_12/ipython_00_12.py | 12 +-
PyTango/log4tango.py | 4 +-
PyTango/pytango_init.py | 85 +--
PyTango/pytango_pprint.py | 17 +-
PyTango/pyutil.py | 61 ++-
PyTango/tango_numpy.py | 14 +-
PyTango/time_val.py | 9 +-
PyTango/utils.py | 204 +++----
PyTango3/__init__.py | 24 -
PyTango3/tango3.py | 156 ------
doc/conf.py | 13 +-
doc/index.rst | 22 +-
doc/itango/highlights.rst | 118 ++--
doc/quicktour.rst | 208 +++----
doc/revision.rst | 10 +
doc/server/index.rst | 215 +++++---
doc/sphinxext/tango_console_highlighting.py | 14 +-
doc/start.rst | 6 +-
src/api_util.cpp | 2 +
src/attribute_info.cpp | 2 +-
src/base_types.cpp | 28 +-
src/connection.cpp | 1 +
src/constants.cpp | 23 +-
src/database.cpp | 29 +-
src/defs.h | 3 +-
src/dev_error.cpp | 11 +-
src/device_attribute.cpp | 531 ++++++++++--------
src/device_attribute_config.cpp | 6 +-
src/device_attribute_numpy.hpp | 26 +-
src/device_data.cpp | 18 +-
src/device_proxy.cpp | 171 +++---
src/exception.cpp | 33 +-
src/fast_from_py.h | 29 +-
src/from_py.cpp | 24 +-
src/from_py.h | 41 +-
src/group.cpp | 260 ++++++++-
src/pytango.cpp | 11 +-
src/pyutils.cpp | 43 ++
src/pyutils.h | 238 ++++++--
src/server/attribute.cpp | 375 ++++++++++++-
src/server/command.cpp | 32 +-
src/server/device_class.cpp | 21 +-
src/server/device_impl.cpp | 121 ++++-
src/server/device_impl.h | 39 +-
src/server/encoded_attribute.cpp | 208 +++----
src/server/log4tango.cpp | 8 +-
src/server/tango_util.cpp | 90 +---
src/server/wattribute.cpp | 212 ++++----
src/server/wattribute_numpy.hpp | 4 +-
src/to_py.h | 34 +-
81 files changed, 3677 insertions(+), 2000 deletions(-)
diff --git a/PyTango/__init__.py b/PyTango/__init__.py
index 4189e71..d1d4631 100644
--- a/PyTango/__init__.py
+++ b/PyTango/__init__.py
@@ -28,6 +28,8 @@ Documentation for this package can be found online:
http://www.tango-controls.org/static/PyTango/latest/doc/html/index.html
"""
+from __future__ import print_function
+
__all__ = [ 'AccessControlType', 'ApiUtil', 'ArchiveEventInfo',
'ArchiveEventProp', 'ArgType', 'AsynCall', 'AsynReplyNotArrived', 'AttReqType',
'Attr', 'AttrConfEventData', 'AttrData', 'AttrDataFormat', 'AttrList',
@@ -51,8 +53,9 @@ __all__ = [ 'AccessControlType', 'ApiUtil', 'ArchiveEventInfo',
'DevVarLongStringArray', 'DevVarShortArray', 'DevVarStringArray',
'DevVarULong64Array', 'DevVarULongArray', 'DevVarUShortArray',
'DevVoid', 'DeviceAttribute', 'DeviceAttributeConfig',
-'DeviceAttributeHistory', 'DeviceClass', 'DeviceData', 'DeviceDataHistory',
-'DeviceDataHistoryList', 'DeviceImpl', 'DeviceInfo', 'DeviceProxy',
+'DeviceAttributeHistory', 'DeviceClass', 'DeviceData', 'DeviceDataList',
+'DeviceDataHistory', 'DeviceDataHistoryList',
+'DeviceImpl', 'DeviceInfo', 'DeviceProxy',
'DeviceUnlocked', 'Device_2Impl', 'Device_3Impl', 'Device_4Impl',
'DispLevel', 'EncodedAttribute', 'ErrSeverity', 'ErrorIt',
'EventData', 'EventProperties', 'EventSystemFailed', 'EventType',
@@ -76,7 +79,7 @@ __all__ = [ 'AccessControlType', 'ApiUtil', 'ArchiveEventInfo',
'class_factory', 'class_list', 'constants', 'constructed_class',
'cpp_class_list', 'delete_class_list', 'get_class', 'get_classes',
'get_constructed_class', 'get_constructed_classes', 'get_cpp_class',
-'get_cpp_classes', 'isBufferLikeType', 'is_array_type', 'is_float_type',
+'get_cpp_classes', 'is_array_type', 'is_float_type',
'is_int_type', 'is_numerical_type', 'is_scalar_type', 'numpy_image',
'numpy_spectrum', 'numpy_type', 'obj_2_str', 'raise_asynch_exception',
'seqStr_2_obj']
@@ -84,22 +87,21 @@ __all__ = [ 'AccessControlType', 'ApiUtil', 'ArchiveEventInfo',
__docformat__ = "restructuredtext"
try:
- from _PyTango import DeviceProxy
-except ImportError, ie:
+ from ._PyTango import DeviceProxy
+except ImportError as ie:
if not ie.args[0].count("_PyTango"):
raise ie
- print 80*"-"
- print ie
- print 80*"-"
- print "Probably your current directory is the PyTango's source installation directory."
- print "You must leave this directory first before using PyTango, otherwise the"
- print "source distribution will conflict with the installed PyTango"
- print 80*"-"
+ print(80*"-")
+ print(ie)
+ print(80*"-")
+ print("Probably your current directory is the PyTango's source installation directory.")
+ print("You must leave this directory first before using PyTango, otherwise the")
+ print("source distribution will conflict with the installed PyTango")
+ print(80*"-")
import sys
sys.exit(1)
-from _PyTango import \
- (AccessControlType, ApiUtil, ArchiveEventInfo,
+from ._PyTango import (AccessControlType, ApiUtil, ArchiveEventInfo,
AsynCall, AsynReplyNotArrived, AttReqType, Attr, AttrConfEventData,
AttrDataFormat, AttrList, AttrProperty, AttrQuality, AttrReadEvent,
AttrSerialModel, AttrWriteType, AttrWrittenEvent, Attribute,
@@ -118,7 +120,7 @@ from _PyTango import \
DevVarLongArray, DevVarLongStringArray, DevVarShortArray, DevVarStringArray,
DevVarULong64Array, DevVarULongArray, DevVarUShortArray, DevVoid,
DeviceAttribute, DeviceAttributeConfig, DeviceAttributeHistory,
- DeviceData, DeviceDataHistory, DeviceDataHistoryList,
+ DeviceData, DeviceDataList, DeviceDataHistory, DeviceDataHistoryList,
DeviceImpl, DeviceInfo, DeviceUnlocked, Device_2Impl,
Device_3Impl, Device_4Impl, DispLevel, EncodedAttribute, ErrSeverity,
EventData, EventSystemFailed, EventType,
@@ -134,12 +136,12 @@ from _PyTango import \
StdGroupCmdReplyVector, StdGroupReplyVector, StdLongVector,
StdNamedDevFailedVector, StdStringVector, SubDevDiag, TimeVal,
UserDefaultAttrProp, WAttribute, WRITE, WrongData, WrongNameSyntax,
- alarm_flags, asyn_req_type, cb_sub_model, constants, isBufferLikeType,
+ alarm_flags, asyn_req_type, cb_sub_model, constants,
raise_asynch_exception)
ArgType = CmdArgType
-from release import Release
+from .release import Release
__author__ = Release.author_lines
__version_info__ = Release.version_info
@@ -149,23 +151,23 @@ __version_number__ = Release.version_number
__version_description__ = Release.version_description
__doc__ = Release.long_description
-from attr_data import AttrData
-from log4tango import TangoStream, LogIt, DebugIt, InfoIt, WarnIt, \
+from .attr_data import AttrData
+from .log4tango import TangoStream, LogIt, DebugIt, InfoIt, WarnIt, \
ErrorIt, FatalIt
-from device_server import ChangeEventProp, PeriodicEventProp, \
+from .device_server import ChangeEventProp, PeriodicEventProp, \
ArchiveEventProp, AttributeAlarm, EventProperties, AttributeConfig, \
AttributeConfig_2, AttributeConfig_3
-from attribute_proxy import AttributeProxy
-from group import Group
-from pyutil import Util
-from device_class import DeviceClass
-from globals import get_class, get_classes, get_cpp_class, get_cpp_classes, \
+from .attribute_proxy import AttributeProxy
+from .group import Group
+from .pyutil import Util
+from .device_class import DeviceClass
+from .globals import get_class, get_classes, get_cpp_class, get_cpp_classes, \
get_constructed_class, get_constructed_classes, class_factory, \
delete_class_list, class_list, cpp_class_list, constructed_class
-from utils import is_scalar_type, is_array_type, is_numerical_type, \
+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 tango_numpy import NumpyType, numpy_type, numpy_spectrum, numpy_image
+from .tango_numpy import NumpyType, numpy_type, numpy_spectrum, numpy_image
-from pytango_init import init as __init
+from .pytango_init import init as __init
__init()
diff --git a/PyTango/api_util.py b/PyTango/api_util.py
index 886ba77..6d5594c 100644
--- a/PyTango/api_util.py
+++ b/PyTango/api_util.py
@@ -25,13 +25,13 @@
This is an internal PyTango module.
"""
-__all__ = []
+__all__ = ["api_util_init"]
__docformat__ = "restructuredtext"
-from _PyTango import ApiUtil
+from ._PyTango import ApiUtil
-from utils import document_method, document_static_method, _get_env_var
+from .utils import document_method, document_static_method, _get_env_var
def __init_api_util():
if not hasattr(ApiUtil, "get_env_var"):
@@ -143,7 +143,7 @@ def __doc_api_util():
New in PyTango 7.1.3
""" )
-def init(doc=True):
+def api_util_init(doc=True):
__init_api_util()
if doc:
__doc_api_util()
\ No newline at end of file
diff --git a/PyTango/attr_data.py b/PyTango/attr_data.py
index 34d34f5..e81b650 100644
--- a/PyTango/attr_data.py
+++ b/PyTango/attr_data.py
@@ -31,8 +31,9 @@ __docformat__ = "restructuredtext"
import operator
-from _PyTango import Except, CmdArgType, AttrDataFormat, AttrWriteType, \
+from ._PyTango import Except, CmdArgType, AttrDataFormat, AttrWriteType, \
DispLevel, UserDefaultAttrProp, Attr, SpectrumAttr, ImageAttr
+import collections
class AttrData(object):
@@ -66,7 +67,7 @@ class AttrData(object):
def __create_user_default_attr_prop(self, attr_name, extra_info):
"""for internal usage only"""
p = UserDefaultAttrProp()
- for k, v in extra_info.iteritems():
+ for k, v in extra_info.items():
k_lower = k.lower()
method_name = "set_%s" % k_lower.replace(' ','_')
if hasattr(p, method_name):
@@ -89,7 +90,7 @@ class AttrData(object):
# check for well defined attribute info
# check parameter
- if not operator.isSequenceType(attr_info):
+ if not isinstance(attr_info, collections.Sequence):
throw_ex("Wrong data type for value for describing attribute %s in "
"class %s\nMust be a sequence with 1 or 2 elements"
% (attr_name, name))
@@ -103,14 +104,14 @@ class AttrData(object):
if len(attr_info) == 2:
# attr_info[1] must be a dictionary
# extra_info = attr_info[1], with all the keys lowercase
- for k, v in attr_info[1].iteritems():
+ for k, v in attr_info[1].items():
extra_info[k.lower()] = v
attr_info = attr_info[0]
attr_info_len = len(attr_info)
# check parameter
- if not operator.isSequenceType(attr_info) or \
+ if not isinstance(attr_info, collections.Sequence) or \
attr_info_len < 3 or attr_info_len > 5:
throw_ex("Wrong data type for describing mandatory information for "
"attribute %s in class %s\nMust be a sequence with 3, 4 "
diff --git a/PyTango/attribute_proxy.py b/PyTango/attribute_proxy.py
index 1334558..66fd972 100644
--- a/PyTango/attribute_proxy.py
+++ b/PyTango/attribute_proxy.py
@@ -29,20 +29,16 @@ To access these members use directly :mod:`PyTango` module and NOT
PyTango.attribute_proxy.
"""
-__all__ = [ "AttributeProxy" ]
+__all__ = [ "AttributeProxy", "attribute_proxy_init"]
__docformat__ = "restructuredtext"
-import operator
-import types
+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
-from _PyTango import StdStringVector
-from _PyTango import DbData, DbDatum
-from PyTango.utils import seq_2_StdStringVector
-from PyTango.utils import seq_2_DbData, DbData_2_dict
-
-from _PyTango import __AttributeProxy as _AttributeProxy
-from _PyTango import DeviceProxy
def __AttributeProxy__get_property(self, propname, value=None):
"""
@@ -77,7 +73,7 @@ def __AttributeProxy__get_property(self, propname, value=None):
DevFailed from database device
"""
- if type(propname) in types.StringTypes or isinstance(propname, StdStringVector):
+ if is_pure_str(propname) or isinstance(propname, StdStringVector):
new_value = value
if new_value is None:
new_value = DbData()
@@ -88,12 +84,12 @@ def __AttributeProxy__get_property(self, propname, value=None):
new_value.append(propname)
self._get_property(new_value)
return DbData_2_dict(new_value)
- elif operator.isSequenceType(propname):
+ elif isinstance(propname, collections.Sequence):
if isinstance(propname, DbData):
self._get_property(propname)
return DbData_2_dict(propname)
- if type(propname[0]) in types.StringTypes:
+ if is_pure_str(propname[0]):
new_propname = StdStringVector()
for i in propname: new_propname.append(i)
new_value = value
@@ -140,16 +136,16 @@ def __AttributeProxy__put_property(self, value):
new_value = DbData()
new_value.append(value)
value = new_value
- elif operator.isSequenceType(value) and not type(value) in types.StringTypes:
+ elif is_non_str_seq(value):
new_value = seq_2_DbData(value)
- elif operator.isMappingType(value):
+ elif isinstance(value, collections.Mapping):
new_value = DbData()
- for k, v in value.iteritems():
+ for k, v in value.items():
if isinstance(v, DbDatum):
new_value.append(v)
continue
db_datum = DbDatum(k)
- if operator.isSequenceType(v) and not type(v) in types.StringTypes:
+ if is_non_str_seq(v):
seq_2_StdStringVector(v, db_datum.value_string)
else:
db_datum.value_string.append(str(v))
@@ -196,21 +192,21 @@ def __AttributeProxy__delete_property(self, value):
DevFailed from device (DB_SQLError)
"""
if isinstance(value, DbData) or isinstance(value, StdStringVector) or \
- type(value) in types.StringTypes:
+ is_pure_str(value):
new_value = value
elif isinstance(value, DbDatum):
new_value = DbData()
new_value.append(value)
- elif operator.isSequenceType(value):
+ elif isinstance(value, collections.Sequence):
new_value = DbData()
for e in value:
if isinstance(e, DbDatum):
new_value.append(e)
else:
new_value.append(DbDatum(str(e)))
- elif operator.isMappingType(value):
+ elif isinstance(value, collections.Mapping):
new_value = DbData()
- for k, v in value.iteritems():
+ for k, v in value.items():
if isinstance(v, DbDatum):
new_value.append(v)
else:
@@ -362,5 +358,5 @@ def __init_AttributeProxy(doc=True):
AttributeProxy.get_last_event_date = _method_device('get_last_event_date', doc=doc)
AttributeProxy.is_event_queue_empty = _method_device('is_event_queue_empty', doc=doc)
-def init(doc=True):
+def attribute_proxy_init(doc=True):
__init_AttributeProxy(doc=doc)
diff --git a/PyTango/base_types.py b/PyTango/base_types.py
index 8b41a5b..af433d2 100644
--- a/PyTango/base_types.py
+++ b/PyTango/base_types.py
@@ -25,13 +25,12 @@
This is an internal PyTango module.
"""
-__all__ = []
+__all__ = ["base_types_init"]
__docformat__ = "restructuredtext"
-import operator
-from _PyTango import (StdStringVector, StdLongVector, StdDoubleVector, \
+from ._PyTango import (StdStringVector, StdLongVector, StdDoubleVector, \
CommandInfoList, AttributeInfoList, AttributeInfoListEx, DbData, \
DbDevInfos, DbDevExportInfos, DbDevImportInfos, DbHistoryList, \
DeviceDataHistoryList, StdGroupReplyVector, \
@@ -42,8 +41,8 @@ from _PyTango import (StdStringVector, StdLongVector, StdDoubleVector, \
DevCommandInfo, CommandInfo, DataReadyEventData, DeviceInfo, \
LockerInfo, PollDevice, TimeVal)
-from utils import document_method
-from utils import document_enum as __document_enum
+from .utils import document_method, is_integer
+from .utils import document_enum as __document_enum
def __StdVector__add(self, seq):
ret = seq.__class__(self)
@@ -52,18 +51,18 @@ def __StdVector__add(self, seq):
def __StdVector__mul(self, n):
ret = self.__class__()
- for _ in xrange(n):
+ for _ in range(n):
ret.extend(self)
return ret
def __StdVector__imul(self, n):
ret = self.__class__()
- for _ in xrange(n):
+ for _ in range(n):
ret.extend(self)
return ret
def __StdVector__getitem(self, key):
- if operator.isNumberType(key) or key.step is None:
+ if is_integer(key) or key.step is None:
return self.__original_getitem(key)
res = self.__class__()
@@ -75,7 +74,7 @@ def __StdVector__getitem(self, key):
if stop > nb:
stop = nb
- for i in xrange(start, stop, key.step or 1):
+ for i in range(start, stop, key.step or 1):
res.append(self[i])
return res
@@ -124,11 +123,6 @@ def __doc_base_types():
of lists
- String : The data will be stored 'as is', the binary data
as it comes from TangoC++ in 'value'.
- - PyTango3 : Backward compatibility mode. If the attribute is
- an scalar, value and w_scalar_value will contain a value.
- If it's an SPECTRUM or IMAGE it will be exported as a flat
- list in value, were both the read and the write part are
- in value.
- Nothing : The value will not be extracted from DeviceAttribute
""" )
@@ -664,7 +658,7 @@ def __doc_base_types():
- tv_usec : microseconds
- tv_nsec : nanoseconds"""
-def init(doc=True):
+def base_types_init(doc=True):
__init_base_types()
if doc:
- __doc_base_types()
\ No newline at end of file
+ __doc_base_types()
diff --git a/PyTango/callback.py b/PyTango/callback.py
index 275e2e4..6b78bb4 100644
--- a/PyTango/callback.py
+++ b/PyTango/callback.py
@@ -25,11 +25,11 @@
This is an internal PyTango module.
"""
-__all__ = []
+__all__ = ["callback_init"]
__docformat__ = "restructuredtext"
-from _PyTango import CmdDoneEvent, AttrReadEvent, AttrWrittenEvent
+from ._PyTango import CmdDoneEvent, AttrReadEvent, AttrWrittenEvent
def __init_Callback():
pass
@@ -74,7 +74,7 @@ def __doc_Callback():
- ext :
"""
-def init(doc=True):
+def callback_init(doc=True):
__init_Callback()
if doc:
__doc_Callback()
diff --git a/PyTango/connection.py b/PyTango/connection.py
index 85a06cc..7211b53 100644
--- a/PyTango/connection.py
+++ b/PyTango/connection.py
@@ -25,17 +25,19 @@
This is an internal PyTango module.
"""
-__all__ = []
+__all__ = ["connection_init"]
__docformat__ = "restructuredtext"
-from _PyTango import Connection, DeviceData, __CallBackAutoDie, CmdArgType
-from _PyTango import DeviceProxy, Database
-from _PyTango import ExtractAs
-from utils import document_method as __document_method
-from utils import document_static_method as __document_static_method
import operator
+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
+import collections
+
+
def __CallBackAutoDie__cmd_ended_aux(self, fn):
def __new_fn(cmd_done_event):
try:
@@ -67,7 +69,7 @@ def __get_command_inout_param(self, cmd_name, cmd_param=None):
if isinstance(cmd_param, str):
param.insert(CmdArgType.DevString, cmd_param)
return param
- elif operator.isSequenceType(cmd_param) and all([isinstance(x,str) for x in cmd_param]):
+ elif isinstance(cmd_param, collections.Sequence) and all([isinstance(x,str) for x in cmd_param]):
param.insert(CmdArgType.DevVarStringArray, cmd_param)
return param
else:
@@ -165,7 +167,7 @@ def __Connection__command_inout_asynch(self, cmd_name, *args):
forget = False
return self.__command_inout_asynch_id(cmd_name, argin, forget)
elif len(args) == 1:
- if callable(args[0]): # command_inout_asynch(lambda)
+ if isinstance(args[0], collections.Callable): # command_inout_asynch(lambda)
cb = __CallBackAutoDie()
cb.cmd_ended = __CallBackAutoDie__cmd_ended_aux(self, args[0])
argin = __get_command_inout_param(self, cmd_name)
@@ -180,7 +182,7 @@ def __Connection__command_inout_asynch(self, cmd_name, *args):
forget = False
return self.__command_inout_asynch_id(cmd_name, argin, forget)
elif len(args) == 2:
- if callable(args[1]): #command_inout_asynch( value, lambda)
+ if isinstance(args[1], collections.Callable): #command_inout_asynch( value, lambda)
cb = __CallBackAutoDie()
cb.cmd_ended = __CallBackAutoDie__cmd_ended_aux(self, args[1])
argin = __get_command_inout_param(self, cmd_name, args[0])
@@ -545,7 +547,18 @@ def __doc_Connection():
New in PyTango 7.0.0
""")
+
+ document_method("get_access_right", """
+ get_access_right(self) -> AccessControlType
+ Returns the current access control type
+
+ Parameters : None
+ Return : (AccessControlType) The current access control type
+
+ New in PyTango 8.0.0
+ """)
+
document_static_method("get_fqdn", """
get_fqdn(self) -> str
@@ -590,7 +603,7 @@ def __doc_Connection():
New in PyTango 7.2.0
""")
-def init(doc=True):
+def connection_init(doc=True):
__init_Connection()
if doc:
__doc_Connection()
diff --git a/PyTango/db.py b/PyTango/db.py
index 38a2677..7611e1a 100644
--- a/PyTango/db.py
+++ b/PyTango/db.py
@@ -25,26 +25,18 @@
This is an internal PyTango module.
"""
-__all__ = []
+__all__ = ["db_init"]
__docformat__ = "restructuredtext"
-import types
-import operator
+from ._PyTango import StdStringVector, Database, DbDatum, DbData, \
+ DbDevInfo, DbDevInfos, DbDevImportInfo, DbDevExportInfo, DbDevExportInfos, \
+ DbHistory, DbServerInfo
-from _PyTango import StdStringVector
-from _PyTango import Database, DbDatum, DbData
-from _PyTango import DbDevInfo, DbDevInfos
-from _PyTango import DbDevImportInfo, DbDevExportInfo
-from _PyTango import DbDevExportInfos
-from _PyTango import DbHistory, DbServerInfo
-
-from utils import seq_2_StdStringVector
-from utils import seq_2_DbDevInfos
-from utils import seq_2_DbDevExportInfos
-from utils import seq_2_DbData
-from utils import DbData_2_dict
-from utils import document_method as __document_method
+from .utils import is_pure_str, is_non_str_seq, seq_2_StdStringVector, \
+ seq_2_DbDevInfos, seq_2_DbDevExportInfos, seq_2_DbData, DbData_2_dict
+from .utils import document_method as __document_method
+import collections
#-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-
# DbDatum extension
@@ -99,7 +91,7 @@ def __Database__add_server(self, servname, dev_info):
Throws : ConnectionFailed, CommunicationFailed, DevFailed from device (DB_SQLError)
"""
- if not operator.isSequenceType(dev_info) and \
+ if not isinstance(dev_info, collections.Sequence) and \
not isinstance(dev_info, DbDevInfo):
raise TypeError('value must be a DbDevInfos, a seq<DbDevInfo> or ' \
'a DbDevInfo')
@@ -126,7 +118,7 @@ def __Database__export_server(self, dev_info):
Throws : ConnectionFailed, CommunicationFailed, DevFailed from device (DB_SQLError)
"""
- if not operator.isSequenceType(dev_info) and \
+ if not isinstance(dev_info, collections.Sequence) and \
not isinstance(dev_info, DbDevExportInfo):
raise TypeError('value must be a DbDevExportInfos, a seq<DbDevExportInfo> or ' \
'a DbDevExportInfo')
@@ -147,19 +139,19 @@ def __Database__generic_get_property(self, obj_name, value, f):
elif isinstance(value, DbDatum):
new_value = DbData()
new_value.append(value)
- elif type(value) in types.StringTypes:
+ elif is_pure_str(value):
new_value = DbData()
new_value.append(DbDatum(value))
- elif operator.isSequenceType(value):
+ elif isinstance(value, collections.Sequence):
new_value = DbData()
for e in value:
if isinstance(e, DbDatum):
new_value.append(e)
else:
new_value.append(DbDatum(str(e)))
- elif operator.isMappingType(value):
+ elif isinstance(value, collections.Mapping):
new_value = DbData()
- for k, v in value.iteritems():
+ for k, v in value.items():
if isinstance(v, DbDatum):
new_value.append(v)
else:
@@ -181,16 +173,16 @@ def __Database__generic_put_property(self, obj_name, value, f):
new_value = DbData()
new_value.append(value)
value = new_value
- elif operator.isSequenceType(value) and not type(value) in types.StringTypes:
+ elif is_non_str_seq(value):
new_value = seq_2_DbData(value)
- elif operator.isMappingType(value):
+ elif isinstance(value, collections.Mapping):
new_value = DbData()
- for k, v in value.iteritems():
+ for k, v in value.items():
if isinstance(v, DbDatum):
new_value.append(v)
continue
db_datum = DbDatum(k)
- if operator.isSequenceType(v) and not type(v) in types.StringTypes:
+ if is_non_str_seq(v):
seq_2_StdStringVector(v, db_datum.value_string)
else:
db_datum.value_string.append(str(v))
@@ -208,19 +200,19 @@ def __Database__generic_delete_property(self, obj_name, value, f):
elif isinstance(value, DbDatum):
new_value = DbData()
new_value.append(value)
- elif type(value) in types.StringTypes:
+ elif is_pure_str(value):
new_value = DbData()
new_value.append(DbDatum(value))
- elif operator.isSequenceType(value):
+ elif isinstance(value, collections.Sequence):
new_value = DbData()
for e in value:
if isinstance(e, DbDatum):
new_value.append(e)
else:
new_value.append(DbDatum(str(e)))
- elif operator.isMappingType(value):
+ elif isinstance(value, collections.Mapping):
new_value = DbData()
- for k, v in value.iteritems():
+ for k, v in value.items():
if isinstance(v, DbDatum):
new_value.append(v)
else:
@@ -407,7 +399,7 @@ def __Database__get_device_property_list(self, dev_name, wildcard, array=None):
return self._get_device_property_list(dev_name, wildcard)
elif isinstance(array, StdStringVector):
return self._get_device_property_list(dev_name, wildcard, array)
- elif operator.isSequenceType(array) and not type(array) in types.StringTypes:
+ elif is_non_str_seq(array):
res = self._get_device_property_list(dev_name, wildcard)
for e in res: array.append(e)
return array
@@ -448,19 +440,19 @@ def __Database__get_device_attribute_property(self, dev_name, value):
elif isinstance(value, DbDatum):
new_value = DbData()
new_value.append(value)
- elif type(value) in types.StringTypes:
+ elif is_pure_str(value):
new_value = DbData()
new_value.append(DbDatum(value))
- elif operator.isSequenceType(value):
+ elif isinstance(value, collections.Sequence):
new_value = DbData()
for e in value:
if isinstance(e, DbDatum):
new_value.append(e)
else:
new_value.append(DbDatum(str(e)))
- elif operator.isMappingType(value):
+ elif isinstance(value, collections.Mapping):
new_value = DbData()
- for k, v in value.iteritems():
+ for k, v in value.items():
if isinstance(v, DbDatum):
new_value.append(v)
else:
@@ -481,7 +473,7 @@ def __Database__get_device_attribute_property(self, dev_name, value):
ret[db_datum.name] = curr_dict
nb_props = int(db_datum[0])
i += 1
- for k in xrange(nb_props):
+ for k in range(nb_props):
db_datum = new_value[i]
curr_dict[db_datum.name] = db_datum.value_string
i += 1
@@ -512,20 +504,20 @@ def __Database__put_device_attribute_property(self, dev_name, value):
Throws : ConnectionFailed, CommunicationFailed, DevFailed from device (DB_SQLError)"""
if isinstance(value, DbData):
pass
- elif operator.isSequenceType(value) and not type(value) in types.StringTypes:
+ elif is_non_str_seq(value):
new_value = seq_2_DbData(value)
- elif operator.isMappingType(value):
+ elif isinstance(value, collections.Mapping):
new_value = DbData()
- for k1, v1 in value.iteritems():
+ for k1, v1 in value.items():
attr = DbDatum(k1)
attr.append(str(len(v1)))
new_value.append(attr)
- for k2, v2 in v1.iteritems():
+ for k2, v2 in v1.items():
if isinstance(v2, DbDatum):
new_value.append(v2)
continue
db_datum = DbDatum(k2)
- if operator.isSequenceType(v2) and not type(v2) in types.StringTypes:
+ if is_non_str_seq(v2):
seq_2_StdStringVector(v2, db_datum.value_string)
else:
db_datum.value_string.append(str(v2))
@@ -556,11 +548,11 @@ def __Database__delete_device_attribute_property(self, dev_name, value):
if isinstance(value, DbData):
new_value = value
- elif operator.isSequenceType(value) and not type(value) in types.StringTypes:
+ elif is_non_str_seq(value):
new_value = seq_2_DbData(value)
- elif operator.isMappingType(value):
+ elif isinstance(value, collections.Mapping):
new_value = DbData()
- for k1, v1 in value.iteritems():
+ for k1, v1 in value.items():
attr = DbDatum(k1)
attr.append(str(len(v1)))
new_value.append(attr)
@@ -681,19 +673,19 @@ def __Database__get_class_attribute_property(self, class_name, value):
elif isinstance(value, DbDatum):
new_value = DbData()
new_value.append(value)
- elif type(value) in types.StringTypes:
+ elif is_pure_str(value):
new_value = DbData()
new_value.append(DbDatum(value))
- elif operator.isSequenceType(value):
+ elif isinstance(value, collections.Sequence):
new_value = DbData()
for e in value:
if isinstance(e, DbDatum):
new_value.append(e)
else:
new_value.append(DbDatum(str(e)))
- elif operator.isMappingType(value):
+ elif isinstance(value, collections.Mapping):
new_value = DbData()
- for k, v in value.iteritems():
+ for k, v in value.items():
if isinstance(v, DbDatum):
new_value.append(v)
else:
@@ -714,7 +706,7 @@ def __Database__get_class_attribute_property(self, class_name, value):
ret[db_datum.name] = curr_dict
nb_props = int(db_datum[0])
i += 1
- for k in xrange(nb_props):
+ for k in range(nb_props):
db_datum = new_value[i]
curr_dict[db_datum.name] = db_datum.value_string
i += 1
@@ -746,20 +738,20 @@ def __Database__put_class_attribute_property(self, class_name, value):
if isinstance(value, DbData):
pass
- elif operator.isSequenceType(value) and not type(value) in types.StringTypes:
+ elif is_non_str_seq(value):
new_value = seq_2_DbData(value)
- elif operator.isMappingType(value):
+ elif isinstance(value, collections.Mapping):
new_value = DbData()
- for k1, v1 in value.iteritems():
+ for k1, v1 in value.items():
attr = DbDatum(k1)
attr.append(str(len(v1)))
new_value.append(attr)
- for k2, v2 in v1.iteritems():
+ for k2, v2 in v1.items():
if isinstance(v2, DbDatum):
new_value.append(v2)
continue
db_datum = DbDatum(k2)
- if operator.isSequenceType(v2) and not type(v2) in types.StringTypes:
+ if is_non_str_seq(v2):
seq_2_StdStringVector(v2, db_datum.value_string)
else:
db_datum.value_string.append(str(v2))
@@ -793,11 +785,11 @@ def __Database__delete_class_attribute_property(self, class_name, value):
if isinstance(value, DbData):
new_value = value
- elif operator.isSequenceType(value) and not type(value) in types.StringTypes:
+ elif is_non_str_seq(value):
new_value = seq_2_DbData(value)
- elif operator.isMappingType(value):
+ elif isinstance(value, collections.Mapping):
new_value = DbData()
- for k1, v1 in value.iteritems():
+ for k1, v1 in value.items():
attr = DbDatum(k1)
attr.append(str(len(v1)))
new_value.append(attr)
@@ -1075,10 +1067,10 @@ def __doc_Database():
Example :
dev_imp_info = db.import_device('my/own/device')
- print dev_imp_info.name
- print dev_imp_info.exported
- print dev_imp_info.ior
- print dev_imp_info.version
+ print(dev_imp_info.name)
+ print(dev_imp_info.exported)
+ print(dev_imp_info.ior)
+ print(dev_imp_info.version)
Parameters :
- dev_name : (str) device name
@@ -2089,7 +2081,7 @@ def __doc_DbServerInfo():
- mode : (str) mode
- level : (str) level"""
-def init(doc=True):
+def db_init(doc=True):
__init_DbDatum()
if doc:
__doc_DbDatum()
diff --git a/PyTango/device_attribute.py b/PyTango/device_attribute.py
index 97ae59f..4859359 100644
--- a/PyTango/device_attribute.py
+++ b/PyTango/device_attribute.py
@@ -25,14 +25,14 @@
This is an internal PyTango module.
"""
-__all__ = []
+__all__ = ["device_attribute_init"]
__docformat__ = "restructuredtext"
import copy
-from utils import document_method as __document_method
-from _PyTango import DeviceAttribute, ExtractAs
+from .utils import document_method as __document_method
+from ._PyTango import DeviceAttribute, ExtractAs
def __DeviceAttribute__get_data(self):
return self.get_data_raw().extract()
@@ -108,12 +108,38 @@ def __doc_DeviceAttribute():
Return : (sequence<DevError>)
""" )
+ document_method("set_w_dim_x", """
+ set_w_dim_x(self, val) -> None
+
+ Sets the write value dim x.
+
+ Parameters :
+ - val : (int) new write dim x
+
+ Return : None
+
+ New in PyTango 8.0.0
+ """ )
+
+ document_method("set_w_dim_y", """
+ set_w_dim_y(self, val) -> None
+
+ Sets the write value dim y.
+
+ Parameters :
+ - val : (int) new write dim y
+
+ Return : None
+
+ New in PyTango 8.0.0
+ """ )
+
def __init_DeviceAttribute():
DeviceAttribute.__init_orig = DeviceAttribute.__init__
DeviceAttribute.__init__ = __DeviceAttribute__init
DeviceAttribute.ExtractAs = ExtractAs
-def init(doc=True):
+def device_attribute_init(doc=True):
__init_DeviceAttribute()
if doc:
__doc_DeviceAttribute()
diff --git a/PyTango/device_class.py b/PyTango/device_class.py
index a8b5bc3..5af4f56 100644
--- a/PyTango/device_class.py
+++ b/PyTango/device_class.py
@@ -25,26 +25,26 @@
This is an internal PyTango module.
"""
-__all__ = [ "DeviceClass" ]
+from __future__ import print_function
+
+__all__ = [ "DeviceClass", "device_class_init" ]
__docformat__ = "restructuredtext"
-import types
-import operator
+import collections
-from _PyTango import Except, DevFailed
-from _PyTango import _DeviceClass
-from _PyTango import CmdArgType, DispLevel
-from _PyTango import UserDefaultAttrProp
+from ._PyTango import Except, DevFailed, _DeviceClass, CmdArgType, \
+ DispLevel, UserDefaultAttrProp
+from .pyutil import Util
-from pyutil import Util
+from .utils import is_pure_str, is_non_str_seq, seqStr_2_obj, obj_2_str, \
+ is_array
+from .utils import document_method as __document_method
-from utils import seqStr_2_obj, obj_2_str, is_array
-from utils import document_method as __document_method
+from .globals import get_class, get_class_by_class, \
+ get_constructed_class_by_class
+from .attr_data import AttrData
-from globals import get_class, get_class_by_class
-from globals import get_constructed_class_by_class
-from attr_data import AttrData
class PropUtil:
"""An internal Property util class"""
@@ -82,14 +82,14 @@ class PropUtil:
Return : None
"""
- for name in class_prop.keys():
+ for name in class_prop:
type = self.get_property_type(name, class_prop)
val = self.get_property_values(name, class_prop)
val = self.values2string(val, type)
desc = self.get_property_description(name, class_prop)
dev_class.add_wiz_class_prop(name, desc, val)
- for name in dev_prop.keys():
+ for name in dev_prop:
type = self.get_property_type(name, dev_prop)
val = self.get_property_values(name, dev_prop)
val = self.values2string(val, type)
@@ -113,16 +113,16 @@ class PropUtil:
return
# call database to get properties
- props = self.db.get_class_property(dev_class.get_name(), class_prop.keys())
+ props = self.db.get_class_property(dev_class.get_name(), list(class_prop.keys()))
# if value defined in database, store it
- for name in class_prop.keys():
+ for name in class_prop:
if props[name]:
type = self.get_property_type(name, class_prop)
values = self.stringArray2values(props[name], type)
self.set_property_values(name, class_prop, values)
else:
- print name, " property NOT found in database"
+ print(name + " property NOT found in database")
def get_device_properties(self, dev, class_prop, dev_prop):
"""
@@ -141,9 +141,9 @@ class PropUtil:
return
# Call database to get properties
- props = self.db.get_device_property(dev.get_name(),dev_prop.keys())
+ props = self.db.get_device_property(dev.get_name(), list(dev_prop.keys()))
# if value defined in database, store it
- for name in dev_prop.keys():
+ for name in dev_prop:
prop_value = props[name]
if len(prop_value):
data_type = self.get_property_type(name, dev_prop)
@@ -181,7 +181,7 @@ class PropUtil:
- v : (object) the object to be analysed
Return : (bool) True if the object is a sequence or False otherwise"""
- return operator.isSequenceType(v)
+ return isinstance(v, collections.Sequence)
def is_empty_seq(self, v):
"""
@@ -244,10 +244,10 @@ class PropUtil:
except:
val = []
- if is_array(tg_type) or (operator.isSequenceType(val) and not len(val)):
+ if is_array(tg_type) or (isinstance(val, collections.Sequence) and not len(val)):
return val
else:
- if operator.isSequenceType(val) and not type(val) in types.StringTypes:
+ if is_non_str_seq(val):
return val[0]
else:
return val
@@ -292,16 +292,14 @@ class DeviceClass(_DeviceClass):
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.keys():
+ 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))
- if hasattr(self, 'write_class_property'):
- self.write_class_property()
- except DevFailed, df:
+ except DevFailed as df:
print("PyDS: %s: A Tango error occured in the constructor:" % name)
Except.print_exception(df)
- except Exception, e:
+ except Exception as e:
print("PyDS: %s: An error occured in the constructor:" % name)
print(str(e))
@@ -322,7 +320,7 @@ class DeviceClass(_DeviceClass):
def __attribute_factory(self, attr_list):
"""for internal usage only"""
- for attr_name, attr_info in self.attr_list.iteritems():
+ for attr_name, attr_info in self.attr_list.items():
attr_data = AttrData(attr_name, self.get_name(), attr_info)
self.__create_attribute(attr_list, attr_data)
@@ -341,7 +339,7 @@ class DeviceClass(_DeviceClass):
def __create_user_default_attr_prop(self, attr_name, extra_info):
"""for internal usage only"""
p = UserDefaultAttrProp()
- for k, v in extra_info.iteritems():
+ for k, v in extra_info.items():
k_lower = k.lower()
method_name = "set_%s" % k_lower.replace(' ','_')
if hasattr(p, method_name):
@@ -368,7 +366,7 @@ class DeviceClass(_DeviceClass):
"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.iteritems():
+ 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):
@@ -378,7 +376,7 @@ class DeviceClass(_DeviceClass):
# check for well defined command info
# check parameter
- if not operator.isSequenceType(cmd_info):
+ 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)
@@ -390,7 +388,7 @@ class DeviceClass(_DeviceClass):
param_info, result_info = cmd_info[0], cmd_info[1]
- if not operator.isSequenceType(param_info):
+ 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)
@@ -413,14 +411,14 @@ class DeviceClass(_DeviceClass):
param_desc = ""
if len(param_info) > 1:
param_desc = param_info[1]
- if not type(param_desc) in types.StringTypes:
+ 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 operator.isSequenceType(result_info):
+ 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)
@@ -443,7 +441,7 @@ class DeviceClass(_DeviceClass):
result_desc = ""
if len(result_info) > 1:
result_desc = result_info[1]
- if not type(result_desc) in types.StringTypes:
+ 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)
@@ -454,7 +452,7 @@ class DeviceClass(_DeviceClass):
if len(cmd_info) == 3:
extra_info = cmd_info[2]
- if not operator.isMappingType(extra_info):
+ 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)
@@ -466,7 +464,7 @@ class DeviceClass(_DeviceClass):
"three elements" % (cmd_name, name)
self.__throw_create_command_exception(msg)
- for info_name, info_value in extra_info.iteritems():
+ for info_name, info_value in extra_info.items():
info_name_lower = info_name.lower()
if info_name_lower == "display level":
try:
@@ -477,7 +475,7 @@ class DeviceClass(_DeviceClass):
"PyTango.DispLevel" % (cmd_name, name)
self.__throw_create_command_exception(msg)
elif info_name_lower == "default command":
- if not type(info_value) in types.StringTypes:
+ 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)
@@ -501,7 +499,7 @@ class DeviceClass(_DeviceClass):
# check that the method to be executed exists
try:
cmd = getattr(deviceimpl_class, cmd_name)
- if not callable(cmd):
+ 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)
@@ -514,7 +512,7 @@ class DeviceClass(_DeviceClass):
is_allowed_name = "is_%s_allowed" % cmd_name
try:
is_allowed = getattr(deviceimpl_class, is_allowed_name)
- if not callable(is_allowed):
+ 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)
@@ -787,6 +785,29 @@ def __doc_DeviceClass():
Parameters : None
Return : (sequence<PyTango.DeviceImpl>) list of PyTango.DeviceImpl objects for this class
""" )
+
+ document_method("get_command_list", """
+ get_command_list(self) -> sequence<PyTango.Command>
+
+ Gets the list of PyTango.Command objects for this class
+
+ Parameters : None
+ Return : (sequence<PyTango.Command>) list of PyTango.Command objects for this class
+
+ New in PyTango 8.0.0
+ """ )
+
+ document_method("get_cmd_by_name", """
+ get_cmd_by_name(self, (str)cmd_name) -> PyTango.Command
+
+ Get a reference to a command object.
+
+ Parameters :
+ - cmd_name : (str) command name
+ Return : (PyTango.Command) PyTango.Command object
+
+ New in PyTango 8.0.0
+ """ )
document_method("add_wiz_dev_prop", """
add_wiz_dev_prop(self, str, str) -> None
@@ -808,7 +829,7 @@ def __doc_DeviceClass():
Return : None
""" )
-def init(doc=True):
+def device_class_init(doc=True):
__init_DeviceClass()
if doc:
__doc_DeviceClass()
diff --git a/PyTango/device_data.py b/PyTango/device_data.py
index 4a7b608..edfed89 100644
--- a/PyTango/device_data.py
+++ b/PyTango/device_data.py
@@ -25,12 +25,12 @@
This is an internal PyTango module.
"""
-__all__ = []
+__all__ = ["device_data_init"]
__docformat__ = "restructuredtext"
-from utils import document_method as __document_method
-from _PyTango import DeviceData
+from .utils import document_method as __document_method
+from ._PyTango import DeviceData
def __DeviceData__get_data(self):
return self.get_data_raw().extract()
@@ -89,7 +89,7 @@ def __doc_DeviceData():
Return : The content arg type.
""" )
-def init(doc=True):
+def device_data_init(doc=True):
__init_DeviceData()
if doc:
__doc_DeviceData()
diff --git a/PyTango/device_proxy.py b/PyTango/device_proxy.py
index 397cd4c..24db823 100644
--- a/PyTango/device_proxy.py
+++ b/PyTango/device_proxy.py
@@ -25,26 +25,23 @@
This is an internal PyTango module.
"""
-__all__ = []
+from __future__ import with_statement
+
+__all__ = ["device_proxy_init"]
__docformat__ = "restructuredtext"
-import operator
-import types
import threading
-from _PyTango import StdStringVector
-from _PyTango import DbData, DbDatum
-from _PyTango import AttributeInfo, AttributeInfoEx
-from _PyTango import AttributeInfoList, AttributeInfoListEx
-from _PyTango import DeviceProxy
-from _PyTango import __CallBackAutoDie, __CallBackPushEvent, EventType
-from _PyTango import DevFailed, Except
-from _PyTango import ExtractAs
-from PyTango.utils import seq_2_StdStringVector, StdStringVector_2_seq
-from PyTango.utils import seq_2_DbData, DbData_2_dict
-from utils import document_method as __document_method
-
+from ._PyTango import StdStringVector, DbData, DbDatum, AttributeInfo, \
+ AttributeInfoEx, AttributeInfoList, AttributeInfoListEx, DeviceProxy, \
+ __CallBackAutoDie, __CallBackPushEvent, EventType, DevFailed, Except, \
+ ExtractAs
+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
class __TangoInfo(object):
"""Helper class for when DeviceProxy.info() is not available"""
@@ -83,7 +80,7 @@ def __DeviceProxy__getattr(self, name):
# ticket http://ipython.scipy.org/ipython/ipython/ticket/229 someday
# and the ugly trait_names could be removed.
if name[:2] == "__" or name == 'trait_names':
- raise AttributeError, name
+ raise AttributeError(name)
name_l = name.lower()
cmd_info = None
@@ -116,7 +113,7 @@ def __DeviceProxy__getattr(self, name):
find_attr = False
if not find_attr or name_l not in self.__attr_cache:
- raise AttributeError, name
+ raise AttributeError(name)
return self.read_attribute(name).value
@@ -139,7 +136,7 @@ def __DeviceProxy__getAttributeNames(self):
try:
lst = [cmd.cmd_name for cmd in self.command_list_query()]
lst += self.get_attribute_list()
- lst += map(str.lower, lst)
+ lst += list(map(str.lower, lst))
lst.sort()
return lst
except Exception:
@@ -194,7 +191,7 @@ def __DeviceProxy__read_attributes_asynch(self, attr_names, cb=None, extract_as=
return self.__read_attributes_asynch(attr_names)
cb2 = __CallBackAutoDie()
- if callable(cb):
+ if isinstance(cb, collections.Callable):
cb2.attr_read = cb
else:
cb2.attr_read = cb.attr_read
@@ -256,7 +253,7 @@ def __DeviceProxy__write_attributes_asynch(self, attr_values, cb=None):
return self.__write_attributes_asynch(attr_values)
cb2 = __CallBackAutoDie()
- if callable(cb):
+ if isinstance(cb, collections.Callable):
cb2.attr_write = cb
else:
cb2.attr_write = cb.attr_write
@@ -309,7 +306,7 @@ def __DeviceProxy__get_property(self, propname, value=None):
DevFailed from database device
"""
- if type(propname) in types.StringTypes or isinstance(propname, StdStringVector):
+ if is_pure_str(propname) or isinstance(propname, StdStringVector):
new_value = value
if new_value is None:
new_value = DbData()
@@ -320,12 +317,12 @@ def __DeviceProxy__get_property(self, propname, value=None):
new_value.append(propname)
self._get_property(new_value)
return DbData_2_dict(new_value)
- elif operator.isSequenceType(propname):
+ elif isinstance(propname, collections.Sequence):
if isinstance(propname, DbData):
self._get_property(propname)
return DbData_2_dict(propname)
- if type(propname[0]) in types.StringTypes:
+ if is_pure_str(propname[0]):
new_propname = StdStringVector()
for i in propname: new_propname.append(i)
new_value = value
@@ -372,16 +369,16 @@ def __DeviceProxy__put_property(self, value):
new_value = DbData()
new_value.append(value)
value = new_value
- elif operator.isSequenceType(value) and not type(value) in types.StringTypes:
+ elif is_non_str_seq(value):
new_value = seq_2_DbData(value)
- elif operator.isMappingType(value):
+ elif isinstance(value, collections.Mapping):
new_value = DbData()
- for k, v in value.iteritems():
+ for k, v in value.items():
if isinstance(v, DbDatum):
new_value.append(v)
continue
db_datum = DbDatum(k)
- if operator.isSequenceType(v) and not type(v) in types.StringTypes:
+ if is_non_str_seq(v):
seq_2_StdStringVector(v, db_datum.value_string)
else:
db_datum.value_string.append(str(v))
@@ -424,21 +421,21 @@ def __DeviceProxy__delete_property(self, value):
DevFailed from device (DB_SQLError)
"""
if isinstance(value, DbData) or isinstance(value, StdStringVector) or \
- type(value) in types.StringTypes:
+ is_pure_str(value):
new_value = value
elif isinstance(value, DbDatum):
new_value = DbData()
new_value.append(value)
- elif operator.isSequenceType(value):
+ elif isinstance(value, collections.Sequence):
new_value = DbData()
for e in value:
if isinstance(e, DbDatum):
new_value.append(e)
else:
new_value.append(DbDatum(str(e)))
- elif operator.isMappingType(value):
+ elif isinstance(value, collections.Mapping):
new_value = DbData()
- for k, v in value.iteritems():
+ for k, v in value.items():
if isinstance(v, DbDatum):
new_value.append(v)
else:
@@ -483,7 +480,7 @@ def __DeviceProxy__get_property_list(self, filter, array=None):
if isinstance(array, StdStringVector):
self._get_property_list(filter, array)
return array
- elif operator.isSequenceType(array):
+ elif isinstance(array, collections.Sequence):
new_array = StdStringVector()
self._get_property_list(filter, new_array)
StdStringVector_2_seq(new_array, array)
@@ -522,9 +519,9 @@ def __DeviceProxy__get_attribute_config(self, value):
Deprecated: use get_attribute_config_ex instead
"""
- if isinstance(value, StdStringVector) or type(value) in types.StringTypes:
+ if isinstance(value, StdStringVector) or is_pure_str(value):
return self._get_attribute_config(value)
- elif operator.isSequenceType(value):
+ elif isinstance(value, collections.Sequence):
v = seq_2_StdStringVector(value)
return self._get_attribute_config(v)
@@ -560,11 +557,11 @@ def __DeviceProxy__get_attribute_config_ex(self, value):
"""
if isinstance(value, StdStringVector):
return self._get_attribute_config_ex(value)
- elif type(value) in types.StringTypes:
+ elif is_pure_str(value):
v = StdStringVector()
v.append(value)
return self._get_attribute_config_ex(v)
- elif operator.isSequenceType(value):
+ elif isinstance(value, collections.Sequence):
v = seq_2_StdStringVector(value)
return self._get_attribute_config_ex(v)
@@ -628,7 +625,7 @@ def __DeviceProxy__set_attribute_config(self, value):
v = value
elif isinstance(value, AttributeInfoListEx):
v = value
- elif operator.isSequenceType(value):
+ elif isinstance(value, collections.Sequence):
if not len(value): return
if isinstance(value[0], AttributeInfoEx):
v = AttributeInfoListEx()
@@ -727,23 +724,21 @@ def __DeviceProxy__subscribe_event ( self, attr_name, event_type, cb_or_queuesiz
other subscribe_event() version.
"""
- if callable(cb_or_queuesize):
+ if isinstance(cb_or_queuesize, collections.Callable):
cb = __CallBackPushEvent()
cb.push_event = cb_or_queuesize
- elif hasattr(cb_or_queuesize, "push_event") and callable(cb_or_queuesize.push_event):
+ elif hasattr(cb_or_queuesize, "push_event") and isinstance(cb_or_queuesize.push_event, collections.Callable):
cb = __CallBackPushEvent()
cb.push_event = cb_or_queuesize.push_event
- elif operator.isNumberType(cb_or_queuesize):
+ elif is_integer(cb_or_queuesize):
cb = cb_or_queuesize # queuesize
else:
raise TypeError("Parameter cb_or_queuesize should be a number, a" + \
" callable object or an object with a 'push_event' method.")
event_id = self.__subscribe_event(attr_name, event_type, cb, filters, stateless, extract_as)
-
- l = self.__get_event_map_lock()
- l.acquire()
- try:
+
+ with self.__get_event_map_lock():
se = self.__get_event_map()
evt_data = se.get(event_id)
if evt_data is not None:
@@ -753,8 +748,6 @@ def __DeviceProxy__subscribe_event ( self, attr_name, event_type, cb_or_queuesiz
(self, attr_name, event_type, event_id, evt_data[2], evt_data[1])
Except.throw_exception("Py_InternalError", desc, "DeviceProxy.subscribe_event")
se[event_id] = (cb, event_type, attr_name)
- finally:
- l.release()
return event_id
def __DeviceProxy__unsubscribe_event(self, event_id):
@@ -773,26 +766,18 @@ def __DeviceProxy__unsubscribe_event(self, event_id):
Throws : EventSystemFailed
"""
- l = self.__get_event_map_lock()
- l.acquire()
- try:
+ with self.__get_event_map_lock():
se = self.__get_event_map()
if event_id not in se:
raise IndexError("This device proxy does not own this subscription " + str(event_id))
del se[event_id]
- finally:
- l.release()
self.__unsubscribe_event(event_id)
def __DeviceProxy__unsubscribe_event_all(self):
- l = self.__get_event_map_lock()
- l.acquire()
- try:
+ with self.__get_event_map_lock():
se = self.__get_event_map()
- event_ids = se.keys()
+ event_ids = list(se.keys())
se.clear()
- finally:
- l.release()
for event_id in event_ids:
self.__unsubscribe_event(event_id)
@@ -847,11 +832,11 @@ def __DeviceProxy__get_events(self, event_id, callback=None, extract_as=ExtractA
else:
assert (False)
raise ValueError("Unknown event_type: " + str(event_type))
- elif callable(callback):
+ elif isinstance(callback, collections.Callable):
cb = __CallBackPushEvent()
cb.push_event = callback
return self.__get_callback_events(event_id, cb, extract_as)
- elif hasattr(callback, 'push_event') and callable(callback.push_event):
+ elif hasattr(callback, 'push_event') and isinstance(callback.push_event, collections.Callable):
cb = __CallBackPushEvent()
cb.push_event = callback.push_event
return self.__get_callback_events(event_id, cb, extract_as)
@@ -866,7 +851,11 @@ def __DeviceProxy___get_info_(self):
except:
return __TangoInfo()
return self._dev_info
-
+
+def __DeviceProxy__str(self):
+ info = self._get_info_()
+ return "%s(%s)" % (info.dev_class, self.dev_name())
+
def __DeviceProxy__str(self):
info = self._get_info_()
return "%s(%s)" % (info.dev_class, self.dev_name())
@@ -940,12 +929,12 @@ def __doc_DeviceProxy():
Return : (DeviceInfo) object
Example :
dev_info = dev.info()
- print dev_info.dev_class
- print dev_info.server_id
- print dev_info.server_host
- print dev_info.server_version
- print dev_info.doc_url
- print dev_info.dev_type
+ print(dev_info.dev_class)
+ print(dev_info.server_id)
+ print(dev_info.server_host)
+ print(dev_info.server_version)
+ print(dev_info.doc_url)
+ print(dev_info.dev_type)
All DeviceInfo fields are strings except for the server_version
which is an integer"
@@ -1036,7 +1025,7 @@ def __doc_DeviceProxy():
command and from which client computer the command
was executed
Example :
- print black_box(4)
+ print(black_box(4))
""" )
#-------------------------------------
@@ -1054,13 +1043,13 @@ def __doc_DeviceProxy():
Throws : ConnectionFailed, CommunicationFailed, DevFailed from device
Example :
com_info = dev.command_query(""DevString"")
- print com_info.cmd_name
- print com_info.cmd_tag
- print com_info.in_type
- print com_info.out_type
- print com_info.in_type_desc
- print com_info.out_type_desc
- print com_info.disp_level
+ print(com_info.cmd_name)
+ print(com_info.cmd_tag)
+ print(com_info.in_type)
+ print(com_info.out_type)
+ print(com_info.in_type_desc)
+ print(com_info.out_type_desc)
+ print(com_info.disp_level)
See CommandInfo documentation string form more detail
""" )
@@ -1083,10 +1072,10 @@ def __doc_DeviceProxy():
Return : (DbDevImportInfo)
Example :
dev_import = dev.import_info()
- print dev_import.name
- print dev_import.exported
- print dev_ior.ior
- print dev_version.version
+ print(dev_import.name)
+ print(dev_import.exported)
+ print(dev_ior.ior)
+ print(dev_version.version)
All DbDevImportInfo fields are strings except for exported which
is an integer"
@@ -1180,6 +1169,14 @@ def __doc_DeviceProxy():
value was. Since 7.1.4, it returns a **(format<str>, data<buffer>)**
unless *extract_as* is String, in which case it returns
**(format<str>, data<str>)**.
+
+ .. versionchanged:: 8.0.0
+ For DevEncoded attributes, now returns a DeviceAttribute.value
+ as a tuple **(format<str>, data<bytes>)** unless *extract_as* is String,
+ 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.
""" )
document_method("read_attributes", """
@@ -1804,7 +1801,7 @@ def __doc_DeviceProxy():
New in PyTango 7.0.0
""" )
-def init(doc=True):
+def device_proxy_init(doc=True):
__init_DeviceProxy()
if doc:
__doc_DeviceProxy()
diff --git a/PyTango/device_server.py b/PyTango/device_server.py
index 1973cc8..22e4d78 100644
--- a/PyTango/device_server.py
+++ b/PyTango/device_server.py
@@ -25,27 +25,26 @@
This is an internal PyTango module.
"""
+from __future__ import print_function
+
__all__ = [ "ChangeEventProp", "PeriodicEventProp", "ArchiveEventProp",
"AttributeAlarm", "EventProperties",
- "AttributeConfig", "AttributeConfig_2", "AttributeConfig_3"]
+ "AttributeConfig", "AttributeConfig_2", "AttributeConfig_3",
+ "device_server_init"]
__docformat__ = "restructuredtext"
import copy
-import _PyTango
-from _PyTango import DeviceImpl, Device_3Impl, Device_4Impl
-from _PyTango import Attribute, WAttribute, MultiAttribute, MultiClassAttribute
-from _PyTango import Attr
-from _PyTango import Logger
-from _PyTango import AttrWriteType, AttrDataFormat, DispLevel
-from _PyTango import UserDefaultAttrProp
+from ._PyTango import DevFailed, DeviceImpl, Device_3Impl, Device_4Impl, \
+ Attribute, WAttribute, MultiAttribute, MultiClassAttribute, \
+ Attr, Logger, AttrWriteType, AttrDataFormat, DispLevel, UserDefaultAttrProp
-from utils import document_method as __document_method
-from utils import copy_doc
-from attr_data import AttrData
+from .utils import document_method as __document_method
+from .utils import copy_doc
+from .attr_data import AttrData
-import log4tango
+from .log4tango import TangoStream
class AttributeAlarm(object):
"""This class represents the python interface for the Tango IDL object
@@ -261,13 +260,14 @@ def __DeviceImpl__get_device_properties(self, ds_class = None):
self.device_property_list = copy.deepcopy(ds_class.device_property_list)
class_prop = ds_class.class_property_list
pu.get_device_properties(self, class_prop, self.device_property_list)
- for prop_name in class_prop.keys():
+ for prop_name in class_prop:
setattr(self, prop_name, pu.get_property_values(prop_name, class_prop))
- for prop_name in self.device_property_list.keys():
+ for prop_name in self.device_property_list:
setattr(self, prop_name, self.prop_util.get_property_values(prop_name, self.device_property_list))
- except _PyTango.DevFailed, e:
- print "----> ", e
- raise e
+ except DevFailed as df:
+ print(80*"-")
+ print(df)
+ raise df
def __DeviceImpl__add_attribute(self, attr, r_meth=None, w_meth=None, is_allo_meth=None):
"""add_attribute(self, attr, r_meth=None, w_meth=None, is_allo_meth=None) -> Attr
@@ -392,7 +392,7 @@ def __DeviceImpl__debug_stream(self, *msg):
Since PyTango 7.1.3, the same can be achieved with::
- print >>self.log_debug, msg
+ print(msg, file=self.log_debug)
Parameters :
- msg : (str) the message to be sent to the debug stream
@@ -408,7 +408,7 @@ def __DeviceImpl__info_stream(self, *msg):
Since PyTango 7.1.3, the same can be achieved with::
- print >>self.log_info, msg
+ print(msg, file=self.log_info)
Parameters :
- msg : (str) the message to be sent to the info stream
@@ -424,7 +424,7 @@ def __DeviceImpl__warn_stream(self, *msg):
Since PyTango 7.1.3, the same can be achieved with::
- print >>self.log_warn, msg
+ print(msg, file=self.log_warn)
Parameters :
- msg : (str) the message to be sent to the warn stream
@@ -440,7 +440,7 @@ def __DeviceImpl__error_stream(self, *msg):
Since PyTango 7.1.3, the same can be achieved with::
- print >>self.log_error, msg
+ print(msg, file=self.log_error)
Parameters :
- msg : (str) the message to be sent to the error stream
@@ -456,7 +456,7 @@ def __DeviceImpl__fatal_stream(self, *msg):
Since PyTango 7.1.3, the same can be achieved with::
- print >>self.log_fatal, msg
+ print(msg, file=self.log_fatal)
Parameters :
- msg : (str) the message to be sent to the fatal stream
@@ -467,31 +467,31 @@ def __DeviceImpl__fatal_stream(self, *msg):
@property
def __DeviceImpl__debug(self):
if not hasattr(self, "_debug_s"):
- self._debug_s = log4tango.TangoStream(self.debug_stream)
+ self._debug_s = TangoStream(self.debug_stream)
return self._debug_s
@property
def __DeviceImpl__info(self):
if not hasattr(self, "_info_s"):
- self._info_s = log4tango.TangoStream(self.info_stream)
+ self._info_s = TangoStream(self.info_stream)
return self._info_s
@property
def __DeviceImpl__warn(self):
if not hasattr(self, "_warn_s"):
- self._warn_s = log4tango.TangoStream(self.warn_stream)
+ self._warn_s = TangoStream(self.warn_stream)
return self._warn_s
@property
def __DeviceImpl__error(self):
if not hasattr(self, "_error_s"):
- self._error_s = log4tango.TangoStream(self.error_stream)
+ self._error_s = TangoStream(self.error_stream)
return self._error_s
@property
def __DeviceImpl__fatal(self):
if not hasattr(self, "_fatal_s"):
- self._fatal_s = log4tango.TangoStream(self.fatal_stream)
+ self._fatal_s = TangoStream(self.fatal_stream)
return self._fatal_s
def __DeviceImpl__str(self):
@@ -2468,7 +2468,7 @@ def __doc_UserDefaultAttrProp():
Return : None
""" )
-def init(doc=True):
+def device_server_init(doc=True):
__init_DeviceImpl()
__init_Attribute()
__init_Attr()
diff --git a/PyTango/encoded_attribute.py b/PyTango/encoded_attribute.py
index afaefd5..48b8ea9 100644
--- a/PyTango/encoded_attribute.py
+++ b/PyTango/encoded_attribute.py
@@ -25,19 +25,18 @@
This is an internal PyTango module.
"""
-__all__ = []
+__all__ = ["encoded_attribute_init"]
__docformat__ = "restructuredtext"
-import types
-import operator
+import collections
-import _PyTango
-from _PyTango import EncodedAttribute
-from _PyTango import ExtractAs
-from _PyTango import _ImageFormat
+from ._PyTango import EncodedAttribute, ExtractAs, _ImageFormat
+from ._PyTango import constants
-if _PyTango.constants.NUMPY_SUPPORT:
+from .utils import is_pure_str
+
+if constants.NUMPY_SUPPORT:
try:
import numpy
np = numpy
@@ -47,7 +46,7 @@ else:
np = None
_allowed_extract = ExtractAs.Numpy, ExtractAs.String, ExtractAs.Tuple, \
- ExtractAs.List, ExtractAs.PyTango3
+ ExtractAs.List
def __EncodedAttribute_encode_jpeg_gray8(self, gray8, width=0, height=0, quality=100.0):
"""Encode a 8 bit grayscale image as JPEG format
@@ -123,11 +122,11 @@ def __EncodedAttribute_encode_gray8(self, gray8, width=0, height=0):
def __EncodedAttribute_generic_encode_gray8(self, gray8, width=0, height=0, quality=0, format=_ImageFormat.RawImage):
"""Internal usage only"""
- if not operator.isSequenceType(gray8):
+ if not isinstance(gray8, collections.Sequence):
raise TypeError("Expected sequence (str, numpy.ndarray, list, tuple "
"or bytearray) as first argument")
- is_str = type(gray8) in types.StringTypes
+ is_str = is_pure_str(gray8)
if is_str:
if not width or not height:
raise ValueError("When giving a string as data, you must also "
@@ -156,7 +155,7 @@ def __EncodedAttribute_generic_encode_gray8(self, gray8, width=0, height=0, qual
raise IndexError("Expected sequence with at least one row")
row0 = gray8[0]
- if not operator.isSequenceType(row0):
+ if not isinstance(row0, collections.Sequence):
raise IndexError("Expected sequence (str, numpy.ndarray, list, tuple or "
"bytearray) inside a sequence")
width = len(row0)
@@ -199,11 +198,11 @@ def __EncodedAttribute_encode_gray16(self, gray16, width=0, height=0):
enc.encode_gray16(data)
attr.set_value(data)
"""
- if not operator.isSequenceType(gray16):
+ if not isinstance(gray16, collections.Sequence):
raise TypeError("Expected sequence (str, numpy.ndarray, list, tuple "
"or bytearray) as first argument")
- is_str = type(gray16) in types.StringTypes
+ is_str = is_pure_str(gray16)
if is_str:
if not width or not height:
raise ValueError("When giving a string as data, you must also "
@@ -233,11 +232,11 @@ def __EncodedAttribute_encode_gray16(self, gray16, width=0, height=0):
raise IndexError("Expected sequence with at least one row")
row0 = gray16[0]
- if not operator.isSequenceType(row0):
+ if not isinstance(row0, collections.Sequence):
raise IndexError("Expected sequence (str, numpy.ndarray, list, tuple or "
"bytearray) inside a sequence")
width = len(row0)
- if type(row0) in types.StringTypes or type(row0) == bytearray:
+ if is_pure_str(row0) or type(row0) == bytearray:
width /= 2
self._encode_gray16(gray16, width, height)
@@ -318,11 +317,11 @@ def __EncodedAttribute_encode_rgb24(self, rgb24, width=0, height=0):
def __EncodedAttribute_generic_encode_rgb24(self, rgb24, width=0, height=0, quality=0, format=_ImageFormat.RawImage):
"""Internal usage only"""
- if not operator.isSequenceType(rgb24):
+ if not isinstance(rgb24, collections.Sequence):
raise TypeError("Expected sequence (str, numpy.ndarray, list, tuple "
"or bytearray) as first argument")
- is_str = type(rgb24) in types.StringTypes
+ is_str = is_pure_str(rgb24)
if is_str:
if not width or not height:
raise ValueError("When giving a string as data, you must also "
@@ -351,11 +350,11 @@ def __EncodedAttribute_generic_encode_rgb24(self, rgb24, width=0, height=0, qual
raise IndexError("Expected sequence with at least one row")
row0 = rgb24[0]
- if not operator.isSequenceType(row0):
+ if not isinstance(row0, collections.Sequence):
raise IndexError("Expected sequence (str, numpy.ndarray, list, tuple or "
"bytearray) inside a sequence")
width = len(row0)
- if type(row0) in types.StringTypes or type(row0) == bytearray:
+ if is_pure_str(row0) or type(row0) == bytearray:
width /= 3
if format == _ImageFormat.RawImage:
self._encode_rgb24(rgb24, width, height)
@@ -394,11 +393,11 @@ def __EncodedAttribute_encode_jpeg_rgb32(self, rgb32, width=0, height=0, quality
enc.encode_jpeg_rgb32(data)
attr.set_value(data)
"""
- if not operator.isSequenceType(rgb32):
+ if not isinstance(rgb32, collections.Sequence):
raise TypeError("Expected sequence (str, numpy.ndarray, list, tuple "
"or bytearray) as first argument")
- is_str = type(rgb32) in types.StringTypes
+ is_str = is_pure_str(rgb32)
if is_str:
if not width or not height:
raise ValueError("When giving a string as data, you must also "
@@ -427,11 +426,11 @@ def __EncodedAttribute_encode_jpeg_rgb32(self, rgb32, width=0, height=0, quality
raise IndexError("Expected sequence with at least one row")
row0 = rgb32[0]
- if not operator.isSequenceType(row0):
+ if not isinstance(row0, collections.Sequence):
raise IndexError("Expected sequence (str, numpy.ndarray, list, tuple or "
"bytearray) inside a sequence")
width = len(row0)
- if type(row0) in types.StringTypes or type(row0) == bytearray:
+ if is_pure_str(row0) or type(row0) == bytearray:
width /= 4
self._encode_jpeg_rgb32(rgb32, width, height, quality)
@@ -469,7 +468,7 @@ def __EncodedAttribute_decode_gray8(self, da, extract_as=ExtractAs.Numpy):
raise TypeError("DeviceAttribute argument must have been obtained from "
"a call which doesn't extract the contents")
if extract_as not in _allowed_extract:
- raise TypeError("extract_as must be one of Numpy, String, Tuple, List, PyTango3")
+ raise TypeError("extract_as must be one of Numpy, String, Tuple, List")
return self._decode_gray8(da, extract_as)
def __EncodedAttribute_decode_gray16(self, da, extract_as=ExtractAs.Numpy):
@@ -504,7 +503,7 @@ def __EncodedAttribute_decode_gray16(self, da, extract_as=ExtractAs.Numpy):
raise TypeError("DeviceAttribute argument must have been obtained from "
"a call which doesn't extract the contents")
if extract_as not in _allowed_extract:
- raise TypeError("extract_as must be one of Numpy, String, Tuple, List, PyTango3")
+ raise TypeError("extract_as must be one of Numpy, String, Tuple, List")
return self._decode_gray16(da, extract_as)
def __EncodedAttribute_decode_rgb32(self, da, extract_as=ExtractAs.Numpy):
@@ -539,7 +538,7 @@ def __EncodedAttribute_decode_rgb32(self, da, extract_as=ExtractAs.Numpy):
raise TypeError("DeviceAttribute argument must have been obtained from "
"a call which doesn't extract the contents")
if extract_as not in _allowed_extract:
- raise TypeError("extract_as must be one of Numpy, String, Tuple, List, PyTango3")
+ raise TypeError("extract_as must be one of Numpy, String, Tuple, List")
return self._decode_rgb32(da, extract_as)
def __init_EncodedAttribute():
@@ -558,7 +557,7 @@ def __init_EncodedAttribute():
def __doc_EncodedAttribute():
pass
-def init(doc=True):
+def encoded_attribute_init(doc=True):
__init_EncodedAttribute()
if doc:
__doc_EncodedAttribute()
diff --git a/PyTango/exception.py b/PyTango/exception.py
index 5aaacf9..b172e04 100644
--- a/PyTango/exception.py
+++ b/PyTango/exception.py
@@ -25,12 +25,12 @@
This is an internal PyTango module.
"""
-__all__ = []
+__all__ = ["exception_init"]
__docformat__ = "restructuredtext"
-from utils import document_static_method as __document_static_method
-from _PyTango import Except, DevError
+from .utils import document_static_method as __document_static_method
+from ._PyTango import Except, DevError
def __to_dev_failed(exc_type=None, exc_value=None, traceback=None):
"""to_dev_failed(exc_type, exc_value, traceback) -> PyTango.DevFailed
@@ -55,7 +55,7 @@ def __to_dev_failed(exc_type=None, exc_value=None, traceback=None):
New in PyTango 7.2.1"""
try:
Except.throw_python_exception(exc_type, exc_value, traceback)
- except Exception, e:
+ except Exception as e:
return e
def __init_Except():
@@ -160,7 +160,7 @@ def __doc_DevError():
- origin : (str) Tango server method in which the error happened"""
-def init(doc=True):
+def exception_init(doc=True):
__init_Except()
if doc:
__doc_Except()
diff --git a/PyTango/globals.py b/PyTango/globals.py
index 409da54..e288607 100644
--- a/PyTango/globals.py
+++ b/PyTango/globals.py
@@ -101,8 +101,8 @@ def class_factory():
local_cpp_class_list = get_cpp_classes()
if ((len(local_class_list) + len(local_cpp_class_list)) == 0):
- print 'Oups, no Tango class defined within this device server !!!'
- print 'Sorry, but I exit'
+ print('Oups, no Tango class defined within this device server !!!')
+ print('Sorry, but I exit')
import sys
sys.exit()
diff --git a/PyTango/group.py b/PyTango/group.py
index fd46e6e..c121e9b 100644
--- a/PyTango/group.py
+++ b/PyTango/group.py
@@ -25,14 +25,31 @@
This is an internal PyTango module.
"""
-__all__ = [ "Group" ]
+__all__ = [ "Group", "group_init" ]
__docformat__ = "restructuredtext"
-from _PyTango import __Group as _RealGroup, GroupElement
-from utils import document_method as __document_method
+import operator
-import group_element
+from ._PyTango import __Group as _RealGroup, StdStringVector
+from .utils import seq_2_StdStringVector
+from .utils import document_method as __document_method
+import collections
+
+def _apply_to(fn, key):
+ if isinstance(key, slice):
+ if key.step:
+ return [ fn(x) for x in range(key.start, key.stop, key.step) ]
+ else:
+ return [ fn(x) for x in range(key.start, key.stop) ]
+ else:
+ return fn(key)
+
+def _get_one_item(group, key):
+ x = group.get_group(key)
+ if x is not None:
+ return x
+ return group.get_device(key)
# I define Group as a proxy to __Group, where group is the actual
# C++ Tango::Group object. Most functions just call the __group object
@@ -44,31 +61,89 @@ import group_element
# The other function that needs to be adapted to this is get_group because
# we want to return a Group, not a __Group!
class Group:
+ """A Tango Group represents a hierarchy of tango devices. The hierarchy
+ may have more than one level. The main goal is to group devices with
+ same attribute(s)/command(s) to be able to do parallel requests."""
+
def __init__(self, name):
if isinstance(name, str):
name = _RealGroup(name)
if not isinstance(name, _RealGroup):
raise TypeError("Constructor expected receives a str")
self.__group = name
-
+
def add(self, pattern_subgroup, timeout_ms=-1):
if isinstance(pattern_subgroup, Group):
name = pattern_subgroup.__group.get_name()
- self.__group.add(pattern_subgroup.__group, timeout_ms)
+ self._add(pattern_subgroup.__group, timeout_ms)
pattern_subgroup.__group = self.get_group(name)
else:
- self.__group.add(pattern_subgroup, timeout_ms)
+ self._add(pattern_subgroup, timeout_ms)
+
+ def _add(self, patterns_or_group, timeout_ms=-1):
+ if isinstance(patterns_or_group, _RealGroup):
+ return self.__group._add(patterns_or_group, timeout_ms)
+ elif isinstance(patterns_or_group, StdStringVector):
+ return self.__group._add(patterns_or_group, timeout_ms)
+ elif isinstance(patterns_or_group, str):
+ return self.__group._add(patterns_or_group, timeout_ms)
+ elif isinstance(patterns_or_group, collections.Sequence):
+ patterns = seq_2_StdStringVector(patterns_or_group)
+ return self.__group._add(patterns, timeout_ms)
+ else:
+ raise TypeError('Parameter patterns_or_group: Should be Group, str or a sequence of strings.')
+
+ def remove(self, patterns, forward=True):
+ if isinstance(patterns, str):
+ return self.__group._remove(patterns, forward)
+ elif isinstance(patterns, collections.Sequence):
+ std_patterns = seq_2_StdStringVector(patterns)
+ return self.__group._remove(std_patterns, forward)
+ else:
+ raise TypeError('Parameter patterns: Should be a str or a sequence of str.')
def get_group(self, group_name):
internal = self.__group.get_group(group_name)
if internal is None:
return None
return Group(internal)
+
+ def __contains__(self, pattern):
+ return self.contains(pattern)
+
+ def __getitem__(self, key):
+ fn = lambda x: _get_one_item(self, x)
+ return _apply_to(fn, key)
+
+ def __delitem__(self, key):
+ fn = lambda x: self.remove(x)
+ return _apply_to(fn, key)
+
+ def __len__(self):
+ return self.get_size()
+
+ def command_inout(self, cmd_name, param=None, forward=True):
+ if param is None:
+ idx = self.command_inout_asynch(cmd_name, forget=False, forward=forward)
+ else:
+ idx = self.command_inout_asynch(cmd_name, param, forget=False, forward=forward)
+ return self.command_inout_reply(idx)
+
+ def read_attribute(self, attr_name, forward=True):
+ idx = self.__group.read_attribute_asynch(attr_name, forward)
+ return self.__group.read_attribute_reply(idx)
+
+ def read_attributes(self, attr_names, forward=True):
+ idx = self.__group.read_attributes_asynch(attr_names, forward)
+ return self.__group.read_attributes_reply(idx)
+
+ def write_attribute(self, attr_name, value, forward=True, multi=False):
+ idx = self.__group.write_attribute_asynch(attr_name, value, forward=forward, multi=multi)
+ return self.__group.write_attribute_reply(idx)
def __init_proxy_Group():
proxy_methods = [
#'add',
- 'command_inout',
'command_inout_asynch',
'command_inout_reply',
'contains',
@@ -84,22 +159,14 @@ def __init_proxy_Group():
'name_equals',
'name_matches',
'ping',
- 'read_attribute',
'read_attribute_asynch',
'read_attribute_reply',
- 'read_attributes',
'read_attributes_asynch',
'read_attributes_reply',
- 'remove',
'remove_all',
'set_timeout_millis',
- 'write_attribute',
'write_attribute_asynch',
- 'write_attribute_reply',
- '__contains__',
- '__delitem__',
- '__getitem__',
- '__len__']
+ 'write_attribute_reply',]
def proxy_call_define(fname):
def fn(self, *args, **kwds):
@@ -110,44 +177,164 @@ 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.__doc__ = _RealGroup.__doc__
+ #Group.add.im_func.__doc__ = _RealGroup.add.__doc__
+ #Group.get_group.im_func.__doc__ = _RealGroup.get_group.__doc__
+ #Group.__doc__ = _RealGroup.__doc__
def __doc_Group():
def document_method(method_name, desc, append=True):
return __document_method(_RealGroup, method_name, desc, append)
- document_method("add", GroupElement.add.__doc__, False)
- document_method("add", """
- add(self, subgroup, timeout_ms=-1) -> None
+ document_method("_add", """
+ add(self, patterns, timeout_ms=-1) -> None
- Attaches a (sub)_RealGroup.
-
- To remove the subgroup use the remove() method.
+ Attaches any device which name matches one of the specified patterns.
+
+ This method first asks to the Tango database the list of device names
+ matching one the patterns. Devices are then attached to the group in
+ the order in which they are returned by the database.
+
+ Any device already present in the hierarchy (i.e. a device belonging to
+ the group or to one of its subgroups), is silently ignored but its
+ client side timeout is set to timeout_ms milliseconds if timeout_ms
+ is different from -1.
Parameters :
- - subgroup : (str)
- - timeout_ms : (int) If timeout_ms parameter is different from -1,
- the client side timeout associated to each device
- composing the _RealGroup added is set to timeout_ms
- milliseconds. If timeout_ms is -1, timeouts are
- not changed.
+ - patterns : (str | sequence<str>) can be a simple device name or
+ a device name pattern (e.g. domain_*/ family/member_*),
+ or a sequence of these.
+ - timeout_ms : (int) If timeout_ms is different from -1, the client
+ side timeouts of all devices matching the
+ specified patterns are set to timeout_ms
+ milliseconds.
Return : None
Throws : TypeError, ArgumentError
""" )
+ document_method("_remove", """
+ remove(self, patterns, forward=True) -> None
+
+ Removes any group or device which name matches the specified pattern.
+
+ The pattern parameter can be a group name, a device name or a device
+ name pattern (e.g domain_*/family/member_*).
+
+ Since we can have groups with the same name in the hierarchy, a group
+ name can be fully qualified to specify which group should be removed.
+ Considering the following group:
+
+ ::
+
+ -> gauges
+ | -> cell-01
+ | |-> penning
+ | | |-> ...
+ | |-> pirani
+ | |-> ...
+ | -> cell-02
+ | |-> penning
+ | | |-> ...
+ | |-> pirani
+ | |-> ...
+ | -> cell-03
+ | |-> ...
+ |
+ | -> ...
+
+ A call to gauges->remove("penning") will remove any group named
+ "penning" in the hierarchy while gauges->remove("gauges.cell-02.penning")
+ will only remove the specified group.
+
+ Parameters :
+ - patterns : (str | sequence<str>) A string with the pattern or a
+ list of patterns.
+ - forward : (bool) If fwd is set to true (the default), the remove
+ request is also forwarded to subgroups. Otherwise,
+ it is only applied to the local set of elements.
+ For instance, the following code remove any
+ stepper motor in the hierarchy:
+
+ root_group->remove("*/stepper_motor/*");
+
+ Return : None
+
+ Throws :
+ """ )
+
document_method("remove_all", """
remove_all(self) -> None
Removes all elements in the _RealGroup. After such a call, the _RealGroup is empty.
""" )
- # I just documented them in group_element.py ...
- #document_method("enable", """""" )
- #document_method("disable", """""" )
+ document_method("contains", """
+ contains(self, pattern, forward=True) -> bool
+
+ Parameters :
+ - pattern : (str) The pattern can be a fully qualified or simple
+ group name, a device name or a device name pattern.
+ - forward : (bool) If fwd is set to true (the default), the remove
+ request is also forwarded to subgroups. Otherwise,
+ it is only applied to the local set of elements.
+
+ Return : (bool) Returns true if the hierarchy contains groups and/or
+ devices which name matches the specified pattern. Returns
+ false otherwise.
+
+ Throws :
+ """ )
+
+
+ document_method("get_device", """
+ get_device(self, dev_name) -> DeviceProxy
+ get_device(self, idx) -> DeviceProxy
+
+ Returns a reference to the specified device or None if there is no
+ device by that name in the group. Or, returns a reference to the
+ "idx-th" device in the hierarchy or NULL if the hierarchy contains
+ less than "idx" devices.
+
+ This method may throw an exception in case the specified device belongs
+ to the group but can't be reached (not registered, down...). See example
+ below:
+
+ ::
+
+ try:
+ dp = g.get_device("my/device/01")
+ if dp is None:
+ # my/device/01 does not belong to the group
+ pass
+ except DevFailed, f:
+ # my/device/01 belongs to the group but can't be reached
+ pass
+
+ The request is systematically forwarded to subgroups (i.e. if no device
+ named device_name could be found in the local set of devices, the
+ request is forwarded to subgroups).
+
+ Parameters :
+ - dev_name : (str) Device name.
+ - idx : (int) Device number.
+
+ Return : (DeviceProxy) Be aware that this method returns a
+ different DeviceProxy referring to the same device each time.
+ So, do not use it directly for permanent things.
+
+ Example:
+ # WRONG: The DeviceProxy will quickly go out of scope
+ # and disappear (thus, the event will be automatically
+ # unsubscribed)
+ g.get_device("my/device/01").subscribe_events('attr', callback)
+
+ # GOOD:
+ dp = g.get_device("my/device/01")
+ dp.subscribe_events('attr', callback)
+
+ Throws : DevFailed
+ """ )
document_method("get_device_list", """
get_device_list(self, forward=True) -> sequence<str>
@@ -209,9 +396,346 @@ def __doc_Group():
Throws :
""" )
+
+ document_method("get_group", """
+ get_group(self, group_name ) -> Group
+
+ Returns a reference to the specified group or None if there is no group
+ by that name. The group_name can be a fully qualified name.
+
+ Considering the following group:
+
+ ::
+
+ -> gauges
+ |-> cell-01
+ | |-> penning
+ | | |-> ...
+ | |-> pirani
+ | |-> ...
+ |-> cell-02
+ | |-> penning
+ | | |-> ...
+ | |-> pirani
+ | |-> ...
+ | -> cell-03
+ | |-> ...
+ |
+ | -> ...
+
+ A call to gauges.get_group("penning") returns the first group named
+ "penning" in the hierarchy (i.e. gauges.cell-01.penning) while
+ gauges.get_group("gauges.cell-02.penning'') returns the specified group.
+
+ The request is systematically forwarded to subgroups (i.e. if no group
+ named group_name could be found in the local set of elements, the request
+ is forwarded to subgroups).
+
+ Parameters :
+ - group_name : (str)
+
+ Return : (Group)
+
+ Throws :
+
+ New in PyTango 7.0.0
+ """ )
+
+# Tango methods (~ DeviceProxy interface)
+ document_method("ping", """
+ ping(self, forward=True) -> bool
+
+ Ping all devices in a group.
+
+ Parameters :
+ - forward : (bool) If fwd is set to true (the default), the request
+ is also forwarded to subgroups. Otherwise, it is
+ only applied to the local set of devices.
+
+ Return : (bool) This method returns true if all devices in
+ the group are alive, false otherwise.
+
+ Throws :
+ """ )
+
+ document_method("set_timeout_millis", """
+ set_timeout_millis(self, timeout_ms) -> bool
+
+ Set client side timeout for all devices composing the group in
+ milliseconds. Any method which takes longer than this time to execute
+ will throw an exception.
+
+ Parameters :
+ - timeout_ms : (int)
+
+ Return : None
+
+ Throws : (errors are ignored)
+
+ New in PyTango 7.0.0
+ """ )
+
+ document_method("command_inout_asynch", """
+ command_inout_asynch(self, cmd_name, forget=False, forward=True, reserved=-1 ) -> int
+ command_inout_asynch(self, cmd_name, param, forget=False, forward=True, reserved=-1 ) -> int
+ command_inout_asynch(self, cmd_name, param_list, forget=False, forward=True, reserved=-1 ) -> int
+
+ Executes a Tango command on each device in the group asynchronously.
+ The method sends the request to all devices and returns immediately.
+ Pass the returned request id to Group.command_inout_reply() to obtain
+ the results.
+
+ Parameters :
+ - cmd_name : (str) Command name
+ - param : (any) parameter value
+ - param_list : (PyTango.DeviceDataList) sequence of parameters.
+ When given, it's length must match the group size.
+ - forget : (bool) Fire and forget flag. If set to true, it means that
+ no reply is expected (i.e. the caller does not care
+ about it and will not even try to get it)
+ - forward : (bool) If it is set to true (the default) request is
+ forwarded to subgroups. Otherwise, it is only applied
+ to the local set of devices.
+ - reserved : (int) is reserved for internal purpose and should not be
+ used. This parameter may disappear in a near future.
+
+ Return : (int) request id. Pass the returned request id to
+ Group.command_inout_reply() to obtain the results.
+
+ Throws :
+ """ )
+
+ document_method("command_inout_reply", """
+ command_inout_reply(self, req_id, timeout_ms=0) -> sequence<GroupCmdReply>
+
+ Returns the results of an asynchronous command.
+
+ Parameters :
+ - req_id : (int) Is a request identifier previously returned by one
+ of the command_inout_asynch methods
+ - timeout_ms : (int) For each device in the hierarchy, if the command
+ result is not yet available, command_inout_reply
+ wait timeout_ms milliseconds before throwing an
+ exception. This exception will be part of the
+ global reply. If timeout_ms is set to 0,
+ command_inout_reply waits "indefinitely".
+
+ Return : (sequence<GroupCmdReply>)
+
+ Throws :
+ """ )
+
+ document_method("read_attribute_asynch", """
+ read_attribute_asynch(self, attr_name, forward=True, reserved=-1 ) -> int
+
+ Reads an attribute on each device in the group asynchronously.
+ The method sends the request to all devices and returns immediately.
+
+ Parameters :
+ - attr_name : (str) Name of the attribute to read.
+ - forward : (bool) If it is set to true (the default) request is
+ forwarded to subgroups. Otherwise, it is only applied
+ to the local set of devices.
+ - reserved : (int) is reserved for internal purpose and should not be
+ used. This parameter may disappear in a near future.
+
+ Return : (int) request id. Pass the returned request id to
+ Group.read_attribute_reply() to obtain the results.
+
+ Throws :
+ """ )
+
+ document_method("read_attributes_asynch", """
+ read_attributes_asynch(self, attr_names, forward=True, reserved=-1 ) -> int
+
+ Reads the attributes on each device in the group asynchronously.
+ The method sends the request to all devices and returns immediately.
+
+ Parameters :
+ - attr_names : (sequence<str>) Name of the attributes to read.
+ - forward : (bool) If it is set to true (the default) request is
+ forwarded to subgroups. Otherwise, it is only applied
+ to the local set of devices.
+ - reserved : (int) is reserved for internal purpose and should not be
+ used. This parameter may disappear in a near future.
+
+ Return : (int) request id. Pass the returned request id to
+ Group.read_attributes_reply() to obtain the results.
+
+ Throws :
+ """ )
+
+ document_method("read_attribute_reply", """
+ read_attribute_reply(self, req_id, timeout_ms=0 ) -> sequence<GroupAttrReply>
+
+ Returns the results of an asynchronous attribute reading.
+
+ Parameters :
+ - req_id : (int) a request identifier previously returned by read_attribute_asynch.
+ - timeout_ms : (int) For each device in the hierarchy, if the attribute
+ value is not yet available, read_attribute_reply
+ wait timeout_ms milliseconds before throwing an
+ exception. This exception will be part of the
+ global reply. If timeout_ms is set to 0,
+ read_attribute_reply waits "indefinitely".
+
+ Return : (sequence<GroupAttrReply>)
+
+ Throws :
+ """ )
+
+ document_method("read_attributes_reply", """
+ read_attributes_reply(self, req_id, timeout_ms=0 ) -> sequence<GroupAttrReply>
+
+ Returns the results of an asynchronous attribute reading.
+
+ Parameters :
+ - req_id : (int) a request identifier previously returned by read_attribute_asynch.
+ - timeout_ms : (int) For each device in the hierarchy, if the attribute
+ value is not yet available, read_attribute_reply
+ ait timeout_ms milliseconds before throwing an
+ exception. This exception will be part of the
+ global reply. If timeout_ms is set to 0,
+ read_attributes_reply waits "indefinitely".
+
+ Return : (sequence<GroupAttrReply>)
+
+ Throws :
+ """ )
+
+ document_method("write_attribute_asynch", """
+ write_attribute_asynch(self, attr_name, value, forward=True, multi=False ) -> int
+
+ Writes an attribute on each device in the group asynchronously.
+ The method sends the request to all devices and returns immediately.
+
+ Parameters :
+ - attr_name : (str) Name of the attribute to write.
+ - value : (any) Value to write. See DeviceProxy.write_attribute
+ - forward : (bool) If it is set to true (the default) request is
+ forwarded to subgroups. Otherwise, it is only applied
+ to the local set of devices.
+ - multi : (bool) If it is set to false (the default), the same
+ value is applied to all devices in the group.
+ Otherwise the value is interpreted as a sequence of
+ values, and each value is applied to the corresponding
+ device in the group. In this case len(value) must be
+ equal to group.get_size()!
+
+ Return : (int) request id. Pass the returned request id to
+ Group.write_attribute_reply() to obtain the acknowledgements.
+
+ Throws :
+ """ )
+
+ document_method("write_attribute_reply", """
+ write_attribute_reply(self, req_id, timeout_ms=0 ) -> sequence<GroupReply>
+
+ Returns the acknowledgements of an asynchronous attribute writing.
-def init(doc=True):
- group_element.init(doc=doc)
+ Parameters :
+ - req_id : (int) a request identifier previously returned by write_attribute_asynch.
+ - timeout_ms : (int) For each device in the hierarchy, if the acknowledgment
+ is not yet available, write_attribute_reply
+ wait timeout_ms milliseconds before throwing an
+ exception. This exception will be part of the
+ global reply. If timeout_ms is set to 0,
+ write_attribute_reply waits "indefinitely".
+
+ Return : (sequence<GroupReply>)
+
+ Throws :
+ """ )
+
+ document_method("get_name", """
+ Get the name of the group. Eg: Group('name').get_name() == 'name'
+ """ )
+ document_method("get_fully_qualified_name", """
+ Get the complete (dpt-separated) name of the group. This takes into
+ consideration the name of the group and its parents.
+ """ )
+ document_method("enable", "Enables a group or a device element in a group.")
+ document_method("disable", "Disables a group or a device element in a group.")
+ document_method("is_enabled", "Check if a group is enabled.\nNew in PyTango 7.0.0")
+ document_method("name_equals", "New in PyTango 7.0.0")
+ document_method("name_matches", "New in PyTango 7.0.0")
+ document_method("get_size", """
+ get_size(self, forward=True) -> int
+
+ Parameters :
+ - forward : (bool) If it is set to true (the default), the request is
+ forwarded to sub-groups.
+
+ Return : (int) The number of the devices in the hierarchy
+
+ Throws :
+ """ )
+
+ def document_method(method_name, desc, append=True):
+ return __document_method(Group, method_name, desc, append)
+
+ document_method("add", _RealGroup._add.__doc__, False)
+ document_method("add", """
+ add(self, subgroup, timeout_ms=-1) -> None
+
+ Attaches a (sub)_RealGroup.
+
+ To remove the subgroup use the remove() method.
+
+ Parameters :
+ - subgroup : (str)
+ - timeout_ms : (int) If timeout_ms parameter is different from -1,
+ the client side timeout associated to each device
+ composing the _RealGroup added is set to timeout_ms
+ milliseconds. If timeout_ms is -1, timeouts are
+ not changed.
+ Return : None
+
+ Throws : TypeError, ArgumentError
+ """ )
+
+ document_method("command_inout", """
+ command_inout(self, cmd_name, forward=True) -> sequence<GroupCmdReply>
+ command_inout(self, cmd_name, param, forward=True) -> sequence<GroupCmdReply>
+ command_inout(self, cmd_name, param_list, forward=True) -> sequence<GroupCmdReply>
+
+ Just a shortcut to do:
+ self.command_inout_reply(self.command_inout_asynch(...))
+
+ Parameters:
+ - cmd_name : (str) Command name
+ - param : (any) parameter value
+ - param_list : (PyTango.DeviceDataList) sequence of parameters.
+ When given, it's length must match the group size.
+ - forward : (bool) If it is set to true (the default) request is
+ forwarded to subgroups. Otherwise, it is only applied
+ to the local set of devices.
+
+ Return : (sequence<GroupCmdReply>)
+ """ )
+
+ document_method("read_attribute", """
+ read_attribute(self, attr_name, forward=True) -> sequence<GroupAttrReply>
+
+ Just a shortcut to do:
+ self.read_attribute_reply(self.read_attribute_asynch(...))
+ """ )
+
+ document_method("read_attributes", """
+ read_attributes(self, attr_names, forward=True) -> sequence<GroupAttrReply>
+
+ Just a shortcut to do:
+ self.read_attributes_reply(self.read_attributes_asynch(...))
+ """ )
+
+ document_method("write_attribute", """
+ write_attribute(self, attr_name, value, forward=True, multi=False) -> sequence<GroupReply>
+
+ Just a shortcut to do:
+ self.write_attribute_reply(self.write_attribute_asynch(...))
+ """ )
+
+def group_init(doc=True):
if doc:
__doc_Group()
__init_proxy_Group()
diff --git a/PyTango/group_element.py b/PyTango/group_element.py
index 29ccc85..16c0a36 100644
--- a/PyTango/group_element.py
+++ b/PyTango/group_element.py
@@ -25,24 +25,24 @@
This is an internal PyTango module.
"""
-__all__ = []
+__all__ = ["group_element_init"]
__docformat__ = "restructuredtext"
import operator
-from _PyTango import StdStringVector
-from _PyTango import GroupElement
+from ._PyTango import StdStringVector, GroupElement
-from utils import document_method as __document_method
-from utils import seq_2_StdStringVector
+from .utils import document_method as __document_method
+from .utils import seq_2_StdStringVector
+import collections
def __apply_to(fn, key):
if isinstance(key, slice):
if key.step:
- return [ fn(x) for x in xrange(key.start, key.stop, key.step) ]
+ return [ fn(x) for x in range(key.start, key.stop, key.step) ]
else:
- return [ fn(x) for x in xrange(key.start, key.stop) ]
+ return [ fn(x) for x in range(key.start, key.stop) ]
else:
return fn(key)
@@ -73,7 +73,7 @@ def __GroupElement__add(self, patterns_or_group, timeout_ms=-1):
return self.__add(patterns_or_group, timeout_ms)
elif isinstance(patterns_or_group, str):
return self.__add(patterns_or_group, timeout_ms)
- elif operator.isSequenceType(patterns_or_group):
+ elif isinstance(patterns_or_group, collections.Sequence):
patterns = seq_2_StdStringVector(patterns_or_group)
return self.__add(patterns, timeout_ms)
else:
@@ -82,7 +82,7 @@ def __GroupElement__add(self, patterns_or_group, timeout_ms=-1):
def __GroupElement__remove(self, patterns, forward=True):
if isinstance(patterns, str):
return self.__remove(patterns, forward)
- elif operator.isSequenceType(patterns):
+ elif isinstance(patterns, collections.Sequence):
std_patterns = seq_2_StdStringVector(patterns)
return self.__remove(std_patterns, forward)
else:
@@ -579,7 +579,7 @@ def __doc_GroupElement():
# get_parent(self)
-def init(doc=True):
+def group_element_init(doc=True):
__init_GroupElement()
if doc:
__doc_GroupElement()
diff --git a/PyTango/group_reply.py b/PyTango/group_reply.py
index 29a75ba..9d045f0 100644
--- a/PyTango/group_reply.py
+++ b/PyTango/group_reply.py
@@ -25,15 +25,12 @@
This is an internal PyTango module.
"""
-__all__ = []
+__all__ = ["group_reply_init"]
__docformat__ = "restructuredtext"
-from utils import document_method as __document_method
-from _PyTango import GroupReply
-from _PyTango import GroupCmdReply
-from _PyTango import GroupAttrReply
-from _PyTango import ExtractAs
+from .utils import document_method as __document_method
+from ._PyTango import GroupReply, GroupCmdReply, GroupAttrReply, ExtractAs
def __GroupCmdReply__get_data(self):
return self.get_data_raw().extract()
@@ -109,7 +106,7 @@ def __doc_GroupReply():
Return : (DeviceAttribute) Whatever is stored there, or None.
""" )
-def init(doc=True):
+def group_reply_init(doc=True):
__init_GroupReply()
if doc:
__doc_GroupReply()
diff --git a/PyTango/group_reply_list.py b/PyTango/group_reply_list.py
index 37fa3c8..272105a 100644
--- a/PyTango/group_reply_list.py
+++ b/PyTango/group_reply_list.py
@@ -25,13 +25,12 @@
This is an internal PyTango module.
"""
-__all__ = []
+__all__ = ["group_reply_list_init"]
__docformat__ = "restructuredtext"
-from _PyTango import GroupReplyList
-from _PyTango import GroupCmdReplyList
-from _PyTango import GroupAttrReplyList
+from ._PyTango import GroupReplyList, GroupCmdReplyList, GroupAttrReplyList
+
def __GroupReplyList__getitem(self, item):
# Accessing an item in GroupReplyList and friends makes a C++ copy
@@ -47,7 +46,7 @@ def __GroupReplyList__getitem(self, item):
# Slices support
if isinstance(item, slice):
- return [self.__getitem__(x) for x in xrange(*item.indices(len(self)))]
+ return [self.__getitem__(x) for x in range(*item.indices(len(self)))]
# We want to get the same cache value for x[-1] as for x[len(x)-1]
if item < 0:
@@ -72,7 +71,7 @@ def __GroupReplyList__getitem(self, item):
def __GroupReplyList__iter(self):
# Same problem as getitem. In this case it is easier for me to just
# reimplement __iter__ in terms of __getitem__
- for x in xrange(len(self)):
+ for x in range(len(self)):
yield self[x]
def __init_GroupReplyList():
@@ -92,7 +91,7 @@ def __init_GroupReplyList():
def __doc_GroupReplyList():
pass
-def init(doc=True):
+def group_reply_list_init(doc=True):
__init_GroupReplyList()
if doc:
__doc_GroupReplyList()
diff --git a/PyTango/ipython/__init__.py b/PyTango/ipython/__init__.py
index 35c6021..8a4e5b3 100644
--- a/PyTango/ipython/__init__.py
+++ b/PyTango/ipython/__init__.py
@@ -30,37 +30,37 @@ from common import get_python_version, get_python_version_number, \
def default_init_ipython(ip, store=True, pytango=True, colors=True,
console=True, magic=True):
- print "Unsupported IPython version (%s) for tango profile" \
- % get_ipython_version()
- print "Supported IPython versions are: >= 0.10"
- print "Starting normal IPython console..."
+ print("Unsupported IPython version (%s) for tango profile" \
+ % get_ipython_version())
+ print("Supported IPython versions are: >= 0.10")
+ print("Starting normal IPython console...")
def default_install(ipydir=None, verbose=True):
- print "Unsupported IPython version (%s) for tango profile" \
- % get_ipython_version()
- print "Supported IPython versions are: 0.10 to 0.13"
- print "Tango extension to IPython will NOT be installed."
+ print("Unsupported IPython version (%s) for tango profile" \
+ % get_ipython_version())
+ print("Supported IPython versions are: >= 0.10")
+ print("Tango extension to IPython will NOT be installed.")
init_ipython = default_init_ipython
install = default_install
ipv = get_ipython_version_list()
if ipv >= [0, 10] and ipv < [0, 11]:
- import ipython_00_10
+ from . import ipython_00_10
init_ipython = ipython_00_10.init_ipython
install = ipython_00_10.install
load_config = None
load_ipython_extension = None
unload_ipython_extension = None
elif ipv >= [0, 11] and ipv < [0, 12]:
- import ipython_00_11
+ from . import ipython_00_11
init_ipython = None
install = ipython_00_11.install
load_config = ipython_00_11.load_config
load_ipython_extension = ipython_00_11.load_ipython_extension
unload_ipython_extension = ipython_00_11.unload_ipython_extension
elif ipv >= [0, 12] and ipv < [1, 0]:
- import ipython_00_12
+ from . import ipython_00_12
init_ipython = None
install = ipython_00_12.install
load_config = ipython_00_12.load_config
diff --git a/PyTango/ipython/common.py b/PyTango/ipython/common.py
index 4f89348..8876a09 100644
--- a/PyTango/ipython/common.py
+++ b/PyTango/ipython/common.py
@@ -46,7 +46,7 @@ def translate_version_str2int(version_str):
v += int(parts[i])*int(math.pow(10,(2-i)*2))
l -= 1
i += 1
- except ValueError,ve:
+ except ValueError:
return v
if not l: return v
return v
@@ -54,21 +54,21 @@ def translate_version_str2int(version_str):
try:
v += 10000*int(parts[0])
l -= 1
- except ValueError,ve:
+ except ValueError:
return v
if not l: return v
try:
v += 100*int(parts[1])
l -= 1
- except ValueError,ve:
+ except ValueError:
return v
if not l: return v
try:
v += int(parts[0])
l -= 1
- except ValueError,ve:
+ except ValueError:
return v
if not l: return v
@@ -109,12 +109,12 @@ def get_ipython_version():
try:
try:
v = IPython.Release.version
- except Exception, e1:
+ except:
try:
v = IPython.release.version
- except Exception, e2:
+ except:
pass
- except Exception, e3:
+ except:
pass
return v
diff --git a/PyTango/ipython/ipython_00_10/ipy_cli.py b/PyTango/ipython/eventlogger.py
similarity index 78%
rename from PyTango/ipython/ipython_00_10/ipy_cli.py
rename to PyTango/ipython/eventlogger.py
index 53931b1..a05b445 100644
--- a/PyTango/ipython/ipython_00_10/ipy_cli.py
+++ b/PyTango/ipython/eventlogger.py
@@ -21,15 +21,17 @@
##
################################################################################
-import re
-import StringIO
+from __future__ import print_function
-import IPython.genutils
+import re
+import io
+import operator
class EventLogger(object):
- def __init__(self, capacity=100000):
+ def __init__(self, capacity=100000, pager=None):
self._capacity = capacity
+ self._pager = pager
self._records = []
def push_event(self, evt):
@@ -62,11 +64,13 @@ class EventLogger(object):
if aexpr is not None:
aexpr = re.compile(aexpr, re.IGNORECASE)
- s = StringIO.StringIO()
- cols = 4, 30, 18, 20, 12, 16
- l = "%{0}s %{1}s %{2}s %{3}s %{4}s %{5}s".format(*cols)
- print >>s, l % ('ID', 'Device', 'Attribute', 'Value', 'Quality', 'Time')
- print >>s, l % (cols[0]*"-", cols[1]*"-", cols[2]*"-", cols[3]*"-", cols[4]*"-", cols[5]*"-")
+ s = io.BytesIO()
+ lengths = 4, 30, 18, 20, 12, 16
+ title = 'ID', 'Device', 'Attribute', 'Value', 'Quality', 'Time'
+ templ = "{0:{l[0]}} {1:{l[1]}} {2:{l[2]}} {3:{l[3]}} {4:{l[4]}} {5:{l[5]}}"
+ print(templ.format(*title, l=lengths), file=s)
+ print(*map(operator.mul, lengths, len(lengths)*"-"), file=s)
+
for i,r in enumerate(self._records):
if dexpr is not None and not dexpr.match(r.dev_name): continue
if aexpr is not None and not aexpr.match(r.s_attr_name): continue
@@ -78,6 +82,10 @@ class EventLogger(object):
v = str(r.attr_value.value)
q = str(r.attr_value.quality)
ts = r.attr_value.time.strftime("%H:%M:%S.%f")
- print >>s, l % (i, r.dev_name, r.s_attr_name, v, q, ts)
+ msg = templ.format(i, r.dev_name, r.s_attr_name, v, q, ts, l=lengths)
+ print(msg, file=s)
s.seek(0)
- IPython.genutils.page(s.read())
\ No newline at end of file
+ if self._pager is None:
+ print(s.read())
+ else:
+ self._pager(s.read())
diff --git a/PyTango/ipython/ipython_00_10/__init__.py b/PyTango/ipython/ipython_00_10/__init__.py
index 5e94cb6..24eac01 100644
--- a/PyTango/ipython/ipython_00_10/__init__.py
+++ b/PyTango/ipython/ipython_00_10/__init__.py
@@ -23,5 +23,5 @@
__all__ = ['init_ipython', 'install']
-from ipython_00_10 import init_ipython
-from ipy_install import install
\ No newline at end of file
+from .ipython_00_10 import init_ipython
+from .ipy_install import install
\ No newline at end of file
diff --git a/PyTango/ipython/ipython_00_10/ipy_install.py b/PyTango/ipython/ipython_00_10/ipy_install.py
index aa7e058..7359889 100644
--- a/PyTango/ipython/ipython_00_10/ipy_install.py
+++ b/PyTango/ipython/ipython_00_10/ipy_install.py
@@ -25,7 +25,7 @@
import sys
import os
-import StringIO
+import io
import IPython.genutils
import PyTango
@@ -50,12 +50,12 @@ def install(ipydir=None,verbose=True):
if verbose:
out = sys.stdout
else:
- out = StringIO.StringIO()
+ out = io.StringIO()
if ipydir is None and os.path.isfile(f_name):
- print "Warning: The file '%s' already exists." % f_name
+ print("Warning: The file '%s' already exists." % f_name)
r = ''
while r.lower() not in ('y', 'n'):
- r = raw_input("Do you wish to override it [Y/n]?")
+ r = input("Do you wish to override it [Y/n]?")
r = r or 'y'
if r.lower() == 'n':
return
@@ -64,13 +64,13 @@ def install(ipydir=None,verbose=True):
out.write("Installing tango extension to ipython... ")
out.flush()
try:
- f = file(f_name, "w")
+ f = open(f_name, "w")
f.write(profile)
f.close()
out.write("[DONE]\n\n")
- except Exception, e:
+ except:
out.write("[FAILED]\n\n")
- raise e
+ raise
ipy_user_config = os.path.join(IPython.genutils.get_ipython_dir(), 'ipy_user_conf.py')
out.write("""\
diff --git a/PyTango/ipython/ipython_00_10/ipy_qt.py b/PyTango/ipython/ipython_00_10/ipy_qt.py
index 5485fcf..38bd4c6 100644
--- a/PyTango/ipython/ipython_00_10/ipy_qt.py
+++ b/PyTango/ipython/ipython_00_10/ipy_qt.py
@@ -319,7 +319,7 @@ class EventLoggerTable(Qt.QTableView):
"""Overwrite of slot rows inserted to do proper resize and scroll to
bottom if desired
"""
- for i in xrange(start,end+1):
+ for i in range(start,end+1):
self.resizeRowToContents(i)
if start == 0:
self.resizeColumnsToContents()
diff --git a/PyTango/ipython/ipython_00_10/ipython_00_10.py b/PyTango/ipython/ipython_00_10/ipython_00_10.py
index e4b0385..450178a 100644
--- a/PyTango/ipython/ipython_00_10/ipython_00_10.py
+++ b/PyTango/ipython/ipython_00_10/ipython_00_10.py
@@ -25,10 +25,12 @@
"""An IPython profile designed to provide a user friendly interface to Tango"""
+from __future__ import print_function
+
import sys
import os
import re
-import StringIO
+import io
import textwrap
import IPython.ipapi
import IPython.ColorANSI
@@ -244,18 +246,18 @@ def magic_lsdev(self, parameter_s=''):
db = __get_db()
if db is None:
- print "You are not connected to any Tango Database. Device list is empty"
+ print("You are not connected to any Tango Database. Device list is empty")
return
data = db._db_cache.devices
- s = StringIO.StringIO()
+ s = io.BytesIO()
cols = 40, 25, 25, 20
l = "%{0}s %{1}s %{2}s %{3}s".format(*cols)
- print >>s, l % ("Device", "Alias", "Server", "Class")
- print >>s, l % (cols[0]*"-", cols[1]*"-", cols[2]*"-", cols[3]*"-")
+ print(l % ("Device", "Alias", "Server", "Class"), file=s)
+ print(l % (cols[0]*"-", cols[1]*"-", cols[2]*"-", cols[3]*"-"), file=s)
for d, v in data.items():
if reg_exp and not reg_exp.match(d): continue
- print >>s, l % (d, v[0], v[1], v[2])
+ print(l % (d, v[0], v[1], v[2]), file=s)
s.seek(0)
IPython.genutils.page(s.read())
@@ -275,11 +277,11 @@ def magic_lsdevclass(self, parameter_s=''):
db = __get_db()
if db is None:
- print "You are not connected to any Tango Database. Device class list is empty"
+ print("You are not connected to any Tango Database. Device class list is empty")
return
data = db._db_cache.klasses
- s = StringIO.StringIO()
+ s = io.BytesIO()
data = [ "%-030s" % klass for klass in data.keys() if not reg_exp or reg_exp.match(klass) ]
s = textwrap.fill(" ".join(data), 80)
IPython.genutils.page(s)
@@ -300,11 +302,11 @@ def magic_lsserv(self, parameter_s=''):
db = __get_db()
if db is None:
- print "You are not connected to any Tango Database. Device class list is empty"
+ print("You are not connected to any Tango Database. Device class list is empty")
return
data = db._db_cache.servers
- s = StringIO.StringIO()
+ s = io.BytesIO()
data = [ "%-030s" % server for server in data.keys() if not reg_exp or reg_exp.match(server) ]
s = textwrap.fill(" ".join(data), 80)
IPython.genutils.page(s)
@@ -315,10 +317,10 @@ def magic_tango_error(self, parameter_s=''):
global _TANGO_ERR
err_info = self.user_ns.get(_TANGO_ERR)
if err_info is None:
- print "No tango error reported so far."
+ print("No tango error reported so far.")
return
- print "Last tango error:"
- print err_info[1]
+ print("Last tango error:")
+ print(err_info[1])
def magic_python_error(self, parameter_s=''):
"""Displays detailed information about the last python error"""
@@ -326,7 +328,7 @@ def magic_python_error(self, parameter_s=''):
global _PYTHON_ERR
err_info = self.user_ns.get(_PYTHON_ERR)
if err_info is None:
- print "No error reported so far."
+ print("No error reported so far.")
return
ip = IPython.ipapi.get()
etype, evalue, etb = err_info[:3]
@@ -336,15 +338,8 @@ _EVT_LOG = None
def __get_event_log():
global _EVT_LOG
if _EVT_LOG is None:
- qthreads = IPython.ipapi.get().options.q4thread
- if qthreads:
- import ipy_qt
- model = ipy_qt.EventLoggerTableModel(capacity=10000)
- _EVT_LOG = ipy_qt.EventLogger(model=model)
- _EVT_LOG.setWindowTitle("ITango - Event Logger Table")
- else:
- import ipy_cli
- _EVT_LOG = ipy_cli.EventLogger(capacity=10000)
+ import PyTango.ipython.eventlogger
+ _EVT_LOG = PyTango.ipython.eventlogger.EventLogger(capacity=10000, pager=IPython.genutils.page)
return _EVT_LOG
def magic_mon(self, parameter_s=''):
@@ -359,12 +354,12 @@ def magic_mon(self, parameter_s=''):
db = __get_db()
if db is None:
- print "You are not connected to any Tango Database."
+ print("You are not connected to any Tango Database.")
return
opts, args = self.parse_options(parameter_s,'adril', mode='list')
if len(args) > 3:
raise IPython.ipapi.UsageError("%mon: too many arguments")
- if opts.has_key('d'):
+ if 'd' in opts:
try:
todel = args[0]
except IndexError:
@@ -378,12 +373,12 @@ def magic_mon(self, parameter_s=''):
del subscriptions[attr.lower()]
d = __get_device_proxy(dev)
d.unsubscribe_event(id)
- print "Stopped monitoring '%s'" % todel
+ print("Stopped monitoring '%s'" % todel)
except KeyError:
raise IPython.ipapi.UsageError(
"%%mon -d: Not monitoring '%s'" % todel)
- elif opts.has_key('a'):
+ elif 'a' in opts:
try:
toadd = args[0]
except IndexError:
@@ -400,14 +395,14 @@ def magic_mon(self, parameter_s=''):
model = w.model()
id = d.subscribe_event(attr, PyTango.EventType.CHANGE_EVENT, model, [])
subscriptions[attr.lower()] = id
- print "'%s' is now being monitored. Type 'mon' to see all events" % toadd
- elif opts.has_key('r'):
+ print("'%s' is now being monitored. Type 'mon' to see all events" % toadd)
+ elif 'r' in opts:
for d, v in db._db_cache.devices.items():
d, subs = v[3], v[4]
for id in subs.values():
d.unsubscribe_event(id)
v[4] = {}
- elif opts.has_key('i'):
+ elif 'i' in opts:
try:
evtid = int(args[0])
except IndexError:
@@ -420,13 +415,13 @@ def magic_mon(self, parameter_s=''):
w = __get_event_log()
e = w.getEvents()[evtid]
if e.err:
- print str(PyTango.DevFailed(*e.errors))
+ print(str(PyTango.DevFailed(*e.errors)))
else:
- print str(e)
+ print(str(e))
except IndexError:
raise IPython.ipapi.UsageError(
"%mon -i: must provide a valid event ID")
- elif opts.has_key('l'):
+ elif 'l' in opts:
try:
dexpr = args[0]
aexpr = args[1]
@@ -455,7 +450,7 @@ def get_device_map():
DeviceProxy to this device, create your own)"""
db = __get_db()
if db is None:
- print "You are not connected to any Tango Database."
+ print("You are not connected to any Tango Database.")
return
return db._db_cache.devices
@@ -464,7 +459,7 @@ def get_server_map():
and value is a sequence of device names that belong to the server"""
db = __get_db()
if db is None:
- print "You are not connected to any Tango Database."
+ print("You are not connected to any Tango Database.")
return
return db._db_cache.servers
@@ -473,7 +468,7 @@ def get_class_map():
sequence of device names that belong to the tango class"""
db = __get_db()
if db is None:
- print "You are not connected to any Tango Database."
+ print("You are not connected to any Tango Database.")
return
return db._db_cache.klasses
@@ -482,7 +477,7 @@ def get_alias_map():
is a the tango device name"""
db = __get_db()
if db is None:
- print "You are not connected to any Tango Database."
+ print("You are not connected to any Tango Database.")
return
return db._db_cache.aliases
@@ -491,7 +486,7 @@ def get_device_list():
database"""
db = __get_db()
if db is None:
- print "You are not connected to any Tango Database."
+ print("You are not connected to any Tango Database.")
return
return db._db_cache.device_list
@@ -500,7 +495,7 @@ def get_alias_list():
database"""
db = __get_db()
if db is None:
- print "You are not connected to any Tango Database."
+ print("You are not connected to any Tango Database.")
return
return db._db_cache.alias_list
@@ -515,15 +510,15 @@ def __exc_handler(ip, etype, value, tb):
ip.user_ns[_TANGO_ERR] = etype, value, tb
if len(value.args):
v = value[0]
- print "%s: %s" % (v.reason ,v.desc)
+ print("%s: %s" % (v.reason ,v.desc))
else:
- print "Empty DevFailed"
- print "(For more detailed information type: tango_error)"
+ print("Empty DevFailed")
+ print("(For more detailed information type: tango_error)")
else:
global _PYTHON_ERR
ip.user_ns[_PYTHON_ERR] = etype, value, tb
- print etype.__name__ + ": " + str(value)
- print "(For more detailed information type: python_error)"
+ print(etype.__name__ + ": " + str(value))
+ print("(For more detailed information type: python_error)")
def __get_default_tango_host():
global _DFT_TANGO_HOST
@@ -575,15 +570,15 @@ def __get_db(host_port=None):
ip.user_ns["DB_NAME"] = host_port
except Exception:
- print
+ print()
if db:
- print "Could not access Database", host_port
+ print("Could not access Database", host_port)
old_host_port = "%s:%s" % (db.get_db_host(), db.get_db_port())
- print "Maintaining connection to Database", old_host_port
+ print("Maintaining connection to Database", old_host_port)
ip.user_ns["DB_NAME"] = old_host_port
else:
- print "Could not access any Database."
- print "Make sure .tangorc, /etc/tangorc or TANGO_HOST environment is defined."
+ print("Could not access any Database.")
+ print("Make sure .tangorc, /etc/tangorc or TANGO_HOST environment is defined.")
ip.user_ns["DB_NAME"] = "OFFLINE"
# register the 'db' in the user namespace
@@ -605,16 +600,16 @@ def __completer_wrapper(f):
def wrapper(ip, evt):
try:
return f(ip, evt)
- except Exception, e:
- print
- print "An unexpected exception ocorred during ITango command completer."
- print "Please send a bug report to the PyTango team with the following informantion:"
- print IPython.ipapi.get().options.banner
- print 80*"-"
- print "Completer:",__get_obj_name(f)
- print 80*"-"
- print str(e)
- print 80*"-"
+ except Exception as e:
+ print()
+ print("An unexpected exception ocorred during ITango command completer.")
+ print("Please send a bug report to the PyTango team with the following informantion:")
+ print(IPython.ipapi.get().options.banner)
+ print(80*"-")
+ print("Completer:",__get_obj_name(f))
+ print(80*"-")
+ print(str(e))
+ print(80*"-")
raise e
return wrapper
@@ -693,7 +688,7 @@ def __store(ip, var):
# we hide the standard output
stdout = sys.stdout
try:
- sys.stdout = StringIO.StringIO()
+ sys.stdout = io.BytesIO()
ip.magic("store %s" % var)
finally:
sys.stdout = stdout
@@ -773,7 +768,7 @@ def init_db(ip, parameter_s=''):
if db is None: return
-# os.environ["TANGO_HOST"] = "%s:%s" % (db.get_db_host(), db.get_db_port())
+ #os.environ["TANGO_HOST"] = "%s:%s" % (db.get_db_host(), db.get_db_port())
# Initialize device and server information
query = "SELECT name, alias, server, class FROM device order by name"
@@ -818,7 +813,7 @@ def init_db(ip, parameter_s=''):
excluded_klasses = "DServer",
for klass, devices in klass_dict.items():
if klass in excluded_klasses: continue
- if not ip.user_ns.has_key(klass) or klass in old_junk:
+ if klass not in ip.user_ns or klass in old_junk:
c = DeviceClassCompleter(klass, devices)
ip.set_hook('complete_command', c, re_key = ".*" + klass + "[^\w\.]+")
exposed_klasses[klass] = PyTango.DeviceProxy
@@ -872,7 +867,7 @@ def init_store(ip):
tango_store = ip.user_ns.get(_TANGO_STORE)
if tango_store is None:
- print "Initializing tango store (should only happen once)"
+ print("Initializing tango store (should only happen once)")
tango_store = {}
ip.to_user_ns( { _TANGO_STORE : tango_store} )
__store(ip, _TANGO_STORE)
diff --git a/PyTango/ipython/ipython_00_11/__init__.py b/PyTango/ipython/ipython_00_11/__init__.py
index 5e43cec..3a11264 100644
--- a/PyTango/ipython/ipython_00_11/__init__.py
+++ b/PyTango/ipython/ipython_00_11/__init__.py
@@ -24,6 +24,6 @@
__all__ = ['load_ipython_extension', 'unload_ipython_extension', 'load_config',
'install']
-from ipython_00_11 import load_ipython_extension, unload_ipython_extension, \
+from .ipython_00_11 import load_ipython_extension, unload_ipython_extension, \
load_config
-from ipy_install import install
\ No newline at end of file
+from .ipy_install import install
\ No newline at end of file
diff --git a/PyTango/ipython/ipython_00_11/ipy_install.py b/PyTango/ipython/ipython_00_11/ipy_install.py
index e873fd2..3eb8906 100644
--- a/PyTango/ipython/ipython_00_11/ipy_install.py
+++ b/PyTango/ipython/ipython_00_11/ipy_install.py
@@ -23,9 +23,11 @@
##
################################################################################
+from __future__ import with_statement
+
import sys
import os
-import StringIO
+import io
import IPython
from IPython.core.profiledir import ProfileDirError, ProfileDir
@@ -53,7 +55,7 @@ def install(ipydir=None, verbose=True, profile='tango'):
if verbose:
out = sys.stdout
else:
- out = StringIO.StringIO()
+ out = io.StringIO()
ipython_dir = ipydir or get_ipython_dir()
try:
@@ -76,14 +78,9 @@ def install(ipydir=None, verbose=True, profile='tango'):
profile = __PROFILE.format(pytangover=PyTango.Release.version,
ipyver=IPython.release.version)
- f = None
- try:
- f = file(abs_config_file_name, "w")
+ with open(abs_config_file_name, "w") as f:
f.write(profile)
- finally:
- if f is not None:
- f.close()
-
+ f.close()
out.write("[DONE]\n\n")
out.write("""\
To start ipython with tango interface simply type on the command line:
diff --git a/PyTango/ipython/ipython_00_11/ipython_00_11.py b/PyTango/ipython/ipython_00_11/ipython_00_11.py
index 40120ac..1d1c063 100644
--- a/PyTango/ipython/ipython_00_11/ipython_00_11.py
+++ b/PyTango/ipython/ipython_00_11/ipython_00_11.py
@@ -25,22 +25,28 @@
"""An IPython profile designed to provide a user friendly interface to Tango"""
+from __future__ import print_function
+
__all__ = ["load_config", "load_ipython_extension", "unload_ipython_extension"]
+import sys
import os
import re
-import StringIO
+import io
+import operator
import textwrap
-from IPython.core import ipapi
from IPython.core.error import UsageError
from IPython.utils.ipstruct import Struct
from IPython.core.page import page
+from IPython.core.interactiveshell import InteractiveShell
+from IPython.config.application import Application
import PyTango
import PyTango.utils
-_TG_EXCEPTIONS = PyTango.DevFailed, PyTango.CommunicationFailed, \
+_TG_EXCEPTIONS = PyTango.DevFailed, PyTango.ConnectionFailed, \
+ PyTango.CommunicationFailed, \
PyTango.NamedDevFailed, PyTango.NamedDevFailedList, \
PyTango.WrongNameSyntax, PyTango.NonDbDevice, PyTango.WrongData, \
PyTango.NonSupportedFeature, PyTango.AsynCall, \
@@ -54,6 +60,33 @@ _TANGO_ERR = "__tango_error"
_PYTHON_ERR = "__python_error"
_tango_init = False
+#-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-
+# IPython utilities
+#-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-
+
+def get_pylab_mode():
+ return get_app().pylab
+
+def get_color_mode():
+ return get_config().InteractiveShell.colors
+
+def get_app():
+ #return TerminalIPythonApp.instance()
+ return Application.instance()
+
+def get_shell():
+ """Get the global InteractiveShell instance."""
+ return get_app().shell
+
+def get_ipapi():
+ """Get the global InteractiveShell instance."""
+ return InteractiveShell.instance()
+
+def get_config():
+ return get_app().config
+
+def get_editor():
+ return get_ipapi().editor
class DeviceClassCompleter(object):
"""Completer class that returns the list of devices of some class when
@@ -172,7 +205,7 @@ def __AttributeProxy_completer(ip, evt):
def __get_device_proxy(dev_name):
db = __get_db()
if db is None: return
- cache = db._db_cacheIPyh
+ cache = db._db_cache
from_alias = cache.aliases.get(dev_name)
if from_alias is not None:
@@ -208,7 +241,7 @@ __monitor_completer = __AttributeProxy_completer
#-------------------------------------------------------------------------------
def magic_refreshdb(self, parameter_s=''):
- init_db(ipapi.get(), parameter_s)
+ init_db(parameter_s)
def magic_switchdb(self, parameter_s=''):
"""Switches the active tango Database.
@@ -225,7 +258,7 @@ def magic_switchdb(self, parameter_s=''):
if parameter_s == '':
raise UsageError("%switchdb: Must specify a tango database name. "\
"See '%switchdb?'")
- return init_db(ipapi.get(), parameter_s)
+ return init_db(parameter_s)
def magic_lsdev(self, parameter_s=''):
"""Lists all known tango devices.
@@ -243,18 +276,21 @@ def magic_lsdev(self, parameter_s=''):
db = __get_db()
if db is None:
- print "You are not connected to any Tango Database. Device list is empty"
+ print("You are not connected to any Tango Database. Device list is empty")
return
data = db._db_cache.devices
- s = StringIO.StringIO()
- cols = 40, 25, 25, 20
- l = "%{0}s %{1}s %{2}s %{3}s".format(*cols)
- print >>s, l % ("Device", "Alias", "Server", "Class")
- print >>s, l % (cols[0]*"-", cols[1]*"-", cols[2]*"-", cols[3]*"-")
+ s = io.BytesIO()
+ lengths = 40, 25, 25, 20
+ title = "Device", "Alias", "Server", "Class"
+ templ = "{0:{l[0]}} {1:{l[1]}} {2:{l[2]}} {3:{l[3]}}"
+ msg = templ.format(*title, l=lengths)
+ print(msg, file=s)
+ print(*map(operator.mul, lengths, len(lengths)*"-"), file=s)
for d, v in data.items():
- if reg_exp and not reg_exp.match(d): continue
- print >>s, l % (d, v[0], v[1], v[2])
+ if reg_exp and not reg_exp.match(d):
+ continue
+ print(templ.format(d, v[0], v[1], v[2], l=lengths), file=s)
s.seek(0)
page(s.read())
@@ -274,11 +310,11 @@ def magic_lsdevclass(self, parameter_s=''):
db = __get_db()
if db is None:
- print "You are not connected to any Tango Database. Device class list is empty"
+ print("You are not connected to any Tango Database. Device class list is empty")
return
data = db._db_cache.klasses
- s = StringIO.StringIO()
+ s = io.BytesIO()
data = [ "%-030s" % klass for klass in data.keys() if not reg_exp or reg_exp.match(klass) ]
s = textwrap.fill(" ".join(data), 80)
page(s)
@@ -299,11 +335,11 @@ def magic_lsserv(self, parameter_s=''):
db = __get_db()
if db is None:
- print "You are not connected to any Tango Database. Device class list is empty"
+ print("You are not connected to any Tango Database. Device class list is empty")
return
data = db._db_cache.servers
- s = StringIO.StringIO()
+ s = io.BytesIO()
data = [ "%-030s" % server for server in data.keys() if not reg_exp or reg_exp.match(server) ]
s = textwrap.fill(" ".join(data), 80)
page(s)
@@ -314,20 +350,19 @@ def magic_tango_error(self, parameter_s=''):
global _TANGO_ERR
err_info = self.user_ns.get(_TANGO_ERR)
if err_info is None:
- print "No tango error reported so far."
+ print("No tango error reported so far.")
return
- print "Last tango error:"
- print err_info[1]
+ print("Last tango error:")
+ print(err_info[1])
def magic_python_error(self, parameter_s=''):
"""Displays detailed information about the last python error"""
-
global _PYTHON_ERR
err_info = self.user_ns.get(_PYTHON_ERR)
if err_info is None:
- print "No error reported so far."
+ print("No error reported so far.")
return
- ip = ipapi.get()
+ ip = get_ipapi()
etype, evalue, etb = err_info[:3]
ip.InteractiveTB(etype=etype, evalue=evalue, etb=etb, tb_offset=None)
@@ -335,15 +370,15 @@ _EVT_LOG = None
def __get_event_log():
global _EVT_LOG
if _EVT_LOG is None:
- qthreads = ipapi.get().options.q4thread
- if qthreads:
- import ipy_qt
- model = ipy_qt.EventLoggerTableModel(capacity=10000)
- _EVT_LOG = ipy_qt.EventLogger(model=model)
- _EVT_LOG.setWindowTitle("ITango - Event Logger Table")
- else:
- import ipy_cli
- _EVT_LOG = ipy_cli.EventLogger(capacity=10000)
+# qthreads = get_config().q4thread
+# if qthreads:
+# import ipy_qt
+# model = ipy_qt.EventLoggerTableModel(capacity=10000)
+# _EVT_LOG = ipy_qt.EventLogger(model=model)
+# _EVT_LOG.setWindowTitle("ITango - Event Logger Table")
+# else:
+ import PyTango.ipython.eventlogger
+ _EVT_LOG = PyTango.ipython.eventlogger.EventLogger(capacity=10000, pager=page)
return _EVT_LOG
def magic_mon(self, parameter_s=''):
@@ -358,12 +393,15 @@ def magic_mon(self, parameter_s=''):
db = __get_db()
if db is None:
- print "You are not connected to any Tango Database."
+ print("You are not connected to any Tango Database.")
return
+
+ # make sure parameter_s is a str and not a unicode
+ parameter_s = str(parameter_s)
opts, args = self.parse_options(parameter_s,'adril', mode='list')
if len(args) > 3:
raise UsageError("%mon: too many arguments")
- if opts.has_key('d'):
+ if 'd' in opts:
try:
todel = args[0]
except IndexError:
@@ -376,11 +414,11 @@ def magic_mon(self, parameter_s=''):
del subscriptions[attr.lower()]
d = __get_device_proxy(dev)
d.unsubscribe_event(id)
- print "Stopped monitoring '%s'" % todel
+ print("Stopped monitoring '%s'" % todel)
except KeyError:
raise UsageError("%%mon -d: Not monitoring '%s'" % todel)
- elif opts.has_key('a'):
+ elif 'a' in opts:
try:
toadd = args[0]
except IndexError:
@@ -395,14 +433,14 @@ def magic_mon(self, parameter_s=''):
model = w.model()
id = d.subscribe_event(attr, PyTango.EventType.CHANGE_EVENT, model, [])
subscriptions[attr.lower()] = id
- print "'%s' is now being monitored. Type 'mon' to see all events" % toadd
- elif opts.has_key('r'):
+ print("'%s' is now being monitored. Type 'mon' to see all events" % toadd)
+ elif 'r' in opts:
for d, v in db._db_cache.devices.items():
d, subs = v[3], v[4]
for id in subs.values():
d.unsubscribe_event(id)
v[4] = {}
- elif opts.has_key('i'):
+ elif 'i' in opts:
try:
evtid = int(args[0])
except IndexError:
@@ -413,12 +451,12 @@ def magic_mon(self, parameter_s=''):
w = __get_event_log()
e = w.getEvents()[evtid]
if e.err:
- print str(PyTango.DevFailed(*e.errors))
+ print(str(PyTango.DevFailed(*e.errors)))
else:
- print str(e)
+ print(str(e))
except IndexError:
raise UsageError("%mon -i: must provide a valid event ID")
- elif opts.has_key('l'):
+ elif 'l' in opts:
try:
dexpr = args[0]
aexpr = args[1]
@@ -447,7 +485,7 @@ def get_device_map():
DeviceProxy to this device, create your own)"""
db = __get_db()
if db is None:
- print "You are not connected to any Tango Database."
+ print("You are not connected to any Tango Database.")
return
return db._db_cache.devices
@@ -456,7 +494,7 @@ def get_server_map():
and value is a sequence of device names that belong to the server"""
db = __get_db()
if db is None:
- print "You are not connected to any Tango Database."
+ print("You are not connected to any Tango Database.")
return
return db._db_cache.servers
@@ -465,7 +503,7 @@ def get_class_map():
sequence of device names that belong to the tango class"""
db = __get_db()
if db is None:
- print "You are not connected to any Tango Database."
+ print("You are not connected to any Tango Database.")
return
return db._db_cache.klasses
@@ -474,7 +512,7 @@ def get_alias_map():
is a the tango device name"""
db = __get_db()
if db is None:
- print "You are not connected to any Tango Database."
+ print("You are not connected to any Tango Database.")
return
return db._db_cache.aliases
@@ -483,7 +521,7 @@ def get_device_list():
database"""
db = __get_db()
if db is None:
- print "You are not connected to any Tango Database."
+ print("You are not connected to any Tango Database.")
return
return db._db_cache.device_list
@@ -492,7 +530,7 @@ def get_alias_list():
database"""
db = __get_db()
if db is None:
- print "You are not connected to any Tango Database."
+ print("You are not connected to any Tango Database.")
return
return db._db_cache.alias_list
@@ -502,20 +540,21 @@ def get_alias_list():
def __exc_handler(ip, etype, value, tb, tb_offset=None):
global _TG_EXCEPTIONS
+ print(etype)
if etype in _TG_EXCEPTIONS:
global _TANGO_ERR
ip.user_ns[_TANGO_ERR] = etype, value, tb, tb_offset
if len(value.args):
v = value[0]
- print "%s: %s" % (v.reason ,v.desc)
+ print("%s: %s" % (v.reason ,v.desc))
else:
- print "Empty DevFailed"
- print "(For more detailed information type: tango_error)"
+ print("Empty DevFailed")
+ print("(For more detailed information type: tango_error)")
else:
global _PYTHON_ERR
ip.user_ns[_PYTHON_ERR] = etype, value, tb, tb_offset
- print etype.__name__ + ": " + str(value)
- print "(For more detailed information type: python_error)"
+ print(etype.__name__ + ": " + str(value))
+ print("(For more detailed information type: python_error)")
def __get_default_tango_host():
global _DFT_TANGO_HOST
@@ -536,7 +575,7 @@ def __get_db(host_port=None):
and return it
"""
- ip = ipapi.get()
+ ip = get_ipapi()
global _DB_SYMB
db = ip.user_ns.get(_DB_SYMB)
@@ -566,17 +605,17 @@ def __get_db(host_port=None):
db = PyTango.Database(*host_port.split(":"))
ip.user_ns["DB_NAME"] = host_port
- except Exception, e:
+ except Exception as e:
if db:
- print "\nCould not access Database %s:" % host_port
- print str(e)
+ print("\nCould not access Database %s:" % host_port)
+ print(str(e))
old_host_port = "%s:%s" % (db.get_db_host(), db.get_db_port())
- print "Maintaining connection to Database", old_host_port
+ print("Maintaining connection to Database", old_host_port)
ip.user_ns["DB_NAME"] = old_host_port
else:
- print "\nCould not access any Database. Make sure:"
- print "\t- .tangorc, /etc/tangorc or TANGO_HOST environment is defined."
- print "\t- the Database DS is running"
+ print("\nCould not access any Database. Make sure:")
+ print("\t- .tangorc, /etc/tangorc or TANGO_HOST environment is defined.")
+ print("\t- the Database DS is running")
ip.user_ns["DB_NAME"] = "OFFLINE"
# register the 'db' in the user namespace
@@ -598,16 +637,16 @@ def __completer_wrapper(f):
def wrapper(ip, evt):
try:
return f(ip, evt)
- except Exception, e:
- print
- print "An unexpected exception ocorred during ITango command completer."
- print "Please send a bug report to the PyTango team with the following information:"
- print 80*"-"
- print "Completer:",__get_obj_name(f)
- print 80*"-"
+ except Exception as e:
+ print()
+ print("An unexpected exception ocorred during ITango command completer.")
+ print("Please send a bug report to the PyTango team with the following information:")
+ print(80*"-")
+ print("Completer:",__get_obj_name(f))
+ print(80*"-")
import traceback
traceback.print_exc()
- print 80*"-"
+ print(80*"-")
raise e
return wrapper
@@ -687,7 +726,8 @@ def init_pytango(ip):
ip.set_custom_exc((Exception,), __exc_handler)
-def init_db(ip, parameter_s=''):
+def init_db(parameter_s=''):
+ ip = get_ipapi()
global _DB_SYMB
old_db = ip.user_ns.get(_DB_SYMB)
@@ -748,7 +788,7 @@ def init_db(ip, parameter_s=''):
for klass, devices in klass_dict.items():
if klass in excluded_klasses:
continue
- exists = ip.user_ns.has_key(klass)
+ exists = klass in ip.user_ns
if not exists or klass in old_junk:
c = DeviceClassCompleter(klass, devices)
ip.set_hook('complete_command', c, re_key = ".*" + klass + "[^\w\.]+")
@@ -818,7 +858,7 @@ def init_magic(ip):
def complete(text):
"""a super complete!!!!"""
- self = ipapi.get().IP
+ self = get_ipapi().IP
complete = self.Completer.complete
state = 0
comps = set()
@@ -953,11 +993,27 @@ def init_display(ip):
html_formatter.for_type(PyTango.DeviceProxy, display_deviceproxy_html)
html_formatter.for_type(PyTango.Database, display_database_html)
+
+from IPython.utils.traitlets import Unicode
+from IPython.frontend.qt.console.rich_ipython_widget import RichIPythonWidget
+
+class ITangoConsole(RichIPythonWidget):
+
+ banner = Unicode(config=True)
+
+ def _banner_default(self):
+ config = get_config()
+ return config.FrontendWidget.banner
+
+import IPython.frontend.qt.console.qtconsoleapp
+IPythonQtConsoleApp = IPython.frontend.qt.console.qtconsoleapp.IPythonQtConsoleApp
+IPythonQtConsoleApp.widget_factory = ITangoConsole
+
def init_ipython(ip=None, store=True, pytango=True, colors=True, console=True,
magic=True):
-
+
if ip is None:
- ip = ipapi.get()
+ ip = get_ipapi()
global _tango_init
if _tango_init is True: return
@@ -967,7 +1023,7 @@ def init_ipython(ip=None, store=True, pytango=True, colors=True, console=True,
if pytango:
init_pytango(ip)
- init_db(ip)
+ init_db()
if magic:
init_magic(ip)
@@ -1000,7 +1056,7 @@ def load_config(config):
# ------------------------------------
i_shell = config.InteractiveShell
i_shell.colors = 'Linux'
- i_shell.prompt_in1 = 'ITango <$DB_NAME> [\\#]: '
+ i_shell.prompt_in1 = 'ITango [\\#]: '
i_shell.prompt_out = 'Result [\\#]: '
# ------------------------------------
@@ -1049,6 +1105,12 @@ object? -> Details about 'object'. ?object also works, ?? prints more.
term_i_shell.banner1 = banner
term_i_shell.banner2 = tango_banner
+ # ------------------------------------
+ # FrontendWidget
+ # ------------------------------------
+ frontend_widget = config.FrontendWidget
+ frontend_widget.banner = banner
+
def load_ipython_extension(ipython):
# The ``ipython`` argument is the currently active
# :class:`InteractiveShell` instance that can be used in any way.
diff --git a/PyTango/ipython/ipython_00_12/__init__.py b/PyTango/ipython/ipython_00_12/__init__.py
index 2766c15..0397776 100644
--- a/PyTango/ipython/ipython_00_12/__init__.py
+++ b/PyTango/ipython/ipython_00_12/__init__.py
@@ -27,5 +27,5 @@ __all__ = ['load_ipython_extension', 'unload_ipython_extension', 'load_config',
from PyTango.ipython.ipython_00_11 import *
#rewrite 0.11's load config
-from ipython_00_12 import load_config
+from .ipython_00_12 import load_config
diff --git a/PyTango/ipython/ipython_00_12/ipython_00_12.py b/PyTango/ipython/ipython_00_12/ipython_00_12.py
index 6321580..e274c40 100644
--- a/PyTango/ipython/ipython_00_12/ipython_00_12.py
+++ b/PyTango/ipython/ipython_00_12/ipython_00_12.py
@@ -28,7 +28,7 @@
__all__ = ["load_config"]
from IPython.utils.ipstruct import Struct
-from IPython.utils.coloransi import TermColors
+from IPython.utils.coloransi import TermColors
def load_config(config):
import PyTango.ipython
@@ -60,7 +60,7 @@ def load_config(config):
# PromptManager
# ------------------------------------
prompt = config.PromptManager
- prompt.in_template = 'ITango {DB_NAME} [\\#]: '
+ prompt.in_template = 'ITango [\\#]: '
#prompt.in2_template =
prompt.out_template = 'Result [\\#]: '
@@ -109,4 +109,10 @@ object? -> Details about 'object'. ?object also works, ?? prints more.
tango_banner = so.tango_banner % d
tango_banner = tango_banner.format(**d)
term_i_shell.banner1 = banner
- term_i_shell.banner2 = tango_banner
\ No newline at end of file
+ term_i_shell.banner2 = tango_banner
+
+ # ------------------------------------
+ # FrontendWidget
+ # ------------------------------------
+ frontend_widget = config.FrontendWidget
+ frontend_widget.banner = banner
diff --git a/PyTango/log4tango.py b/PyTango/log4tango.py
index 26725ad..06a5961 100644
--- a/PyTango/log4tango.py
+++ b/PyTango/log4tango.py
@@ -127,7 +127,7 @@ class LogIt(object):
d = args[0]
if not self.is_enabled(d):
return f(*args, **kwargs)
- in_msg = "-> %s(" % f.func_name
+ in_msg = "-> %s(" % f.__name__
if self._show_args:
in_msg += ", ".join(map(self.__compact, args[1:]))
if self._show_kwargs:
@@ -139,7 +139,7 @@ class LogIt(object):
out_msg = ""
if self._show_ret:
out_msg += self.__compact(ret) + " "
- out_msg += "<- %s()" % f.func_name
+ out_msg += "<- %s()" % f.__name__
self.get_log_func(d)(out_msg)
return ret
return log_stream
diff --git a/PyTango/pytango_init.py b/PyTango/pytango_init.py
index 193880b..eaf6270 100644
--- a/PyTango/pytango_init.py
+++ b/PyTango/pytango_init.py
@@ -29,29 +29,37 @@ __all__ = ['init']
__docformat__ = "restructuredtext"
-import attribute_proxy
-import base_types
-import exception
-import callback
-import api_util
-import encoded_attribute
-import connection
-import db
-import device_attribute
-import device_class
-import device_data
-import device_proxy
-import device_server
-import group
-import group_reply
-import group_reply_list
-import pytango_pprint
-import pyutil
-import time_val
+from .attribute_proxy import attribute_proxy_init
+from .base_types import base_types_init
+from .exception import exception_init
+from .callback import callback_init
+from .api_util import api_util_init
+from .encoded_attribute import encoded_attribute_init
+from .connection import connection_init
+from .db import db_init
+from .device_attribute import device_attribute_init
+from .device_class import device_class_init
+from .device_data import device_data_init
+from .device_proxy import device_proxy_init
+from .device_server import device_server_init
+from .group import group_init
+from .group_reply import group_reply_init
+from .group_reply_list import group_reply_list_init
+from .pytango_pprint import pytango_pprint_init
+from .pyutil import pyutil_init
+from .time_val import time_val_init
+from ._PyTango import constants
__INITIALIZED = False
__DOC = True
+def init_constants():
+
+ tgver = tuple(map(int, constants.TgLibVers.split(".")))
+ tgver_str = "0x%02d%02d%02d00" % (tgver[0], tgver[1], tgver[2])
+ constants.TANGO_VERSION_HEX = int(tgver_str, 16)
+
+
def init():
global __INITIALIZED
if __INITIALIZED:
@@ -59,26 +67,27 @@ def init():
global __DOC
doc = __DOC
- base_types.init(doc=doc)
- exception.init(doc=doc)
- callback.init(doc=doc)
- api_util.init(doc=doc)
- encoded_attribute.init(doc=doc)
- connection.init(doc=doc)
- db.init(doc=doc)
- device_attribute.init(doc=doc)
- device_class.init(doc=doc)
- device_data.init(doc=doc)
- device_proxy.init(doc=doc)
- device_server.init(doc=doc)
- group.init(doc=doc)
- group_reply.init(doc=doc)
- group_reply_list.init(doc=doc)
- pytango_pprint.init(doc=doc)
- pyutil.init(doc=doc)
- time_val.init(doc=doc)
+ init_constants()
+ base_types_init(doc=doc)
+ exception_init(doc=doc)
+ callback_init(doc=doc)
+ api_util_init(doc=doc)
+ encoded_attribute_init(doc=doc)
+ connection_init(doc=doc)
+ db_init(doc=doc)
+ device_attribute_init(doc=doc)
+ device_class_init(doc=doc)
+ device_data_init(doc=doc)
+ device_proxy_init(doc=doc)
+ device_server_init(doc=doc)
+ group_init(doc=doc)
+ group_reply_init(doc=doc)
+ group_reply_list_init(doc=doc)
+ pytango_pprint_init(doc=doc)
+ pyutil_init(doc=doc)
+ time_val_init(doc=doc)
# must come last: depends on device_proxy.init()
- attribute_proxy.init(doc=doc)
+ attribute_proxy_init(doc=doc)
__INITIALIZED = True
diff --git a/PyTango/pytango_pprint.py b/PyTango/pytango_pprint.py
index bcfdc39..416c35a 100644
--- a/PyTango/pytango_pprint.py
+++ b/PyTango/pytango_pprint.py
@@ -25,13 +25,13 @@
This is an internal PyTango module.
"""
-__all__ = []
+__all__ = ["pytango_pprint_init"]
__docformat__ = "restructuredtext"
import operator
-from _PyTango import (StdStringVector, StdLongVector, CommandInfoList,
+from ._PyTango import (StdStringVector, StdLongVector, CommandInfoList,
AttributeInfoList, AttributeInfoListEx,
DeviceDataHistoryList,
GroupReplyList, GroupAttrReplyList, GroupCmdReplyList,
@@ -46,14 +46,15 @@ from _PyTango import (StdStringVector, StdLongVector, CommandInfoList,
DevError, EventData, AttrConfEventData, DataReadyEventData,
TimeVal, DevFailed, CmdArgType)
-from device_server import AttributeAlarm, EventProperties
-from device_server import ChangeEventProp, PeriodicEventProp, ArchiveEventProp
-from device_server import AttributeConfig, AttributeConfig_2, AttributeConfig_3
+from .device_server import AttributeAlarm, EventProperties
+from .device_server import ChangeEventProp, PeriodicEventProp, ArchiveEventProp
+from .device_server import AttributeConfig, AttributeConfig_2, AttributeConfig_3
+import collections
def __inc_param(obj, name):
ret = not name.startswith('_')
ret &= not name in ('except_flags',)
- ret &= not callable(getattr(obj,name))
+ ret &= not isinstance(getattr(obj,name), collections.Callable)
return ret
def __single_param(obj, param_name, f=repr, fmt='%s = %s'):
@@ -107,7 +108,7 @@ def __registerSeqStr():
seq.__repr__ = _SeqRepr
def __str__DevFailed(self):
- if operator.isSequenceType(self.args):
+ if isinstance(self.args, collections.Sequence):
return 'DevFailed[\n%s]' % '\n'.join(map(str,self.args))
return 'DevFailed[%s]' % (self.args)
@@ -152,6 +153,6 @@ def __registerStructStr():
DevError.__str__ = __str__DevError
-def init(doc=True):
+def pytango_pprint_init(doc=True):
__registerSeqStr()
__registerStructStr()
diff --git a/PyTango/pyutil.py b/PyTango/pyutil.py
index 8ead49f..6f71e24 100644
--- a/PyTango/pyutil.py
+++ b/PyTango/pyutil.py
@@ -25,19 +25,19 @@
This is an internal PyTango module.
"""
-__all__ = [ "Util" ]
+__all__ = [ "Util", "pyutil_init" ]
__docformat__ = "restructuredtext"
import os
import copy
-from _PyTango import _Util, Except, DevFailed, DbDevInfo
-from utils import document_method as __document_method
+from ._PyTango import _Util, Except, DevFailed, DbDevInfo
+from .utils import document_method as __document_method
#from utils import document_static_method as __document_static_method
-from globals import class_list
-from globals import cpp_class_list
-from globals import get_constructed_classes
+from .globals import class_list, cpp_class_list, get_constructed_classes
+import collections
+
def __simplify_device_name(dev_name):
if dev_name.startswith("tango://"):
@@ -91,7 +91,7 @@ def __Util__create_device(self, klass_name, device_name, alias=None, cb=None):
device name (str). Default value is None meaning no callback
Return : None"""
- if cb is not None and not callable(cb):
+ if cb is not None and not isinstance(cb, collections.Callable):
Except.throw_exception("PyAPI_InvalidParameter",
"The optional cb parameter must be a python callable",
"Util.create_device")
@@ -103,7 +103,7 @@ def __Util__create_device(self, klass_name, device_name, alias=None, cb=None):
device_exists = True
try:
db.import_device(device_name)
- except DevFailed, df:
+ except DevFailed as df:
device_exists = not df[0].reason == "DB_DeviceNotDefined"
# 1 - Make sure device name doesn't exist already in the database
@@ -177,7 +177,7 @@ def __Util__delete_device(self, klass_name, device_name):
device_exists = True
try:
db.import_device(device_name)
- except DevFailed, df:
+ except DevFailed as df:
device_exists = not df[0].reason == "DB_DeviceNotDefined"
# 1 - Make sure device name exists in the database
@@ -220,7 +220,7 @@ class Util(_Util):
class and its constructor is not public. Example::
util = PyTango.Util.instance()
- print util.get_host_name()"""
+ print(util.get_host_name())"""
def __init__(self, args):
args = copy.copy(args)
@@ -294,7 +294,7 @@ def __doc_Util():
#
# Static method that gets the singleton object reference.
# If the class has not been initialised with it's init method,
-# this method print a message and abort the device server process
+# this method prints a message and aborts the device server process
#
# Parameters :
# - exit : (bool)
@@ -558,7 +558,42 @@ def __doc_Util():
Parameters : None
Return : (int) the maximun number of threads in the polling threads pool
""" )
-
+
+ document_method("is_svr_starting", """
+ is_svr_starting(self) -> bool
+
+ Check if the device server process is in its starting phase
+
+ Parameters : None
+ Return : (bool) True if the server is in its starting phase
+
+ New in PyTango 8.0.0
+ """ )
+
+ document_method("is_svr_shutting_down", """
+ is_svr_shutting_down(self) -> bool
+
+ Check if the device server process is in its shutting down sequence
+
+ Parameters : None
+ Return : (bool) True if the server is in its shutting down phase.
+
+ New in PyTango 8.0.0
+ """ )
+
+ document_method("is_device_restarting", """
+ is_device_restarting(self, (str)dev_name) -> bool
+
+ Check if the device is actually restarted by the device server
+ process admin device with its DevRestart command
+
+ Parameters :
+ dev_name : (str) device name
+ Return : (bool) True if the device is restarting.
+
+ New in PyTango 8.0.0
+ """ )
+
document_method("get_sub_dev_diag", """
get_sub_dev_diag(self) -> SubDevDiag
@@ -666,7 +701,7 @@ def __doc_Util():
# Return : None
# """ )
-def init(doc=True):
+def pyutil_init(doc=True):
__init_Util()
if doc:
__doc_Util()
diff --git a/PyTango/tango_numpy.py b/PyTango/tango_numpy.py
index bb3edaf..98649bd 100644
--- a/PyTango/tango_numpy.py
+++ b/PyTango/tango_numpy.py
@@ -29,25 +29,27 @@ __all__ = [ "NumpyType", "numpy_type", "numpy_spectrum", "numpy_image" ]
__docformat__ = "restructuredtext"
-import _PyTango
+from ._PyTango import Except
+from ._PyTango import constants
+
+from .attribute_proxy import AttributeProxy
+import collections
def _numpy_invalid(*args, **kwds):
- _PyTango.Except.throw_exception(
+ Except.throw_exception(
"PyTango_InvalidConversion",
"There's no registered conversor to numpy.",
"NumpyType.tango_to_numpy"
)
def _define_numpy():
- if not _PyTango.constants.NUMPY_SUPPORT:
+ if not constants.NUMPY_SUPPORT:
return None, _numpy_invalid, _numpy_invalid, _numpy_invalid
try:
import numpy
import operator
- from attribute_proxy import AttributeProxy
-
ArgType = _PyTango.CmdArgType
AttributeInfo = _PyTango.AttributeInfo
Attribute = _PyTango.Attribute
@@ -115,7 +117,7 @@ def _define_numpy():
- sequence:
"""
np_type = NumpyType.tango_to_numpy(tg_type)
- if operator.isSequenceType(dim_x):
+ if isinstance(dim_x, collections.Sequence):
return numpy.array(dim_x, dtype=np_type)
else:
return numpy.ndarray(shape=(dim_x,), dtype=np_type)
diff --git a/PyTango/time_val.py b/PyTango/time_val.py
index c3d7fae..c0edd3a 100644
--- a/PyTango/time_val.py
+++ b/PyTango/time_val.py
@@ -25,7 +25,7 @@
This is an internal PyTango module.
"""
-__all__ = []
+__all__ = ["time_val_init"]
__docformat__ = "restructuredtext"
@@ -33,7 +33,8 @@ import time
import datetime
import operator
-from _PyTango import TimeVal
+from ._PyTango import TimeVal
+import numbers
def __TimeVal__init(self, a=None, b=None, c=None):
TimeVal.__init_original(self)
@@ -44,7 +45,7 @@ def __TimeVal__init(self, a=None, b=None, c=None):
assert(b is None and c is None)
a = time.mktime(a.timetuple()) + a.microsecond*1E-6
- elif operator.isNumberType(a):
+ elif isinstance(a, numbers.Number):
if b is None:
self.tv_sec = int(a)
usec = (a - self.tv_sec) * 1E6
@@ -192,6 +193,6 @@ def __init_TimeVal():
TimeVal.isoformat = __TimeVal__isoformat
TimeVal.__str__ = __TimeVal__str__
-def init(doc=True):
+def time_val_init(doc=True):
__init_TimeVal()
diff --git a/PyTango/utils.py b/PyTango/utils.py
index 96be935..f429068 100644
--- a/PyTango/utils.py
+++ b/PyTango/utils.py
@@ -25,77 +25,27 @@
This is an internal PyTango module.
"""
-__all__ = [ "is_scalar_type", "is_array_type", "is_numerical_type",
+from __future__ import with_statement
+from __future__ import print_function
+
+__all__ = [ "is_pure_str", "is_non_str_seq", "is_integer", "is_number",
+ "is_scalar_type", "is_array_type", "is_numerical_type",
"is_int_type", "is_float_type", "obj_2_str", "seqStr_2_obj",
"document_method", "document_static_method", "document_enum",
"CaselessList", "CaselessDict", "EventCallBack", "get_home",
- "from_version_str_to_hex_str", "from_version_str_to_int",
- "wraps", "update_wrapper"]
+ "from_version_str_to_hex_str", "from_version_str_to_int", ]
__docformat__ = "restructuredtext"
import sys
import os
-import socket
-import types
-import operator
-
-try:
- from functools import wraps, update_wrapper
-except ImportError:
- # -------------------
- # Python 2.4 fallback
- # -------------------
- def curry(_curried_func, *args, **kwargs):
- def _curried(*moreargs, **morekwargs):
- return _curried_func(*(args+moreargs), **dict(kwargs, **morekwargs))
- return _curried
-
- WRAPPER_ASSIGNMENTS = ('__module__', '__name__', '__doc__')
- WRAPPER_UPDATES = ('__dict__',)
- def update_wrapper(wrapper,
- wrapped,
- assigned = WRAPPER_ASSIGNMENTS,
- updated = WRAPPER_UPDATES):
- """Update a wrapper function to look like the wrapped function
-
- wrapper is the function to be updated
- wrapped is the original function
- assigned is a tuple naming the attributes assigned directly
- from the wrapped function to the wrapper function (defaults to
- functools.WRAPPER_ASSIGNMENTS)
- updated is a tuple naming the attributes off the wrapper that
- are updated with the corresponding attribute from the wrapped
- function (defaults to functools.WRAPPER_UPDATES)
- """
- for attr in assigned:
- try:
- setattr(wrapper, attr, getattr(wrapped, attr))
- except TypeError: # Python 2.3 doesn't allow assigning to __name__.
- pass
- for attr in updated:
- getattr(wrapper, attr).update(getattr(wrapped, attr))
- # Return the wrapper so this can be used as a decorator via curry()
- return wrapper
-
- def wraps(wrapped,
- assigned = WRAPPER_ASSIGNMENTS,
- updated = WRAPPER_UPDATES):
- """Decorator factory to apply update_wrapper() to a wrapper function
-
- Returns a decorator that invokes update_wrapper() with the decorated
- function as the wrapper argument and the arguments to wraps() as the
- remaining arguments. Default arguments are as for update_wrapper().
- This is a convenience function to simplify applying curry() to
- update_wrapper().
- """
- return curry(update_wrapper, wrapped=wrapped,
- assigned=assigned, updated=updated)
+import collections
+import numbers
-
-from _PyTango import StdStringVector, StdDoubleVector
-from _PyTango import DbData, DbDevInfos, DbDevExportInfos, CmdArgType, AttrDataFormat
-from _PyTango import EventData, AttrConfEventData, DataReadyEventData
+from ._PyTango import StdStringVector, StdDoubleVector, \
+ DbData, DbDevInfos, DbDevExportInfos, CmdArgType, AttrDataFormat, \
+ EventData, AttrConfEventData, DataReadyEventData
+from ._PyTango import constants
_scalar_int_types = (CmdArgType.DevShort, CmdArgType.DevUShort,
CmdArgType.DevInt, CmdArgType.DevLong, CmdArgType.DevULong,
@@ -140,6 +90,47 @@ _scalar_to_array_type = {
CmdArgType.ConstDevString : CmdArgType.DevVarStringArray,
}
+__str_klasses = str,
+__int_klasses = int,
+__number_klasses = numbers.Number,
+
+__use_unicode = False
+try:
+ unicode
+ __use_unicode = True
+ __str_klasses = tuple(list(__str_klasses) + [unicode])
+except:
+ pass
+
+__use_long = False
+try:
+ long
+ __use_long = True
+ __int_klasses = tuple(list(__int_klasses) + [long])
+except:
+ pass
+
+if constants.NUMPY_SUPPORT:
+ import numpy
+ __int_klasses = tuple(list(__int_klasses) + [numpy.integer])
+ __number_klasses = tuple(list(__number_klasses) + [numpy.number])
+
+__str_klasses = tuple(__str_klasses)
+__int_klasses = tuple(__int_klasses)
+__number_klasses = tuple(__number_klasses)
+
+def is_pure_str(obj):
+ return isinstance(obj , __str_klasses)
+
+def is_non_str_seq(obj):
+ return isinstance(obj, collections.Sequence) and not is_pure_str(obj)
+
+def is_integer(obj):
+ return isinstance(obj, __int_klasses)
+
+def is_number(obj):
+ return isinstance(obj, __number_klasses)
+
def is_scalar(tg_type):
"""Tells if the given tango type is a scalar
@@ -385,8 +376,8 @@ def seqStr_2_obj(seq, tg_type, tg_format=None):
def _seqStr_2_obj_from_type(seq, tg_type):
- if type(seq) in types.StringTypes:
- seq = (seq,)
+ if is_pure_str(seq):
+ seq = seq,
# Scalar cases
global _scalar_int_types
@@ -475,7 +466,7 @@ def obj_2_str(obj, tg_type):
ret = ""
if tg_type in _scalar_types:
# scalar cases
- if operator.isSequenceType(obj):
+ if isinstance(obj, collections.Sequence):
if not len(obj):
return ret
obj = obj[0]
@@ -485,25 +476,39 @@ def obj_2_str(obj, tg_type):
ret = '\n'.join([ str(i) for i in obj ])
return ret
+def __get_meth_func(klass, method_name):
+ meth = getattr(klass, method_name)
+ func = meth
+ if hasattr(meth, '__func__'):
+ func = meth.__func__
+ elif hasattr(meth, 'im_func'):
+ func = meth.im_func
+ return meth, func
+
def copy_doc(klass, fnname):
- """Copies documentation string of a method from the super class into the rewritten method of the given class"""
- getattr(klass, fnname).im_func.__doc__ = getattr(klass.__base__, fnname).im_func.__doc__
+ """Copies documentation string of a method from the super class into the
+ rewritten method of the given class"""
+ base_meth, base_func = __get_meth_func(klass.__base__, fnname)
+ meth, func = __get_meth_func(klass, fnname)
+ func.__doc__ = base_func.__doc__
def document_method(klass, method_name, d, add=True):
+ meth, func = __get_meth_func(klass, method_name)
if add:
- cpp_doc = getattr(klass, method_name).__doc__
+ cpp_doc = meth.__doc__
if cpp_doc:
- getattr(klass, method_name).im_func.__doc__ = "%s\n%s" % (d, cpp_doc)
+ func.__doc__ = "%s\n%s" % (d, cpp_doc)
return
- getattr(klass, method_name).im_func.__doc__ = d
+ func.__doc__ = d
def document_static_method(klass, method_name, d, add=True):
+ meth, func = __get_meth_func(klass, method_name)
if add:
- cpp_doc = getattr(klass, method_name).__doc__
+ cpp_doc = meth.__doc__
if cpp_doc:
- getattr(klass, method_name).__doc__ = "%s\n%s" % (d, cpp_doc)
+ meth.__doc__ = "%s\n%s" % (d, cpp_doc)
return
- getattr(klass, method_name).__doc__ = d
+ meth.__doc__ = d
def document_enum(klass, enum_name, desc, append=True):
# derived = type(base)('derived', (base,), {'__doc__': 'desc'})
@@ -764,13 +769,9 @@ __NOTIFD_FACTORY_PREFIX = "notifd/factory/"
def notifd2db(notifd_ior_file=__DEFAULT_FACT_IOR_FILE, files=None, host=None, out=sys.stdout):
ior_string = ""
- ior_file = None
- try:
- ior_file = file(notifd_ior_file)
+ with file(notifd_ior_file) as ior_file:
ior_string = ior_file.read()
- finally:
- if ior_file is not None:
- ior_file.close()
+
if files is None:
return _notifd2db_real_db(ior_string, host=host, out=out)
else:
@@ -779,17 +780,17 @@ def notifd2db(notifd_ior_file=__DEFAULT_FACT_IOR_FILE, files=None, host=None, ou
def _notifd2db_file_db(ior_string, files, out=sys.stdout):
raise RuntimeError("Not implemented yet")
- #print >>out, "going to export notification service event factory to " \
- # "device server property file(s) ..."
- #for f in files:
- # with file(f, "w"):
- # pass
- #return
+ print("going to export notification service event factory to " \
+ "device server property file(s) ...", file=out)
+ for f in files:
+ with file(f, "w"):
+ pass
+ return
def _notifd2db_real_db(ior_string, host=None, out=sys.stdout):
import PyTango
- print >>out, "going to export notification service event factory to " \
- "Tango database ..."
+ print("going to export notification service event factory to " \
+ "Tango database ...", file=out)
num_retries = 3
while num_retries > 0:
@@ -797,15 +798,16 @@ def _notifd2db_real_db(ior_string, host=None, out=sys.stdout):
db = PyTango.Database()
db.set_timeout_millis(10000)
num_retries = 0
- except PyTango.DevFailed, df:
+ except PyTango.DevFailed as df:
num_retries -= 1
if num_retries == 0:
- print >>out, "Can't create Tango database object"
- print >>out, str(df)
+ print("Can't create Tango database object", file=out)
+ print(str(df), file=out)
return
- print >>out, "Can't create Tango database object, retrying...."
+ print("Can't create Tango database object, retrying....", file=out)
if host is None:
+ import socket
host_name = socket.getfqdn()
global __NOTIFD_FACTORY_PREFIX
@@ -817,10 +819,10 @@ def _notifd2db_real_db(ior_string, host=None, out=sys.stdout):
while num_retries > 0:
try:
db.command_inout("DbExportEvent", args)
- print >>out, "Successfully exported notification service event " \
- "factory for host", host_name, "to Tango database !"
+ print("Successfully exported notification service event " \
+ "factory for host", host_name, "to Tango database !", file=out)
break
- except PyTango.CommunicationFailed, cf:
+ except PyTango.CommunicationFailed as cf:
if len(cf.errors) >= 2:
if cf.errors[1].reason == "API_DeviceTimedOut":
if num_retries > 0:
@@ -833,8 +835,8 @@ def _notifd2db_real_db(ior_string, host=None, out=sys.stdout):
num_retries = 0
if num_retries == 0:
- print >>out, "Failed to export notification service event factory " \
- "to TANGO database"
+ print("Failed to export notification service event factory " \
+ "to TANGO database", file=out)
class EventCallBack(object):
@@ -880,9 +882,9 @@ class EventCallBack(object):
"""Internal usage only"""
try:
self._push_event(evt)
- except Exception, e:
- print >>self._fd, "Unexpected error in callback for %s: %s" \
- % (str(evt), str(e))
+ except Exception as e:
+ print("Unexpected error in callback for %s: %s" \
+ % (str(evt), str(e)), file=self._fd)
def _push_event(self, evt):
"""Internal usage only"""
@@ -911,12 +913,12 @@ class EventCallBack(object):
attr_name = "<UNKNOWN>"
try:
value = self._get_value(evt)
- except Exception, e:
+ except Exception as e:
value = "Unexpected exception in getting event value: %s" % str(e)
d = { "date" : date, "reception_date" : reception_date,
"type" : evt_type, "dev_name" : dev_name, "name" : attr_name,
"value" : value }
- print >>self._fd, self._msg.format(**d)
+ print(self._msg.format(**d), file=self._fd)
def _append(self, evt):
"""Internal usage only"""
diff --git a/PyTango3/__init__.py b/PyTango3/__init__.py
deleted file mode 100644
index be52507..0000000
--- a/PyTango3/__init__.py
+++ /dev/null
@@ -1,24 +0,0 @@
-################################################################################
-##
-## This file is part of Taurus, a Tango User Interface Library
-##
-## 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/>.
-##
-################################################################################
-
-from tango3 import *
diff --git a/PyTango3/tango3.py b/PyTango3/tango3.py
deleted file mode 100644
index 37db285..0000000
--- a/PyTango3/tango3.py
+++ /dev/null
@@ -1,156 +0,0 @@
-################################################################################
-##
-## This file is part of Taurus, a Tango User Interface Library
-##
-## 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/>.
-##
-################################################################################
-
-from PyTango import *
-
-import PyTango
-PyTango.EventType.CHANGE = PyTango.EventType.CHANGE_EVENT
-PyTango.EventType.QUALITY = PyTango.EventType.QUALITY_EVENT
-PyTango.EventType.PERIODIC = PyTango.EventType.PERIODIC_EVENT
-PyTango.EventType.ARCHIVE = PyTango.EventType.ARCHIVE_EVENT
-PyTango.EventType.USER = PyTango.EventType.USER_EVENT
-PyTango.EventType.DATA_READY = PyTango.EventType.DATA_READY_EVENT
-PyTango.EventType.ATTR_CONF = PyTango.EventType.ATTR_CONF_EVENT
-
-PyUtil = PyTango.Util
-PyDeviceClass = PyTango.DeviceClass
-
-set_attribute_value = PyTango.Attribute.set_value
-set_attribute_value_date_quality = PyTango.Attribute.set_value_date_quality
-
-class AttributeValue(PyTango.DeviceAttribute):
- pass
-
-__original_DeviceProxy = PyTango.DeviceProxy
-
-class DeviceProxy3(__original_DeviceProxy):
- defaultCommandExtractAs = ExtractAs.PyTango3
-
- def __init__(self, *args, **kwds):
- self.__init_state_status()
- super(DeviceProxy3, self).__init__(*args, **kwds)
-
- def __init_state_status(self):
- if hasattr(self, "State"):
- if callable(getattr(self, "State")):
- self.dev_state = self.State
- if hasattr(self, "Status"):
- if callable(getattr(self, "Status")):
- self.dev_status = self.Status
-
- def write_attribute(self, attr_name, value=None):
- if isinstance(attr_name, PyTango.DeviceAttribute):
- if value is not None:
- raise AttributeError('Using DeviceAttribute as attribute, only one parameter is expected.')
- da = attr_name
- attr_name = da.name
- value = da.value
- return super(DeviceProxy3, self).write_attribute(attr_name, value)
-
- def read_attribute(self, attr_name, extract_as=DeviceAttribute.ExtractAs.PyTango3):
- return super(DeviceProxy3, self).read_attribute(attr_name, extract_as)
-
- def read_attribute_as_str(self, attr_name):
- """
- read_attribute_as_str( (DeviceProxy)self, (str)attr_name ) -> DeviceAttribute :
- Read a single attribute.
- Parameters :
- - attr_name : A string, the name of the attribute to read.
- Return : a PyTango.DeviceAttribute. It's "value" field will contain
- a string representing the raw data sent by Tango.
-
- Throws : ConnectionFailed, CommunicationFailed, DevFailed from Device
- """
- return super(DeviceProxy3, self).read_attribute(attr_name, DeviceAttribute.ExtractAs.String)
-
-
- def read_attributes(self, attr_names, extract_as=DeviceAttribute.ExtractAs.PyTango3):
- return super(DeviceProxy3, self).read_attributes(attr_names, extract_as)
-
- def read_attributes_as_str(self, attr_names):
- """
- read_attributes( (DeviceProxy)self, (object)attr_names, (ExtractAs)extract_as) -> object :
- Read the list of specified attributes.
- Parameters :
- - attr_names : A list of attributes to read. It should
- be a StdStringVector or a sequence of str.
- Return : a list of PyTango.DeviceAttribute. The "value" field
- is just a string representing the raw data.
-
- Throws : ConnectionFailed, CommunicationFailed, DevFailed from device
- """
- return super(DeviceProxy3, self).read_attribute(attr_names, DeviceAttribute.ExtractAs.String)
-
-
-
- def write_read_attribute(self, attr_name, value, extract_as=DeviceAttribute.ExtractAs.PyTango3):
- return super(DeviceProxy3, self).write_read_attribute(attr_name, extract_as)
-
- def write_read_attribute_as_str(self, args):
- """
- write_read_attribute( (DeviceProxy)self, (str)attr_name, (object)values, (ExtractAs)xs) -> object :
- Write then read a single attribute in a single network call. By
- default (serialisation by device), the execution of this call in
- the server can't be interrupted by other clients.
- Parameters : see write_attribute(attr_name, value)
- Return : A PyTango.DeviceAttribute object. See read_attribute_as_str()
-
- Throws : ConnectionFailed, CommunicationFailed, DeviceUnlocked, DevFailed from device, WrongData
- New in PyTango 7.0.0
- """
- return super(DeviceProxy3, self).write_read_attribute(attr_name, DeviceAttribute.ExtractAs.String)
-
-
- def read_attributes_reply(self, idx, timeout=None, extract_as=DeviceAttribute.ExtractAs.PyTango3):
- if timeout is None:
- return super(DeviceProxy3, self).read_attributes_reply(idx, extract_as=extract_as)
- else:
- return super(DeviceProxy3, self).read_attributes_reply(idx, timeout, extract_as)
-
- def read_attribute_reply(self, idx, timeout=None, extract_as=DeviceAttribute.ExtractAs.PyTango3):
- return self.read_attributes_reply(idx, timeout, extract_as)[0]
-
- def read_attributes_reply_as_str(self, idx, timeout=None):
- """
- See read_attributes_reply().
- The result is given as in read_attributes_as_str().
- New in PyTango 7.0.0
- """
- return self.read_attributes_reply(idx, timeout, extract_as=DeviceAttribute.ExtractAs.String)
-
- def read_attribute_reply_as_str(self, idx, timeout=None):
- """
- New in PyTango 7.0.0
- """
- return self.read_attributes_reply_as_str(idx, timeout)[0]
-
-
-def __copy_doc(fnname):
- getattr(DeviceProxy3, fnname).im_func.__doc__ = getattr(DeviceProxy3.__base__, fnname).im_func.__doc__
-
-__copy_doc('read_attribute')
-__copy_doc('read_attributes')
-__copy_doc('read_attribute_reply')
-__copy_doc('read_attributes_reply')
-
-DeviceProxy = DeviceProxy3
diff --git a/doc/conf.py b/doc/conf.py
index 69f2a65..6946518 100644
--- a/doc/conf.py
+++ b/doc/conf.py
@@ -33,7 +33,8 @@
# All configuration values have a default; values that are commented out
# serve to show the default.
-import sys, os
+import sys
+import os
import re
import PyTango
@@ -49,11 +50,15 @@ sys.path.append(os.path.abspath('sphinxext'))
extensions = ['sphinx.ext.pngmath',
'sphinx.ext.autodoc',
'sphinx.ext.doctest',
- 'sphinx.ext.graphviz',
'sphinx.ext.intersphinx',
'ipython_console_highlighting',
'tango_console_highlighting']
+# disable until graphviz works in pyhon 3
+if sys.hexversion < 0x03000000:
+ extensions.append('sphinx.ext.graphviz')
+
+
# Add any paths that contain templates here, relative to this directory.
templates_path = ['_templates']
@@ -139,10 +144,10 @@ html_theme = 'default'
# The name for this set of Sphinx documents. If None, it defaults to
# "<project> v<release> documentation".
-#html_title = None
+#html_title = "PyTango documentation"
# A shorter title for the navigation bar. Default is the same as html_title.
-#html_short_title = None
+#html_short_title = "PyTango"
# The name of an image file (relative to this directory) to place at the top
# of the sidebar.
diff --git a/doc/index.rst b/doc/index.rst
index 820bb56..a20343a 100644
--- a/doc/index.rst
+++ b/doc/index.rst
@@ -14,10 +14,10 @@ PyTango is a python module that exposes to Python_ the complete Tango_ C++ API
This means that you can write not only tango applications (scripts, CLIs, GUIs)
that access tango device servers but also tango device servers themselves, all
-of this in pure Python_.
+of this in pure python.
-.. figure:: itango/itango05.png
- :width: 700
+.. figure:: _static/banner.png
+ :width: 80%
:align: center
:alt: ITango
@@ -26,7 +26,19 @@ build and/or install PyTango and after that the :ref:`quick tour <quick-tour>`
can help you with the first steps in the PyTango world.
If you need help understanding what Tango itself really is, you can check the
-Tango_ homepage where you will find plenty of documentation, faq and tutorials.
+Tango_ homepage where you will find plenty of documentation, FAQ and tutorials.
+
+.. only:: html
+
+ For convenience here are the links to other versions:
+
+ .. hlist::
+ :columns: 4
+
+ - `Latest development <http://www.tango-controls.org/static/PyTango/development/doc/html>`_
+ - `Latest stable <http://www.tango-controls.org/static/PyTango/latest/doc/html>`_
+ - `7.2.3 <http://www.tango-controls.org/static/PyTango/v723/doc/html/index.html>`_
+ - `7.1.6 <http://www.tango-controls.org/static/PyTango/v716/doc/html/index.html>`_
.. toctree::
:hidden:
@@ -38,4 +50,4 @@ Tango_ homepage where you will find plenty of documentation, faq and tutorials.
.. _Python: http://www.python.org/
.. _IPython: http://ipython.scipy.org/
-.. _Tango: http://www.tango-controls.org/
\ No newline at end of file
+.. _Tango: http://www.tango-controls.org/
diff --git a/doc/itango/highlights.rst b/doc/itango/highlights.rst
index d8d4f0c..bb416c7 100644
--- a/doc/itango/highlights.rst
+++ b/doc/itango/highlights.rst
@@ -16,28 +16,28 @@ These include:
.. sourcecode:: itango
- ITango <homer:10000> [1]: PyTango
- Result [1]: <module 'PyTango' from ...>
+ ITango [1]: PyTango
+ Result [1]: <module 'PyTango' from ...>
- The :class:`DeviceProxy` (=Device), :class:`AttributeProxy` (=Attribute),
:class:`Database` and :class:`Group` classes
.. sourcecode:: itango
- ITango <homer:10000> [1]: De<tab>
+ ITango [1]: De<tab>
DeprecationWarning Device DeviceProxy
- ITango <homer:10000> [2]: Device
- Result [2]: <class 'PyTango._PyTango.DeviceProxy'>
+ ITango [2]: Device
+ Result [2]: <class 'PyTango._PyTango.DeviceProxy'>
- ITango <homer:10000> [3]: Device("sys/tg_test/1")
- Result [3]: DeviceProxy(sys/tg_test/1)
+ ITango [3]: Device("sys/tg_test/1")
+ Result [3]: DeviceProxy(sys/tg_test/1)
- ITango <homer:10000> [4]: Datab<tab>
+ ITango [4]: Datab<tab>
- ITango <homer:10000> [4]: Database
+ ITango [4]: Database
- ITango <homer:10000> [4]: Att<tab>
+ ITango [4]: Att<tab>
Attribute AttributeError AttributeProxy
- The tango :class:`PyTango.Database` object to which the itango session is
@@ -45,8 +45,8 @@ These include:
.. sourcecode:: itango
- ITango <homer:10000> [1]: db
- Result [1]: Database(homer, 10000)
+ ITango [1]: db
+ Result [1]: Database(homer, 10000)
Device name completion
----------------------
@@ -57,13 +57,13 @@ tango database. This means that when you try to create a new Device, by pressing
.. sourcecode:: itango
- ITango <homer:10000> [1]: test = Device("<tab>
+ ITango [1]: test = Device("<tab>
Display all 3654 possibilities? (y or n) n
- ITango <homer:10000> [1]: test = Device("sys<tab>
+ ITango [1]: test = Device("sys<tab>
sys/access_control/1 sys/database/2 sys/tautest/1 sys/tg_test/1
- ITango <homer:10000> [2]: test = Device("sys/tg_test/1")
+ ITango [2]: test = Device("sys/tg_test/1")
Attribute name completion
-------------------------
@@ -73,10 +73,10 @@ where the attribute resides is running.
.. sourcecode:: itango
- ITango <homer:10000> [1]: short_scalar = Attribute("sys<tab>
+ ITango [1]: short_scalar = Attribute("sys<tab>
sys/access_control/1/ sys/database/2/ sys/tautest/1/ sys/tg_test/1/
- ITango <homer:10000> [1]: short_scalar = Attribute("sys/tg_test/1/<tab>
+ ITango [1]: short_scalar = Attribute("sys/tg_test/1/<tab>
sys/tg_test/1/State sys/tg_test/1/no_value
sys/tg_test/1/Status sys/tg_test/1/short_image
sys/tg_test/1/ampli sys/tg_test/1/short_image_ro
@@ -90,9 +90,9 @@ where the attribute resides is running.
sys/tg_test/1/double_scalar sys/tg_test/1/string_image_ro
...
- ITango <homer:10000> [1]: short_scalar = Attribute("sys/tg_test/1/short_scalar")
+ ITango [1]: short_scalar = Attribute("sys/tg_test/1/short_scalar")
- ITango <homer:10000> [29]: print test.read()
+ ITango [29]: print test.read()
DeviceAttribute[
data_format = PyTango._PyTango.AttrDataFormat.SCALAR
dim_x = 1
@@ -121,9 +121,9 @@ and attributes if the device is currently running)
.. sourcecode:: itango
- ITango <homer:10000> [1]: test = Device("sys/tg_test/1")
+ ITango [1]: test = Device("sys/tg_test/1")
- ITango <homer:10000> [2]: test.<tab>
+ ITango [2]: test.<tab>
Display all 240 possibilities? (y or n)
...
test.DevVoid test.get_access_control
@@ -133,14 +133,14 @@ and attributes if the device is currently running)
test.SwitchStates test.get_attribute_list
...
- ITango <homer:10000> [2]: test.short_<tab>
+ ITango [2]: test.short_<tab>
test.short_image test.short_scalar test.short_scalar_rww test.short_spectrum
test.short_image_ro test.short_scalar_ro test.short_scalar_w test.short_spectrum_ro
- ITango <homer:10000> [2]: test.short_scalar # old style: test.read_attribute("short_scalar").value
- Result [2]: 252
+ ITango [2]: test.short_scalar # old style: test.read_attribute("short_scalar").value
+ Result [2]: 252
- ITango <homer:10000> [3]: test.Dev<tab>
+ ITango [3]: test.Dev<tab>
test.DevBoolean test.DevUShort test.DevVarShortArray
test.DevDouble test.DevVarCharArray test.DevVarStringArray
test.DevFloat test.DevVarDoubleArray test.DevVarULongArray
@@ -149,8 +149,8 @@ and attributes if the device is currently running)
test.DevString test.DevVarLongArray
test.DevULong test.DevVarLongStringArray
- ITango <homer:10000> [3]: test.DevDouble(56.433) # old style: test.command_inout("DevDouble").
- Result [3]: 56.433
+ ITango [3]: test.DevDouble(56.433) # old style: test.command_inout("DevDouble").
+ Result [3]: 56.433
Tango classes as :class:`DeviceProxy`
---------------------------------------------
@@ -161,7 +161,7 @@ This way, if you want to create a device of class which you already know
.. sourcecode:: itango
- ITango <homer:10000> [1]: lib01 = Libera("BO01/DI/BPM-01")
+ ITango [1]: lib01 = Libera("BO01/DI/BPM-01")
One great advantage is that the tango device name completion is sensitive to the
type of device you want to create. This means that if you are in the middle of
@@ -170,7 +170,7 @@ class 'Libera' will show up as possible completions.
.. sourcecode:: itango
- ITango <homer:10000> [1]: bpm1 = Libera("<tab>
+ ITango [1]: bpm1 = Libera("<tab>
BO01/DI/BPM-01 BO01/DI/BPM-09 BO02/DI/BPM-06 BO03/DI/BPM-03 BO03/DI/BPM-11 BO04/DI/BPM-08
BO01/DI/BPM-02 BO01/DI/BPM-10 BO02/DI/BPM-07 BO03/DI/BPM-04 BO04/DI/BPM-01 BO04/DI/BPM-09
BO01/DI/BPM-03 BO01/DI/BPM-11 BO02/DI/BPM-08 BO03/DI/BPM-05 BO04/DI/BPM-02 BO04/DI/BPM-10
@@ -180,11 +180,11 @@ class 'Libera' will show up as possible completions.
BO01/DI/BPM-07 BO02/DI/BPM-04 BO03/DI/BPM-01 BO03/DI/BPM-09 BO04/DI/BPM-06
BO01/DI/BPM-08 BO02/DI/BPM-05 BO03/DI/BPM-02 BO03/DI/BPM-10 BO04/DI/BPM-07
- ITango <homer:10000> [1]: bpm1 = Libera("BO01<tab>
+ ITango [1]: bpm1 = Libera("BO01<tab>
BO01/DI/BPM-01 BO01/DI/BPM-03 BO01/DI/BPM-05 BO01/DI/BPM-07 BO01/DI/BPM-09 BO01/DI/BPM-11
BO01/DI/BPM-02 BO01/DI/BPM-04 BO01/DI/BPM-06 BO01/DI/BPM-08 BO01/DI/BPM-10
- ITango <homer:10000> [1]: bpm1 = Libera("BO01/DI/BPM-
+ ITango [1]: bpm1 = Libera("BO01/DI/BPM-
List tango devices, classes, servers
@@ -196,7 +196,7 @@ current database.
.. sourcecode:: itango
- ITango <homer:10000> [1]: lsdev
+ ITango [1]: lsdev
Device Alias Server Class
---------------------------------------- ------------------------- ------------------------- --------------------
expchan/BL99_Dummy0DCtrl/1 BL99_0D1 Pool/BL99 ZeroDExpChannel
@@ -219,7 +219,7 @@ current database.
expchan/BL99_UxTimerCtrl1/1 BL99_Timer Pool/BL99 CTExpChannel
...
- ITango <homer:10000> [1]: lsdevclass
+ ITango [1]: lsdevclass
SimuCoTiCtrl TangoAccessControl ZeroDExpChannel
Door Motor DataBase
MotorGroup IORegister SimuMotorCtrl
@@ -227,7 +227,7 @@ current database.
SimuMotor SimuCounterEx MeasurementGroup
Pool CTExpChannel
- ITango <homer:10000> [1]: lsserv
+ ITango [1]: lsserv
MacroServer/BL99 MacroServer/BL98 Pool/V2
Pool/BL99 Pool/BL98 TangoTest/test
Pool/tcoutinho Simulator/BL98
@@ -245,13 +245,13 @@ the magic command 'tango_error'.
.. sourcecode:: itango
- ITango <homer:10000> [1]: test = Device("sys/tg_test/1")
+ ITango [1]: test = Device("sys/tg_test/1")
- ITango <homer:10000> [2]: test.no_value
+ ITango [2]: test.no_value
API_AttrValueNotSet : Read value for attribute no_value has not been updated
For more detailed information type: tango_error
- ITango <homer:10000> [3]: tango_error
+ ITango [3]: tango_error
Last tango error:
DevFailed[
DevError[
@@ -273,7 +273,7 @@ command.
.. sourcecode:: itango
- ITango <homer:10000> [1]: switchdb
+ ITango [1]: switchdb
Must give new database name in format <host>[:<port>].
<port> is optional. If not given it defaults to 10000.
@@ -283,11 +283,23 @@ command.
switchdb homer 10005
switchdb homer
- ITango <homer:10000> [2]: switchdb bart # by default port is 10000
+ ITango [2]: db
+ Database(homer, 10000)
- ITango <bart:10000> [3]: switchdb lisa 10005 # you can use spaces between host and port
+ ITango [3]: switchdb bart # by default port is 10000
- ITango <lisa:10005> [4]: switchdb marge:10005 # or the traditional ':'
+ ITango [4]: db
+ Database(bart, 10000)
+
+ ITango [5]: switchdb lisa 10005 # you can use spaces between host and port
+
+ ITango [6]: db
+ Database(lisa, 10005)
+
+ ITango [7]: switchdb marge:10005 # or the traditional ':'
+
+ ITango [8]: db
+ Database(marge, 10005)
Refreshing the database
--------------------------
@@ -303,7 +315,7 @@ all tango information from the database.
.. sourcecode:: itango
- ITango <homer:10000> [1]: refreshdb
+ ITango [1]: refreshdb
Storing your favorite tango objects for later usage
-------------------------------------------------------
@@ -320,18 +332,18 @@ then store these for the next time you startup IPython_ with itango profile.
.. sourcecode:: itango
- ITango <homer:10000> [1]: theta = Motor("BL99_M1") # notice how we used tango alias
+ ITango [1]: theta = Motor("BL99_M1") # notice how we used tango alias
- ITango <homer:10000> [2]: store theta
+ ITango [2]: store theta
Stored 'theta' (DeviceProxy)
- ITango <homer:10000> [3]: Ctrl+D
+ ITango [3]: Ctrl+D
(IPython session is closed and started again...)
- ITango <homer:10000> [1]: store -r # in some versions of IPython you may need to do this ...
+ ITango [1]: store -r # in some versions of IPython you may need to do this ...
- ITango <homer:10000> [1]: print theta
+ ITango [1]: print theta
DeviceProxy(motor/bl99/1)
Adding itango to your own ipython profile
@@ -370,9 +382,9 @@ The way to do this is by editing your default ipython configuration file:
.. sourcecode:: itango
- ITango <homer:10000> [1]: import IPython.utils.path
+ ITango [1]: import IPython.utils.path
- ITango <homer:10000> [2]: IPython.utils.path.get_ipython_dir()
+ ITango [2]: IPython.utils.path.get_ipython_dir()
<IPYTHON_DIR>
now edit <IPYTHON_DIR>/profile_default/ipython_config.py and add the
@@ -549,14 +561,14 @@ To start monitoring the change events of an attribute:
.. sourcecode:: itango
- ITango <homer:10000> [1]: mon -a BL99_M1/Position
+ ITango [1]: mon -a BL99_M1/Position
'BL99_M1/Position' is now being monitored. Type 'mon' to see all events
To list all events that have been intercepted:
.. sourcecode:: itango
- ITango <homer:10000> [2]: mon
+ ITango [2]: mon
ID Device Attribute Value Quality Time
---- ---------------- ------------ ---------------- ------------- ----------------
0 motor/bl99/1 state ON ATTR_VALID 17:11:08.026472
@@ -578,7 +590,7 @@ To list all events that have been intercepted:
16 motor/bl99/1 position 100.0 ATTR_ALARM 17:12:13.738136
17 motor/bl99/1 state ALARM ATTR_VALID 17:12:13.743481
- ITango <homer:10000> [3]: mon -l mot.* state
+ ITango [3]: mon -l mot.* state
ID Device Attribute Value Quality Time
---- ---------------- ------------ ---------------- ------------- ----------------
0 motor/bl99/1 state ON ATTR_VALID 17:11:08.026472
@@ -589,7 +601,7 @@ To stop monitoring the attribute:
.. sourcecode:: itango
- ITango <homer:10000> [1]: mon -d BL99_M1/Position
+ ITango [1]: mon -d BL99_M1/Position
Stopped monitoring 'BL99_M1/Position'
.. note::
diff --git a/doc/quicktour.rst b/doc/quicktour.rst
index 874be64..fd9c649 100644
--- a/doc/quicktour.rst
+++ b/doc/quicktour.rst
@@ -25,33 +25,33 @@ and type:
.. sourcecode:: itango
- ITango <homer:10000> [1]: PyTango.__version__
- Result [1]: '7.1.2'
+ ITango [1]: PyTango.__version__
+ Result [1]: '7.1.2'
- ITango <homer:10000> [2]: PyTango.__version_long__
- Result [2]: '7.1.2dev0'
+ ITango [2]: PyTango.__version_long__
+ Result [2]: '7.1.2dev0'
- ITango <homer:10000> [3]: PyTango.__version_number__
- Result [3]: 712
+ ITango [3]: PyTango.__version_number__
+ Result [3]: 712
- ITango <homer:10000> [4]: PyTango.__version_description__
- Result [4]: 'This version implements the C++ Tango 7.1 API.'
+ ITango [4]: PyTango.__version_description__
+ Result [4]: 'This version implements the C++ Tango 7.1 API.'
or alternatively:
.. sourcecode:: itango
- ITango <homer:10000> [1]: PyTango.Release.version
- Result [1]: '7.1.2'
+ ITango [1]: PyTango.Release.version
+ Result [1]: '7.1.2'
- ITango <homer:10000> [2]: PyTango.Release.version_long
- Result [2]: '7.1.2dev0'
+ ITango [2]: PyTango.Release.version_long
+ Result [2]: '7.1.2dev0'
- ITango <homer:10000> [3]: PyTango.Release.version_number
- Result [3]: 712
+ ITango [3]: PyTango.Release.version_number
+ Result [3]: 712
- ITango <homer:10000> [4]: PyTango.Release.version_description
- Result [4]: 'This version implements the C++ Tango 7.1 API.'
+ ITango [4]: PyTango.Release.version_description
+ Result [4]: 'This version implements the C++ Tango 7.1 API.'
.. tip::
@@ -69,10 +69,10 @@ From a client (This is only possible since PyTango 7.0.0)
.. sourcecode:: itango
- ITango <homer:10000> [1]: import PyTango.constants
+ ITango [1]: import PyTango.constants
- ITango <homer:10000> [2]: PyTango.constants.TgLibVers
- Result [2]: '7.1.1'
+ ITango [2]: PyTango.constants.TgLibVers
+ Result [2]: '7.1.1'
From a server you can alternatively do::
@@ -88,8 +88,8 @@ determine if it is running or not.
.. sourcecode:: itango
- ITango <homer:10000> [1]: # What is a DeviceProxy, really?
- ITango <homer:10000> [1]: DeviceProxy?
+ ITango [1]: # What is a DeviceProxy, really?
+ ITango [1]: DeviceProxy?
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
@@ -99,19 +99,19 @@ determine if it is running or not.
Example :
dev = PyTango.DeviceProxy("sys/tg_test/1")
- ITango <homer:10000> [2]: tangotest = DeviceProxy("sys/tg_test/1")
+ ITango [2]: tangotest = DeviceProxy("sys/tg_test/1")
- ITango <homer:10000> [3]: # ping it
- ITango <homer:10000> [4]: tangotest.ping()
- Result [4]: 110
+ ITango [3]: # ping it
+ ITango [4]: tangotest.ping()
+ Result [4]: 110
- ITango <homer:10000> [3]: # Lets test the state
- ITango <homer:10000> [5]: tangotest.state()
- Result [5]: PyTango._PyTango.DevState.RUNNING
+ ITango [5]: # Lets test the state
+ ITango [6]: tangotest.state()
+ Result [6]: PyTango._PyTango.DevState.RUNNING
- ITango <homer:10000> [3]: # And now the status
- ITango <homer:10000> [5]: tangotest.status()
- Result [5]: 'The device is in RUNNING state.'
+ ITango [7]: # And now the status
+ ITango [8]: tangotest.status()
+ Result [8]: 'The device is in RUNNING state.'
.. note::
Did you notice that you didn't write PyTango.DeviceProxy but instead just
@@ -146,21 +146,21 @@ automatically manages the data types, and writing scripts is quite easy.
.. sourcecode:: itango
- ITango <homer:10000> [1]: tangotest = TangoTest("sys/tg_test/1")
+ ITango [1]: tangotest = TangoTest("sys/tg_test/1")
- ITango <homer:10000> [2]: # classical way
- ITango <homer:10000> [2]: r = tangotest.command_inout("DevString", "Hello, world!")
+ ITango [2]: # classical way
+ ITango [2]: r = tangotest.command_inout("DevString", "Hello, world!")
- ITango <homer:10000> [3]: print "Result of execution of DevString command =", r
+ ITango [3]: print "Result of execution of DevString command =", r
Result of execution of DevString command = Hello, world!
- ITango <homer:10000> [4]: # 'pythonic' way
- ITango <homer:10000> [5]: tangotest.DevString("Hello, world!")
- Result [5]: 'Hello, world!'
+ ITango [4]: # 'pythonic' way
+ ITango [5]: tangotest.DevString("Hello, world!")
+ Result [5]: 'Hello, world!'
- ITango <homer:10000> [6]: # type is automatically managed by PyTango
- ITango <homer:10000> [7]: tangotest.DevULong(12456)
- Result [7]: 12456
+ ITango [6]: # type is automatically managed by PyTango
+ ITango [7]: tangotest.DevULong(12456)
+ Result [7]: 12456
Execute commands with more complex types
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
@@ -170,12 +170,12 @@ structures.
.. sourcecode:: itango
- ITango <homer:10000> [1]: tangotest = TangoTest("sys/tg_test/1")
+ ITango [1]: tangotest = TangoTest("sys/tg_test/1")
- ITango <homer:10000> [2]: argin = [1, 2, 3], ["Hello", "World"]
+ ITango [2]: argin = [1, 2, 3], ["Hello", "World"]
- ITango <homer:10000> [3]: tango_test.DevVarLongArray(argin)
- Result [3]: [array([1, 2, 3]), ['Hello', 'World']]
+ ITango [3]: tango_test.DevVarLongArray(argin)
+ Result [3]: [array([1, 2, 3]), ['Hello', 'World']]
.. note::
notice that the command returns a list of two elements. The first element is
@@ -190,8 +190,8 @@ Basic read/write attribute operations.
.. sourcecode:: itango
- ITango <homer:10000> [1]: # Read a scalar attribute
- ITango <homer:10000> [2]: print tangotest.read_attribute("long_scalar")
+ ITango [1]: # Read a scalar attribute
+ ITango [2]: print tangotest.read_attribute("long_scalar")
DeviceAttribute[
data_format = PyTango._PyTango.AttrDataFormat.SCALAR
dim_x = 1
@@ -211,8 +211,8 @@ Basic read/write attribute operations.
w_dimension = AttributeDimension(dim_x = 1, dim_y = 0)
w_value = 0]
- ITango <homer:10000> [3]: # Read a spectrum attribute
- ITango <pc151:10000> [4]: print tangotest.read_attribute("double_spectrum")
+ ITango [3]: # Read a spectrum attribute
+ ITango [4]: print tangotest.read_attribute("double_spectrum")
DeviceAttribute[
data_format = PyTango._PyTango.AttrDataFormat.SPECTRUM
dim_x = 20
@@ -234,18 +234,18 @@ Basic read/write attribute operations.
w_value = array([ 0., 1., 2., 3., 4., 5., 6., 7., 8., 9., 10.,
11., 12., 13., 14., 15., 16., 17., 18., 19.])]
- ITango <homer:10000> [5]: # Write a scalar attribute
- ITango <homer:10000> [6]: scalar_value = 18
- ITango <homer:10000> [7]: tangotest.write_attribute("long_scalar", scalar_value)
+ ITango [5]: # Write a scalar attribute
+ ITango [6]: scalar_value = 18
+ ITango [7]: tangotest.write_attribute("long_scalar", scalar_value)
- ITango <homer:10000> [8]: # Write a spectrum attribute
- ITango <homer:10000> [9]: spectrum_value = numpy.random.rand(100)*10
- ITango <homer:10000> [10]: tangotest.write_attribute("double_spectrum", spectrum_value)
+ ITango [8]: # Write a spectrum attribute
+ ITango [9]: spectrum_value = numpy.random.rand(100)*10
+ ITango [10]: tangotest.write_attribute("double_spectrum", spectrum_value)
- ITango <homer:10000> [11]: # Write an image attribute
- ITango <homer:10000> [12]: image_value = numpy.random.randint(0,10,size=(10,10))
- ITango <homer:10000> [13]: tangotest.write_attribute("long_image", image_value)
+ ITango [11]: # Write an image attribute
+ ITango [12]: image_value = numpy.random.randint(0,10,size=(10,10))
+ ITango [13]: tangotest.write_attribute("long_image", image_value)
.. tip::
@@ -253,14 +253,14 @@ Basic read/write attribute operations.
.. sourcecode:: itango
- ITango <homer:10000> [1]: tangotest.long_scalar
- Result [1]: 239
+ ITango [1]: tangotest.long_scalar
+ Result [1]: 239
The same is valid for writting a new value to an attribute:
.. sourcecode:: itango
- ITango <homer:10000> [1]: tangotest.long_scalar = 18
+ ITango [1]: tangotest.long_scalar = 18
.. note::
@@ -288,28 +288,28 @@ Defining devices in the Tango DataBase:
.. sourcecode:: itango
- ITango <homer:10000> [1]: # The 3 devices name we want to create
- ITango <homer:10000> [2]: # Note: these 3 devices will be served by the same DServer
- ITango <homer:10000> [3]: new_device_name1="px1/tdl/mouse1"
- ITango <homer:10000> [4]: new_device_name2="px1/tdl/mouse2"
- ITango <homer:10000> [5]: new_device_name3="px1/tdl/mouse3"
+ ITango [1]: # The 3 devices name we want to create
+ ITango [2]: # Note: these 3 devices will be served by the same DServer
+ ITango [3]: new_device_name1="px1/tdl/mouse1"
+ ITango [4]: new_device_name2="px1/tdl/mouse2"
+ ITango [5]: new_device_name3="px1/tdl/mouse3"
- ITango <homer:10000> [6]: # Define the Tango Class served by this DServer
- ITango <homer:10000> [7]: new_device_info_mouse = PyTango.DbDevInfo()
- ITango <homer:10000> [8]: new_device_info_mouse._class = "Mouse"
- ITango <homer:10000> [9]: new_device_info_mouse.server = "ds_Mouse/server_mouse"
+ ITango [6]: # Define the Tango Class served by this DServer
+ ITango [7]: new_device_info_mouse = PyTango.DbDevInfo()
+ ITango [8]: new_device_info_mouse._class = "Mouse"
+ ITango [9]: new_device_info_mouse.server = "ds_Mouse/server_mouse"
- ITango <homer:10000> [10]: # add the first device
- ITango <homer:10000> [11]: new_device_info_mouse.name = new_device_name1
- ITango <homer:10000> [12]: db.add_device(new_device_info_mouse)
+ ITango [10]: # add the first device
+ ITango [11]: new_device_info_mouse.name = new_device_name1
+ ITango [12]: db.add_device(new_device_info_mouse)
- ITango <homer:10000> [13]: # add the next device
- ITango <homer:10000> [14]: new_device_info_mouse.name = new_device_name2
- ITango <homer:10000> [15]: db.add_device(new_device_info_mouse)
+ ITango [13]: # add the next device
+ ITango [14]: new_device_info_mouse.name = new_device_name2
+ ITango [15]: db.add_device(new_device_info_mouse)
- ITango <homer:10000> [16]: # add the third device
- ITango <homer:10000> [17]: new_device_info_mouse.name = new_device_name3
- ITango <homer:10000> [18]: db.add_device(new_device_info_mouse)
+ ITango [16]: # add the third device
+ ITango [17]: new_device_info_mouse.name = new_device_name3
+ ITango [18]: db.add_device(new_device_info_mouse)
Setting up Device properties
~~~~~~~~~~~~~~~~~~~~~~~~~~~~
@@ -321,11 +321,11 @@ API should be accessed from Python.
.. sourcecode:: itango
- ITango <homer:10000> [1]: # connecting to the motor axis device
- ITango <homer:10000> [2]: axis1 = DeviceProxy ("microxas/motorisation/galilbox")
+ ITango [1]: # connecting to the motor axis device
+ ITango [2]: axis1 = DeviceProxy ("microxas/motorisation/galilbox")
- ITango <homer:10000> [3]: # Getting Device Properties
- ITango <homer:10000> [4]: property_names = ["AxisBoxAttachement",
+ ITango [3]: # Getting Device Properties
+ ITango [4]: property_names = ["AxisBoxAttachement",
....: "AxisEncoderType",
....: "AxisNumber",
....: "CurrentAcceleration",
@@ -345,36 +345,36 @@ API should be accessed from Python.
....: "UserEncoderRatio",
....: "UserOffset"]
- ITango <homer:10000> [5]: axis_properties = axis1.get_property(property_names)
- ITango <homer:10000> [6]: for prop in axis_properties.keys():
+ ITango [5]: axis_properties = axis1.get_property(property_names)
+ ITango [6]: for prop in axis_properties.keys():
....: print "%s: %s" % (prop, axis_properties[prop][0])
- ITango <homer:10000> [7]: # Changing Properties
- ITango <homer:10000> [8]: axis_properties["AxisBoxAttachement"] = ["microxas/motorisation/galilbox"]
- ITango <homer:10000> [9]: axis_properties["AxisEncoderType"] = ["1"]
- ITango <homer:10000> [10]: axis_properties["AxisNumber"] = ["6"]
- ITango <homer:10000> [11]: axis1.put_property(axis_properties)
+ ITango [7]: # Changing Properties
+ ITango [8]: axis_properties["AxisBoxAttachement"] = ["microxas/motorisation/galilbox"]
+ ITango [9]: axis_properties["AxisEncoderType"] = ["1"]
+ ITango [10]: axis_properties["AxisNumber"] = ["6"]
+ ITango [11]: axis1.put_property(axis_properties)
- ITango <homer:10000> [12]: # Reading attributes
- ITango <homer:10000> [13]: att_list = axis.get_attribute_list()
- ITango <homer:10000> [14]: for att in att_list:
+ ITango [12]: # Reading attributes
+ ITango [13]: att_list = axis.get_attribute_list()
+ ITango [14]: for att in att_list:
....: att_val = axis.read_attribute(att)
....: print "%s: %s" % (att.name, att_val.value)
- ITango <homer:10000> [15]: # Changing some attribute values
- ITango <homer:10000> [16]: axis1.write_attribute("AxisBackslash", 0.5)
- ITango <homer:10000> [17]: axis1.write_attribute("AxisDirection", 1.0)
- ITango <homer:10000> [18]: axis1.write_attribute("AxisVelocity", 1000.0)
- ITango <homer:10000> [19]: axis1.write_attribute("AxisOvershoot", 500.0)
+ ITango [15]: # Changing some attribute values
+ ITango [16]: axis1.write_attribute("AxisBackslash", 0.5)
+ ITango [17]: axis1.write_attribute("AxisDirection", 1.0)
+ ITango [18]: axis1.write_attribute("AxisVelocity", 1000.0)
+ ITango [19]: axis1.write_attribute("AxisOvershoot", 500.0)
- ITango <homer:10000> [20]: # Testing some device commands
- ITango <homer:10000> [21]: pos1=axis1.read_attribute("AxisCurrentPosition")
- ITango <homer:10000> [22]: axis1.command_inout("AxisBackward")
- ITango <homer:10000> [23]: while pos1.value > 1000.0:
+ ITango [20]: # Testing some device commands
+ ITango [21]: pos1=axis1.read_attribute("AxisCurrentPosition")
+ ITango [22]: axis1.command_inout("AxisBackward")
+ ITango [23]: while pos1.value > 1000.0:
....: pos1 = axis1.read_attribute("AxisCurrentPosition")
....: print "position axis 1 = ", pos1.value
- ITango <homer:10000> [24]: axis1.command_inout("AxisStop")
+ ITango [24]: axis1.command_inout("AxisStop")
A quick tour of Tango device server binding through an example
--------------------------------------------------------------
@@ -535,4 +535,4 @@ The following code is the complete device server code::
except Exception,e:
print '-------> An unforeseen exception occured....',e
-.. _IPython: http://ipython.scipy.org/
\ No newline at end of file
+.. _IPython: http://ipython.scipy.org/
diff --git a/doc/revision.rst b/doc/revision.rst
index 5dc866d..ab57cc0 100644
--- a/doc/revision.rst
+++ b/doc/revision.rst
@@ -65,6 +65,8 @@ History of modifications:
+----------+----------------------------------------------------------------------------------+-----------------------------------------------------+-----------------------+
| 24/04/12 | `8.13 <http://www.tango-controls.org/static/PyTango/v723/doc/html/index.html>`_ | Update to PyTango 7.2.3 | T\. Coutinho |
+----------+----------------------------------------------------------------------------------+-----------------------------------------------------+-----------------------+
+| /09/12 | `8.14 <http://www.tango-controls.org/static/PyTango/v800/doc/html/index.html>`_ | Update to PyTango 8.0.0 | T\. Coutinho |
++----------+----------------------------------------------------------------------------------+-----------------------------------------------------+-----------------------+
.. _version-history:
@@ -74,6 +76,14 @@ Version history
+------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| version | Changes |
+============+==============================================================================================================================================================================+
+| 8.0.0 | Features: |
+| | - Implemented tango C++ 8.0 API |
+| | - Python 3k compatible |
+| | Bug fixes: |
+| | - from sourceforge: |
+| | - `3023857: DevEncoded write attribute not supported <https://sourceforge.net/tracker/?func=detail&aid=3023857&group_id=57612&atid=484769>`_ |
+| | - `3530535: PyTango group writting fails <https://sourceforge.net/tracker/?func=detail&aid=3530535&group_id=57612&atid=484769>`_ |
++------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| 7.2.3 | Features: |
| | - from sourceforge: |
| | - `3495607: DeviceClass.device_name_factory is missing <https://sourceforge.net/tracker/?func=detail&aid=3495607&group_id=57612&atid=484772>`_ |
diff --git a/doc/server/index.rst b/doc/server/index.rst
index 6f9cbc8..1c7a747 100644
--- a/doc/server/index.rst
+++ b/doc/server/index.rst
@@ -400,74 +400,153 @@ will be the used for the input arguments. Also, it is recomended to use numpy
arrays of the appropiate type for output arguments as well, as it is much more
efficient.
-+-------------------------+-------------------------------------------------------------------+
-| Tango data type | Python type |
-+=========================+===================================================================+
-| DEV_VOID | No data |
-+-------------------------+-------------------------------------------------------------------+
-| DEV_BOOLEAN | :py:obj:`bool` |
-+-------------------------+-------------------------------------------------------------------+
-| DEV_SHORT | :py:obj:`int` |
-+-------------------------+-------------------------------------------------------------------+
-| DEV_LONG | :py:obj:`int` |
-+-------------------------+-------------------------------------------------------------------+
-| DEV_LONG64 | :py:obj:`long` (on a 32 bits computer) or |
-| | :py:obj:`int` (on a 64 bits computer) |
-+-------------------------+-------------------------------------------------------------------+
-| DEV_FLOAT | :py:obj:`float` |
-+-------------------------+-------------------------------------------------------------------+
-| DEV_DOUBLE | :py:obj:`float` |
-+-------------------------+-------------------------------------------------------------------+
-| DEV_USHORT | :py:obj:`int` |
-+-------------------------+-------------------------------------------------------------------+
-| DEV_ULONG | :py:obj:`int` |
-+-------------------------+-------------------------------------------------------------------+
-| DEV_ULONG64 | :py:obj:`long` (on a 32 bits computer) or |
-| | :py:obj:`int` (on a 64 bits computer) |
-+-------------------------+-------------------------------------------------------------------+
-| DEV_STRING | :py:obj:`str` |
-+-------------------------+-------------------------------------------------------------------+
-| DEVVAR_CHARARRAY | :py:class:`numpy.ndarray` (dtype= :py:obj:`numpy.uint8`) or |
-| | sequence<:py:obj:`int`> |
-+-------------------------+-------------------------------------------------------------------+
-| DEVVAR_SHORTARRAY | :py:class:`numpy.ndarray` (dtype=:py:obj:`numpy.int16`) or |
-| | sequence<:py:obj:`int`> |
-+-------------------------+-------------------------------------------------------------------+
-| DEVVAR_LONGARRAY | :py:class:`numpy.ndarray` (dtype= :py:obj:`numpy.int32`) or |
-| | sequence<:py:obj:`int`> |
-+-------------------------+-------------------------------------------------------------------+
-| DEVVAR_LONG64ARRAY | :py:class:`numpy.ndarray` (dtype= :py:obj:`numpy.int64`) or |
-| | sequence<:py:obj:`long`> (on a 32 bits computer) or |
-| | sequence<:py:obj:`int`> (on a 64 bits computer) |
-+-------------------------+-------------------------------------------------------------------+
-| DEVVAR_FLOATARRAY | :py:class:`numpy.ndarray` (dtype= :py:obj:`numpy.float32`) or |
-| | sequence<:py:obj:`float`> |
-+-------------------------+-------------------------------------------------------------------+
-| DEVVAR_DOUBLEARRAY | :py:class:`numpy.ndarray` (dtype= :py:obj:`numpy.float64`) or |
-| | sequence<:py:obj:`float`> |
-+-------------------------+-------------------------------------------------------------------+
-| DEVVAR_USHORTARRAY | :py:class:`numpy.ndarray` (dtype= :py:obj:`numpy.uint16`) or |
-| | sequence<:py:obj:`int`> |
-+-------------------------+-------------------------------------------------------------------+
-| DEVVAR_ULONGARRAY | numpy.ndarray(dtype= :py:obj:`numpy.uint32`) or |
-| | sequence<:py:obj:`int`> |
-+-------------------------+-------------------------------------------------------------------+
-| DEVVAR_ULONG64ARRAY | :py:class:`numpy.ndarray` (dtype= :py:obj:`numpy.uint64`) or |
-| | sequence<:py:obj:`long`> (on a 32 bits computer) or |
-| | sequence<:py:obj:`int`> (on a 64 bits computer) |
-+-------------------------+-------------------------------------------------------------------+
-| DEVVAR_STRINGARRAY | sequence<:py:obj:`str`> |
-+-------------------------+-------------------------------------------------------------------+
-| | A sequence with two elements: |
-| DEVVAR_LONGSTRINGARRAY | 1. :py:class:`numpy.ndarray` (dtype= :py:obj:`numpy.int32`) or |
-| | sequence<:py:obj:`int`> |
-| | 2. sequence<:py:obj:`str`> |
-+-------------------------+-------------------------------------------------------------------+
-| | A sequence with two elements: |
-|DEVVAR_DOUBLESTRINGARRAY | 1. :py:class:`numpy.ndarray` (dtype= :py:obj:`numpy.float64`) or |
-| | sequence<:py:obj:`float`> |
-| | 2. sequence<:py:obj:`str`> |
-+-------------------------+-------------------------------------------------------------------+
++-------------------------+---------------------------------------------------------------------------+---------------------------------------------------------------------------+
+| Tango data type | Python 2.x type | Python 3.x type (*New in PyTango 8.0*) |
++=========================+===========================================================================+===========================================================================+
+| DEV_VOID | No data | No data |
++-------------------------+---------------------------------------------------------------------------+---------------------------------------------------------------------------+
+| DEV_BOOLEAN | :py:obj:`bool` | :py:obj:`bool` |
++-------------------------+---------------------------------------------------------------------------+---------------------------------------------------------------------------+
+| DEV_SHORT | :py:obj:`int` | :py:obj:`int` |
++-------------------------+---------------------------------------------------------------------------+---------------------------------------------------------------------------+
+| DEV_LONG | :py:obj:`int` | :py:obj:`int` |
++-------------------------+---------------------------------------------------------------------------+---------------------------------------------------------------------------+
+| DEV_LONG64 | - :py:obj:`long` (on a 32 bits computer) | :py:obj:`int` |
+| | - :py:obj:`int` (on a 64 bits computer) | |
++-------------------------+---------------------------------------------------------------------------+---------------------------------------------------------------------------+
+| DEV_FLOAT | :py:obj:`float` | :py:obj:`float` |
++-------------------------+---------------------------------------------------------------------------+---------------------------------------------------------------------------+
+| DEV_DOUBLE | :py:obj:`float` | :py:obj:`float` |
++-------------------------+---------------------------------------------------------------------------+---------------------------------------------------------------------------+
+| DEV_USHORT | :py:obj:`int` | :py:obj:`int` |
++-------------------------+---------------------------------------------------------------------------+---------------------------------------------------------------------------+
+| DEV_ULONG | :py:obj:`int` | :py:obj:`int` |
++-------------------------+---------------------------------------------------------------------------+---------------------------------------------------------------------------+
+| DEV_ULONG64 | * :py:obj:`long` (on a 32 bits computer) | :py:obj:`int` |
+| | * :py:obj:`int` (on a 64 bits computer) | |
++-------------------------+---------------------------------------------------------------------------+---------------------------------------------------------------------------+
+| DEV_STRING | :py:obj:`str` | :py:obj:`str` (decoded with *latin-1*, aka *ISO-8859-1*) |
++-------------------------+---------------------------------------------------------------------------+---------------------------------------------------------------------------+
+| | sequence of two elements: | sequence of two elements: |
+| DEV_ENCODED | | |
+| (*New in PyTango 8.0*) | 0. :py:obj:`str` | 0. :py:obj:`str` (decoded with *latin-1*, aka *ISO-8859-1*) |
+| | 1. :py:obj:`bytes` (for any value of *extract_as*) | 1. :py:obj:`bytes` (for any value of *extract_as*, except String. |
+| | | In this case it is :py:obj:`str` (decoded with default python |
+| | | encoding *utf-8*)) |
++-------------------------+---------------------------------------------------------------------------+---------------------------------------------------------------------------+
+| | ========= ============================================================ | ========= =============================================================== |
+| | ExtractAs Data Type | ExtractAs Data Type |
+| | ========= ============================================================ | ========= =============================================================== |
+| DEVVAR_CHARARRAY | [Numpy] :py:class:`numpy.ndarray` (dtype= :py:obj:`numpy.uint8`) | [Numpy] :py:class:`numpy.ndarray` (dtype= :py:obj:`numpy.uint8`) |
+| | Bytes :py:obj:`bytes` (which is in fact equal to :py:obj:`str`) | Bytes :py:obj:`bytes` |
+| | ByteArray :py:obj:`bytearray` | ByteArray :py:obj:`bytearray` |
+| | String :py:obj:`str` | String :py:obj:`str` (decoded with default python encoding *utf-8*!!!) |
+| | List :py:class:`list` <:py:obj:`int`> | List :py:class:`list` <:py:obj:`int`> |
+| | Tuple :py:class:`tuple` <:py:obj:`int`> | Tuple :py:class:`tuple` <:py:obj:`int`> |
+| | ========= ============================================================ | ========= =============================================================== |
++-------------------------+---------------------------------------------------------------------------+---------------------------------------------------------------------------+
+| | ========= =============================================================== | ========= =============================================================== |
+| | ExtractAs Data Type | ExtractAs Data Type |
+| | ========= =============================================================== | ========= =============================================================== |
+| DEVVAR_SHORTARRAY | [Numpy] :py:class:`numpy.ndarray` (dtype= :py:obj:`numpy.uint16`) | [Numpy] :py:class:`numpy.ndarray` (dtype= :py:obj:`numpy.uint16`) |
+| | Bytes :py:obj:`bytes` (which is in fact equal to :py:obj:`str`) | Bytes :py:obj:`bytes` |
+| | ByteArray :py:obj:`bytearray` | ByteArray :py:obj:`bytearray` |
+| | String :py:obj:`str` | String :py:obj:`str` (decoded with default python encoding *utf-8*!!!) |
+| | List :py:class:`list` <:py:obj:`int`> | List :py:class:`list` <:py:obj:`int`> |
+| | Tuple :py:class:`tuple` <:py:obj:`int`> | Tuple :py:class:`tuple` <:py:obj:`int`> |
+| | ========= =============================================================== | ========= =============================================================== |
++-------------------------+---------------------------------------------------------------------------+---------------------------------------------------------------------------+
+| | ========= =============================================================== | ========= =============================================================== |
+| | ExtractAs Data Type | ExtractAs Data Type |
+| | ========= =============================================================== | ========= =============================================================== |
+| DEVVAR_LONGARRAY | [Numpy] :py:class:`numpy.ndarray` (dtype= :py:obj:`numpy.uint32`) | [Numpy] :py:class:`numpy.ndarray` (dtype= :py:obj:`numpy.uint32`) |
+| | Bytes :py:obj:`bytes` (which is in fact equal to :py:obj:`str`) | Bytes :py:obj:`bytes` |
+| | ByteArray :py:obj:`bytearray` | ByteArray :py:obj:`bytearray` |
+| | String :py:obj:`str` | String :py:obj:`str` (decoded with default python encoding *utf-8*!!!) |
+| | List :py:class:`list` <:py:obj:`int`> | List :py:class:`list` <:py:obj:`int`> |
+| | Tuple :py:class:`tuple` <:py:obj:`int`> | Tuple :py:class:`tuple` <:py:obj:`int`> |
+| | ========= =============================================================== | ========= =============================================================== |
++-------------------------+---------------------------------------------------------------------------+---------------------------------------------------------------------------+
+| | ========= =============================================================== | ========= =============================================================== |
+| | ExtractAs Data Type | ExtractAs Data Type |
+| | ========= =============================================================== | ========= =============================================================== |
+| DEVVAR_LONG64ARRAY | [Numpy] :py:class:`numpy.ndarray` (dtype= :py:obj:`numpy.uint64`) | [Numpy] :py:class:`numpy.ndarray` (dtype= :py:obj:`numpy.uint64`) |
+| | Bytes :py:obj:`bytes` (which is in fact equal to :py:obj:`str`) | Bytes :py:obj:`bytes` |
+| | ByteArray :py:obj:`bytearray` | ByteArray :py:obj:`bytearray` |
+| | String :py:obj:`str` | String :py:obj:`str` (decoded with default python encoding *utf-8*!!!) |
+| | List :py:class:`list` <int (64 bits) / long (32 bits)> | List :py:class:`list` <:py:obj:`int`> |
+| | Tuple :py:class:`tuple` <int (64 bits) / long (32 bits)> | Tuple :py:class:`tuple` <:py:obj:`int`> |
+| | ========= =============================================================== | ========= =============================================================== |
++-------------------------+---------------------------------------------------------------------------+---------------------------------------------------------------------------+
+| | ========= =============================================================== | ========= =============================================================== |
+| | ExtractAs Data Type | ExtractAs Data Type |
+| | ========= =============================================================== | ========= =============================================================== |
+| DEVVAR_FLOATARRAY | [Numpy] :py:class:`numpy.ndarray` (dtype= :py:obj:`numpy.float32`) | [Numpy] :py:class:`numpy.ndarray` (dtype= :py:obj:`numpy.float32`) |
+| | Bytes :py:obj:`bytes` (which is in fact equal to :py:obj:`str`) | Bytes :py:obj:`bytes` |
+| | ByteArray :py:obj:`bytearray` | ByteArray :py:obj:`bytearray` |
+| | String :py:obj:`str` | String :py:obj:`str` (decoded with default python encoding *utf-8*!!!) |
+| | List :py:class:`list` <:py:obj:`int`> | List :py:class:`list` <:py:obj:`int`> |
+| | Tuple :py:class:`tuple` <:py:obj:`int`> | Tuple :py:class:`tuple` <:py:obj:`int`> |
+| | ========= =============================================================== | ========= =============================================================== |
++-------------------------+---------------------------------------------------------------------------+---------------------------------------------------------------------------+
+| | ========= =============================================================== | ========= =============================================================== |
+| | ExtractAs Data Type | ExtractAs Data Type |
+| | ========= =============================================================== | ========= =============================================================== |
+| DEVVAR_DOUBLEARRAY | [Numpy] :py:class:`numpy.ndarray` (dtype= :py:obj:`numpy.float64`) | [Numpy] :py:class:`numpy.ndarray` (dtype= :py:obj:`numpy.float64`) |
+| | Bytes :py:obj:`bytes` (which is in fact equal to :py:obj:`str`) | Bytes :py:obj:`bytes` |
+| | ByteArray :py:obj:`bytearray` | ByteArray :py:obj:`bytearray` |
+| | String :py:obj:`str` | String :py:obj:`str` (decoded with default python encoding *utf-8*!!!) |
+| | List :py:class:`list` <:py:obj:`int`> | List :py:class:`list` <:py:obj:`int`> |
+| | Tuple :py:class:`tuple` <:py:obj:`int`> | Tuple :py:class:`tuple` <:py:obj:`int`> |
+| | ========= =============================================================== | ========= =============================================================== |
++-------------------------+---------------------------------------------------------------------------+---------------------------------------------------------------------------+
+| | ========= =============================================================== | ========= =============================================================== |
+| | ExtractAs Data Type | ExtractAs Data Type |
+| | ========= =============================================================== | ========= =============================================================== |
+| DEVVAR_USHORTARRAY | [Numpy] :py:class:`numpy.ndarray` (dtype= :py:obj:`numpy.uint16`) | [Numpy] :py:class:`numpy.ndarray` (dtype= :py:obj:`numpy.uint16`) |
+| | Bytes :py:obj:`bytes` (which is in fact equal to :py:obj:`str`) | Bytes :py:obj:`bytes` |
+| | ByteArray :py:obj:`bytearray` | ByteArray :py:obj:`bytearray` |
+| | String :py:obj:`str` | String :py:obj:`str` (decoded with default python encoding *utf-8*!!!) |
+| | List :py:class:`list` <:py:obj:`int`> | List :py:class:`list` <:py:obj:`int`> |
+| | Tuple :py:class:`tuple` <:py:obj:`int`> | Tuple :py:class:`tuple` <:py:obj:`int`> |
+| | ========= =============================================================== | ========= =============================================================== |
++-------------------------+---------------------------------------------------------------------------+---------------------------------------------------------------------------+
+| | ========= =============================================================== | ========= =============================================================== |
+| | ExtractAs Data Type | ExtractAs Data Type |
+| | ========= =============================================================== | ========= =============================================================== |
+| DEVVAR_ULONGARRAY | [Numpy] :py:class:`numpy.ndarray` (dtype= :py:obj:`numpy.uint32`) | [Numpy] :py:class:`numpy.ndarray` (dtype= :py:obj:`numpy.uint32`) |
+| | Bytes :py:obj:`bytes` (which is in fact equal to :py:obj:`str`) | Bytes :py:obj:`bytes` |
+| | ByteArray :py:obj:`bytearray` | ByteArray :py:obj:`bytearray` |
+| | String :py:obj:`str` | String :py:obj:`str` (decoded with default python encoding *utf-8*!!!) |
+| | List :py:class:`list` <:py:obj:`int`> | List :py:class:`list` <:py:obj:`int`> |
+| | Tuple :py:class:`tuple` <:py:obj:`int`> | Tuple :py:class:`tuple` <:py:obj:`int`> |
+| | ========= =============================================================== | ========= =============================================================== |
++-------------------------+---------------------------------------------------------------------------+---------------------------------------------------------------------------+
+| | ========= =============================================================== | ========= =============================================================== |
+| | ExtractAs Data Type | ExtractAs Data Type |
+| | ========= =============================================================== | ========= =============================================================== |
+| DEVVAR_ULONG64ARRAY | [Numpy] :py:class:`numpy.ndarray` (dtype= :py:obj:`numpy.uint64`) | [Numpy] :py:class:`numpy.ndarray` (dtype= :py:obj:`numpy.uint64`) |
+| | Bytes :py:obj:`bytes` (which is in fact equal to :py:obj:`str`) | Bytes :py:obj:`bytes` |
+| | ByteArray :py:obj:`bytearray` | ByteArray :py:obj:`bytearray` |
+| | String :py:obj:`str` | String :py:obj:`str` (decoded with default python encoding *utf-8*!!!) |
+| | List :py:class:`list` <int (64 bits) / long (32 bits)> | List :py:class:`list` <:py:obj:`int`> |
+| | Tuple :py:class:`tuple` <int (64 bits) / long (32 bits)> | Tuple :py:class:`tuple` <:py:obj:`int`> |
+| | ========= =============================================================== | ========= =============================================================== |
++-------------------------+---------------------------------------------------------------------------+---------------------------------------------------------------------------+
+| DEVVAR_STRINGARRAY | sequence<:py:obj:`str`> | sequence<:py:obj:`str`> (decoded with *latin-1*, aka *ISO-8859-1*) |
++-------------------------+---------------------------------------------------------------------------+---------------------------------------------------------------------------+
+| | sequence of two elements: | sequence of two elements: |
+| DEV_LONGSTRINGARRAY | | |
+| | 0. :py:class:`numpy.ndarray` (dtype= :py:obj:`numpy.int32`) or | 0. :py:class:`numpy.ndarray` (dtype= :py:obj:`numpy.int32`) or |
+| | sequence<:py:obj:`int`> | sequence<:py:obj:`int`> |
+| | 1. sequence<:py:obj:`str`> | 1. sequence<:py:obj:`str`> (decoded with *latin-1*, aka *ISO-8859-1*) |
++-------------------------+---------------------------------------------------------------------------+---------------------------------------------------------------------------+
+| | sequence of two elements: | sequence of two elements: |
+| DEV_DOUBLESTRINGARRAY | | |
+| | 0. :py:class:`numpy.ndarray` (dtype= :py:obj:`numpy.float64`) or | 0. :py:class:`numpy.ndarray` (dtype= :py:obj:`numpy.float64`) or |
+| | sequence<:py:obj:`int`> | sequence<:py:obj:`int`> |
+| | 1. sequence<:py:obj:`str`> | 1. sequence<:py:obj:`str`> (decoded with *latin-1*, aka *ISO-8859-1*) |
++-------------------------+---------------------------------------------------------------------------+---------------------------------------------------------------------------+
The following code is an example of how you write code executed when a client
calls a command named IOLong::
diff --git a/doc/sphinxext/tango_console_highlighting.py b/doc/sphinxext/tango_console_highlighting.py
index ffff5b9..fa70aff 100644
--- a/doc/sphinxext/tango_console_highlighting.py
+++ b/doc/sphinxext/tango_console_highlighting.py
@@ -49,7 +49,7 @@ DftStyle = pygments.styles.get_style_by_name("default")
class TangoStyle(DftStyle):
styles = copy.copy(DftStyle.styles)
- styles[Generic.Prompt] = 'bold #800080'
+ styles[Generic.Prompt] = 'bold #00AA00'
class TangoConsoleLexer(Lexer):
"""
@@ -57,15 +57,15 @@ class TangoConsoleLexer(Lexer):
.. sourcecode:: itango
- ITango <homer:10000> [1]: a = 'foo'
+ ITango [1]: a = 'foo'
- ITango <homer:10000> [2]: a
+ ITango [2]: a
Result [2]: 'foo'
- ITango <homer:10000> [3]: print a
+ ITango [3]: print a
foo
- ITango <homer:10000> [4]: 1 / 0
+ ITango [4]: 1 / 0
Notes:
@@ -77,7 +77,7 @@ class TangoConsoleLexer(Lexer):
name = 'ITango console session'
aliases = ['itango']
mimetypes = ['text/x-itango-console']
- input_prompt = re.compile("(ITango \<\w+:\d+\> \[(?P<N>[0-9]+)\]: )|( \.\.\.+:)")
+ input_prompt = re.compile("(ITango \[(?P<N>[0-9]+)\]: )|( \.\.\.+:)")
output_prompt = re.compile("(\s*Result \[(?P<N>[0-9]+)\]: )|( \.\.\.+:)")
continue_prompt = re.compile(" \.\.\.+:")
tb_start = re.compile("\-+")
@@ -136,4 +136,4 @@ def setup(app):
#-----------------------------------------------------------------------------
# Register the extension as a valid pygments lexer
-highlighting.lexers['itango'] = TangoConsoleLexer()
\ No newline at end of file
+highlighting.lexers['itango'] = TangoConsoleLexer()
diff --git a/doc/start.rst b/doc/start.rst
index 24ecf5b..28483cb 100644
--- a/doc/start.rst
+++ b/doc/start.rst
@@ -281,8 +281,8 @@ then, in ITango type:
.. sourcecode:: itango
- ITango <homer:10000> [1]: PyTango.Release.version
- Result [1]: '7.2.3'
+ ITango [1]: PyTango.Release.version
+ Result [1]: '7.2.3'
(if you are wondering, :ref:`itango` automaticaly does ``import PyTango`` for you!)
@@ -299,4 +299,4 @@ and type:
Quick tour <quicktour>
Quick tour (original) <quicktour_old>
-.. _IPython: http://ipython.scipy.org/
\ No newline at end of file
+.. _IPython: http://ipython.scipy.org/
diff --git a/src/api_util.cpp b/src/api_util.cpp
index 6954487..0b82982 100644
--- a/src/api_util.cpp
+++ b/src/api_util.cpp
@@ -67,5 +67,7 @@ void export_api_util()
.def("is_event_consumer_created", &Tango::ApiUtil::is_event_consumer_created)
.def("get_user_connect_timeout", &Tango::ApiUtil::get_user_connect_timeout)
+
+ .def("get_ip_from_if", &Tango::ApiUtil::get_ip_from_if)
;
}
diff --git a/src/attribute_info.cpp b/src/attribute_info.cpp
index d9d9f18..215ef9c 100644
--- a/src/attribute_info.cpp
+++ b/src/attribute_info.cpp
@@ -30,7 +30,7 @@ void export_attribute_info()
{
class_<Tango::AttributeInfo, bases<Tango::DeviceAttributeConfig> >
("AttributeInfo")
- .def(init<const Tango::AttributeInfoEx&>())
+ .def(init<const Tango::AttributeInfo&>())
.def_readwrite("disp_level", &Tango::AttributeInfo::disp_level)
;
}
diff --git a/src/base_types.cpp b/src/base_types.cpp
index 7bf2839..b2fd009 100644
--- a/src/base_types.cpp
+++ b/src/base_types.cpp
@@ -176,30 +176,15 @@ int raise_asynch_exception(long thread_id, boost::python::object exp_klass)
return PyThreadState_SetAsyncExc(thread_id, exp_klass.ptr());
}
-bool isBufferLikeType(PyObject* obj)
-{
-#if PY_VERSION_HEX < 0x02060000
- // Returns true for buffer
- if (PyBuffer_Check(obj))
- return true;
- if (PyString_Check(obj))
- return true;
-#else
- // Returns true for str, buffer bytes, bytearray, memoryview
- if (PyObject_CheckBuffer(obj))
- return true;
-#endif
- return false;
-}
-
void export_base_types()
{
enum_<PyTango::ExtractAs>("ExtractAs")
.value("Numpy", PyTango::ExtractAsNumpy)
+ .value("ByteArray", PyTango::ExtractAsByteArray)
+ .value("Bytes", PyTango::ExtractAsBytes)
.value("Tuple", PyTango::ExtractAsTuple)
.value("List", PyTango::ExtractAsList)
.value("String", PyTango::ExtractAsString)
- .value("PyTango3", PyTango::ExtractAsPyTango3)
.value("Nothing", PyTango::ExtractAsNothing)
;
@@ -276,6 +261,9 @@ void export_base_types()
class_<std::vector<Tango::DbHistory> >("DbHistoryList")
.def(vector_indexing_suite<std::vector<Tango::DbHistory>, true>());
+ class_<std::vector<Tango::DeviceData> >("DeviceDataList")
+ .def(vector_indexing_suite<std::vector<Tango::DeviceData>, true>());
+
class_<Tango::DeviceDataHistoryList>("DeviceDataHistoryList")
.def(vector_indexing_suite<Tango::DeviceDataHistoryList, true>());
@@ -291,8 +279,8 @@ void export_base_types()
class_< StdGroupAttrReplyVector_ >("StdGroupAttrReplyVector")
.def(vector_indexing_suite<StdGroupAttrReplyVector_, true>());
- //to_python_converter<CORBA::String_member, CORBA_String_member_to_str>();
- to_python_converter<_CORBA_String_member, CORBA_String_member_to_str2>();
+ to_python_converter<CORBA::String_member, CORBA_String_member_to_str>();
+ //to_python_converter<_CORBA_String_member, CORBA_String_member_to_str2>();
to_python_converter<_CORBA_String_element, CORBA_String_element_to_str>();
to_python_converter<Tango::DevErrorList, CORBA_sequence_to_tuple<Tango::DevErrorList> >();
@@ -363,6 +351,4 @@ void export_base_types()
export_time_val();
def("raise_asynch_exception", &raise_asynch_exception);
-
- def("isBufferLikeType", &isBufferLikeType);
}
diff --git a/src/connection.cpp b/src/connection.cpp
index 2317801..a8ca2c4 100644
--- a/src/connection.cpp
+++ b/src/connection.cpp
@@ -159,5 +159,6 @@ void export_connection()
.def("get_access_control", &Tango::Connection::get_access_control)
.def("set_access_control", &Tango::Connection::set_access_control)
+ .def("get_access_right", &Tango::Connection::get_access_right)
;
}
diff --git a/src/constants.cpp b/src/constants.cpp
index cf31f66..d54044a 100644
--- a/src/constants.cpp
+++ b/src/constants.cpp
@@ -43,17 +43,6 @@ void export_constants()
consts_scope.attr("NUMPY_SUPPORT") = true;
#endif
- str py_TgLibVers = TgLibVers;
- boost::python::list pylist_TgLibVers = py_TgLibVers.split(".");
- long_ major = long_(pylist_TgLibVers[0]);
- long_ minor = long_(pylist_TgLibVers[1]);
- long_ patch = long_(pylist_TgLibVers[2]);
- object h = "0x%02d%02d%02d00" % boost::python::make_tuple(major, minor, patch);
- PyObject *ptr = PyInt_FromString(PyString_AsString(h.ptr()), NULL, 0);
- TANGO_VERSION_HEX = PyInt_AsLong(ptr);
- Py_DECREF(ptr);
- consts_scope.attr("TANGO_VERSION_HEX") = TANGO_VERSION_HEX;
-
//
// From tango_const.h
//
@@ -61,6 +50,9 @@ void export_constants()
//
// Some general interest define
//
+ consts_scope.attr("TANGO_VERSION_MAJOR") = TANGO_VERSION_MAJOR;
+ consts_scope.attr("TANGO_VERSION_MINOR") = TANGO_VERSION_MINOR;
+ consts_scope.attr("TANGO_VERSION_PATCH") = TANGO_VERSION_PATCH;
consts_scope.attr("TgLibVers") = TgLibVers;
consts_scope.attr("DevVersion") = DevVersion;
@@ -195,4 +187,13 @@ void export_constants()
consts_scope.attr("NotANumber") = NotANumber;
consts_scope.attr("MemNotUsed") = MemNotUsed;
consts_scope.attr("MemAttrPropName") = MemAttrPropName;
+
+#ifdef TANGO_LONG64
+ consts_scope.attr("TANGO_LONG32") = false;
+ consts_scope.attr("TANGO_LONG64") = true;
+#else
+ consts_scope.attr("TANGO_LONG32") = true;
+ consts_scope.attr("TANGO_LONG64") = false;
+#endif
+
}
diff --git a/src/database.cpp b/src/database.cpp
index d8edef7..c7b1910 100644
--- a/src/database.cpp
+++ b/src/database.cpp
@@ -25,8 +25,6 @@
#include "defs.h"
#include "pytgutils.h"
-using namespace boost::python;
-
extern const char *param_must_be_seq;
extern const char *unreachable_code;
extern const char *non_string_seq;
@@ -36,18 +34,18 @@ const char *param_numb_or_str_numb = "Second parameter must be an int or a "
struct PyDatabase
{
- struct PickleSuite : pickle_suite
+ struct PickleSuite : bopy::pickle_suite
{
- static tuple getinitargs(Tango::Database& self)
+ static bopy::tuple getinitargs(Tango::Database& self)
{
std::string& host = self.get_db_host();
std::string& port = self.get_db_port();
if (host.size() > 0 && port.size() > 0)
{
- return make_tuple(host, port);
+ return bopy::make_tuple(host, port);
}
else
- return make_tuple();
+ return bopy::make_tuple();
}
};
@@ -218,16 +216,14 @@ void export_database()
void (Tango::Database::*delete_attribute_alias_)(std::string &) =
&Tango::Database::delete_attribute_alias;
-
- class_<Tango::Database, bases<Tango::Connection> > Database(
- "Database",
- init<>())
+ bopy::class_<Tango::Database, bopy::bases<Tango::Connection> > Database("Database", bopy::init<>())
;
Database
- .def("__init__", make_constructor(PyDatabase::makeDatabase_host_port1))
- .def("__init__", make_constructor(PyDatabase::makeDatabase_host_port2))
- .def("__init__", make_constructor(PyDatabase::makeDatabase_file))
+ .def(bopy::init<const Tango::Database &>())
+ .def("__init__", bopy::make_constructor(PyDatabase::makeDatabase_host_port1))
+ .def("__init__", bopy::make_constructor(PyDatabase::makeDatabase_host_port2))
+ .def("__init__", bopy::make_constructor(PyDatabase::makeDatabase_file))
//
// Pickle
@@ -249,10 +245,10 @@ void export_database()
&Tango::Database::set_access_checked)
.def("get_access_except_errors",
&Tango::Database::get_access_except_errors,
- return_internal_reference<1>())
+ bopy::return_internal_reference<1>())
.def("is_multi_tango_host", &Tango::Database::is_multi_tango_host)
.def("get_file_name", &Tango::Database::get_file_name,
- return_value_policy<copy_const_reference>())
+ bopy::return_value_policy<bopy::copy_const_reference>())
//
// General methods
@@ -362,7 +358,8 @@ void export_database()
.def("get_device_class_list",
(Tango::DbDatum (Tango::Database::*) (const std::string &))
get_device_class_list_)
-
+ .def("get_server_release", &Tango::Database::get_server_release)
+
//
// property methods
//
diff --git a/src/defs.h b/src/defs.h
index 0dbdbb0..f837c78 100644
--- a/src/defs.h
+++ b/src/defs.h
@@ -34,10 +34,11 @@ namespace PyTango
{
enum ExtractAs {
ExtractAsNumpy,
+ ExtractAsByteArray,
+ ExtractAsBytes,
ExtractAsTuple,
ExtractAsList,
ExtractAsString,
- ExtractAsPyTango3,
ExtractAsNothing
};
diff --git a/src/dev_error.cpp b/src/dev_error.cpp
index 1fb80e2..c630721 100644
--- a/src/dev_error.cpp
+++ b/src/dev_error.cpp
@@ -22,26 +22,25 @@
*******************************************************************************/
#include "precompiled_header.hpp"
+#include "pyutils.h"
#include <tango.h>
-using namespace boost::python;
-
struct PyDevError
{
static inline PyObject* get_reason(Tango::DevError &de)
- { return PyString_FromString(de.reason); }
+ { return from_char_to_str(de.reason); }
static inline PyObject* get_desc(Tango::DevError &de)
- { return PyString_FromString(de.desc); }
+ { return from_char_to_str(de.desc); }
static inline PyObject* get_origin(Tango::DevError &de)
- { return PyString_FromString(de.origin); }
+ { return from_char_to_str(de.origin); }
};
void export_dev_error()
{
- class_<Tango::DevError>("DevError")
+ bopy::class_<Tango::DevError>("DevError")
.add_property("reason", &PyDevError::get_reason)
.def_readonly("severity", &Tango::DevError::severity)
.add_property("desc", &PyDevError::get_desc)
diff --git a/src/device_attribute.cpp b/src/device_attribute.cpp
index 55c7445..306c3d6 100644
--- a/src/device_attribute.cpp
+++ b/src/device_attribute.cpp
@@ -44,33 +44,35 @@ static const char* has_failed_attr_name = "has_failed";
template<long tangoTypeConst>
-struct python_tangocpp {
+struct python_tangocpp
+{
typedef typename TANGO_const2type(tangoTypeConst) TangoScalarType;
- static inline void to_cpp(const object & py_value, TangoScalarType & result)
+ static inline void to_cpp(const bopy::object & py_value, TangoScalarType & result)
{
- result = extract<TangoScalarType>(py_value);
+ result = bopy::extract<TangoScalarType>(py_value);
}
- static inline object to_python(const TangoScalarType & value)
+ static inline bopy::object to_python(const TangoScalarType & value)
{
- return object(value);
+ return bopy::object(value);
}
};
template<>
-struct python_tangocpp<Tango::DEV_STRING> {
+struct python_tangocpp<Tango::DEV_STRING>
+{
static const long tangoTypeConst = Tango::DEV_STRING;
typedef TANGO_const2type(tangoTypeConst) TangoScalarType;
- static inline void to_cpp(const object & py_value, TangoScalarType & result)
+ static inline void to_cpp(const bopy::object & py_value, TangoScalarType & result)
{
- result = CORBA::string_dup(extract<TangoScalarType>(py_value));
+ result = CORBA::string_dup(bopy::extract<TangoScalarType>(py_value));
}
- static inline object to_python(const TangoScalarType & value)
+ static inline bopy::object to_python(const TangoScalarType & value)
{
- return object(std::string(value));
+ return bopy::object(std::string(value));
}
};
@@ -78,175 +80,278 @@ struct python_tangocpp<Tango::DEV_STRING> {
# include "device_attribute_numpy.hpp"
#endif
-namespace PyDeviceAttribute {
+#define EXTRACT_VALUE(self, value_ptr) \
+try { \
+ self >> value_ptr; \
+} catch (Tango::DevFailed &e ) { \
+ if (strcmp(e.errors[0].reason.in(),"API_EmptyDeviceAttribute") != 0) \
+ throw; \
+}
+
- template<long tangoTypeConst>
- static inline void _update_value_as_string(Tango::DeviceAttribute &self, object py_value)
+namespace PyDeviceAttribute
+{
+ template<long tangoTypeConst> static inline void
+ _update_value_as_bin(Tango::DeviceAttribute &self,
+ bopy::object py_value, bool read_only)
{
typedef typename TANGO_const2type(tangoTypeConst) TangoScalarType;
typedef typename TANGO_const2arraytype(tangoTypeConst) TangoArrayType;
// Extract the actual data from Tango::DeviceAttribute (self)
TangoArrayType* value_ptr = 0;
- try {
- self >> value_ptr;
- } catch (Tango::DevFailed &e ) {
- if (strcmp(e.errors[0].reason.in(),"API_EmptyDeviceAttribute") != 0)
- throw;
- }
- std::auto_ptr<TangoArrayType> guard_value_ptr(value_ptr);
+ EXTRACT_VALUE(self, value_ptr)
+ unique_pointer<TangoArrayType> guard_value_ptr(value_ptr);
- if (value_ptr == 0) {
- py_value.attr(value_attr_name) = boost::python::str();
- py_value.attr(w_value_attr_name) = object();
+ py_value.attr(w_value_attr_name) = bopy::object();
+
+ if (value_ptr == 0)
+ {
+ if (read_only)
+ {
+ py_value.attr(value_attr_name) =
+ bopy::object(bopy::handle<>(_PyObject_New(&PyBytes_Type)));
+ }
+ else
+ {
+ py_value.attr(value_attr_name) =
+ bopy::object(bopy::handle<>(_PyObject_New(&PyByteArray_Type)));
+ }
return;
}
TangoScalarType* buffer = value_ptr->get_buffer();
const char *ch_ptr = reinterpret_cast<char *>(buffer);
- size_t nb_bytes = value_ptr->length() * sizeof(TangoScalarType);
+ Py_ssize_t nb_bytes = (Py_ssize_t)value_ptr->length() * sizeof(TangoScalarType);
- py_value.attr(value_attr_name) = str(ch_ptr, (size_t)nb_bytes);
- py_value.attr(w_value_attr_name) = object();
+ PyObject* data_ptr = NULL;
+ if (read_only)
+ {
+ data_ptr = PyBytes_FromStringAndSize(ch_ptr, nb_bytes);
+ }
+ else
+ {
+ data_ptr = PyByteArray_FromStringAndSize(ch_ptr, nb_bytes);
+ }
+ py_value.attr(value_attr_name) = bopy::object(bopy::handle<>(data_ptr));
}
- template<>
- inline void _update_value_as_string<Tango::DEV_ENCODED>(Tango::DeviceAttribute &self, object py_value)
+ template<> inline void
+ _update_value_as_bin<Tango::DEV_ENCODED>(Tango::DeviceAttribute &self,
+ bopy::object py_value,
+ bool read_only)
{
- Tango::DevVarEncodedArray* value;
- self >> value;
- std::auto_ptr<Tango::DevVarEncodedArray> guard(value);
+ Tango::DevVarEncodedArray* value_ptr;
+ EXTRACT_VALUE(self, value_ptr)
+ unique_pointer<Tango::DevVarEncodedArray> guard(value_ptr);
- Tango::DevEncoded* buffer = value->get_buffer();
+ Tango::DevEncoded* buffer = value_ptr->get_buffer();
+ Tango::DevEncoded& r_buffer = buffer[0];
+ bopy::str r_encoded_format(r_buffer.encoded_format);
- boost::python::str encoded_format(buffer[0].encoded_format);
- boost::python::str encoded_data((const char*)buffer[0].encoded_data.get_buffer(),
- buffer[0].encoded_data.length());
+ Tango::DevVarCharArray& r_encoded_data_array = r_buffer.encoded_data;
+ char* r_ch_ptr = (char*) r_encoded_data_array.get_buffer();
+ Py_ssize_t r_size = r_encoded_data_array.length();
+ PyObject* r_encoded_data_ptr = NULL;
+ if (read_only)
+ {
+ r_encoded_data_ptr = PyBytes_FromStringAndSize(r_ch_ptr, r_size);
+ }
+ else
+ {
+ r_encoded_data_ptr = PyByteArray_FromStringAndSize(r_ch_ptr, r_size);
+ }
+ bopy::object r_encoded_data = bopy::object(bopy::handle<>(r_encoded_data_ptr));
+
+ py_value.attr(value_attr_name) =
+ bopy::make_tuple(r_encoded_format, r_encoded_data);
+
+ if (self.get_written_dim_x() > 0)
+ {
+ bool is_write_type = self.get_written_dim_x() && (value_ptr->length() < 2);
+ if (is_write_type)
+ {
+ bopy::object w_encoded_format(r_encoded_format);
+ bopy::object w_encoded_data(r_encoded_data);
+ py_value.attr(w_value_attr_name) =
+ bopy::make_tuple(w_encoded_format, w_encoded_data);
+ }
+ else
+ {
+ Tango::DevEncoded& w_buffer = buffer[1];
+ bopy::str w_encoded_format(w_buffer.encoded_format);
+
+ Tango::DevVarCharArray& w_encoded_data_array = w_buffer.encoded_data;
+ char* w_ch_ptr = (char*) w_encoded_data_array.get_buffer();
+ PyObject* w_encoded_data_ptr = NULL;
+ PyByteArray_FromStringAndSize(w_ch_ptr, w_encoded_data_array.length());
+ Py_ssize_t w_size = w_encoded_data_array.length();
+ if (read_only)
+ {
+ w_encoded_data_ptr = PyBytes_FromStringAndSize(w_ch_ptr, w_size);
+ }
+ else
+ {
+ w_encoded_data_ptr = PyByteArray_FromStringAndSize(w_ch_ptr, w_size);
+ }
+ bopy::object w_encoded_data = bopy::object(bopy::handle<>(w_encoded_data_ptr));
+
+ py_value.attr(value_attr_name) =
+ bopy::make_tuple(w_encoded_format, w_encoded_data);
+ }
+ }
+ else
+ {
+ py_value.attr(w_value_attr_name) = bopy::object();
+ }
+ }
+
+ template<long tangoTypeConst> static inline void
+ _update_value_as_string(Tango::DeviceAttribute &self,
+ bopy::object py_value)
+ {
+ typedef typename TANGO_const2type(tangoTypeConst) TangoScalarType;
+ typedef typename TANGO_const2arraytype(tangoTypeConst) TangoArrayType;
+
+ // Extract the actual data from Tango::DeviceAttribute (self)
+ TangoArrayType* value_ptr = 0;
+ EXTRACT_VALUE(self, value_ptr)
+ unique_pointer<TangoArrayType> guard_value_ptr(value_ptr);
+
+ if (value_ptr == 0)
+ {
+ py_value.attr(value_attr_name) = bopy::str();
+ py_value.attr(w_value_attr_name) = bopy::object();
+ return;
+ }
+
+ TangoScalarType* buffer = value_ptr->get_buffer();
+
+ const char* ch_ptr = reinterpret_cast<char *>(buffer);
+ size_t nb_bytes = value_ptr->length() * sizeof(TangoScalarType);
+
+ py_value.attr(value_attr_name) = bopy::str(ch_ptr, (size_t)nb_bytes);
+ py_value.attr(w_value_attr_name) = bopy::object();
+ }
+
+ template<> inline void
+ _update_value_as_string<Tango::DEV_ENCODED>(Tango::DeviceAttribute &self,
+ bopy::object py_value)
+ {
+ Tango::DevVarEncodedArray* value_ptr;
+ EXTRACT_VALUE(self, value_ptr)
+ unique_pointer<Tango::DevVarEncodedArray> guard(value_ptr);
- py_value.attr(value_attr_name) = boost::python::make_tuple(encoded_format, encoded_data);
-
- if (self.get_written_dim_x() > 0) {
- bool is_write_type = self.get_written_dim_x() && (value->length() < 2);
- if (is_write_type) {
- object w_encoded_format(encoded_format);
- object w_encoded_data(encoded_data);
- py_value.attr(w_value_attr_name) = boost::python::make_tuple(w_encoded_format, w_encoded_data);
- } else {
- str w_encoded_format(buffer[1].encoded_format);
- str w_encoded_data((const char*)buffer[1].encoded_data.get_buffer(),
- buffer[1].encoded_data.length());
- py_value.attr(w_value_attr_name) = boost::python::make_tuple(w_encoded_format, w_encoded_data);
+ Tango::DevEncoded* buffer = value_ptr->get_buffer();
+
+ Tango::DevEncoded& r_buffer = buffer[0];
+ bopy::str r_encoded_format(r_buffer.encoded_format);
+
+ Tango::DevVarCharArray& r_encoded_data_array = r_buffer.encoded_data;
+ char* r_ch_ptr = (char*)r_encoded_data_array.get_buffer();
+ bopy::str r_encoded_data(r_ch_ptr, r_encoded_data_array.length());
+
+ py_value.attr(value_attr_name) =
+ bopy::make_tuple(r_encoded_format, r_encoded_data);
+
+ if (self.get_written_dim_x() > 0)
+ {
+ bool is_write_type = self.get_written_dim_x() && (value_ptr->length() < 2);
+ if (is_write_type)
+ {
+ bopy::object w_encoded_format(r_encoded_format);
+ bopy::object w_encoded_data(r_encoded_data);
+ py_value.attr(w_value_attr_name) =
+ bopy::make_tuple(w_encoded_format, w_encoded_data);
}
- } else {
- py_value.attr(w_value_attr_name) = object();
+ else
+ {
+ Tango::DevEncoded& w_buffer = buffer[1];
+ bopy::str w_encoded_format(w_buffer.encoded_format);
+
+ Tango::DevVarCharArray& w_encoded_data_array = w_buffer.encoded_data;
+ char* w_ch_ptr = (char*)w_encoded_data_array.get_buffer();
+ bopy::str w_encoded_data(w_ch_ptr, w_encoded_data_array.length());
+ py_value.attr(w_value_attr_name) =
+ bopy::make_tuple(w_encoded_format, w_encoded_data);
+ }
+ }
+ else
+ {
+ py_value.attr(w_value_attr_name) = bopy::object();
}
}
-
- template<long tangoTypeConst>
- static inline void _update_scalar_values(Tango::DeviceAttribute &self, object py_value)
+
+ template<long tangoTypeConst> static inline void
+ _update_scalar_values(Tango::DeviceAttribute &self, bopy::object py_value)
{
typedef typename TANGO_const2type(tangoTypeConst) TangoScalarType;
- if (self.get_written_dim_x() > 0) {
+ if (self.get_written_dim_x() > 0)
+ {
std::vector<TangoScalarType> val;
self.extract_read(val);
// In the following lines, the cast is absolutely necessary because
// vector<TangoScalarType> may not be a vector<TangoScalarType> at
// compile time. For example, for vector<DevBoolean>, the compiler
// may create a std::_Bit_reference type.
- py_value.attr(value_attr_name) = object((TangoScalarType)val[0]);
+ py_value.attr(value_attr_name) = bopy::object((TangoScalarType)val[0]);
self.extract_set(val);
- py_value.attr(w_value_attr_name) = object((TangoScalarType)val[0]);
- } else {
+ py_value.attr(w_value_attr_name) = bopy::object((TangoScalarType)val[0]);
+ }
+ else
+ {
TangoScalarType rvalue;
- self >> rvalue;
- py_value.attr(value_attr_name) = object(rvalue);
- py_value.attr(w_value_attr_name) = object();
+ EXTRACT_VALUE(self, rvalue)
+ py_value.attr(value_attr_name) = bopy::object(rvalue);
+ py_value.attr(w_value_attr_name) = bopy::object();
}
}
- template<>
- inline void _update_scalar_values<Tango::DEV_ENCODED>(Tango::DeviceAttribute &self, object py_value)
+ template<> inline void
+ _update_scalar_values<Tango::DEV_ENCODED>(Tango::DeviceAttribute &self,
+ bopy::object py_value)
{
- Tango::DevVarEncodedArray* value;
- self >> value;
- std::auto_ptr<Tango::DevVarEncodedArray> guard_value(value);
-
- Tango::DevEncoded* buffer = value->get_buffer();
-
- boost::python::str r_encoded_format(buffer[0].encoded_format);
-
- Tango::DevVarCharArray &encReadBuffer = buffer[0].encoded_data;
- Py_ssize_t size = encReadBuffer.length();
-
- char *rawReadBuffer = (char *)encReadBuffer.get_buffer();
- PyObject *readArray = PyString_FromStringAndSize(rawReadBuffer, size);
-
- object r_encoded_data = object(handle<>(readArray));
-
- py_value.attr(value_attr_name) = boost::python::make_tuple(r_encoded_format, r_encoded_data);
-
- if (self.get_written_dim_x() > 0) {
- bool is_write_type = self.get_written_dim_x() && (value->length() < 2);
- if (is_write_type) {
- object w_encoded_format(r_encoded_format);
- object w_encoded_data(r_encoded_data);
- py_value.attr(w_value_attr_name) = boost::python::make_tuple(w_encoded_format, w_encoded_data);
- } else {
- str w_encoded_format(buffer[1].encoded_format);
-
- Tango::DevVarCharArray &encWriteBuffer = buffer[1].encoded_data;
- int size = encWriteBuffer.length();
- CORBA::Octet *rawWriteBuffer = encWriteBuffer.get_buffer(1);
-
- PyObject *writeArray = PyBuffer_FromReadWriteMemory(rawWriteBuffer, size);
-
- object w_encoded_data = object(handle<>(writeArray));
-
- py_value.attr(w_value_attr_name) = boost::python::make_tuple(w_encoded_format, w_encoded_data);
- }
- } else {
- py_value.attr(w_value_attr_name) = object();
- }
+ _update_value_as_string<Tango::DEV_ENCODED>(self, py_value);
}
- template<>
- inline void _update_scalar_values<Tango::DEV_STRING>(Tango::DeviceAttribute &self, object py_value)
+ template<> inline void
+ _update_scalar_values<Tango::DEV_STRING>(Tango::DeviceAttribute &self,
+ bopy::object py_value)
{
- if (self.get_written_dim_x() > 0) {
- std::vector<std::string> val;
- self.extract_read(val);
- py_value.attr(value_attr_name) = object(val[0]);
- self.extract_set(val);
- py_value.attr(w_value_attr_name) = object(val[0]);
- } else {
+ if (self.get_written_dim_x() > 0)
+ {
+ std::vector<std::string> r_val, w_val;
+ self.extract_read(r_val);
+ py_value.attr(value_attr_name) = object(r_val[0]);
+ self.extract_set(w_val);
+ py_value.attr(w_value_attr_name) = object(w_val[0]);
+ }
+ else
+ {
std::string rvalue;
- self >> rvalue;
+ EXTRACT_VALUE(self, rvalue)
py_value.attr(value_attr_name) = object(rvalue);
py_value.attr(w_value_attr_name) = object();
}
}
- template<long tangoTypeConst>
- static inline void _update_array_values_as_lists(Tango::DeviceAttribute &self, bool isImage, object py_value)
+ template<long tangoTypeConst> static inline void
+ _update_array_values_as_lists(Tango::DeviceAttribute &self, bool isImage,
+ bopy::object py_value)
{
typedef typename TANGO_const2type(tangoTypeConst) TangoScalarType;
typedef typename TANGO_const2arraytype(tangoTypeConst) TangoArrayType;
// Extract the actual data from Tango::DeviceAttribute (self)
TangoArrayType* value_ptr = 0;
- try {
- self >> value_ptr;
- } catch (Tango::DevFailed &e ) {
- if (strcmp(e.errors[0].reason.in(),"API_EmptyDeviceAttribute") != 0)
- throw;
- }
- std::auto_ptr<TangoArrayType> guard_value_ptr(value_ptr);
+ EXTRACT_VALUE(self, value_ptr)
+ unique_pointer<TangoArrayType> guard_value_ptr(value_ptr);
if (value_ptr == 0) {
// Empty device attribute
- py_value.attr(value_attr_name) = boost::python::list();
+ py_value.attr(value_attr_name) = bopy::list();
py_value.attr(w_value_attr_name) = object();
return;
}
@@ -272,14 +377,14 @@ namespace PyDeviceAttribute {
py_value.attr(w_value_attr_name) = py_value.attr(value_attr_name);
continue;
}
- boost::python::list result;
+ bopy::list result;
if (isImage) {
const int dim_x = it? self.get_dim_x() : self.get_written_dim_x();
const int dim_y = it? self.get_dim_y() : self.get_written_dim_y();
for (int y=0; y < dim_y; ++y) {
- boost::python::list row;
+ bopy::list row;
for (int x=0; x < dim_x; ++x)
row.append(python_tangocpp<tangoTypeConst>::to_python(buffer[offset + x + y*dim_x]));
result.append(row);
@@ -295,67 +400,21 @@ namespace PyDeviceAttribute {
}
}
- template<long tangoTypeConst>
- static inline void _update_array_values_as_pytango3(Tango::DeviceAttribute &self, bool isImage, object py_value)
+ template<long tangoTypeConst> static void
+ _update_array_values_as_tuples(Tango::DeviceAttribute &self, bool isImage,
+ bopy::object py_value)
{
typedef typename TANGO_const2type(tangoTypeConst) TangoScalarType;
typedef typename TANGO_const2arraytype(tangoTypeConst) TangoArrayType;
// Extract the actual data from Tango::DeviceAttribute (self)
TangoArrayType* value_ptr = 0;
- try {
- self >> value_ptr;
- } catch (Tango::DevFailed &e ) {
- if (strcmp(e.errors[0].reason.in(),"API_EmptyDeviceAttribute") != 0)
- throw;
- }
- std::auto_ptr<TangoArrayType> guard_value_ptr(value_ptr);
+ EXTRACT_VALUE(self, value_ptr)
+ unique_pointer<TangoArrayType> guard_value_ptr(value_ptr);
if (value_ptr == 0) {
// Empty device attribute
- py_value.attr(value_attr_name) = boost::python::list();
- py_value.attr(w_value_attr_name) = object();
- return;
- }
-
- TangoScalarType* buffer = value_ptr->get_buffer();
-
- long sz = value_ptr->length();
- boost::python::list res;
- for (long x =0; x<sz; ++x) {
- res.append(python_tangocpp<tangoTypeConst>::to_python(buffer[x]));
- }
-
- py_value.attr(value_attr_name) = res;
- py_value.attr(w_value_attr_name) = object();
- }
-
- template<>
- inline void _update_array_values_as_pytango3<Tango::DEV_ENCODED>(Tango::DeviceAttribute &self, bool isImage, object py_value)
- {
- /// @todo DevEncoded didn't even exist in PyTango3...
- _update_array_values_as_tuples<Tango::DEV_ENCODED>(self, isImage, py_value);
- }
-
- template<long tangoTypeConst>
- void _update_array_values_as_tuples(Tango::DeviceAttribute &self, bool isImage, object py_value)
- {
- typedef typename TANGO_const2type(tangoTypeConst) TangoScalarType;
- typedef typename TANGO_const2arraytype(tangoTypeConst) TangoArrayType;
-
- // Extract the actual data from Tango::DeviceAttribute (self)
- TangoArrayType* value_ptr = 0;
- try {
- self >> value_ptr;
- } catch (Tango::DevFailed &e ) {
- if (strcmp(e.errors[0].reason.in(),"API_EmptyDeviceAttribute") != 0)
- throw;
- }
- std::auto_ptr<TangoArrayType> guard_value_ptr(value_ptr);
-
- if (value_ptr == 0) {
- // Empty device attribute
- py_value.attr(value_attr_name) = boost::python::tuple();
+ py_value.attr(value_attr_name) = bopy::tuple();
py_value.attr(w_value_attr_name) = object();
return;
}
@@ -389,13 +448,13 @@ namespace PyDeviceAttribute {
PyObject * result = PyTuple_New(dim_y);
if (!result)
- boost::python::throw_error_already_set();
+ bopy::throw_error_already_set();
result_guard = object(handle<>(result));
for (int y=0; y < dim_y; ++y) {
PyObject * row = PyTuple_New(dim_x);
if (!row)
- boost::python::throw_error_already_set();
+ bopy::throw_error_already_set();
object row_guard = object(handle<>(row));
for (int x=0; x < dim_x; ++x) {
object el = python_tangocpp<tangoTypeConst>::to_python(buffer[offset + x + y*dim_x]);
@@ -411,7 +470,7 @@ namespace PyDeviceAttribute {
PyObject * result = PyTuple_New(dim_x);
if (!result)
- boost::python::throw_error_already_set();
+ bopy::throw_error_already_set();
result_guard = object(handle<>(result));
for (int x=0; x < dim_x; ++x) {
@@ -425,13 +484,16 @@ namespace PyDeviceAttribute {
}
}
- void update_values(Tango::DeviceAttribute &self, object& py_value, PyTango::ExtractAs extract_as/*=ExtractAsNumpy*/)
+ void
+ update_values(Tango::DeviceAttribute &self, bopy::object& py_value,
+ PyTango::ExtractAs extract_as/*=ExtractAsNumpy*/)
{
// We do not want is_empty to launch an exception!!
self.reset_exceptions(Tango::DeviceAttribute::isempty_flag);
+
// self.get_type() already does self.is_empty()
const int data_type = self.get_type();
- const bool is_empty = data_type < 0; /*self.is_empty()*/
+ const bool is_empty = data_type < 0;
const bool has_failed = self.has_failed();
Tango::AttrDataFormat data_format = self.get_data_format();
@@ -449,23 +511,40 @@ namespace PyDeviceAttribute {
bool is_image = false;
switch (data_format) {
case Tango::SCALAR:
- switch (extract_as)
+ if (data_type == Tango::DEV_ENCODED)
{
- default:
- case PyTango::ExtractAsNumpy:
- case PyTango::ExtractAsTuple:
- case PyTango::ExtractAsList:
- TANGO_CALL_ON_ATTRIBUTE_DATA_TYPE(data_type, _update_scalar_values, self, py_value);
- break;
- case PyTango::ExtractAsString:
- TANGO_CALL_ON_ATTRIBUTE_DATA_TYPE(data_type, _update_value_as_string, self, py_value);
- break;
- case PyTango::ExtractAsPyTango3:
- TANGO_CALL_ON_ATTRIBUTE_DATA_TYPE(data_type, _update_scalar_values, self, py_value);
- py_value.attr("w_scalar_value") = py_value.attr(w_value_attr_name);
- break;
- case PyTango::ExtractAsNothing:
- break;
+ switch (extract_as)
+ {
+ default:
+ case PyTango::ExtractAsNumpy:
+ case PyTango::ExtractAsTuple:
+ case PyTango::ExtractAsList:
+ TANGO_CALL_ON_ATTRIBUTE_DATA_TYPE(data_type,
+ _update_scalar_values, self, py_value);
+ break;
+ case PyTango::ExtractAsBytes:
+ TANGO_CALL_ON_ATTRIBUTE_DATA_TYPE(data_type,
+ _update_value_as_bin, self, py_value, true);
+ break;
+ case PyTango::ExtractAsByteArray:
+ TANGO_CALL_ON_ATTRIBUTE_DATA_TYPE(data_type,
+ _update_value_as_bin, self, py_value, false);
+ break;
+ case PyTango::ExtractAsString:
+ TANGO_CALL_ON_ATTRIBUTE_DATA_TYPE(data_type,
+ _update_value_as_string, self, py_value);
+ break;
+ case PyTango::ExtractAsNothing:
+ break;
+ }
+ }
+ else
+ {
+ if (extract_as != PyTango::ExtractAsNothing)
+ {
+ TANGO_CALL_ON_ATTRIBUTE_DATA_TYPE(data_type,
+ _update_scalar_values, self, py_value);
+ }
}
break;
case Tango::IMAGE:
@@ -476,25 +555,29 @@ namespace PyDeviceAttribute {
default:
case PyTango::ExtractAsNumpy:
# ifndef DISABLE_PYTANGO_NUMPY
- TANGO_CALL_ON_ATTRIBUTE_DATA_TYPE(data_type, _update_array_values,
- self, is_image, py_value);
+ TANGO_CALL_ON_ATTRIBUTE_DATA_TYPE(data_type,
+ _update_array_values, self, is_image, py_value);
break;
# endif
case PyTango::ExtractAsTuple:
- TANGO_CALL_ON_ATTRIBUTE_DATA_TYPE(data_type, _update_array_values_as_tuples,
- self, is_image, py_value);
+ TANGO_CALL_ON_ATTRIBUTE_DATA_TYPE(data_type,
+ _update_array_values_as_tuples, self, is_image, py_value);
break;
case PyTango::ExtractAsList:
- TANGO_CALL_ON_ATTRIBUTE_DATA_TYPE(data_type, _update_array_values_as_lists,
- self, is_image, py_value);
+ TANGO_CALL_ON_ATTRIBUTE_DATA_TYPE(data_type,
+ _update_array_values_as_lists, self, is_image, py_value);
break;
- case PyTango::ExtractAsString:
- TANGO_CALL_ON_ATTRIBUTE_DATA_TYPE(data_type, _update_value_as_string,
- self, py_value);
+ case PyTango::ExtractAsBytes:
+ TANGO_CALL_ON_ATTRIBUTE_DATA_TYPE(data_type,
+ _update_value_as_bin, self, py_value, true);
break;
- case PyTango::ExtractAsPyTango3:
- TANGO_CALL_ON_ATTRIBUTE_DATA_TYPE(data_type, _update_array_values_as_pytango3,
- self, is_image, py_value);
+ case PyTango::ExtractAsByteArray:
+ TANGO_CALL_ON_ATTRIBUTE_DATA_TYPE(data_type,
+ _update_value_as_bin, self, py_value, false);
+ break;
+ case PyTango::ExtractAsString:
+ TANGO_CALL_ON_ATTRIBUTE_DATA_TYPE(data_type,
+ _update_value_as_string, self, py_value);
break;
case PyTango::ExtractAsNothing:
break;
@@ -507,8 +590,9 @@ namespace PyDeviceAttribute {
}
}
- template<long tangoTypeConst>
- static inline void _fill_list_attribute(Tango::DeviceAttribute & dev_attr, const bool isImage, const object & py_value)
+ template<long tangoTypeConst> static inline void
+ _fill_list_attribute(Tango::DeviceAttribute & dev_attr, const bool isImage,
+ const bopy::object & py_value)
{
typedef typename TANGO_const2type(tangoTypeConst) TangoScalarType;
typedef typename TANGO_const2arraytype(tangoTypeConst) TangoArrayType;
@@ -527,7 +611,7 @@ namespace PyDeviceAttribute {
}
// -- Allocate memory
- std::auto_ptr<TangoArrayType> value;
+ unique_pointer<TangoArrayType> value;
TangoScalarType* buffer = TangoArrayType::allocbuf(nelems);
try {
value.reset(new TangoArrayType(nelems, nelems, buffer, true));
@@ -559,20 +643,25 @@ namespace PyDeviceAttribute {
value.release(); // Do not delete value, it is handled by dev_attr now!
}
- template<>
- inline void _fill_list_attribute<Tango::DEV_ENCODED>(Tango::DeviceAttribute & dev_attr, const bool isImage, const object & py_value)
+ template<> inline void
+ _fill_list_attribute<Tango::DEV_ENCODED>(Tango::DeviceAttribute & dev_attr,
+ const bool isImage,
+ const bopy::object & py_value)
{
/// @todo really? This is really not gonna happen?
// Unsupported
assert(false);
}
- static inline object undefined_attribute(Tango::DeviceAttribute* self)
+ static inline bopy::object
+ undefined_attribute(Tango::DeviceAttribute* self)
{
return object(); // None
}
- void reset_values(Tango::DeviceAttribute & self, int data_type, Tango::AttrDataFormat data_format, object py_value)
+ void
+ reset_values(Tango::DeviceAttribute & self, int data_type,
+ Tango::AttrDataFormat data_format, bopy::object py_value)
{
bool isImage = false;
switch(data_format)
@@ -610,13 +699,17 @@ namespace PyDeviceAttribute {
}
}
- void reset(Tango::DeviceAttribute & self, const Tango::AttributeInfo &attr_info, object py_value)
+ void
+ reset(Tango::DeviceAttribute & self, const Tango::AttributeInfo &attr_info,
+ bopy::object py_value)
{
self.set_name(const_cast<std::string&>(attr_info.name));
reset_values(self, attr_info.data_type, attr_info.data_format, py_value);
}
- void reset(Tango::DeviceAttribute & self, const std::string &attr_name, Tango::DeviceProxy &dev_proxy, object py_value)
+ void
+ reset(Tango::DeviceAttribute & self, const std::string &attr_name,
+ Tango::DeviceProxy &dev_proxy, bopy::object py_value)
{
Tango::AttributeInfoEx attr_info;
{
@@ -661,5 +754,7 @@ void export_device_attribute()
return_internal_reference<>())
.def("get_err_stack", &Tango::DeviceAttribute::get_err_stack,
return_value_policy<copy_const_reference>())
+ .def("set_w_dim_x", &Tango::DeviceAttribute::set_w_dim_x)
+ .def("set_w_dim_y", &Tango::DeviceAttribute::set_w_dim_y)
;
}
diff --git a/src/device_attribute_config.cpp b/src/device_attribute_config.cpp
index a3fa257..9ad336c 100644
--- a/src/device_attribute_config.cpp
+++ b/src/device_attribute_config.cpp
@@ -29,7 +29,7 @@ using namespace boost::python;
void export_device_attribute_config()
{
class_<Tango::DeviceAttributeConfig>("DeviceAttributeConfig")
- .def(init<const Tango::AttributeInfoEx&>())
+ .def(init<const Tango::DeviceAttributeConfig&>())
.def_readwrite("name", &Tango::DeviceAttributeConfig::name)
.def_readwrite("writable", &Tango::DeviceAttributeConfig::writable)
.def_readwrite("data_format", &Tango::DeviceAttributeConfig::data_format)
@@ -37,7 +37,9 @@ void export_device_attribute_config()
.def_readwrite("max_dim_x", &Tango::DeviceAttributeConfig::max_dim_x)
.def_readwrite("max_dim_y", &Tango::DeviceAttributeConfig::max_dim_y)
.def_readwrite("description", &Tango::DeviceAttributeConfig::description)
- .def_readwrite("label", &Tango::DeviceAttributeConfig::label)
+ //.def_readwrite("label", &Tango::DeviceAttributeConfig::label)
+ .add_property("label", make_getter(&Tango::DeviceAttributeConfig::label, return_value_policy<return_by_value>()),
+ make_setter(&Tango::DeviceAttributeConfig::label, return_value_policy<return_by_value>()))
.def_readwrite("unit", &Tango::DeviceAttributeConfig::unit)
.def_readwrite("standard_unit", &Tango::DeviceAttributeConfig::standard_unit)
.def_readwrite("display_unit", &Tango::DeviceAttributeConfig::display_unit)
diff --git a/src/device_attribute_numpy.hpp b/src/device_attribute_numpy.hpp
index 90eeb92..069b3f0 100644
--- a/src/device_attribute_numpy.hpp
+++ b/src/device_attribute_numpy.hpp
@@ -35,14 +35,24 @@ namespace PyDeviceAttribute {
/// @param ptr_ The array object.
/// @param type_ The type of the array objects. We need it to convert ptr_
/// to the proper type before deleting it. ex: Tango::DEV_SHORT.
- static void _dev_var_x_array_deleter(void * ptr_, void *type_)
+#ifdef PYCAPSULE_OLD
+ template<long type>
+ static void _dev_var_x_array_deleter(void * ptr_)
{
- long type = reinterpret_cast<long>(type_);
-
TANGO_DO_ON_ATTRIBUTE_DATA_TYPE(type,
delete static_cast<TANGO_const2arraytype(tangoTypeConst)*>(ptr_);
);
}
+#else
+ template<long type>
+ static void _dev_var_x_array_deleter(PyObject* obj)
+ {
+ void * ptr_ = PyCapsule_GetPointer(obj, NULL);
+ TANGO_DO_ON_ATTRIBUTE_DATA_TYPE(type,
+ delete static_cast<TANGO_const2arraytype(tangoTypeConst)*>(ptr_);
+ );
+ }
+#endif
template<long tangoTypeConst>
static inline void _update_array_values(Tango::DeviceAttribute &self, bool isImage, object py_value)
@@ -123,18 +133,18 @@ namespace PyDeviceAttribute {
// the last copy of numpy.ndarray() disappears.
// PyCObject is intended for that kind of things. It's seen as a
// black box object from python. We assign him a function to be called
- // when it is deleted -> the function deletes de data.
- PyObject* guard = PyCObject_FromVoidPtrAndDesc(
+ // when it is deleted -> the function deletes the data.
+ PyObject* guard = PyCapsule_New(
static_cast<void*>(value_ptr),
- reinterpret_cast<void*>(tangoTypeConst),
- _dev_var_x_array_deleter);
+ NULL,
+ _dev_var_x_array_deleter<tangoTypeConst>);
if (!guard ) {
Py_XDECREF(array);
Py_XDECREF(warray);
delete value_ptr;
throw_error_already_set();
}
-
+
PyArray_BASE(array) = guard;
py_value.attr(value_attr_name) = boost::python::object(boost::python::handle<>(array));
diff --git a/src/device_data.cpp b/src/device_data.cpp
index 9e4845c..9123f54 100644
--- a/src/device_data.cpp
+++ b/src/device_data.cpp
@@ -50,6 +50,21 @@ namespace PyDeviceData {
self << val;
}
template <>
+ void insert_scalar<Tango::DEV_ENCODED>(Tango::DeviceData &self, object py_value)
+ {
+ object p0 = py_value[0];
+ object p1 = py_value[1];
+ const char* encoded_format = extract<const char *> (p0.ptr());
+ const char* encoded_data = extract<const char *> (p1.ptr());
+
+ CORBA::ULong nb = boost::python::len(p1);
+ Tango::DevVarCharArray arr(nb, nb, (CORBA::Octet*)encoded_data, false);
+ Tango::DevEncoded val;
+ val.encoded_format = CORBA::string_dup(encoded_format);
+ val.encoded_data = arr;
+ self << val;
+ }
+ template <>
void insert_scalar<Tango::DEV_VOID>(Tango::DeviceData &self, object py_value)
{
raise_(PyExc_TypeError, "Trying to insert a value in a DEV_VOID DeviceData!");
@@ -62,7 +77,7 @@ namespace PyDeviceData {
/// @{
template <long tangoArrayTypeConst>
void insert_array(Tango::DeviceData &self, object py_value)
- {
+ {
typedef typename TANGO_const2type(tangoArrayTypeConst) TangoArrayType;
// self << val; -->> This ends up doing:
@@ -131,7 +146,6 @@ namespace PyDeviceData {
return to_py_numpy<tangoArrayTypeConst>(tmp_ptr, py_self);
# endif
case PyTango::ExtractAsList:
- case PyTango::ExtractAsPyTango3:
return to_py_list(tmp_ptr);
case PyTango::ExtractAsTuple:
return to_py_tuple(tmp_ptr);
diff --git a/src/device_proxy.cpp b/src/device_proxy.cpp
index 1c7dd69..dfc6e8d 100644
--- a/src/device_proxy.cpp
+++ b/src/device_proxy.cpp
@@ -27,8 +27,6 @@
#include "defs.h"
#include "pytgutils.h"
-using namespace boost::python;
-
extern const char *param_must_be_seq;
extern const char *unreachable_code;
extern const char *non_string_seq;
@@ -38,12 +36,13 @@ BOOST_PYTHON_MEMBER_FUNCTION_OVERLOADS(unlock_overloads, Tango::DeviceProxy::unl
namespace PyDeviceProxy
{
- struct PickleSuite : pickle_suite
+ struct PickleSuite : bopy::pickle_suite
{
- static tuple getinitargs(Tango::DeviceProxy& self)
+ static bopy::tuple getinitargs(Tango::DeviceProxy& self)
{
- std::string ret = self.get_db_host() + ":" + self.get_db_port() + "/" + self.dev_name();
- return make_tuple(ret);
+ std::string ret = self.get_db_host() + ":" + self.get_db_port() +
+ "/" + self.dev_name();
+ return bopy::make_tuple(ret);
}
};
@@ -65,22 +64,23 @@ namespace PyDeviceProxy
return self.ping();
}
- static inline void pylist_to_devattrs(Tango::DeviceProxy& self, object &py_list, std::vector<Tango::DeviceAttribute> &dev_attrs)
+ static inline void pylist_to_devattrs(Tango::DeviceProxy& self,
+ bopy::object &py_list, std::vector<Tango::DeviceAttribute> &dev_attrs)
{
std::vector<std::string> attr_names;
- std::vector<object> py_values;
+ std::vector<bopy::object> py_values;
long size = len(py_list);
// Fill attr_names and py_values
for (long n = 0; n < size; ++n) {
- object tup = py_list[n];
- std::string attr_name = extract<std::string>(tup[0]);
+ bopy::object tup = py_list[n];
+ std::string attr_name = bopy::extract<std::string>(tup[0]);
attr_names.push_back(attr_name);
py_values.push_back(tup[1]);
}
// Get attr_info for all the attr_names
- std::auto_ptr<Tango::AttributeInfoListEx> attr_infos;
+ unique_pointer<Tango::AttributeInfoListEx> attr_infos;
{
AutoPythonAllowThreads guard;
attr_infos.reset(self.get_attribute_config_ex(attr_names));
@@ -93,7 +93,7 @@ namespace PyDeviceProxy
}
}
- static inline object read_attribute(Tango::DeviceProxy& self, const string & attr_name, PyTango::ExtractAs extract_as)
+ static inline bopy::object read_attribute(Tango::DeviceProxy& self, const string & attr_name, PyTango::ExtractAs extract_as)
{
// Even if there's an exception in convert_to_python, the
// DeviceAttribute will be deleted there, so we don't need to worry.
@@ -106,7 +106,7 @@ namespace PyDeviceProxy
return PyDeviceAttribute::convert_to_python(dev_attr, self, extract_as);
}
- static inline object read_attributes(Tango::DeviceProxy& self, object py_attr_names, PyTango::ExtractAs extract_as)
+ static inline bopy::object read_attributes(Tango::DeviceProxy& self, bopy::object py_attr_names, PyTango::ExtractAs extract_as)
{
CSequenceFromPython<StdStringVector> attr_names(py_attr_names);
@@ -119,7 +119,7 @@ namespace PyDeviceProxy
return PyDeviceAttribute::convert_to_python(dev_attr_vec, self, extract_as);
}
- static inline void write_attribute(Tango::DeviceProxy& self, const Tango::AttributeInfo & attr_info, object py_value)
+ static inline void write_attribute(Tango::DeviceProxy& self, const Tango::AttributeInfo & attr_info, bopy::object py_value)
{
Tango::DeviceAttribute da;
PyDeviceAttribute::reset(da, attr_info, py_value);
@@ -127,7 +127,7 @@ namespace PyDeviceProxy
self.write_attribute(da);
}
- static inline void write_attribute(Tango::DeviceProxy& self, const string & attr_name, object py_value)
+ static inline void write_attribute(Tango::DeviceProxy& self, const string & attr_name, bopy::object py_value)
{
Tango::DeviceAttribute dev_attr;
PyDeviceAttribute::reset(dev_attr, attr_name, self, py_value);
@@ -137,7 +137,7 @@ namespace PyDeviceProxy
}
}
- static inline void write_attributes(Tango::DeviceProxy& self, object py_list)
+ static inline void write_attributes(Tango::DeviceProxy& self, bopy::object py_list)
{
std::vector<Tango::DeviceAttribute> dev_attrs;
pylist_to_devattrs(self, py_list, dev_attrs);
@@ -146,10 +146,10 @@ namespace PyDeviceProxy
self.write_attributes(dev_attrs);
}
- static inline object write_read_attribute(Tango::DeviceProxy& self, const string & attr_name, object py_value, PyTango::ExtractAs extract_as)
+ static inline bopy::object write_read_attribute(Tango::DeviceProxy& self, const string & attr_name, bopy::object py_value, PyTango::ExtractAs extract_as)
{
Tango::DeviceAttribute w_dev_attr;
- std::auto_ptr<Tango::DeviceAttribute> r_dev_attr(0);
+ unique_pointer<Tango::DeviceAttribute> r_dev_attr;
// Prepare dev_attr structure
PyDeviceAttribute::reset(w_dev_attr, attr_name, self, py_value);
@@ -164,11 +164,11 @@ namespace PyDeviceProxy
return PyDeviceAttribute::convert_to_python(r_dev_attr.release(), self, extract_as);
}
- static inline object
- command_history(Tango::DeviceProxy& self, const std::string & cmd_name, int depth)
+ static inline bopy::object
+ command_history(Tango::DeviceProxy& self, const std::string& cmd_name, int depth)
{
- vector<Tango::DeviceDataHistory>* device_data_hist = NULL;
- boost::python::list ret;
+ std::vector<Tango::DeviceDataHistory>* device_data_hist = NULL;
+ bopy::list ret;
{
AutoPythonAllowThreads guard;
device_data_hist =
@@ -184,10 +184,10 @@ namespace PyDeviceProxy
return ret;
}
- static inline object
+ static inline bopy::object
attribute_history(Tango::DeviceProxy& self, const std::string & attr_name, int depth, PyTango::ExtractAs extract_as)
{
- std::auto_ptr< vector<Tango::DeviceAttributeHistory> > att_hist;
+ unique_pointer< vector<Tango::DeviceAttributeHistory> > att_hist;
{
AutoPythonAllowThreads guard;
att_hist.reset(self.attribute_history(const_cast<std::string&>(attr_name), depth));
@@ -196,7 +196,7 @@ namespace PyDeviceProxy
}
- static inline long read_attributes_asynch(Tango::DeviceProxy& self, object py_attr_names)
+ static inline long read_attributes_asynch(Tango::DeviceProxy& self, bopy::object py_attr_names)
{
CSequenceFromPython<StdStringVector> attr_names(py_attr_names);
@@ -206,7 +206,7 @@ namespace PyDeviceProxy
- static inline object read_attributes_reply(Tango::DeviceProxy& self, long id, PyTango::ExtractAs extract_as)
+ static inline bopy::object read_attributes_reply(Tango::DeviceProxy& self, long id, PyTango::ExtractAs extract_as)
{
PyDeviceAttribute::AutoDevAttrVector dev_attr_vec;
{
@@ -216,7 +216,7 @@ namespace PyDeviceProxy
return PyDeviceAttribute::convert_to_python(dev_attr_vec, self, extract_as);
}
- static inline object read_attributes_reply(Tango::DeviceProxy& self, long id, long timeout, PyTango::ExtractAs extract_as)
+ static inline bopy::object read_attributes_reply(Tango::DeviceProxy& self, long id, long timeout, PyTango::ExtractAs extract_as)
{
PyDeviceAttribute::AutoDevAttrVector dev_attr_vec;
{
@@ -226,7 +226,7 @@ namespace PyDeviceProxy
return PyDeviceAttribute::convert_to_python(dev_attr_vec, self, extract_as);
}
- static inline long write_attributes_asynch(Tango::DeviceProxy& self, object py_list)
+ static inline long write_attributes_asynch(Tango::DeviceProxy& self, bopy::object py_list)
{
std::vector<Tango::DeviceAttribute> dev_attrs;
pylist_to_devattrs(self, py_list, dev_attrs);
@@ -247,12 +247,12 @@ namespace PyDeviceProxy
self.write_attributes_reply(id);
}
- static inline void read_attributes_asynch(object py_self, object py_attr_names, object py_cb, PyTango::ExtractAs extract_as)
+ static inline void read_attributes_asynch(bopy::object py_self, bopy::object py_attr_names, bopy::object py_cb, PyTango::ExtractAs extract_as)
{
- Tango::DeviceProxy* self = extract<Tango::DeviceProxy*>(py_self);
+ Tango::DeviceProxy* self = bopy::extract<Tango::DeviceProxy*>(py_self);
CSequenceFromPython<StdStringVector> attr_names(py_attr_names);
- PyCallBackAutoDie* cb = extract<PyCallBackAutoDie*>(py_cb);
+ PyCallBackAutoDie* cb = bopy::extract<PyCallBackAutoDie*>(py_cb);
cb->set_autokill_references(py_cb, py_self);
cb->set_extract_as(extract_as);
@@ -265,13 +265,13 @@ namespace PyDeviceProxy
}
}
- static inline void write_attributes_asynch(object py_self, object py_list, object py_cb)
+ static inline void write_attributes_asynch(bopy::object py_self, bopy::object py_list, bopy::object py_cb)
{
- Tango::DeviceProxy* self = extract<Tango::DeviceProxy*>(py_self);
+ Tango::DeviceProxy* self = bopy::extract<Tango::DeviceProxy*>(py_self);
std::vector<Tango::DeviceAttribute> dev_attrs;
pylist_to_devattrs(*self, py_list, dev_attrs);
- PyCallBackAutoDie* cb = extract<PyCallBackAutoDie*>(py_cb);
+ PyCallBackAutoDie* cb = bopy::extract<PyCallBackAutoDie*>(py_cb);
cb->set_autokill_references(py_cb, py_self);
try {
@@ -284,21 +284,21 @@ namespace PyDeviceProxy
}
static int subscribe_event(
- object py_self,
+ bopy::object py_self,
const string &attr_name,
Tango::EventType event,
- object py_cb_or_queuesize,
- object &py_filters,
+ bopy::object py_cb_or_queuesize,
+ bopy::object &py_filters,
bool stateless,
PyTango::ExtractAs extract_as )
{
- Tango::DeviceProxy& self = extract<Tango::DeviceProxy&>(py_self);
+ Tango::DeviceProxy& self = bopy::extract<Tango::DeviceProxy&>(py_self);
CSequenceFromPython<StdStringVector> filters(py_filters);
PyCallBackPushEvent* cb = 0;
int event_queue_size = 0;
- if (extract<PyCallBackPushEvent&>(py_cb_or_queuesize).check()) {
- cb = extract<PyCallBackPushEvent*>(py_cb_or_queuesize);
+ if (bopy::extract<PyCallBackPushEvent&>(py_cb_or_queuesize).check()) {
+ cb = bopy::extract<PyCallBackPushEvent*>(py_cb_or_queuesize);
cb->set_device(py_self);
cb->set_extract_as(extract_as);
@@ -306,9 +306,10 @@ namespace PyDeviceProxy
AutoPythonAllowThreads guard;
return self.subscribe_event(attr_name, event, cb, *filters, stateless);
} else {
- event_queue_size = extract<int>(py_cb_or_queuesize);
+ event_queue_size = bopy::extract<int>(py_cb_or_queuesize);
AutoPythonAllowThreads guard;
- return self.subscribe_event(attr_name, event, event_queue_size, *filters, stateless);
+ return self.subscribe_event(attr_name, event, event_queue_size,
+ *filters, stateless);
}
}
@@ -321,26 +322,26 @@ namespace PyDeviceProxy
}
template<typename ED, typename EDList>
- static object
- get_events__aux(object py_self, int event_id, PyTango::ExtractAs extract_as=PyTango::ExtractAsNumpy)
+ static bopy::object
+ get_events__aux(bopy::object py_self, int event_id,
+ PyTango::ExtractAs extract_as=PyTango::ExtractAsNumpy)
{
- Tango::DeviceProxy &self = extract<Tango::DeviceProxy&>(py_self);
+ Tango::DeviceProxy &self = bopy::extract<Tango::DeviceProxy&>(py_self);
EDList event_list;
self.get_events(event_id, event_list);
- boost::python::list r;
+ bopy::list r;
for (size_t i=0; i < event_list.size(); ++i) {
ED* event_data = event_list[i];
- object py_ev(handle<>(
- to_python_indirect<
- ED*,
- detail::make_owning_holder>()(event_data)));
+ bopy::object py_ev(bopy::handle<>(
+ bopy::to_python_indirect<
+ ED*, bopy::detail::make_owning_holder>()(event_data)));
// EventDataList deletes EventData's on destructor, so once
- // we are handling it somewhere else (as an object) we must
+ // we are handling it somewhere else (as an bopy::object) we must
// unset the reference
event_list[i] = 0;
@@ -352,9 +353,10 @@ namespace PyDeviceProxy
}
static void
- get_events__callback(object py_self, int event_id, PyCallBackPushEvent *cb, PyTango::ExtractAs extract_as)
+ get_events__callback(bopy::object py_self, int event_id,
+ PyCallBackPushEvent *cb, PyTango::ExtractAs extract_as)
{
- Tango::DeviceProxy& self = extract<Tango::DeviceProxy&>(py_self);
+ Tango::DeviceProxy& self = bopy::extract<Tango::DeviceProxy&>(py_self);
cb->set_device(py_self);
cb->set_extract_as(extract_as);
@@ -362,22 +364,22 @@ namespace PyDeviceProxy
self.get_events(event_id, cb);
}
- static object
- get_events__attr_conf(object py_self, int event_id)
+ static bopy::object
+ get_events__attr_conf(bopy::object py_self, int event_id)
{
return get_events__aux<Tango::AttrConfEventData, Tango::AttrConfEventDataList>
(py_self, event_id);
}
- static object
- get_events__data(object py_self, int event_id, PyTango::ExtractAs extract_as)
+ static bopy::object
+ get_events__data(bopy::object py_self, int event_id, PyTango::ExtractAs extract_as)
{
return get_events__aux<Tango::EventData, Tango::EventDataList>
(py_self, event_id, extract_as);
}
- static object
- get_events__data_ready(object py_self, int event_id)
+ static bopy::object
+ get_events__data_ready(bopy::object py_self, int event_id)
{
return get_events__aux<Tango::DataReadyEventData, Tango::DataReadyEventDataList>
(py_self, event_id);
@@ -396,15 +398,14 @@ void export_device_proxy()
void (Tango::DeviceProxy::*delete_property_)(std::string &) =
&Tango::DeviceProxy::delete_property;
- class_<Tango::DeviceProxy, bases<Tango::Connection> > DeviceProxy(
- "DeviceProxy",
- init<>())
+ bopy::class_<Tango::DeviceProxy, bopy::bases<Tango::Connection> >
+ DeviceProxy("DeviceProxy", bopy::init<>())
;
DeviceProxy
- .def(init<const char *>())
- .def(init<const char *, bool>())
- .def(init<const Tango::DeviceProxy &>())
+ .def(bopy::init<const char *>())
+ .def(bopy::init<const char *, bool>())
+ .def(bopy::init<const Tango::DeviceProxy &>())
//
// Pickle
@@ -418,10 +419,10 @@ void export_device_proxy()
.def("info", &Tango::DeviceProxy::info,
( arg_("self") ),
- return_internal_reference<1>() )
+ bopy::return_internal_reference<1>() )
.def("get_device_db", &Tango::DeviceProxy::get_device_db,
- return_value_policy<reference_existing_object>())
+ bopy::return_value_policy<bopy::reference_existing_object>())
.def("status", &PyDeviceProxy::status,
( arg_("self") ) )
@@ -447,7 +448,7 @@ void export_device_proxy()
.def("black_box", &Tango::DeviceProxy::black_box,
( arg_("self"), arg_("n") ),
- return_value_policy<manage_new_object>() )
+ bopy::return_value_policy<bopy::manage_new_object>() )
//
// device methods
@@ -458,7 +459,7 @@ void export_device_proxy()
.def("command_list_query", &Tango::DeviceProxy::command_list_query,
( arg_("self") ),
- return_value_policy<manage_new_object>() )
+ bopy::return_value_policy<bopy::manage_new_object>() )
.def("import_info", &Tango::DeviceProxy::import_info,
( arg_("self") ) )
@@ -505,13 +506,13 @@ void export_device_proxy()
.def("get_attribute_list", &Tango::DeviceProxy::get_attribute_list,
( arg_("self") ),
- return_value_policy<manage_new_object>() )
+ bopy::return_value_policy<bopy::manage_new_object>() )
.def("_get_attribute_config",
(Tango::AttributeInfoList* (Tango::DeviceProxy::*)(StdStringVector &))
&Tango::DeviceProxy::get_attribute_config,
( arg_("self"), arg_("attr_names") ),
- return_value_policy<manage_new_object>() )
+ bopy::return_value_policy<bopy::manage_new_object>() )
.def("_get_attribute_config",
(Tango::AttributeInfoEx (Tango::DeviceProxy::*)(const std::string&))
@@ -521,19 +522,19 @@ void export_device_proxy()
.def("_get_attribute_config_ex",
&Tango::DeviceProxy::get_attribute_config_ex,
( arg_("self"), arg_("attr_names") ),
- return_value_policy<manage_new_object>() )
+ bopy::return_value_policy<bopy::manage_new_object>() )
.def("attribute_query", &Tango::DeviceProxy::attribute_query,
( arg_("self"), arg_("attr_name") ) )
.def("attribute_list_query", &Tango::DeviceProxy::attribute_list_query,
( arg_("self") ),
- return_value_policy<manage_new_object>() )
+ bopy::return_value_policy<bopy::manage_new_object>() )
.def("attribute_list_query_ex",
&Tango::DeviceProxy::attribute_list_query_ex,
( arg_("self") ),
- return_value_policy<manage_new_object>() )
+ bopy::return_value_policy<bopy::manage_new_object>() )
.def("_set_attribute_config",
(void (Tango::DeviceProxy::*)(Tango::AttributeInfoList &))
@@ -554,12 +555,12 @@ void export_device_proxy()
( arg_("self"), arg_("attr_names"), arg_("extract_as")=PyTango::ExtractAsNumpy ) )
.def("write_attribute",
- (void (*)(Tango::DeviceProxy&, const string &, object ))
+ (void (*)(Tango::DeviceProxy&, const string &, bopy::object ))
&PyDeviceProxy::write_attribute,
( arg_("self"), arg_("attr_name"), arg_("value") ) )
.def("write_attribute",
- (void (*)(Tango::DeviceProxy&, const Tango::AttributeInfo &, object ))
+ (void (*)(Tango::DeviceProxy&, const Tango::AttributeInfo &, bopy::object ))
&PyDeviceProxy::write_attribute,
( arg_("self"), arg_("attr_info"), arg_("value") ) )
@@ -590,7 +591,7 @@ void export_device_proxy()
.def("polling_status", &Tango::DeviceProxy::polling_status,
( arg_("self") ),
- return_value_policy<manage_new_object>() )
+ bopy::return_value_policy<bopy::manage_new_object>() )
.def("poll_command",
(void (Tango::DeviceProxy::*)(const char *, int)) &Tango::DeviceProxy::poll_command,
@@ -628,17 +629,17 @@ void export_device_proxy()
// Asynchronous methods
//
.def("__read_attributes_asynch",
- (long (*) (Tango::DeviceProxy &, object))
+ (long (*) (Tango::DeviceProxy &, bopy::object))
&PyDeviceProxy::read_attributes_asynch,
( arg_("self"), arg_("attr_names") ) )
.def("read_attributes_reply",
- (object (*) (Tango::DeviceProxy &, long, PyTango::ExtractAs))
+ (bopy::object (*) (Tango::DeviceProxy &, long, PyTango::ExtractAs))
&PyDeviceProxy::read_attributes_reply,
( arg_("self"), arg_("id"), arg_("extract_as")=PyTango::ExtractAsNumpy ) )
.def("read_attributes_reply",
- (object (*) (Tango::DeviceProxy &, long, long, PyTango::ExtractAs))
+ (bopy::object (*) (Tango::DeviceProxy &, long, long, PyTango::ExtractAs))
&PyDeviceProxy::read_attributes_reply,
( arg_("self"), arg_("id"), arg_("timeout"), arg_("extract_as")=PyTango::ExtractAsNumpy ) )
@@ -647,7 +648,7 @@ void export_device_proxy()
( arg_("self"), arg_("req_type") ) )
.def("__write_attributes_asynch",
- (long (*) (Tango::DeviceProxy &, object))
+ (long (*) (Tango::DeviceProxy &, bopy::object))
&PyDeviceProxy::write_attributes_asynch,
( arg_("self"), arg_("values") ) )
@@ -662,12 +663,12 @@ void export_device_proxy()
( arg_("self"), arg_("id"), arg_("timeout") ) )
.def("__read_attributes_asynch",
- (void (*) (object, object, object, PyTango::ExtractAs))
+ (void (*) (bopy::object, bopy::object, bopy::object, PyTango::ExtractAs))
&PyDeviceProxy::read_attributes_asynch,
( arg_("self"), arg_("attr_names"), arg_("callback"), arg_("extract_as")=PyTango::ExtractAsNumpy ) )
.def("__write_attributes_asynch",
- (void (*) (object, object, object))
+ (void (*) (bopy::object, bopy::object, bopy::object))
&PyDeviceProxy::write_attributes_asynch,
( arg_("self"), arg_("values"), arg_("callback") ) )
@@ -701,7 +702,7 @@ void export_device_proxy()
arg_("attr_name"),
arg_("event"),
arg_("cb_or_queuesize"),
- arg_("filters")=boost::python::list(),
+ arg_("filters")=bopy::list(),
arg_("stateless")=false,
arg_("extract_as")=PyTango::ExtractAsNumpy )
)
@@ -752,6 +753,6 @@ void export_device_proxy()
( arg_("self"), arg_("lockinfo") ))
/// This is to be used by the python layer of this api...
- //.setattr("__subscribed_events", boost::python::dict())
+ //.setattr("__subscribed_events", bopy::dict())
;
}
diff --git a/src/exception.cpp b/src/exception.cpp
index b1fd337..ab86894 100644
--- a/src/exception.cpp
+++ b/src/exception.cpp
@@ -181,48 +181,39 @@ Tango::DevFailed to_dev_failed(PyObject *type, PyObject *value,
PyObject *tracebackModule = PyImport_ImportModule("traceback");
if (tracebackModule != NULL)
{
- PyObject *tbList, *emptyString, *strRetval;
-
//
// Format the traceback part of the Python exception
// and store it in the origin part of the Tango exception
//
- tbList = PyObject_CallMethod(
+ PyObject *tbList_ptr = PyObject_CallMethod(
tracebackModule,
(char *)"format_tb",
(char *)"O",
traceback == NULL ? Py_None : traceback);
-
- emptyString = PyString_FromString("");
- strRetval = PyObject_CallMethod(emptyString, (char *)"join", (char *)"O", tbList);
-
- dev_err[0].origin = CORBA::string_dup(PyString_AsString(strRetval));
-
- Py_DECREF(tbList);
- Py_DECREF(emptyString);
- Py_DECREF(strRetval);
+
+ boost::python::object tbList = object(handle<>(tbList_ptr));
+ boost::python::str origin = str("").join(tbList);
+ char const* origin_ptr = boost::python::extract<char const*>(origin);
+ dev_err[0].origin = CORBA::string_dup(origin_ptr);
//
// Format the exec and value part of the Python exception
// and store it in the desc part of the Tango exception
//
- tbList = PyObject_CallMethod(
+ tbList_ptr = PyObject_CallMethod(
tracebackModule,
(char *)"format_exception_only",
(char *)"OO",
type,
value == NULL ? Py_None : value);
+
+ tbList = object(handle<>(tbList_ptr));
+ boost::python::str desc = str("").join(tbList);
+ char const* desc_ptr = boost::python::extract<char const*>(desc);
+ dev_err[0].desc = CORBA::string_dup(desc_ptr);
- emptyString = PyString_FromString("");
- strRetval = PyObject_CallMethod(emptyString, (char *)"join", (char *)"O", tbList);
-
- dev_err[0].desc = CORBA::string_dup(PyString_AsString(strRetval));
-
- Py_DECREF(tbList);
- Py_DECREF(emptyString);
- Py_DECREF(strRetval);
Py_DECREF(tracebackModule);
dev_err[0].reason = CORBA::string_dup("PyDs_PythonError");
diff --git a/src/fast_from_py.h b/src/fast_from_py.h
index 8d96be8..d68cf61 100644
--- a/src/fast_from_py.h
+++ b/src/fast_from_py.h
@@ -176,16 +176,35 @@ DEFINE_FAST_TANGO_FROMPY_NUM(Tango::DEV_ULONG64, Tango::DevULong64, PyLong_AsUns
DEFINE_FAST_TANGO_FROMPY_NUM(Tango::DEV_FLOAT, double, PyFloat_AsDouble)
DEFINE_FAST_TANGO_FROMPY_NUM(Tango::DEV_DOUBLE, double, PyFloat_AsDouble)
+inline char* obj_to_new_char(PyObject* obj_ptr)
+{
+ Tango::DevString ret = NULL;
+ if(PyUnicode_Check(obj_ptr))
+ {
+ PyObject* obj_bytes_ptr = PyUnicode_AsLatin1String(obj_ptr);
+ ret = CORBA::string_dup(PyBytes_AsString(obj_bytes_ptr));
+ Py_DECREF(obj_bytes_ptr);
+ }
+ else
+ {
+ ret = CORBA::string_dup(PyBytes_AsString(obj_ptr));
+ }
+ return ret;
+}
+
+inline char* obj_to_new_char(boost::python::object &obj)
+{
+ return obj_to_new_char(obj.ptr());
+}
+
+
/// @bug Not a bug per se, but you should keep in mind: It returns a new
/// string, so if you pass it to Tango with a release flag there will be
/// no problems, but if you have to use it yourself then you must remember
/// to delete[] it!
-inline Tango::DevString PyString_AsCorbaString(PyObject* ob)
+inline Tango::DevString PyString_AsCorbaString(PyObject* obj_ptr)
{
- const char* str = PyString_AsString(ob);
- if (!str)
- return 0;
- return CORBA::string_dup(str);
+ return obj_to_new_char(obj_ptr);
}
// DEFINE_FAST_TANGO_FROMPY(Tango::DEV_STRING, PyString_AsString)
diff --git a/src/from_py.cpp b/src/from_py.cpp
index c0b0728..e18f6bf 100644
--- a/src/from_py.cpp
+++ b/src/from_py.cpp
@@ -36,9 +36,9 @@ void convert2array(const boost::python::object &py_value, Tango::DevVarCharArray
size_t size = boost::python::len(py_value);
result.length(size);
- if (PyString_Check(py_value_ptr))
+ if (PyBytes_Check(py_value_ptr))
{
- char *ch = PyString_AS_STRING(py_value_ptr);
+ char *ch = PyBytes_AS_STRING(py_value_ptr);
for (size_t i=0; i < size; ++i) {
result[i] = ch[i];
}
@@ -60,9 +60,15 @@ void convert2array(const object &py_value, StdStringVector & result)
raise_(PyExc_TypeError, param_must_be_seq);
}
- if (PyString_Check(py_value_ptr))
+ if (PyBytes_Check(py_value_ptr))
{
- result.push_back(PyString_AsString(py_value_ptr));
+ result.push_back(PyBytes_AS_STRING(py_value_ptr));
+ }
+ else if(PyUnicode_Check(py_value_ptr))
+ {
+ PyObject* py_bytes_value_ptr = PyUnicode_AsLatin1String(py_value_ptr);
+ result.push_back(PyBytes_AS_STRING(py_bytes_value_ptr));
+ Py_DECREF(py_bytes_value_ptr);
}
else
{
@@ -84,10 +90,16 @@ void convert2array(const object &py_value, Tango::DevVarStringArray & result)
raise_(PyExc_TypeError, param_must_be_seq);
}
- if (PyString_Check(py_value_ptr))
+ if (PyBytes_Check(py_value_ptr))
{
result.length(1);
- result[0] = CORBA::string_dup(PyString_AsString(py_value_ptr));
+ result[0] = CORBA::string_dup(PyBytes_AS_STRING(py_value_ptr));
+ }
+ else if(PyUnicode_Check(py_value_ptr))
+ {
+ PyObject* py_bytes_value_ptr = PyUnicode_AsLatin1String(py_value_ptr);
+ result[0] = CORBA::string_dup(PyBytes_AS_STRING(py_bytes_value_ptr));
+ Py_DECREF(py_bytes_value_ptr);
}
else
{
diff --git a/src/from_py.h b/src/from_py.h
index 269d580..1b0a19a 100644
--- a/src/from_py.h
+++ b/src/from_py.h
@@ -140,8 +140,16 @@ struct from_sequence
for(Py_ssize_t i = 0; i < len; ++i)
{
PyObject *o_ptr = PySequence_GetItem(seq_ptr, i);
- a.push_back(Tango::DbDatum(PyString_AsString(o_ptr)));
- boost::python::decref(o_ptr);
+ if (PyBytes_Check(o_ptr))
+ {
+ a.push_back(Tango::DbDatum(PyBytes_AS_STRING(o_ptr)));
+ }
+ else if(PyUnicode_Check(o_ptr))
+ {
+ PyObject* o_bytes_ptr = PyUnicode_AsLatin1String(o_ptr);
+ a.push_back(Tango::DbDatum(PyBytes_AS_STRING(o_bytes_ptr)));
+ Py_DECREF(o_bytes_ptr);
+ }
}
}
@@ -169,7 +177,6 @@ struct from_sequence
boost::python::tuple pair = (boost::python::tuple)it.attr("next")();
boost::python::object key = pair[0];
boost::python::object value = pair[1];
- PyObject *value_ptr = value.ptr();
boost::python::extract<Tango::DbDatum> ext(value);
if(ext.check())
@@ -177,16 +184,28 @@ struct from_sequence
db_data.push_back(ext());
continue;
}
-
- Tango::DbDatum db_datum(PyString_AsString(key.ptr()));
- if((PySequence_Check(value_ptr)) && (!PyString_Check(value_ptr)))
+
+ char const* key_str = boost::python::extract<char const*>(key);
+ Tango::DbDatum db_datum(key_str);
+
+ boost::python::extract<char const*> value_str(value);
+
+ if(value_str.check())
{
- from_sequence<StdStringVector>::convert(value, db_datum.value_string);
+ db_datum.value_string.push_back(value_str());
}
else
{
- boost::python::object value_str = value.attr("__str__")();
- db_datum.value_string.push_back(PyString_AsString(value_str.ptr()));
+ if(PySequence_Check(value.ptr()))
+ {
+ from_sequence<StdStringVector>::convert(value, db_datum.value_string);
+ }
+ else
+ {
+ boost::python::object str_value = value.attr("__str__")();
+ boost::python::extract<char const*> str_value_str(str_value);
+ db_datum.value_string.push_back(str_value_str());
+ }
}
db_data.push_back(db_datum);
}
@@ -218,7 +237,9 @@ class CSequenceFromPython
} else {
if (PySequence_Check(py_obj.ptr()) == 0)
raise_(PyExc_TypeError, param_must_be_seq);
- if (PyString_Check(py_obj.ptr()) != 0)
+ if (PyUnicode_Check(py_obj.ptr()) != 0)
+ raise_(PyExc_TypeError, param_must_be_seq);
+ if (PyUnicode_Check(py_obj.ptr()) != 0)
raise_(PyExc_TypeError, param_must_be_seq);
m_own = true;
diff --git a/src/group.cpp b/src/group.cpp
index b497c8e..cc5477c 100644
--- a/src/group.cpp
+++ b/src/group.cpp
@@ -27,7 +27,7 @@
void export_group_reply_list();
void export_group_reply();
-void export_group_element();
+//void export_group_element();
namespace PyGroup
@@ -51,6 +51,120 @@ namespace PyGroup
" already been inserted in another group." );
}
}
+
+ Tango::GroupCmdReplyList command_inout_reply(Tango::Group &self, long req_id, long timeout_ms)
+ {
+ AutoPythonAllowThreads guard;
+ return self.command_inout_reply(req_id, timeout_ms);
+ }
+
+ static void __update_data_format(Tango::Group &self, Tango::GroupAttrReplyList& r)
+ {
+ // Usually we pass a device_proxy to "convert_to_python" in order to
+ // get the data_format of the DeviceAttribute for Tango versions
+ // older than 7.0. However, GroupAttrReply has no device_proxy to use!
+ // So, we are using update_data_format() in here.
+ // The conver_to_python method is called, without the usual
+ // device_proxy argument, in PyGroupAttrReply::get_data().
+ Tango::GroupAttrReplyList::iterator i, e = r.end();
+ for (i=r.begin(); i != e; ++i) {
+ Tango::DeviceProxy* dev_proxy = self.get_device(i->dev_name());
+ if (!dev_proxy)
+ continue;
+ PyDeviceAttribute::update_data_format( *dev_proxy, &(i->get_data()), 1 );
+ }
+ }
+
+ Tango::GroupAttrReplyList read_attribute_reply (Tango::Group &self, long req_id, long timeout_ms = 0 )
+ {
+ Tango::GroupAttrReplyList r;
+ {
+ AutoPythonAllowThreads guard;
+ r = self.read_attribute_reply(req_id, timeout_ms);
+ }
+ __update_data_format(self, r);
+ return r;
+ }
+
+ Tango::GroupAttrReplyList read_attributes_reply (Tango::Group &self, long req_id, long timeout_ms = 0)
+ {
+ Tango::GroupAttrReplyList r;
+ {
+ AutoPythonAllowThreads guard;
+ r = self.read_attributes_reply(req_id, timeout_ms);
+ }
+ __update_data_format(self, r);
+ return r;
+ }
+
+ long read_attributes_asynch (Tango::Group &self, object py_value, bool forward = true)
+ {
+ StdStringVector r;
+ convert2array(py_value, r);
+ return self.read_attributes_asynch(r, forward);
+ }
+
+ long
+ write_attribute_asynch(Tango::Group &self, const std::string &attr_name,
+ bopy::object py_value, bool forward = true,
+ bool multi = false)
+ {
+ Tango::DeviceProxy* dev_proxy = self.get_device(1);
+ // If !dev_proxy (no device added in self or his children) then we
+ // don't initialize dev_attr. As a result, the reply will be empty.
+ /// @todo or should we raise an exception instead?
+ if(!dev_proxy)
+ {
+ Tango::DeviceAttribute dev_attr;
+ AutoPythonAllowThreads guard;
+ return self.write_attribute_asynch(dev_attr, forward);
+ }
+
+ if(multi)
+ {
+ if(!PySequence_Check(py_value.ptr()))
+ {
+ raise_(PyExc_TypeError,
+ "When multi is set, value must be a python sequence "
+ "(ex: list or tuple)" );
+ }
+
+ Tango::AttributeInfoEx attr_info;
+ {
+ AutoPythonAllowThreads guard;
+ attr_info = dev_proxy->get_attribute_config(attr_name);
+ }
+
+ int attr_nb = bopy::len(py_value);
+ std::vector<Tango::DeviceAttribute> dev_attr(attr_nb);
+ for(int i = 0; i < attr_nb; ++i)
+ {
+ PyDeviceAttribute::reset(dev_attr[i], attr_info, py_value[i]);
+ }
+
+ AutoPythonAllowThreads guard;
+ return self.write_attribute_asynch(dev_attr, forward);
+ }
+ else
+ {
+ Tango::DeviceAttribute dev_attr;
+ Tango::DeviceProxy* dev_proxy = self.get_device(1);
+ if (dev_proxy)
+ PyDeviceAttribute::reset(dev_attr, attr_name, *dev_proxy, py_value);
+ // If !dev_proxy (no device added in self or his children) then we
+ // don't initialize dev_attr. As a result, the reply will be empty.
+ /// @todo or should we raise an exception instead?
+
+ AutoPythonAllowThreads guard;
+ return self.write_attribute_asynch(dev_attr, forward);
+ }
+ }
+
+ Tango::GroupReplyList write_attribute_reply (Tango::Group &self, long req_id, long timeout_ms = 0)
+ {
+ AutoPythonAllowThreads guard;
+ return self.write_attribute_reply(req_id, timeout_ms);
+ }
}
void export_group()
@@ -59,25 +173,46 @@ void export_group()
export_group_reply();
export_group_reply_list();
- export_group_element();
+// export_group_element();
- class_<Tango::Group, bases<Tango::GroupElement>, std::auto_ptr<Tango::Group>, boost::noncopyable > Group(
- "__Group",
- init<const std::string&>())
+// class_<Tango::Group, bases<Tango::GroupElement>,
+// unique_pointer<Tango::Group>, boost::noncopyable > Group(
+// "__Group",
+// init<const std::string&>())
+// ;
+ class_<Tango::Group, std::auto_ptr<Tango::Group>, boost::noncopyable >
+ Group("__Group",
+ init<const std::string&>())
;
Group
- .def("__add",
+ .def("_add",
(void (Tango::Group::*) (const std::string &, int))
&Tango::Group::add,
(arg_("self"), arg_("pattern"), arg_("timeout_ms")=-1) )
- .def("__add",
+ .def("_add",
(void (Tango::Group::*) (const std::vector<std::string> &, int))
&Tango::Group::add,
(arg_("self"), arg_("patterns"), arg_("timeout_ms")=-1))
- .def("__add",
+ .def("_add",
PyGroup::add,
(arg_("self"), arg_("group"), arg_("timeout_ms")=-1) )
+
+ .def("_remove",
+ (void (Tango::Group::*) (const std::string &, bool))
+ &Tango::Group::remove,
+ (arg_("self"), arg_("pattern"), arg_("forward")=true))
+ .def("_remove",
+ (void (Tango::Group::*) (const std::vector<std::string> &, bool))
+ &Tango::Group::remove,
+ (arg_("self"), arg_("patterns"), arg_("forward")=true))
+ .def("get_group",
+ &Tango::Group::get_group,
+ (arg_("self"), arg_("group_name")),
+ return_internal_reference<1>() )
+ .def("get_size",
+ &Tango::Group::get_size,
+ (arg_("self"), arg_("forward")=true) )
.def("remove_all", &Tango::Group::remove_all)
@@ -100,6 +235,115 @@ void export_group()
.def("get_device_list",
&Tango::Group::get_device_list,
(arg_("self"), arg_("forward")=true) )
+
+ .def("command_inout_asynch",
+ (long (Tango::Group::*) (const std::string&, bool, bool))
+ &Tango::Group::command_inout_asynch,
+ ( arg_("self"),
+ arg_("cmd_name"),
+ arg_("forget")=false,
+ arg_("forward")=true) )
+ .def("command_inout_asynch",
+ (long (Tango::Group::*) (const std::string&, const Tango::DeviceData&, bool, bool))
+ &Tango::Group::command_inout_asynch,
+ ( arg_("self"),
+ arg_("cmd_name"),
+ arg_("param"),
+ arg_("forget")=false,
+ arg_("forward")=true) )
+ .def("command_inout_asynch",
+ (long (Tango::Group::*) (const std::string&, const std::vector<Tango::DeviceData>&, bool, bool))
+ &Tango::Group::command_inout_asynch,
+ ( arg_("self"),
+ arg_("cmd_name"),
+ arg_("param"),
+ arg_("forget")=false,
+ arg_("forward")=true) )
+ .def("command_inout_reply",
+ PyGroup::command_inout_reply,
+ ( arg_("self"),
+ arg_("req_id"),
+ arg_("timeout_ms")=0 ) )
+ .def("read_attribute_asynch",
+ &Tango::Group::read_attribute_asynch,
+ ( arg_("self"),
+ arg_("attr_name"),
+ arg_("forward")=true) )
+ .def("read_attribute_reply",
+ PyGroup::read_attribute_reply,
+ ( arg_("self"),
+ arg_("req_id"),
+ arg_("timeout_ms")=0 ) )
+ .def("read_attributes_asynch",
+ PyGroup::read_attributes_asynch,
+ ( arg_("self"),
+ arg_("attr_names"),
+ arg_("forward")=true) )
+ .def("read_attributes_reply",
+ PyGroup::read_attributes_reply,
+ ( arg_("self"),
+ arg_("req_id"),
+ arg_("timeout_ms")=0 ) )
+ .def("write_attribute_asynch",
+ PyGroup::write_attribute_asynch,
+ ( arg_("self"),
+ arg_("attr_name"),
+ arg_("value"),
+ arg_("forward")=true,
+ arg_("multi")=false) )
+ .def("write_attribute_reply",
+ PyGroup::write_attribute_reply,
+ ( arg_("self"),
+ arg_("req_id"),
+ arg_("timeout_ms")=0 ) )
+
+
+ .def("get_parent",
+ &Tango::Group::get_parent,
+ (arg_("self")),
+ return_internal_reference<1>() )
+ .def("contains",
+ &Tango::Group::contains,
+ (arg_("self"), arg_("pattern"), arg_("forward")=true) )
+ .def("get_device",
+ (Tango::DeviceProxy* (Tango::Group::*) (const std::string &))
+ &Tango::Group::get_device,
+ (arg_("self"), arg_("dev_name")),
+ return_internal_reference<1>() )
+ .def("get_device",
+ (Tango::DeviceProxy* (Tango::Group::*) (long))
+ &Tango::Group::get_device,
+ (arg_("self"), arg_("idx")),
+ return_internal_reference<1>() )
+ .def("ping",
+ &Tango::Group::ping,
+ (arg_("self"), arg_("forward")=true) )
+ .def("set_timeout_millis",
+ &Tango::Group::set_timeout_millis,
+ (arg_("self"), arg_("timeout_ms")) )
+ .def("get_name",
+ &Tango::Group::get_name,
+ (arg_("self")),
+ return_value_policy<copy_const_reference>() )
+ .def("get_fully_qualified_name",
+ &Tango::Group::get_fully_qualified_name,
+ (arg_("self")) )
+ .def("enable",
+ &Tango::Group::enable,
+ (arg_("self")) )
+ .def("disable",
+ &Tango::Group::disable,
+ (arg_("self")) )
+ .def("is_enabled",
+ &Tango::Group::is_enabled,
+ (arg_("self")) )
+ .def("name_equals",
+ &Tango::Group::name_equals,
+ (arg_("self")) )
+ .def("name_matches",
+ &Tango::Group::name_matches,
+ (arg_("self")) )
+
;
// I am not exporting "find", so all the GroupElemens will be
diff --git a/src/pytango.cpp b/src/pytango.cpp
index f3b2544..3d5de12 100644
--- a/src/pytango.cpp
+++ b/src/pytango.cpp
@@ -65,6 +65,13 @@ void export_device_impl();
void export_group();
void export_log4tango();
+void init_numpy()
+{
+# ifndef DISABLE_PYTANGO_NUMPY
+ import_array1();
+# endif
+}
+
BOOST_PYTHON_MODULE(_PyTango)
{
@@ -83,9 +90,7 @@ BOOST_PYTHON_MODULE(_PyTango)
PyEval_InitThreads();
-# ifndef DISABLE_PYTANGO_NUMPY
- import_array();
-# endif
+ init_numpy();
export_callback(); /// @todo not sure were to put it...
diff --git a/src/pyutils.cpp b/src/pyutils.cpp
index cfffc9c..89e1879 100644
--- a/src/pyutils.cpp
+++ b/src/pyutils.cpp
@@ -27,6 +27,49 @@
using namespace boost::python;
+PyObject* from_char_to_str(const std::string& in,
+ const char* encoding /*=NULL defaults to latin-1 */,
+ const char* errors /*="strict" */)
+{
+ return from_char_to_str(in.c_str(), in.size(), encoding, errors);
+}
+
+PyObject* from_char_to_str(const char* in, Py_ssize_t size /* =-1 */,
+ const char* encoding /*=NULL defaults to latin-1 */,
+ const char* errors /*="strict" */)
+{
+if (size < 0)
+{
+ size = strlen(in);
+}
+#ifdef PYTANGO_PY3K
+ if (!encoding)
+ {
+ return PyUnicode_DecodeLatin1(in, size, errors);
+ }
+ else
+ {
+ return PyUnicode_Decode(in, size, encoding, errors);
+ }
+#else
+ return PyString_FromStringAndSize(in, size);
+#endif
+}
+
+void from_str_to_char(PyObject* in, std::string& out)
+{
+ if (PyUnicode_Check(in))
+ {
+ PyObject *bytes_in = PyUnicode_AsLatin1String(in);
+ out = PyBytes_AsString(bytes_in);
+ Py_DECREF(bytes_in);
+ }
+ else
+ {
+ out = std::string(PyBytes_AsString(in), PyBytes_Size(in));
+ }
+}
+
bool is_method_defined(object &obj, const std::string &method_name)
{
return is_method_defined(obj.ptr(), method_name);
diff --git a/src/pyutils.h b/src/pyutils.h
index 36c21f1..13ed9df 100644
--- a/src/pyutils.h
+++ b/src/pyutils.h
@@ -27,6 +27,10 @@
#define arg_(a) boost::python::arg(a)
+#if PY_MAJOR_VERSION >= 3
+#define PYTANGO_PY3K
+#endif
+
#if PY_VERSION_HEX < 0x02050000
typedef int Py_ssize_t;
#endif
@@ -56,48 +60,188 @@ inline PyObject *PyImport_ImportModule_(const std::string &name)
return PyImport_ImportModule(attr);
}
-// -----------------------------------------------------------------------------
-// The following section defines missing symbols in python <3.0 with macros
-
-#if PY_VERSION_HEX < 0x02070000
- #if PY_VERSION_HEX < 0x02060000
- #define PyObject_CheckBuffer(object) (0)
-
- #define PyObject_GetBuffer(obj, view, flags) (PyErr_SetString(PyExc_NotImplementedError, \
- "new buffer interface is not available"), -1)
- #define PyBuffer_FillInfo(view, obj, buf, len, readonly, flags) (PyErr_SetString(PyExc_NotImplementedError, \
- "new buffer interface is not available"), -1)
- #define PyBuffer_Release(obj) (PyErr_SetString(PyExc_NotImplementedError, \
- "new buffer interface is not available"), -1)
- // Bytes->String
- #define PyBytes_FromStringAndSize PyString_FromStringAndSize
- #define PyBytes_FromString PyString_FromString
- #define PyBytes_AsString PyString_AsString
- #define PyBytes_Size PyString_Size
- #endif
-
- #define PyMemoryView_FromBuffer(info) (PyErr_SetString(PyExc_NotImplementedError, \
- "new buffer interface is not available"), (PyObject *)NULL)
- #define PyMemoryView_FromObject(object) (PyErr_SetString(PyExc_NotImplementedError, \
- "new buffer interface is not available"), (PyObject *)NULL)
+// Bytes interface
+#if PY_VERSION_HEX < 0x02060000
+ #define PyBytesObject PyStringObject
+ #define PyBytes_Type PyString_Type
+
+ #define PyBytes_Check PyString_Check
+ #define PyBytes_CheckExact PyString_CheckExact
+ #define PyBytes_CHECK_INTERNED PyString_CHECK_INTERNED
+ #define PyBytes_AS_STRING PyString_AS_STRING
+ #define PyBytes_GET_SIZE PyString_GET_SIZE
+ #define Py_TPFLAGS_BYTES_SUBCLASS Py_TPFLAGS_STRING_SUBCLASS
+
+ #define PyBytes_FromStringAndSize PyString_FromStringAndSize
+ #define PyBytes_FromString PyString_FromString
+ #define PyBytes_FromFormatV PyString_FromFormatV
+ #define PyBytes_FromFormat PyString_FromFormat
+ #define PyBytes_Size PyString_Size
+ #define PyBytes_AsString PyString_AsString
+ #define PyBytes_Repr PyString_Repr
+ #define PyBytes_Concat PyString_Concat
+ #define PyBytes_ConcatAndDel PyString_ConcatAndDel
+ #define _PyBytes_Resize _PyString_Resize
+ #define _PyBytes_Eq _PyString_Eq
+ #define PyBytes_Format PyString_Format
+ #define _PyBytes_FormatLong _PyString_FormatLong
+ #define PyBytes_DecodeEscape PyString_DecodeEscape
+ #define _PyBytes_Join _PyString_Join
+ #define PyBytes_Decode PyString_Decode
+ #define PyBytes_Encode PyString_Encode
+ #define PyBytes_AsEncodedObject PyString_AsEncodedObject
+ #define PyBytes_AsEncodedString PyString_AsEncodedString
+ #define PyBytes_AsDecodedObject PyString_AsDecodedObject
+ #define PyBytes_AsDecodedString PyString_AsDecodedString
+ #define PyBytes_AsStringAndSize PyString_AsStringAndSize
+ #define _PyBytes_InsertThousandsGrouping _PyString_InsertThousandsGrouping
+#else
+ #include <bytesobject.h>
#endif
-#if PY_VERSION_HEX >= 0x03000000
- // for buffers
- #define Py_END_OF_BUFFER ((Py_ssize_t) 0)
+/* PyCapsule definitions for old python */
- #define PyObject_CheckReadBuffer(object) (0)
+#if ( (PY_VERSION_HEX < 0x02070000) \
+ || ((PY_VERSION_HEX >= 0x03000000) \
+ && (PY_VERSION_HEX < 0x03010000)) )
- #define PyBuffer_FromMemory(ptr, s) (PyErr_SetString(PyExc_NotImplementedError, \
- "old buffer interface is not available"), (PyObject *)NULL)
- #define PyBuffer_FromReadWriteMemory(ptr, s) (PyErr_SetString(PyExc_NotImplementedError, \
- "old buffer interface is not available"), (PyObject *)NULL)
- #define PyBuffer_FromObject(object, offset, size) (PyErr_SetString(PyExc_NotImplementedError, \
- "old buffer interface is not available"), (PyObject *)NULL)
- #define PyBuffer_FromReadWriteObject(object, offset, size) (PyErr_SetString(PyExc_NotImplementedError, \
- "old buffer interface is not available"), (PyObject *)NULL)
+#define PYCAPSULE_OLD
+
+#define __PyCapsule_GetField(capsule, field, default_value) \
+ ( PyCapsule_CheckExact(capsule) \
+ ? (((PyCObject *)capsule)->field) \
+ : (default_value) \
+ ) \
+
+#define __PyCapsule_SetField(capsule, field, value) \
+ ( PyCapsule_CheckExact(capsule) \
+ ? (((PyCObject *)capsule)->field = value), 1 \
+ : 0 \
+ ) \
+
+
+#define PyCapsule_Type PyCObject_Type
+
+#define PyCapsule_CheckExact(capsule) (PyCObject_Check(capsule))
+#define PyCapsule_IsValid(capsule, name) (PyCObject_Check(capsule))
-#endif
+
+#define PyCapsule_New(pointer, name, destructor) \
+ (PyCObject_FromVoidPtr(pointer, destructor))
+
+
+#define PyCapsule_GetPointer(capsule, name) \
+ (PyCObject_AsVoidPtr(capsule))
+
+/* Don't call PyCObject_SetPointer here, it fails if there's a destructor */
+#define PyCapsule_SetPointer(capsule, pointer) \
+ __PyCapsule_SetField(capsule, cobject, pointer)
+
+
+#define PyCapsule_GetDestructor(capsule) \
+ __PyCapsule_GetField(capsule, destructor)
+
+#define PyCapsule_SetDestructor(capsule, dtor) \
+ __PyCapsule_SetField(capsule, destructor, dtor)
+
+
+/*
+ * Sorry, there's simply no place
+ * to store a Capsule "name" in a CObject.
+ */
+#define PyCapsule_GetName(capsule) NULL
+
+static int
+PyCapsule_SetName(PyObject *capsule, const char *unused)
+{
+ unused = unused;
+ PyErr_SetString(PyExc_NotImplementedError,
+ "can't use PyCapsule_SetName with CObjects");
+ return 1;
+}
+
+
+
+#define PyCapsule_GetContext(capsule) \
+ __PyCapsule_GetField(capsule, descr)
+
+#define PyCapsule_SetContext(capsule, context) \
+ __PyCapsule_SetField(capsule, descr, context)
+
+
+static void *
+PyCapsule_Import(const char *name, int no_block)
+{
+ PyObject *object = NULL;
+ void *return_value = NULL;
+ char *trace;
+ size_t name_length = (strlen(name) + 1) * sizeof(char);
+ char *name_dup = (char *)PyMem_MALLOC(name_length);
+
+ if (!name_dup) {
+ return NULL;
+ }
+
+ memcpy(name_dup, name, name_length);
+
+ trace = name_dup;
+ while (trace) {
+ char *dot = strchr(trace, '.');
+ if (dot) {
+ *dot++ = '\0';
+ }
+
+ if (object == NULL) {
+ if (no_block) {
+ object = PyImport_ImportModuleNoBlock(trace);
+ } else {
+ object = PyImport_ImportModule(trace);
+ if (!object) {
+ PyErr_Format(PyExc_ImportError,
+ "PyCapsule_Import could not "
+ "import module \"%s\"", trace);
+ }
+ }
+ } else {
+ PyObject *object2 = PyObject_GetAttrString(object, trace);
+ Py_DECREF(object);
+ object = object2;
+ }
+ if (!object) {
+ goto EXIT;
+ }
+
+ trace = dot;
+ }
+
+ if (PyCObject_Check(object)) {
+ PyCObject *cobject = (PyCObject *)object;
+ return_value = cobject->cobject;
+ } else {
+ PyErr_Format(PyExc_AttributeError,
+ "PyCapsule_Import \"%s\" is not valid",
+ name);
+ }
+
+EXIT:
+ Py_XDECREF(object);
+ if (name_dup) {
+ PyMem_FREE(name_dup);
+ }
+ return return_value;
+}
+
+#endif /* #if PY_VERSION_HEX < 0x02070000 */
+
+PyObject* from_char_to_str(const char* in, Py_ssize_t size=-1,
+ const char* encoding=NULL, /* defaults to latin-1 */
+ const char* errors="strict");
+
+PyObject* from_char_to_str(const std::string& in,
+ const char* encoding=NULL, /* defaults to latin-1 */
+ const char* errors="strict");
+
+void from_str_to_char(PyObject* in, std::string& out);
inline void raise_(PyObject *type, const char *message)
{
@@ -113,10 +257,24 @@ class AutoPythonAllowThreads
public:
- inline void giveup() { if (m_save) { PyEval_RestoreThread(m_save); m_save = 0; } }
+ inline void giveup()
+ {
+ if (m_save)
+ {
+ PyEval_RestoreThread(m_save);
+ m_save = 0;
+ }
+ }
+
+ inline AutoPythonAllowThreads()
+ {
+ m_save = PyEval_SaveThread();
+ }
- inline AutoPythonAllowThreads() { m_save = PyEval_SaveThread(); } ;
- inline ~AutoPythonAllowThreads() {giveup();} ;
+ inline ~AutoPythonAllowThreads()
+ {
+ giveup();
+ }
};
/**
diff --git a/src/server/attribute.cpp b/src/server/attribute.cpp
index 06444c6..af0065a 100644
--- a/src/server/attribute.cpp
+++ b/src/server/attribute.cpp
@@ -43,6 +43,9 @@ using namespace boost::python;
struct timeval tv; PYTG_TIME_FROM_DOUBLE(dbl, tv)
#endif
+#ifndef TgLibVersNb
+# define TgLibVersNb 80005
+#endif
inline static void throw_wrong_python_data_type(const std::string &att_name,
const char *method)
@@ -430,6 +433,21 @@ namespace PyAttribute
att.set_properties(tg_attr_cfg, dev_ptr);
}
+ void set_upd_properties(Tango::Attribute &att, boost::python::object &attr_cfg)
+ {
+ Tango::AttributeConfig_3 tg_attr_cfg;
+ from_py_object(attr_cfg, tg_attr_cfg);
+ att.set_upd_properties(tg_attr_cfg);
+ }
+
+ void set_upd_properties(Tango::Attribute &att, boost::python::object &attr_cfg, boost::python::object &dev_name)
+ {
+ Tango::AttributeConfig_3 tg_attr_cfg;
+ from_py_object(attr_cfg, tg_attr_cfg);
+ string tg_dev_name = boost::python::extract<string>(dev_name);
+ att.set_upd_properties(tg_attr_cfg,tg_dev_name);
+ }
+
inline void fire_change_event(Tango::Attribute &self)
{
self.fire_change_event();
@@ -451,6 +469,335 @@ namespace PyAttribute
o.str(),
"fire_change_event()");
}
+
+#if TgLibVersNb >= 80100 // set_min_alarm
+
+ template<long tangoTypeConst>
+ inline void _set_min_alarm(Tango::Attribute &self, boost::python::object value)
+ {
+ typedef typename TANGO_const2type(tangoTypeConst) TangoScalarType;
+ TangoScalarType c_value = boost::python::extract<TangoScalarType>(value);
+ self.set_min_alarm(c_value);
+ }
+
+#else // set_min_alarm
+
+ template<typename TangoScalarType>
+ inline void __set_min_alarm(Tango::Attribute &self, boost::python::object value)
+ {
+ TangoScalarType c_value = boost::python::extract<TangoScalarType>(value);
+ self.set_min_alarm(c_value);
+ }
+
+ template<>
+ inline void __set_min_alarm<Tango::DevEncoded>(Tango::Attribute &self, boost::python::object value)
+ {
+ string err_msg = "Attribute properties cannot be set with Tango::DevEncoded data type";
+ Tango::Except::throw_exception((const char *)"API_MethodArgument",
+ (const char *)err_msg.c_str(),
+ (const char *)"Attribute::set_min_alarm()");
+ }
+
+ template<long tangoTypeConst>
+ inline void _set_min_alarm(Tango::Attribute &self, boost::python::object value)
+ {
+ typedef typename TANGO_const2type(tangoTypeConst) TangoScalarType;
+ __set_min_alarm<TangoScalarType>(self,value);
+ }
+
+#endif // set_min_alarm
+
+ inline void set_min_alarm(Tango::Attribute &self, boost::python::object value)
+ {
+ bopy::extract<string> value_convert(value);
+
+ if (value_convert.check())
+ {
+ self.set_min_alarm(value_convert());
+ }
+ else
+ {
+ long tangoTypeConst = self.get_data_type();
+ // TODO: the below line is a neat trick to properly raise a Tango exception if a property is set
+ // for one of the forbidden attribute data types; code dependent on Tango C++ implementation
+ if(tangoTypeConst == Tango::DEV_STRING || tangoTypeConst == Tango::DEV_BOOLEAN || tangoTypeConst == Tango::DEV_STATE)
+ tangoTypeConst = Tango::DEV_DOUBLE;
+ else if(tangoTypeConst == Tango::DEV_ENCODED)
+ tangoTypeConst = Tango::DEV_UCHAR;
+
+ TANGO_CALL_ON_ATTRIBUTE_DATA_TYPE(tangoTypeConst, _set_min_alarm, self, value);
+ }
+ }
+
+#if TgLibVersNb >= 80100 // set_max_alarm
+
+ template<long tangoTypeConst>
+ inline void _set_max_alarm(Tango::Attribute &self, boost::python::object value)
+ {
+ typedef typename TANGO_const2type(tangoTypeConst) TangoScalarType;
+ TangoScalarType c_value = boost::python::extract<TangoScalarType>(value);
+ self.set_max_alarm(c_value);
+ }
+
+#else // set_max_alarm
+
+ template<typename TangoScalarType>
+ inline void __set_max_alarm(Tango::Attribute &self, boost::python::object value)
+ {
+ TangoScalarType c_value = boost::python::extract<TangoScalarType>(value);
+ self.set_max_alarm(c_value);
+ }
+
+ template<>
+ inline void __set_max_alarm<Tango::DevEncoded>(Tango::Attribute &self, boost::python::object value)
+ {
+ string err_msg = "Attribute properties cannot be set with Tango::DevEncoded data type";
+ Tango::Except::throw_exception((const char *)"API_MethodArgument",
+ (const char *)err_msg.c_str(),
+ (const char *)"Attribute::set_max_alarm()");
+ }
+
+ template<long tangoTypeConst>
+ inline void _set_max_alarm(Tango::Attribute &self, boost::python::object value)
+ {
+ typedef typename TANGO_const2type(tangoTypeConst) TangoScalarType;
+ __set_max_alarm<TangoScalarType>(self,value);
+ }
+
+#endif // set_max_alarm
+
+ inline void set_max_alarm(Tango::Attribute &self, boost::python::object value)
+ {
+ bopy::extract<string> value_convert(value);
+
+ if (value_convert.check())
+ {
+ self.set_max_alarm(value_convert());
+ }
+ else
+ {
+ long tangoTypeConst = self.get_data_type();
+ // TODO: the below line is a neat trick to properly raise a Tango exception if a property is set
+ // for one of the forbidden attribute data types; code dependent on Tango C++ implementation
+ if(tangoTypeConst == Tango::DEV_STRING || tangoTypeConst == Tango::DEV_BOOLEAN || tangoTypeConst == Tango::DEV_STATE)
+ tangoTypeConst = Tango::DEV_DOUBLE;
+ else if(tangoTypeConst == Tango::DEV_ENCODED)
+ tangoTypeConst = Tango::DEV_UCHAR;
+
+ TANGO_CALL_ON_ATTRIBUTE_DATA_TYPE(tangoTypeConst, _set_max_alarm, self, value);
+ }
+ }
+
+#if TgLibVersNb >= 80100 // set_min_warning
+
+ template<long tangoTypeConst>
+ inline void _set_min_warning(Tango::Attribute &self, boost::python::object value)
+ {
+ typedef typename TANGO_const2type(tangoTypeConst) TangoScalarType;
+ TangoScalarType c_value = boost::python::extract<TangoScalarType>(value);
+ self.set_min_warning(c_value);
+ }
+
+#else // set_min_warning
+
+ template<typename TangoScalarType>
+ inline void __set_min_warning(Tango::Attribute &self, boost::python::object value)
+ {
+ TangoScalarType c_value = boost::python::extract<TangoScalarType>(value);
+ self.set_min_warning(c_value);
+ }
+
+ template<>
+ inline void __set_min_warning<Tango::DevEncoded>(Tango::Attribute &self, boost::python::object value)
+ {
+ string err_msg = "Attribute properties cannot be set with Tango::DevEncoded data type";
+ Tango::Except::throw_exception((const char *)"API_MethodArgument",
+ (const char *)err_msg.c_str(),
+ (const char *)"Attribute::set_min_warning()");
+ }
+
+ template<long tangoTypeConst>
+ inline void _set_min_warning(Tango::Attribute &self, boost::python::object value)
+ {
+ typedef typename TANGO_const2type(tangoTypeConst) TangoScalarType;
+ __set_min_warning<TangoScalarType>(self,value);
+ }
+
+#endif // set_min_warning
+
+ inline void set_min_warning(Tango::Attribute &self, boost::python::object value)
+ {
+ bopy::extract<string> value_convert(value);
+
+ if (value_convert.check())
+ {
+ self.set_min_warning(value_convert());
+ }
+ else
+ {
+ long tangoTypeConst = self.get_data_type();
+ // TODO: the below line is a neat trick to properly raise a Tango exception if a property is set
+ // for one of the forbidden attribute data types; code dependent on Tango C++ implementation
+ if(tangoTypeConst == Tango::DEV_STRING || tangoTypeConst == Tango::DEV_BOOLEAN || tangoTypeConst == Tango::DEV_STATE)
+ tangoTypeConst = Tango::DEV_DOUBLE;
+ else if(tangoTypeConst == Tango::DEV_ENCODED)
+ tangoTypeConst = Tango::DEV_UCHAR;
+
+ TANGO_CALL_ON_ATTRIBUTE_DATA_TYPE(tangoTypeConst, _set_min_warning, self, value);
+ }
+ }
+
+#if TgLibVersNb >= 80100 // set_max_warning
+
+ template<long tangoTypeConst>
+ inline void _set_max_warning(Tango::Attribute &self, boost::python::object value)
+ {
+ typedef typename TANGO_const2type(tangoTypeConst) TangoScalarType;
+ TangoScalarType c_value = boost::python::extract<TangoScalarType>(value);
+ self.set_max_warning(c_value);
+ }
+
+#else // set_max_warning
+
+ template<typename TangoScalarType>
+ inline void __set_max_warning(Tango::Attribute &self, boost::python::object value)
+ {
+ TangoScalarType c_value = boost::python::extract<TangoScalarType>(value);
+ self.set_max_warning(c_value);
+ }
+
+ template<>
+ inline void __set_max_warning<Tango::DevEncoded>(Tango::Attribute &self, boost::python::object value)
+ {
+ string err_msg = "Attribute properties cannot be set with Tango::DevEncoded data type";
+ Tango::Except::throw_exception((const char *)"API_MethodArgument",
+ (const char *)err_msg.c_str(),
+ (const char *)"Attribute::set_max_warning()");
+ }
+
+ template<long tangoTypeConst>
+ inline void _set_max_warning(Tango::Attribute &self, boost::python::object value)
+ {
+ typedef typename TANGO_const2type(tangoTypeConst) TangoScalarType;
+ __set_max_warning<TangoScalarType>(self,value);
+ }
+
+#endif // set_max_warning
+
+ inline void set_max_warning(Tango::Attribute &self, boost::python::object value)
+ {
+ bopy::extract<string> value_convert(value);
+
+ if (value_convert.check())
+ {
+ self.set_max_warning(value_convert());
+ }
+ else
+ {
+ long tangoTypeConst = self.get_data_type();
+ // TODO: the below line is a neat trick to properly raise a Tango exception if a property is set
+ // for one of the forbidden attribute data types; code dependent on Tango C++ implementation
+ if(tangoTypeConst == Tango::DEV_STRING || tangoTypeConst == Tango::DEV_BOOLEAN || tangoTypeConst == Tango::DEV_STATE)
+ tangoTypeConst = Tango::DEV_DOUBLE;
+ else if(tangoTypeConst == Tango::DEV_ENCODED)
+ tangoTypeConst = Tango::DEV_UCHAR;
+
+ TANGO_CALL_ON_ATTRIBUTE_DATA_TYPE(tangoTypeConst, _set_max_warning, self, value);
+ }
+ }
+
+ template<long tangoTypeConst>
+ PyObject* __get_min_alarm(Tango::Attribute &att)
+ {
+ typedef typename TANGO_const2type(tangoTypeConst) TangoScalarType;
+
+ TangoScalarType tg_val;
+ att.get_min_alarm(tg_val);
+ boost::python::object py_value(tg_val);
+
+ return boost::python::incref(py_value.ptr());
+ }
+
+ PyObject *get_min_alarm(Tango::Attribute &att)
+ {
+ long tangoTypeConst = att.get_data_type();
+
+ if(tangoTypeConst == Tango::DEV_ENCODED)
+ tangoTypeConst = Tango::DEV_UCHAR;
+
+ TANGO_CALL_ON_ATTRIBUTE_DATA_TYPE(tangoTypeConst, return __get_min_alarm, att);
+ return 0;
+ }
+
+ template<long tangoTypeConst>
+ PyObject* __get_max_alarm(Tango::Attribute &att)
+ {
+ typedef typename TANGO_const2type(tangoTypeConst) TangoScalarType;
+
+ TangoScalarType tg_val;
+ att.get_max_alarm(tg_val);
+ boost::python::object py_value(tg_val);
+
+ return boost::python::incref(py_value.ptr());
+ }
+
+ PyObject *get_max_alarm(Tango::Attribute &att)
+ {
+ long tangoTypeConst = att.get_data_type();
+
+ if(tangoTypeConst == Tango::DEV_ENCODED)
+ tangoTypeConst = Tango::DEV_UCHAR;
+
+ TANGO_CALL_ON_ATTRIBUTE_DATA_TYPE(tangoTypeConst, return __get_max_alarm, att);
+ return 0;
+ }
+
+ template<long tangoTypeConst>
+ PyObject* __get_min_warning(Tango::Attribute &att)
+ {
+ typedef typename TANGO_const2type(tangoTypeConst) TangoScalarType;
+
+ TangoScalarType tg_val;
+ att.get_min_warning(tg_val);
+ boost::python::object py_value(tg_val);
+
+ return boost::python::incref(py_value.ptr());
+ }
+
+ PyObject *get_min_warning(Tango::Attribute &att)
+ {
+ long tangoTypeConst = att.get_data_type();
+
+ if(tangoTypeConst == Tango::DEV_ENCODED)
+ tangoTypeConst = Tango::DEV_UCHAR;
+
+ TANGO_CALL_ON_ATTRIBUTE_DATA_TYPE(tangoTypeConst, return __get_min_warning, att);
+ return 0;
+ }
+
+ template<long tangoTypeConst>
+ PyObject* __get_max_warning(Tango::Attribute &att)
+ {
+ typedef typename TANGO_const2type(tangoTypeConst) TangoScalarType;
+
+ TangoScalarType tg_val;
+ att.get_max_warning(tg_val);
+ boost::python::object py_value(tg_val);
+
+ return boost::python::incref(py_value.ptr());
+ }
+
+ PyObject *get_max_warning(Tango::Attribute &att)
+ {
+ long tangoTypeConst = att.get_data_type();
+
+ if(tangoTypeConst == Tango::DEV_ENCODED)
+ tangoTypeConst = Tango::DEV_UCHAR;
+
+ TANGO_CALL_ON_ATTRIBUTE_DATA_TYPE(tangoTypeConst, return __get_max_warning, att);
+ return 0;
+ }
+
};
BOOST_PYTHON_MEMBER_FUNCTION_OVERLOADS(set_quality_overloads,
@@ -511,7 +858,25 @@ void export_attribute()
.def("get_polling_period", &Tango::Attribute::get_polling_period)
.def("set_attr_serial_model", &Tango::Attribute::set_attr_serial_model)
.def("get_attr_serial_model", &Tango::Attribute::get_attr_serial_model)
-
+
+ .def("set_min_alarm", &PyAttribute::set_min_alarm)
+ .def("set_max_alarm", &PyAttribute::set_max_alarm)
+ .def("set_min_warning", &PyAttribute::set_min_warning)
+ .def("set_max_warning", &PyAttribute::set_max_warning)
+
+ .def("get_min_alarm",
+ (PyObject* (*) (Tango::Attribute &))
+ &PyAttribute::get_min_alarm)
+ .def("get_max_alarm",
+ (PyObject* (*) (Tango::Attribute &))
+ &PyAttribute::get_max_alarm)
+ .def("get_min_warning",
+ (PyObject* (*) (Tango::Attribute &))
+ &PyAttribute::get_min_warning)
+ .def("get_max_warning",
+ (PyObject* (*) (Tango::Attribute &))
+ &PyAttribute::get_max_warning)
+
.def("set_value",
(void (*) (Tango::Attribute &, boost::python::object &))
&PyAttribute::set_value)
@@ -560,6 +925,14 @@ void export_attribute()
.def("_set_properties", &PyAttribute::set_properties)
.def("_set_properties_3", &PyAttribute::set_properties_3)
+ .def("set_upd_properties",
+ (void (*) (Tango::Attribute &, boost::python::object &))
+ &PyAttribute::set_upd_properties)
+
+ .def("set_upd_properties",
+ (void (*) (Tango::Attribute &, boost::python::object &, boost::python::object &))
+ &PyAttribute::set_upd_properties)
+
.def("fire_change_event",
(void (*) (Tango::Attribute &))
&PyAttribute::fire_change_event)
diff --git a/src/server/command.cpp b/src/server/command.cpp
index 069d788..b5d88d0 100644
--- a/src/server/command.cpp
+++ b/src/server/command.cpp
@@ -172,14 +172,24 @@ void extract_scalar<Tango::DEV_VOID>(const CORBA::Any &any, boost::python::objec
/// @param type_ The type of the array objects. We need it to convert ptr_
/// to the proper type before deleting it.
/// ex: Tango::DEVVAR_SHORTARRAY.
-static void dev_var_x_array_deleter__(void * ptr_, void *type_)
-{
- long type = reinterpret_cast<long>(type_);
-
- TANGO_DO_ON_ATTRIBUTE_DATA_TYPE(type,
- delete static_cast<TANGO_const2type(tangoTypeConst)*>(ptr_);
- );
-}
+# ifdef PYCAPSULE_OLD
+ template<long type>
+ static void dev_var_x_array_deleter__(void * ptr_)
+ {
+ TANGO_DO_ON_ATTRIBUTE_DATA_TYPE(type,
+ delete static_cast<TANGO_const2type(tangoTypeConst)*>(ptr_);
+ );
+ }
+# else
+ template<long type>
+ static void dev_var_x_array_deleter__(PyObject* obj)
+ {
+ void * ptr_ = PyCapsule_GetPointer(obj, NULL);
+ TANGO_DO_ON_ATTRIBUTE_DATA_TYPE(type,
+ delete static_cast<TANGO_const2type(tangoTypeConst)*>(ptr_);
+ );
+ }
+#endif
#endif
template<long tangoArrayTypeConst>
@@ -206,10 +216,10 @@ void extract_array(const CORBA::Any &any, boost::python::object &py_result)
// PyCObject is intended for that kind of things. It's seen as a
// black box object from python. We assign him a function to be called
// when it is deleted -> the function deletes de data.
- PyObject* guard = PyCObject_FromVoidPtrAndDesc(
+ PyObject* guard = PyCapsule_New(
static_cast<void*>(copy_ptr),
- reinterpret_cast<void*>(tangoArrayTypeConst),
- dev_var_x_array_deleter__);
+ NULL,
+ dev_var_x_array_deleter__<tangoArrayTypeConst>);
if (!guard ) {
delete copy_ptr;
throw_error_already_set();
diff --git a/src/server/device_class.cpp b/src/server/device_class.cpp
index 4af89ba..7c203b9 100644
--- a/src/server/device_class.cpp
+++ b/src/server/device_class.cpp
@@ -267,7 +267,23 @@ namespace PyDeviceClass
}
return py_dev_list;
}
-
+
+ object get_command_list(CppDeviceClass &self)
+ {
+ 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)
+ {
+ object py_value = object(
+ handle<>(
+ to_python_indirect<
+ Tango::Command*,
+ detail::make_reference_holder>()(*it)));
+ py_cmd_list.append(py_value);
+ }
+ return py_cmd_list;
+ }
+
/*
void add_device(CppDeviceClass &self, auto_ptr<Tango::DeviceImpl> dev)
{
@@ -336,6 +352,9 @@ void export_device_class()
.def("get_cvs_location",&Tango::DeviceClass::get_cvs_location,
return_value_policy<copy_non_const_reference>())
.def("get_device_list",&PyDeviceClass::get_device_list)
+ .def("get_command_list",&PyDeviceClass::get_device_list)
+ .def("get_cmd_by_name",&Tango::DeviceClass::get_cmd_by_name,
+ return_internal_reference<>())
.def("set_type",
(void (Tango::DeviceClass::*) (const char *))
&Tango::DeviceClass::set_type)
diff --git a/src/server/device_impl.cpp b/src/server/device_impl.cpp
index 911f20a..16bd950 100644
--- a/src/server/device_impl.cpp
+++ b/src/server/device_impl.cpp
@@ -86,11 +86,14 @@ using namespace boost::python;
__AUX_CATCH_PY_EXCEPTION \
__AUX_CATCH_EXCEPTION(name)
+// we don't use extract<> from boost bellow to get attribute name because it is
+// considerably slow
#define SAFE_PUSH(dev, attr, attr_name) \
- char *__att_name_ptr = PyString_AsString(attr_name.ptr()); \
+ std::string __att_name; \
+ from_str_to_char(attr_name.ptr(), __att_name); \
AutoPythonAllowThreads python_guard_ptr; \
Tango::AutoTangoMonitor tango_guard(&dev); \
- Tango::Attribute & attr = dev.get_device_attr()->get_attr_by_name(__att_name_ptr); \
+ Tango::Attribute & attr = dev.get_device_attr()->get_attr_by_name(__att_name.c_str()); \
python_guard_ptr.giveup();
#define SAFE_PUSH_CHANGE_EVENT(dev, attr_name, data) \
@@ -583,10 +586,11 @@ namespace PyDeviceImpl
self.add_attribute(attr_ptr);
}
- void remove_attribute(Tango::DeviceImpl &self, const char *att_name)
+ void remove_attribute(Tango::DeviceImpl &self, const char *att_name,
+ bool clean_db = true)
{
string str(att_name);
- self.remove_attribute(str, false);
+ self.remove_attribute(str, false, clean_db);
}
inline void debug(Tango::DeviceImpl &self, const string &msg)
@@ -634,6 +638,54 @@ namespace PyDeviceImpl
from_py_object(py_attr_conf_list, attr_conf_list);
self.set_attribute_config(attr_conf_list);
}
+
+ bool is_attribute_polled(Tango::DeviceImpl &self, const std::string &att_name)
+ {
+ DeviceImplWrap *self_w = (DeviceImplWrap*)(&self);
+ return self_w->_is_attribute_polled(att_name);
+ }
+
+ bool is_command_polled(Tango::DeviceImpl &self, const std::string &cmd_name)
+ {
+ DeviceImplWrap *self_w = (DeviceImplWrap*)(&self);
+ return self_w->_is_command_polled(cmd_name);
+ }
+
+ int get_attribute_poll_period(Tango::DeviceImpl &self, const std::string &att_name)
+ {
+ DeviceImplWrap *self_w = (DeviceImplWrap*)(&self);
+ return self_w->_get_attribute_poll_period(att_name);
+ }
+
+ int get_command_poll_period(Tango::DeviceImpl &self, const std::string &cmd_name)
+ {
+ DeviceImplWrap *self_w = (DeviceImplWrap*)(&self);
+ return self_w->_get_command_poll_period(cmd_name);
+ }
+
+ void poll_attribute(Tango::DeviceImpl &self, const std::string &att_name, int period)
+ {
+ DeviceImplWrap *self_w = (DeviceImplWrap*)(&self);
+ self_w->_poll_attribute(att_name, period);
+ }
+
+ void poll_command(Tango::DeviceImpl &self, const std::string &cmd_name, int period)
+ {
+ DeviceImplWrap *self_w = (DeviceImplWrap*)(&self);
+ self_w->_poll_command(cmd_name, period);
+ }
+
+ void stop_poll_attribute(Tango::DeviceImpl &self, const std::string &att_name)
+ {
+ DeviceImplWrap *self_w = (DeviceImplWrap*)(&self);
+ self_w->_stop_poll_attribute(att_name);
+ }
+
+ void stop_poll_command(Tango::DeviceImpl &self, const std::string &cmd_name)
+ {
+ DeviceImplWrap *self_w = (DeviceImplWrap*)(&self);
+ self_w->_stop_poll_command(cmd_name);
+ }
}
DeviceImplWrap::DeviceImplWrap(PyObject *self, CppDeviceClass *cl,
@@ -658,6 +710,48 @@ void DeviceImplWrap::init_device()
this->get_override("init_device")();
}
+bool DeviceImplWrap::_is_attribute_polled(const std::string &att_name)
+{
+ return this->is_attribute_polled(att_name);
+}
+
+bool DeviceImplWrap::_is_command_polled(const std::string &cmd_name)
+{
+ return this->is_command_polled(cmd_name);
+}
+
+int DeviceImplWrap::_get_attribute_poll_period(const std::string &att_name)
+{
+ return this->get_attribute_poll_period(att_name);
+}
+
+int DeviceImplWrap::_get_command_poll_period(const std::string &cmd_name)
+{
+ return this->get_command_poll_period(cmd_name);
+}
+
+void DeviceImplWrap::_poll_attribute(const std::string &att_name, int period)
+{
+ this->poll_attribute(att_name, period);
+}
+
+void DeviceImplWrap::_poll_command(const std::string &cmd_name, int period)
+{
+ this->poll_command(cmd_name, period);
+}
+
+void DeviceImplWrap::_stop_poll_attribute(const std::string &att_name)
+{
+ this->stop_poll_attribute(att_name);
+}
+
+void DeviceImplWrap::_stop_poll_command(const std::string &cmd_name)
+{
+ this->stop_poll_command(cmd_name);
+}
+
+
+
Device_2ImplWrap::Device_2ImplWrap(PyObject *self, CppDeviceClass *cl,
std::string &st)
:Tango::Device_2Impl(cl,st),m_self(self)
@@ -1051,7 +1145,9 @@ BOOST_PYTHON_MEMBER_FUNCTION_OVERLOADS(set_archive_event_overload,
BOOST_PYTHON_MEMBER_FUNCTION_OVERLOADS(push_data_ready_event_overload,
Tango::DeviceImpl::push_data_ready_event, 1, 2)
-
+BOOST_PYTHON_FUNCTION_OVERLOADS(remove_attribute_overload,
+ PyDeviceImpl::remove_attribute, 2, 3)
+
void export_device_impl()
{
@@ -1100,12 +1196,19 @@ void export_device_impl()
&Tango::DeviceImpl::set_archive_event,
set_archive_event_overload())
.def("_add_attribute", &PyDeviceImpl::add_attribute)
- .def("_remove_attribute", &PyDeviceImpl::remove_attribute)
+ .def("_remove_attribute", &PyDeviceImpl::remove_attribute,
+ remove_attribute_overload())
//@TODO .def("get_device_class")
- //@TODO .def("get_device_attr")
//@TODO .def("get_db_device")
-
-
+ .def("is_attribute_polled", &PyDeviceImpl::is_attribute_polled)
+ .def("is_command_polled", &PyDeviceImpl::is_command_polled)
+ .def("get_attribute_poll_period", &PyDeviceImpl::get_attribute_poll_period)
+ .def("get_command_poll_period", &PyDeviceImpl::get_command_poll_period)
+ .def("poll_attribute", &PyDeviceImpl::poll_attribute)
+ .def("poll_command", &PyDeviceImpl::poll_command)
+ .def("stop_poll_attribute", &PyDeviceImpl::stop_poll_attribute)
+ .def("stop_poll_command", &PyDeviceImpl::stop_poll_command)
+
.def("get_exported_flag", &Tango::DeviceImpl::get_exported_flag)
.def("get_poll_ring_depth", &Tango::DeviceImpl::get_poll_ring_depth)
.def("get_poll_old_factor", &Tango::DeviceImpl::get_poll_old_factor)
diff --git a/src/server/device_impl.h b/src/server/device_impl.h
index 91d4a5e..6ac340d 100644
--- a/src/server/device_impl.h
+++ b/src/server/device_impl.h
@@ -73,6 +73,15 @@ public:
* Invokes the actual init_device
*/
void init_device();
+
+ bool _is_attribute_polled(const std::string &att_name);
+ bool _is_command_polled(const std::string &cmd_name);
+ int _get_attribute_poll_period(const std::string &att_name);
+ int _get_command_poll_period(const std::string &cmd_name);
+ void _poll_attribute(const std::string &att_name, int period);
+ void _poll_command(const std::string &cmd_name, int period);
+ void _stop_poll_attribute(const std::string &att_name);
+ void _stop_poll_command(const std::string &cmd_name);
};
/**
@@ -172,21 +181,6 @@ public:
virtual ~Device_3ImplWrap();
/**
- * A wrapper around the add_attribute in order to process some
- * internal information
- *
- * @param att the attribute reference containning information about
- * the new attribute to be added
- */
- void _add_attribute(const Tango::Attr &att);
-
- /**
- * Wrapper around the remove_attribute in order to simplify
- * string & to const string & conversion and default parameters
- */
- void _remove_attribute(const char *att_name);
-
- /**
* Necessary init_device implementation to call python
*/
virtual void init_device();
@@ -314,21 +308,6 @@ public:
virtual ~Device_4ImplWrap();
/**
- * A wrapper around the add_attribute in order to process some
- * internal information
- *
- * @param att the attribute reference containning information about
- * the new attribute to be added
- */
- void _add_attribute(const Tango::Attr &att);
-
- /**
- * Wrapper around the remove_attribute in order to simplify
- * string & to const string & conversion and default parameters
- */
- void _remove_attribute(const char *att_name);
-
- /**
* Necessary init_device implementation to call python
*/
virtual void init_device();
diff --git a/src/server/encoded_attribute.cpp b/src/server/encoded_attribute.cpp
index 62708ea..4a44179 100644
--- a/src/server/encoded_attribute.cpp
+++ b/src/server/encoded_attribute.cpp
@@ -34,30 +34,43 @@ const int i = 1;
namespace PyEncodedAttribute
{
- /// This callback is run to delete char* objects.
+ /// This callback is run to delete char* objects.
/// It is called by python. The array was associated with an attribute
/// value object that is not being used anymore.
/// @param ptr_ The array object.
/// @param type_ The type of data. We don't need it for now
-
- static void __ptr_deleter(void * ptr_, void *type_)
- {
- long t = reinterpret_cast<long>(type_);
- if (1 == t)
- delete [] (static_cast<unsigned char*>(ptr_));
- else if (2 == t)
- delete [] (static_cast<unsigned short*>(ptr_));
- else if (4 == t)
- delete [] (static_cast<Tango::DevULong*>(ptr_));
- }
+# ifdef PYCAPSULE_OLD
+ template<long type>
+ static void __ptr_deleter(void * ptr_)
+ {
+ if (1 == type)
+ delete [] (static_cast<unsigned char*>(ptr_));
+ else if (2 == type)
+ delete [] (static_cast<unsigned short*>(ptr_));
+ else if (4 == type)
+ delete [] (static_cast<Tango::DevULong*>(ptr_));
+ }
+# else
+ template<long type>
+ static void __ptr_deleter(PyObject* obj)
+ {
+ void * ptr_ = PyCapsule_GetPointer(obj, NULL);
+ if (1 == type)
+ delete [] (static_cast<unsigned char*>(ptr_));
+ else if (2 == type)
+ delete [] (static_cast<unsigned short*>(ptr_));
+ else if (4 == type)
+ delete [] (static_cast<Tango::DevULong*>(ptr_));
+ }
+# endif
void encode_gray8(Tango::EncodedAttribute &self, object py_value, int w, int h)
{
PyObject *py_value_ptr = py_value.ptr();
unsigned char *buffer = NULL;
- if (PyString_Check(py_value_ptr))
+ if (PyBytes_Check(py_value_ptr))
{
- buffer = reinterpret_cast<unsigned char*>(PyString_AsString(py_value_ptr));
+ buffer = reinterpret_cast<unsigned char*>(PyBytes_AsString(py_value_ptr));
self.encode_gray8(buffer, w, h);
return;
}
@@ -74,9 +87,9 @@ namespace PyEncodedAttribute
#endif
// It must be a py sequence
// we are sure that w and h are given by python (see encoded_attribute.py)
- const int length = w*h;
- unsigned char *raw_b = new unsigned char[length];
- auto_ptr<unsigned char> b(raw_b);
+ const int length = w*h;
+ unsigned char *raw_b = new unsigned char[length];
+ unique_pointer<unsigned char> b(raw_b);
buffer = raw_b;
unsigned char *p = raw_b;
int w_bytes = w;
@@ -93,16 +106,16 @@ namespace PyEncodedAttribute
boost::python::throw_error_already_set();
}
// The given object is a sequence of strings were each string is the entire row
- if (PyString_Check(row))
+ if (PyBytes_Check(row))
{
- if (PyString_Size(row) != w_bytes)
+ if (PyBytes_Size(row) != w_bytes)
{
Py_DECREF(row);
PyErr_SetString(PyExc_TypeError,
"All sequences inside a sequence must have same size");
boost::python::throw_error_already_set();
}
- memcpy(p, PyString_AsString(row), w_bytes);
+ memcpy(p, PyBytes_AsString(row), w_bytes);
p += w;
}
else
@@ -123,9 +136,9 @@ namespace PyEncodedAttribute
Py_DECREF(row);
boost::python::throw_error_already_set();
}
- if (PyString_Check(cell))
+ if (PyBytes_Check(cell))
{
- if (PyString_Size(cell) != 1)
+ if (PyBytes_Size(cell) != 1)
{
Py_DECREF(row);
Py_DECREF(cell);
@@ -133,10 +146,10 @@ namespace PyEncodedAttribute
"All string items must have length one");
boost::python::throw_error_already_set();
}
- char byte = PyString_AsString(cell)[0];
+ char byte = PyBytes_AsString(cell)[0];
*p = byte;
}
- else if (PyInt_Check(cell) || PyLong_Check(cell))
+ else if (PyLong_Check(cell))
{
long byte = PyLong_AsLong(cell);
if (byte==-1 && PyErr_Occurred())
@@ -169,9 +182,9 @@ namespace PyEncodedAttribute
{
PyObject *py_value_ptr = py_value.ptr();
unsigned char *buffer = NULL;
- if (PyString_Check(py_value_ptr))
+ if (PyBytes_Check(py_value_ptr))
{
- buffer = reinterpret_cast<unsigned char*>(PyString_AsString(py_value_ptr));
+ buffer = reinterpret_cast<unsigned char*>(PyBytes_AsString(py_value_ptr));
self.encode_jpeg_gray8(buffer, w, h, quality);
return;
}
@@ -188,10 +201,10 @@ namespace PyEncodedAttribute
#endif
// It must be a py sequence
// we are sure that w and h are given by python (see encoded_attribute.py)
- const int length = w*h;
+ const int length = w*h;
unsigned char *raw_b = new unsigned char[length];
- auto_ptr<unsigned char> b(raw_b);
- buffer = raw_b;
+ unique_pointer<unsigned char> b(raw_b);
+ buffer = raw_b;
unsigned char *p = raw_b;
int w_bytes = w;
for (long y=0; y<h; ++y)
@@ -207,16 +220,16 @@ namespace PyEncodedAttribute
boost::python::throw_error_already_set();
}
// The given object is a sequence of strings were each string is the entire row
- if (PyString_Check(row))
+ if (PyBytes_Check(row))
{
- if (PyString_Size(row) != w_bytes)
+ if (PyBytes_Size(row) != w_bytes)
{
Py_DECREF(row);
PyErr_SetString(PyExc_TypeError,
"All sequences inside a sequence must have same size");
boost::python::throw_error_already_set();
}
- memcpy(p, PyString_AsString(row), w_bytes);
+ memcpy(p, PyBytes_AsString(row), w_bytes);
p += w;
}
else
@@ -237,9 +250,9 @@ namespace PyEncodedAttribute
Py_DECREF(row);
boost::python::throw_error_already_set();
}
- if (PyString_Check(cell))
+ if (PyBytes_Check(cell))
{
- if (PyString_Size(cell) != 1)
+ if (PyBytes_Size(cell) != 1)
{
Py_DECREF(row);
Py_DECREF(cell);
@@ -247,10 +260,10 @@ namespace PyEncodedAttribute
"All string items must have length one");
boost::python::throw_error_already_set();
}
- char byte = PyString_AsString(cell)[0];
+ char byte = PyBytes_AsString(cell)[0];
*p = byte;
}
- else if (PyInt_Check(cell) || PyLong_Check(cell))
+ else if (PyLong_Check(cell))
{
long byte = PyLong_AsLong(cell);
if (byte==-1 && PyErr_Occurred())
@@ -283,9 +296,9 @@ namespace PyEncodedAttribute
{
PyObject *py_value_ptr = py_value.ptr();
unsigned short *buffer = NULL;
- if (PyString_Check(py_value_ptr))
+ if (PyBytes_Check(py_value_ptr))
{
- buffer = reinterpret_cast<unsigned short*>(PyString_AsString(py_value_ptr));
+ buffer = reinterpret_cast<unsigned short*>(PyBytes_AsString(py_value_ptr));
self.encode_gray16(buffer, w, h);
return;
}
@@ -302,10 +315,10 @@ namespace PyEncodedAttribute
#endif
// It must be a py sequence
// we are sure that w and h are given by python (see encoded_attribute.py)
- const int length = w*h;
+ const int length = w*h;
unsigned short *raw_b = new unsigned short[length];
- auto_ptr<unsigned short> b(raw_b);
- buffer = raw_b;
+ unique_pointer<unsigned short> b(raw_b);
+ buffer = raw_b;
unsigned short *p = raw_b;
int w_bytes = 2*w;
for (long y=0; y<h; ++y)
@@ -321,16 +334,16 @@ namespace PyEncodedAttribute
boost::python::throw_error_already_set();
}
// The given object is a sequence of strings were each string is the entire row
- if (PyString_Check(row))
+ if (PyBytes_Check(row))
{
- if (PyString_Size(row) != w_bytes)
+ if (PyBytes_Size(row) != w_bytes)
{
Py_DECREF(row);
PyErr_SetString(PyExc_TypeError,
"All sequences inside a sequence must have same size");
boost::python::throw_error_already_set();
}
- memcpy(p, PyString_AsString(row), w_bytes);
+ memcpy(p, PyBytes_AsString(row), w_bytes);
p += w;
}
else
@@ -351,9 +364,9 @@ namespace PyEncodedAttribute
Py_DECREF(row);
boost::python::throw_error_already_set();
}
- if (PyString_Check(cell))
+ if (PyBytes_Check(cell))
{
- if (PyString_Size(cell) != 2)
+ if (PyBytes_Size(cell) != 2)
{
Py_DECREF(row);
Py_DECREF(cell);
@@ -361,10 +374,10 @@ namespace PyEncodedAttribute
"All string items must have length two");
boost::python::throw_error_already_set();
}
- unsigned short *word = reinterpret_cast<unsigned short *>(PyString_AsString(cell));
+ unsigned short *word = reinterpret_cast<unsigned short *>(PyBytes_AsString(cell));
*p = *word;
}
- else if (PyInt_Check(cell) || PyLong_Check(cell))
+ else if (PyLong_Check(cell))
{
unsigned short word = (unsigned short)PyLong_AsUnsignedLong(cell);
if (PyErr_Occurred())
@@ -396,9 +409,9 @@ namespace PyEncodedAttribute
{
PyObject *py_value_ptr = py_value.ptr();
unsigned char *buffer = NULL;
- if (PyString_Check(py_value_ptr))
+ if (PyBytes_Check(py_value_ptr))
{
- buffer = reinterpret_cast<unsigned char*>(PyString_AsString(py_value_ptr));
+ buffer = reinterpret_cast<unsigned char*>(PyBytes_AsString(py_value_ptr));
self.encode_rgb24(buffer, w, h);
return;
}
@@ -412,10 +425,10 @@ namespace PyEncodedAttribute
#endif
// It must be a py sequence
// we are sure that w and h are given by python (see encoded_attribute.py)
- const int length = w*h;
+ const int length = w*h;
unsigned char *raw_b = new unsigned char[length];
- auto_ptr<unsigned char> b(raw_b);
- buffer = raw_b;
+ unique_pointer<unsigned char> b(raw_b);
+ buffer = raw_b;
unsigned char *p = raw_b;
int w_bytes = 3*w;
for (long y=0; y<h; ++y)
@@ -431,16 +444,16 @@ namespace PyEncodedAttribute
boost::python::throw_error_already_set();
}
// The given object is a sequence of strings were each string is the entire row
- if (PyString_Check(row))
+ if (PyBytes_Check(row))
{
- if (PyString_Size(row) != w_bytes)
+ if (PyBytes_Size(row) != w_bytes)
{
Py_DECREF(row);
PyErr_SetString(PyExc_TypeError,
"All sequences inside a sequence must have same size");
boost::python::throw_error_already_set();
}
- memcpy(p, PyString_AsString(row), w_bytes);
+ memcpy(p, PyBytes_AsString(row), w_bytes);
p += w;
}
else
@@ -461,9 +474,9 @@ namespace PyEncodedAttribute
Py_DECREF(row);
boost::python::throw_error_already_set();
}
- if (PyString_Check(cell))
+ if (PyBytes_Check(cell))
{
- if (PyString_Size(cell) != 3)
+ if (PyBytes_Size(cell) != 3)
{
Py_DECREF(row);
Py_DECREF(cell);
@@ -471,12 +484,12 @@ namespace PyEncodedAttribute
"All string items must have length one");
boost::python::throw_error_already_set();
}
- char *byte = PyString_AsString(cell);
+ char *byte = PyBytes_AsString(cell);
*p = *byte; p++; byte++;
*p = *byte; p++; byte++;
*p = *byte; p++;
}
- else if (PyInt_Check(cell) || PyLong_Check(cell))
+ else if (PyLong_Check(cell))
{
long byte = PyLong_AsLong(cell);
if (byte==-1 && PyErr_Occurred())
@@ -510,9 +523,9 @@ namespace PyEncodedAttribute
{
PyObject *py_value_ptr = py_value.ptr();
unsigned char *buffer = NULL;
- if (PyString_Check(py_value_ptr))
+ if (PyBytes_Check(py_value_ptr))
{
- buffer = reinterpret_cast<unsigned char*>(PyString_AsString(py_value_ptr));
+ buffer = reinterpret_cast<unsigned char*>(PyBytes_AsString(py_value_ptr));
self.encode_jpeg_rgb24(buffer, w, h, quality);
return;
}
@@ -528,7 +541,7 @@ namespace PyEncodedAttribute
// we are sure that w and h are given by python (see encoded_attribute.py)
const int length = w*h;
unsigned char *raw_b = new unsigned char[length];
- auto_ptr<unsigned char> b(raw_b);
+ unique_pointer<unsigned char> b(raw_b);
buffer = raw_b;
unsigned char *p = raw_b;
int w_bytes = 3*w;
@@ -545,16 +558,16 @@ namespace PyEncodedAttribute
boost::python::throw_error_already_set();
}
// The given object is a sequence of strings were each string is the entire row
- if (PyString_Check(row))
+ if (PyBytes_Check(row))
{
- if (PyString_Size(row) != w_bytes)
+ if (PyBytes_Size(row) != w_bytes)
{
Py_DECREF(row);
PyErr_SetString(PyExc_TypeError,
"All sequences inside a sequence must have same size");
boost::python::throw_error_already_set();
}
- memcpy(p, PyString_AsString(row), w_bytes);
+ memcpy(p, PyBytes_AsString(row), w_bytes);
p += w;
}
else
@@ -575,9 +588,9 @@ namespace PyEncodedAttribute
Py_DECREF(row);
boost::python::throw_error_already_set();
}
- if (PyString_Check(cell))
+ if (PyBytes_Check(cell))
{
- if (PyString_Size(cell) != 3)
+ if (PyBytes_Size(cell) != 3)
{
Py_DECREF(row);
Py_DECREF(cell);
@@ -585,12 +598,12 @@ namespace PyEncodedAttribute
"All string items must have length one");
boost::python::throw_error_already_set();
}
- char *byte = PyString_AsString(cell);
+ char *byte = PyBytes_AsString(cell);
*p = *byte; p++; byte++;
*p = *byte; p++; byte++;
*p = *byte; p++;
}
- else if (PyInt_Check(cell) || PyLong_Check(cell))
+ else if (PyLong_Check(cell))
{
long byte = PyLong_AsLong(cell);
if (byte==-1 && PyErr_Occurred())
@@ -624,9 +637,9 @@ namespace PyEncodedAttribute
{
PyObject *py_value_ptr = py_value.ptr();
unsigned char *buffer = NULL;
- if (PyString_Check(py_value_ptr))
+ if (PyBytes_Check(py_value_ptr))
{
- buffer = reinterpret_cast<unsigned char*>(PyString_AsString(py_value_ptr));
+ buffer = reinterpret_cast<unsigned char*>(PyBytes_AsString(py_value_ptr));
self.encode_jpeg_rgb32(buffer, w, h, quality);
return;
}
@@ -642,7 +655,7 @@ namespace PyEncodedAttribute
// we are sure that w and h are given by python (see encoded_attribute.py)
const int length = w*h;
unsigned char *raw_b = new unsigned char[length];
- auto_ptr<unsigned char> b(raw_b);
+ unique_pointer<unsigned char> b(raw_b);
buffer = raw_b;
unsigned char *p = raw_b;
int w_bytes = 4*w;
@@ -659,16 +672,16 @@ namespace PyEncodedAttribute
boost::python::throw_error_already_set();
}
// The given object is a sequence of strings were each string is the entire row
- if (PyString_Check(row))
+ if (PyBytes_Check(row))
{
- if (PyString_Size(row) != w_bytes)
+ if (PyBytes_Size(row) != w_bytes)
{
Py_DECREF(row);
PyErr_SetString(PyExc_TypeError,
"All sequences inside a sequence must have same size");
boost::python::throw_error_already_set();
}
- memcpy(p, PyString_AsString(row), w_bytes);
+ memcpy(p, PyBytes_AsString(row), w_bytes);
p += w;
}
else
@@ -689,9 +702,9 @@ namespace PyEncodedAttribute
Py_DECREF(row);
boost::python::throw_error_already_set();
}
- if (PyString_Check(cell))
+ if (PyBytes_Check(cell))
{
- if (PyString_Size(cell) != 3)
+ if (PyBytes_Size(cell) != 3)
{
Py_DECREF(row);
Py_DECREF(cell);
@@ -699,13 +712,13 @@ namespace PyEncodedAttribute
"All string items must have length one");
boost::python::throw_error_already_set();
}
- char *byte = PyString_AsString(cell);
+ char *byte = PyBytes_AsString(cell);
*p = *byte; p++; byte++;
*p = *byte; p++; byte++;
*p = *byte; p++; byte++;
*p = *byte; p++;
}
- else if (PyInt_Check(cell) || PyLong_Check(cell))
+ else if (PyLong_Check(cell))
{
long byte = PyLong_AsLong(cell);
if (byte==-1 && PyErr_Occurred())
@@ -764,10 +777,10 @@ namespace PyEncodedAttribute
// PyCObject is intended for that kind of things. It's seen as a
// black box object from python. We assign him a function to be called
// when it is deleted -> the function deletes de data.
- PyObject* guard = PyCObject_FromVoidPtrAndDesc(
- static_cast<void*>(ch_ptr),
- reinterpret_cast<void*>(1),
- __ptr_deleter);
+ PyObject* guard = PyCapsule_New(
+ static_cast<void*>(ch_ptr),
+ NULL,
+ __ptr_deleter<1>);
if (!guard)
{
@@ -789,7 +802,7 @@ namespace PyEncodedAttribute
throw_error_already_set();
}
size_t nb_bytes = width*height*sizeof(char);
- PyObject *buffer_str = PyString_FromStringAndSize(ch_ptr, nb_bytes);
+ PyObject *buffer_str = PyBytes_FromStringAndSize(ch_ptr, nb_bytes);
if (!buffer_str)
{
Py_XDECREF(ret);
@@ -823,7 +836,7 @@ namespace PyEncodedAttribute
}
for (long x=0; x < width; ++x)
{
- PyTuple_SetItem(row, x, PyString_FromStringAndSize(ch_ptr + y*width+x, 1));
+ PyTuple_SetItem(row, x, PyBytes_FromStringAndSize(ch_ptr + y*width+x, 1));
}
PyTuple_SetItem(ret, y, row);
}
@@ -831,7 +844,6 @@ namespace PyEncodedAttribute
delete [] buffer;
break;
}
- case PyTango::ExtractAsPyTango3:
case PyTango::ExtractAsList:
{
ret = PyList_New(height);
@@ -852,7 +864,7 @@ namespace PyEncodedAttribute
}
for (long x=0; x < width; ++x)
{
- PyList_SetItem(row, x, PyString_FromStringAndSize(ch_ptr + y*width+x, 1));
+ PyList_SetItem(row, x, PyBytes_FromStringAndSize(ch_ptr + y*width+x, 1));
}
PyList_SetItem(ret, y, row);
}
@@ -899,10 +911,10 @@ namespace PyEncodedAttribute
// PyCObject is intended for that kind of things. It's seen as a
// black box object from python. We assign him a function to be called
// when it is deleted -> the function deletes de data.
- PyObject* guard = PyCObject_FromVoidPtrAndDesc(
+ PyObject* guard = PyCapsule_New(
static_cast<void*>(ch_ptr),
- reinterpret_cast<void*>(2),
- __ptr_deleter);
+ NULL,
+ __ptr_deleter<2>);
if (!guard)
{
@@ -925,7 +937,7 @@ namespace PyEncodedAttribute
}
size_t nb_bytes = width*height*sizeof(unsigned short);
- PyObject *buffer_str = PyString_FromStringAndSize(
+ PyObject *buffer_str = PyBytes_FromStringAndSize(
reinterpret_cast<char *>(ch_ptr), nb_bytes);
delete [] buffer;
@@ -969,7 +981,6 @@ namespace PyEncodedAttribute
delete [] buffer;
break;
}
- case PyTango::ExtractAsPyTango3:
case PyTango::ExtractAsList:
{
ret = PyList_New(height);
@@ -1036,11 +1047,11 @@ namespace PyEncodedAttribute
// the last copy of numpy.ndarray() disappears.
// PyCObject is intended for that kind of things. It's seen as a
// black box object from python. We assign him a function to be called
- PyObject* guard = PyCObject_FromVoidPtrAndDesc(
// when it is deleted -> the function deletes de data.
+ PyObject* guard = PyCapsule_New(
static_cast<void*>(ch_ptr),
- reinterpret_cast<void*>(2),
- __ptr_deleter);
+ NULL,
+ __ptr_deleter<4>);
if (!guard)
{
@@ -1063,7 +1074,7 @@ namespace PyEncodedAttribute
}
size_t nb_bytes = width*height*4;
- PyObject *buffer_str = PyString_FromStringAndSize(
+ PyObject *buffer_str = PyBytes_FromStringAndSize(
reinterpret_cast<char *>(ch_ptr), nb_bytes);
delete [] buffer;
@@ -1127,7 +1138,6 @@ namespace PyEncodedAttribute
delete [] buffer;
break;
}
- case PyTango::ExtractAsPyTango3:
case PyTango::ExtractAsList:
{
ret = PyList_New(height);
@@ -1209,4 +1219,4 @@ void export_encoded_attribute()
.def("_decode_gray16", &PyEncodedAttribute::decode_gray16)
.def("_decode_rgb32", &PyEncodedAttribute::decode_rgb32)
;
-}
\ No newline at end of file
+}
diff --git a/src/server/log4tango.cpp b/src/server/log4tango.cpp
index c7674d2..eb29b87 100644
--- a/src/server/log4tango.cpp
+++ b/src/server/log4tango.cpp
@@ -45,7 +45,9 @@ namespace PyLogging
par.length(len);
for(int i = 0; i < len; ++i)
{
- par[i] = CORBA::string_dup(PyString_AsString(PySequence_GetItem(obj_ptr, i)));
+ PyObject* item_ptr = PySequence_GetItem(obj_ptr, i);
+ str item = str(handle<>(item_ptr));
+ par[i] = CORBA::string_dup(extract<const char*>(item));
}
Tango::Logging::add_logging_target(&par);
}
@@ -63,7 +65,9 @@ namespace PyLogging
par.length(len);
for(int i = 0; i < len; ++i)
{
- par[i] = CORBA::string_dup(PyString_AsString(PySequence_GetItem(obj_ptr, i)));
+ PyObject* item_ptr = PySequence_GetItem(obj_ptr, i);
+ str item = str(handle<>(item_ptr));
+ par[i] = CORBA::string_dup(extract<const char*>(item));
}
Tango::Logging::remove_logging_target(&par);
}
diff --git a/src/server/tango_util.cpp b/src/server/tango_util.cpp
index 3469f7d..ad4f1f9 100644
--- a/src/server/tango_util.cpp
+++ b/src/server/tango_util.cpp
@@ -29,83 +29,6 @@
using namespace boost::python;
-#ifndef _TG_WINDOWS_
-#include <unistd.h>
-#include <signal.h>
-#include <dlfcn.h>
-#endif /* _TG_WINDOWS_ */
-
-typedef Tango::DeviceClass *(*Cpp_creator_ptr)(const char *);
-
-Tango::DeviceClass* create_cpp_class(const std::string& class_name,
- const std::string& par_name)
-{
- std::string lib_name = class_name;
- std::string sym_name = "_create_" + class_name + "_class";
-
-#ifdef _TG_WINDOWS_
- HMODULE mod;
-
- if ((mod = LoadLibrary(lib_name.c_str())) == NULL)
- {
- char *str = 0;
-
- DWORD l_err = GetLastError();
- ::FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM,NULL,
- l_err,MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),(char *)&str,0,NULL);
-
- cerr << "Error: " << str << endl;
-
- TangoSys_OMemStream o;
- o << "Trying to load shared library " << lib_name
- << " failed. It returns error: " << str << ends;
- ::LocalFree((HLOCAL)str);
-
- Tango::Except::throw_exception("API_ClassNotFound", o.str(),
- "DServer::create_cpp_class");
- }
- FARPROC proc;
-
- if ((proc = GetProcAddress(mod,sym_name.c_str())) == NULL)
- {
- TangoSys_OMemStream o;
- o << "Class " << class_name << " does not have the C creator function "
- "(_create_<Class name>_class)" << ends;
-
- Tango::Except::throw_exception("API_ClassNotFound", o.str(),
- "DServer::create_cpp_class");
- }
- Cpp_creator_ptr mt = (Cpp_creator_ptr)proc;
-#else
- lib_name += ".so";
-
- void *lib_ptr = dlopen(lib_name.c_str(), RTLD_NOW);
- if (lib_ptr == NULL)
- {
- TangoSys_OMemStream o;
- o << "Trying to load shared library " << lib_name
- << " failed. It returns error: " << dlerror() << ends;
-
- Tango::Except::throw_exception("API_ClassNotFound",o.str(),
- "DServer::create_cpp_class");
- }
-
- void *sym = dlsym(lib_ptr,sym_name.c_str());
- if (sym == NULL)
- {
- TangoSys_OMemStream o;
- o << "Class " << class_name << " does not have the C creator function "
- "(_create_<Class name>_class)" << ends;
-
- Tango::Except::throw_exception("API_ClassNotFound", o.str(),
- "DServer::create_cpp_class");
- }
- Cpp_creator_ptr mt = (Cpp_creator_ptr)sym;
-#endif /* _TG_WINDOWS_ */
- Tango::DeviceClass *dc = (*mt)(par_name.c_str());
- return dc;
-}
-
namespace PyUtil
{
void _class_factory(Tango::DServer* dserver)
@@ -124,8 +47,7 @@ namespace PyUtil
tuple class_info = extract<tuple>(cpp_class_list[i]);
char *class_name = extract<char *>(class_info[0]);
char *par_name = extract<char *>(class_info[1]);
- Tango::DeviceClass* cpp_dc = create_cpp_class(class_name, par_name);
- dserver->_add_class(cpp_dc);
+ dserver->_create_cpp_class(class_name, par_name);
}
//
@@ -171,10 +93,11 @@ namespace PyUtil
Tango::Util* res = 0;
try {
-
for(int i = 0; i < argc; ++i)
{
- argv[i] = PyString_AsString(PySequence_GetItem(obj_ptr, i));
+ PyObject* item_ptr = PySequence_GetItem(obj_ptr, i);
+ str item = str(handle<>(item_ptr));
+ argv[i] = extract<char *>(item);
}
res = Tango::Util::init(argc, argv);
} catch (...) {
@@ -296,6 +219,9 @@ void export_util()
.def("trigger_attr_polling", &Tango::Util::trigger_attr_polling)
.def("set_polling_threads_pool_size", &Tango::Util::set_polling_threads_pool_size)
.def("get_polling_threads_pool_size", &Tango::Util::get_polling_threads_pool_size)
+ .def("is_svr_starting", &Tango::Util::is_svr_starting)
+ .def("is_svr_shutting_down", &Tango::Util::is_svr_shutting_down)
+ .def("is_device_restarting", &Tango::Util::is_device_restarting)
.def("get_sub_dev_diag", &Tango::Util::get_sub_dev_diag,
return_internal_reference<>())
.def("connect_db", &Tango::Util::connect_db)
@@ -311,4 +237,4 @@ void export_util()
.def("init_python", init_python)
.staticmethod("init_python")
;
-}
\ No newline at end of file
+}
diff --git a/src/server/wattribute.cpp b/src/server/wattribute.cpp
index c7fa5fd..f5ca5b2 100644
--- a/src/server/wattribute.cpp
+++ b/src/server/wattribute.cpp
@@ -28,6 +28,10 @@
using namespace boost::python;
+#ifndef TgLibVersNb
+# define TgLibVersNb 80005
+#endif
+
/**
* Helper method to Limit the max number of element to send to C++
*
@@ -83,9 +87,10 @@ namespace PyWAttribute
{
long type = att.get_data_type();
- TANGO_DO_ON_NUMERICAL_ATTRIBUTE_DATA_TYPE(type,
- return __get_min_value<tangoTypeConst>(att)
- );
+ if(type == Tango::DEV_ENCODED)
+ type = Tango::DEV_UCHAR;
+
+ TANGO_CALL_ON_ATTRIBUTE_DATA_TYPE(type, return __get_min_value, att);
return 0;
}
@@ -104,42 +109,129 @@ namespace PyWAttribute
{
long type = att.get_data_type();
- TANGO_DO_ON_NUMERICAL_ATTRIBUTE_DATA_TYPE(type,
- return __get_max_value<tangoTypeConst>(att)
- );
+ if(type == Tango::DEV_ENCODED)
+ type = Tango::DEV_UCHAR;
+
+ TANGO_CALL_ON_ATTRIBUTE_DATA_TYPE(type, return __get_max_value, att);
return 0;
}
+#if TgLibVersNb >= 80100 // set_min_value
+
template<long tangoTypeConst>
- void __set_min_value(Tango::WAttribute &att, boost::python::object &v)
+ inline void _set_min_value(Tango::WAttribute &self, boost::python::object value)
{
- typedef typename TANGO_const2type(tangoTypeConst) TangoScalarType;
+ typedef typename TANGO_const2type(tangoTypeConst) TangoScalarType;
+ TangoScalarType c_value = boost::python::extract<TangoScalarType>(value);
+ self.set_min_value(c_value);
+ }
- TangoScalarType tg_val = boost::python::extract<TangoScalarType>(v);
+#else // set_min_value
- att.set_min_value(tg_val);
+ template<typename TangoScalarType>
+ inline void __set_min_value(Tango::WAttribute &self, boost::python::object value)
+ {
+ TangoScalarType c_value = boost::python::extract<TangoScalarType>(value);
+ self.set_min_value(c_value);
}
- void set_min_value(Tango::WAttribute &att, boost::python::object &v)
+ template<>
+ inline void __set_min_value<Tango::DevEncoded>(Tango::WAttribute &self, boost::python::object value)
{
- long type = att.get_data_type();
- TANGO_CALL_ON_NUMERICAL_ATTRIBUTE_DATA_TYPE(type, __set_min_value, att, v);
+ string err_msg = "Attribute properties cannot be set with Tango::DevEncoded data type";
+ Tango::Except::throw_exception((const char *)"API_MethodArgument",
+ (const char *)err_msg.c_str(),
+ (const char *)"WAttribute::set_min_value()");
}
template<long tangoTypeConst>
- void __set_max_value(Tango::WAttribute &att, boost::python::object &v)
+ inline void _set_min_value(Tango::WAttribute &self, boost::python::object value)
{
- typedef typename TANGO_const2type(tangoTypeConst) TangoScalarType;
+ typedef typename TANGO_const2type(tangoTypeConst) TangoScalarType;
+ __set_min_value<TangoScalarType>(self,value);
+ }
- TangoScalarType tg_val = boost::python::extract<TangoScalarType>(v);
+#endif // set_min_value
- att.set_max_value(tg_val);
+ inline void set_min_value(Tango::WAttribute &self, boost::python::object value)
+ {
+ bopy::extract<string> value_convert(value);
+
+ if (value_convert.check())
+ {
+ self.set_min_value(value_convert());
+ }
+ else
+ {
+ long tangoTypeConst = self.get_data_type();
+ // TODO: the below line is a neat trick to properly raise a Tango exception if a property is set
+ // for one of the forbidden attribute data types; code dependent on Tango C++ implementation
+ if(tangoTypeConst == Tango::DEV_STRING || tangoTypeConst == Tango::DEV_BOOLEAN || tangoTypeConst == Tango::DEV_STATE)
+ tangoTypeConst = Tango::DEV_DOUBLE;
+ else if(tangoTypeConst == Tango::DEV_ENCODED)
+ tangoTypeConst = Tango::DEV_UCHAR;
+
+ TANGO_CALL_ON_ATTRIBUTE_DATA_TYPE(tangoTypeConst, _set_min_value, self, value);
+ }
}
- void set_max_value(Tango::WAttribute &att, boost::python::object &v)
+#if TgLibVersNb >= 80100 // set_max_value
+
+ template<long tangoTypeConst>
+ inline void _set_max_value(Tango::WAttribute &self, boost::python::object value)
{
- long type = att.get_data_type();
- TANGO_CALL_ON_NUMERICAL_ATTRIBUTE_DATA_TYPE(type, __set_max_value, att, v);
+ typedef typename TANGO_const2type(tangoTypeConst) TangoScalarType;
+ TangoScalarType c_value = boost::python::extract<TangoScalarType>(value);
+ self.set_max_value(c_value);
+ }
+
+#else // set_max_value
+
+ template<typename TangoScalarType>
+ inline void __set_max_value(Tango::WAttribute &self, boost::python::object value)
+ {
+ TangoScalarType c_value = boost::python::extract<TangoScalarType>(value);
+ self.set_max_value(c_value);
+ }
+
+ template<>
+ inline void __set_max_value<Tango::DevEncoded>(Tango::WAttribute &self, boost::python::object value)
+ {
+ string err_msg = "Attribute properties cannot be set with Tango::DevEncoded data type";
+ Tango::Except::throw_exception((const char *)"API_MethodArgument",
+ (const char *)err_msg.c_str(),
+ (const char *)"WAttribute::set_max_value()");
+ }
+
+ template<long tangoTypeConst>
+ inline void _set_max_value(Tango::WAttribute &self, boost::python::object value)
+ {
+ typedef typename TANGO_const2type(tangoTypeConst) TangoScalarType;
+ __set_max_value<TangoScalarType>(self,value);
+ }
+
+#endif // set_max_value
+
+ inline void set_max_value(Tango::WAttribute &self, boost::python::object value)
+ {
+ bopy::extract<string> value_convert(value);
+
+ if (value_convert.check())
+ {
+ self.set_max_value(value_convert());
+ }
+ else
+ {
+ long tangoTypeConst = self.get_data_type();
+ // TODO: the below line is a neat trick to properly raise a Tango exception if a property is set
+ // for one of the forbidden attribute data types; code dependent on Tango C++ implementation
+ if(tangoTypeConst == Tango::DEV_STRING || tangoTypeConst == Tango::DEV_BOOLEAN || tangoTypeConst == Tango::DEV_STATE)
+ tangoTypeConst = Tango::DEV_DOUBLE;
+ else if(tangoTypeConst == Tango::DEV_ENCODED)
+ tangoTypeConst = Tango::DEV_UCHAR;
+
+ TANGO_CALL_ON_ATTRIBUTE_DATA_TYPE(tangoTypeConst, _set_max_value, self, value);
+ }
}
/// @}
@@ -345,47 +437,6 @@ namespace PyWAttribute
/// @{
template<long tangoTypeConst>
- void __get_write_value_pytango3(Tango::WAttribute &att, boost::python::list &seq)
- {
- typedef typename TANGO_const2type(tangoTypeConst) TangoScalarType;
-
- const TangoScalarType *ptr;
-
- long length = att.get_write_value_length();
-
- att.get_write_value(ptr);
-
- for (long l = 0; l < length; ++l)
- {
- seq.append(ptr[l]);
- }
- }
-
- template<>
- void __get_write_value_pytango3<Tango::DEV_STRING>(Tango::WAttribute &att,
- boost::python::list &seq)
- {
- const Tango::ConstDevString *ptr;
-
- long length = att.get_write_value_length();
-
- att.get_write_value(ptr);
-
- for (long l = 0; l < length; ++l)
- {
- seq.append(ptr[l]);
- }
- }
-
- inline void get_write_value_pytango3(Tango::WAttribute &att,
- boost::python::list &value)
- {
- long type = att.get_data_type();
- TANGO_CALL_ON_ATTRIBUTE_DATA_TYPE(type, __get_write_value_pytango3, att, value);
- }
-
-
- template<long tangoTypeConst>
void __get_write_value_scalar(Tango::WAttribute &att, boost::python::object* obj)
{
typedef typename TANGO_const2type(tangoTypeConst) TangoScalarType;
@@ -404,33 +455,6 @@ namespace PyWAttribute
}
template<long tangoTypeConst>
- void __get_write_value_array_pytango3(Tango::WAttribute &att, boost::python::object* obj)
- {
- typedef typename TANGO_const2type(tangoTypeConst) TangoScalarType;
-
- const TangoScalarType * buffer;
- att.get_write_value(buffer);
- size_t length = att.get_write_value_length();
-
- boost::python::list o;
- for (size_t n = 0; n < length; ++n)
- o.append(buffer[n]);
- *obj = o;
- }
-
- template<>
- void __get_write_value_array_pytango3<Tango::DEV_STRING>(Tango::WAttribute &att, boost::python::object* obj)
- {
- const Tango::ConstDevString *ptr;
- long length = att.get_write_value_length();
- att.get_write_value(ptr);
- boost::python::list o;
- for (long l = 0; l < length; ++l)
- o.append(ptr[l]);
- }
-
-
- template<long tangoTypeConst>
void __get_write_value_array_lists(Tango::WAttribute &att, boost::python::object* obj)
{
typedef typename TANGO_const2type(tangoTypeConst) TangoScalarType;
@@ -510,11 +534,6 @@ namespace PyWAttribute
TANGO_CALL_ON_ATTRIBUTE_DATA_TYPE(type, __get_write_value_scalar, att, &value);
} else {
switch (extract_as) {
- case PyTango::ExtractAsPyTango3: {
- TANGO_CALL_ON_ATTRIBUTE_DATA_TYPE(type,
- __get_write_value_array_pytango3, att, &value);
- break;
- }
case PyTango::ExtractAsNumpy: {
# ifndef DISABLE_PYTANGO_NUMPY
TANGO_CALL_ON_ATTRIBUTE_DATA_TYPE(type,
@@ -567,13 +586,6 @@ void export_wattribute()
.def("set_write_value",
(void (*) (Tango::WAttribute &, boost::python::object &, long, long))
&PyWAttribute::set_write_value)
-
- // old style get_write_value
- .def("get_write_value",
- &PyWAttribute::get_write_value_pytango3,
- ( arg_("self"), arg_("empty_list")))
-
- // new style get_write_value
.def("get_write_value",
&PyWAttribute::get_write_value,
( arg_("self"), arg_("extract_as")=PyTango::ExtractAsNumpy ))
diff --git a/src/server/wattribute_numpy.hpp b/src/server/wattribute_numpy.hpp
index f26e90e..4ff7d1c 100644
--- a/src/server/wattribute_numpy.hpp
+++ b/src/server/wattribute_numpy.hpp
@@ -41,7 +41,7 @@ namespace PyWAttribute {
// Copy buffer in a python raw buffer
const char *original_ch_buffer = reinterpret_cast<const char *>(buffer);
- PyObject* str_guard = PyString_FromStringAndSize(original_ch_buffer, length*sizeof(TangoScalarType));
+ PyObject* str_guard = PyBytes_FromStringAndSize(original_ch_buffer, length*sizeof(TangoScalarType));
if (!str_guard) {
throw_error_already_set();
@@ -52,7 +52,7 @@ namespace PyWAttribute {
npy_intp dims[2];
int nd = 1;
- char* ch_buffer = PyString_AsString(str_guard);
+ char* ch_buffer = PyBytes_AsString(str_guard);
if (att.get_data_format() == Tango::IMAGE) {
nd = 2;
diff --git a/src/to_py.h b/src/to_py.h
index d094fa4..d9716ae 100644
--- a/src/to_py.h
+++ b/src/to_py.h
@@ -27,6 +27,7 @@
#include <tango.h>
#include "defs.h"
+#include "pyutils.h"
struct DevEncoded_to_tuple
{
@@ -104,6 +105,7 @@ struct CORBA_sequence_to_tuple<Tango::DevVarStringArray>
PyObject *t = PyTuple_New(size);
for(unsigned long i=0; i < size; ++i)
{
+
boost::python::str x(a[i].in());
PyTuple_SetItem(t, i, boost::python::incref(x.ptr()));
}
@@ -272,30 +274,50 @@ struct CORBA_String_member_to_str
{
static inline PyObject* convert(CORBA::String_member const& cstr)
{
- return boost::python::incref(boost::python::str(cstr.in()).ptr());
+ return from_char_to_str(cstr.in());
}
- static const PyTypeObject* get_pytype() { return &PyString_Type; }
+ //static const PyTypeObject* get_pytype() { return &PyBytes_Type; }
};
struct CORBA_String_member_to_str2
{
static inline PyObject* convert(_CORBA_String_member const& cstr)
{
- return boost::python::incref(boost::python::str(cstr.in()).ptr());
+ return from_char_to_str(cstr.in());
}
- static const PyTypeObject* get_pytype() { return &PyString_Type; }
+ //static const PyTypeObject* get_pytype() { return &PyBytes_Type; }
};
struct CORBA_String_element_to_str
{
static inline PyObject* convert(_CORBA_String_element const& cstr)
{
- return boost::python::incref(boost::python::str(cstr.in()).ptr());
+ return from_char_to_str(cstr.in());
}
- static const PyTypeObject* get_pytype() { return &PyString_Type; }
+ //static const PyTypeObject* get_pytype() { return &PyBytes_Type; }
+};
+
+struct String_to_str
+{
+ static inline PyObject* convert(std::string const& cstr)
+ {
+ return from_char_to_str(cstr);
+ }
+
+ //static const PyTypeObject* get_pytype() { return &PyBytes_Type; }
+};
+
+struct char_ptr_to_str
+{
+ static inline PyObject* convert(const char *cstr)
+ {
+ return from_char_to_str(cstr);
+ }
+
+ //static const PyTypeObject* get_pytype() { return &PyBytes_Type; }
};
boost::python::object to_py(const Tango::AttributeAlarm &);
--
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