From c77bb16369660d2cca6501d6f6d0c470663b7905 Mon Sep 17 00:00:00 2001
From: snijder <snijder@astron.nl>
Date: Wed, 1 Feb 2023 17:04:24 +0100
Subject: [PATCH] worked on fixing the code

---
 Attribute_wrapper/__init__.py          |  2 +-
 Attribute_wrapper/attribute_wrapper.py | 25 +++++++++++++------
 Attribute_wrapper/cool_module.py       |  6 -----
 VERSION                                |  1 +
 requirements.txt                       |  4 ++-
 tests/test_attr_wrapper.py             | 34 +++++++++++---------------
 tests/test_client.py                   |  8 +++---
 tox.ini                                |  9 ++++---
 8 files changed, 46 insertions(+), 43 deletions(-)
 delete mode 100644 Attribute_wrapper/cool_module.py
 create mode 100644 VERSION

diff --git a/Attribute_wrapper/__init__.py b/Attribute_wrapper/__init__.py
index a917d91..2787b16 100644
--- a/Attribute_wrapper/__init__.py
+++ b/Attribute_wrapper/__init__.py
@@ -5,4 +5,4 @@ try:
 except ImportError:  # for Python<3.8
     import importlib_metadata as metadata
 
-__version__ = metadata.version("AttributeWrapper")
+#__version__ = metadata.version("AttributeWrapper")
diff --git a/Attribute_wrapper/attribute_wrapper.py b/Attribute_wrapper/attribute_wrapper.py
index 4923c17..cbb0138 100644
--- a/Attribute_wrapper/attribute_wrapper.py
+++ b/Attribute_wrapper/attribute_wrapper.py
@@ -4,6 +4,7 @@
 import logging
 from functools import reduce
 from operator import mul
+from functools import wraps
 
 import numpy
 from tango import AttrWriteType, AttReqType
@@ -13,6 +14,7 @@ logger = logging.getLogger()
 
 __all__ = ["AttributeWrapper"]
 
+
 def fault_on_error():
     """
     Wrapper to catch exceptions. Sets the device in a FAULT state if any occurs.
@@ -63,7 +65,8 @@ class AttributeIO(object):
     def cached_write_function(self, value):
         """Writes the given value to the device, and updates the cache."""
 
-        # flexible array sizes are not supported by all clients. make sure we only write arrays of maximum size.
+        # flexible array sizes are not supported by all clients. make sure we only
+        # write arrays of maximum size.
         if self.attribute_wrapper.shape != ():
             if isinstance(value, numpy.ndarray):
                 value_shape = value.shape
@@ -117,14 +120,19 @@ class AttributeWrapper(attribute):
                 f"Attribute needs to be a Tango-supported numpy, str or bool type, but has type {datatype}"
             )
 
-        self.comms_id = comms_id  # store data that can be used to identify the comms interface to use. not used by the wrapper itself
-        self.comms_annotation = comms_annotation  # store data that can be used by the comms interface. not used by the wrapper itself
+        # store data that can be used to identify the comms interface to use. not
+        # used by the wrapper itself
+        self.comms_id = comms_id
+        # store data that can be used by the comms interface. not used by the
+        # wrapper itself
+        self.comms_annotation = comms_annotation
 
         self.datatype = datatype
 
         if dims == (1,):
             # scalar
-            # Tango defines a scalar as having dimensions (1,0), see https://pytango.readthedocs.io/en/stable/server_api/attribute.html
+            # Tango defines a scalar as having dimensions (1,0), see
+            # https://pytango.readthedocs.io/en/stable/server_api/attribute.html
             max_dim_x = 1
             max_dim_y = 0
             dtype = datatype
@@ -181,7 +189,8 @@ class AttributeWrapper(attribute):
                 read_func_wrapper reads the attribute value, stores it and returns it"
                 """
 
-                # lofar.read_attribute ignores fisallowed. So check again if we're allowed to read.
+                # lofar.read_attribute ignores fisallowed. So check again if we're
+                # allowed to read.
                 if not device.is_attribute_access_allowed(AttReqType.READ_REQ):
                     return None
 
@@ -205,7 +214,8 @@ class AttributeWrapper(attribute):
                 read_func_wrapper reads the attribute value, stores it and returns it"
                 """
 
-                # lofar.read_attribute ignores fisallowed. So check again if we're allowed to read.
+                # lofar.read_attribute ignores fisallowed. So check again if we're
+                # allowed to read.
                 if not device.is_attribute_access_allowed(AttReqType.READ_REQ):
                     return None
 
@@ -225,7 +235,8 @@ class AttributeWrapper(attribute):
         # The provided function will be used with the call signature "(device: Device, req_type: AttReqType) -> bool".
         #
         # NOTE: fisallowed=<callable> does not work: https://gitlab.com/tango-controls/pytango/-/issues/435
-        # So we have to use fisallowed=<str> here, which causes the function device.<str> to be called.
+        # So we have to use fisallowed=<str> here, which causes the function
+        # device.<str> to be called.
         super().__init__(
             dtype=dtype,
             max_dim_y=max_dim_y,
diff --git a/Attribute_wrapper/cool_module.py b/Attribute_wrapper/cool_module.py
deleted file mode 100644
index bd9416c..0000000
--- a/Attribute_wrapper/cool_module.py
+++ /dev/null
@@ -1,6 +0,0 @@
-""" Cool module containing functions, classes and other useful things """
-
-
-def greeter():
-    """Prints a nice message"""
-    print("Hello World!")
diff --git a/VERSION b/VERSION
new file mode 100644
index 0000000..49d5957
--- /dev/null
+++ b/VERSION
@@ -0,0 +1 @@
+0.1
diff --git a/requirements.txt b/requirements.txt
index 87f0831..ad16c92 100644
--- a/requirements.txt
+++ b/requirements.txt
@@ -1,2 +1,4 @@
 numpy >= 1.20.0 # BSD
-testtools>=2.2.0 # MIT
\ No newline at end of file
+stestr>=3.0.0 # Apache-2.0
+testscenarios>=0.5.0 # Apache-2.0/BSD
+testtools>=2.4.0 # MIT
\ No newline at end of file
diff --git a/tests/test_attr_wrapper.py b/tests/test_attr_wrapper.py
index 24d7988..97985b1 100644
--- a/tests/test_attr_wrapper.py
+++ b/tests/test_attr_wrapper.py
@@ -6,7 +6,7 @@
 
 import asyncio
 
-import mock
+from unittest import mock
 import numpy
 
 # External imports
@@ -15,11 +15,10 @@ from tango.server import attribute, command, Device, DeviceMeta
 
 # Test imports
 from tango.test_context import DeviceTestContext
-import AttributeWrapper
-from tangostationcontrol.test import base
+from Attribute_wrapper.attribute_wrapper import AttributeWrapper
 
 # Internal imports
-from test.test_client import TestClient
+from test_client import TestClient
 
 SCALAR_DIMS = (1,)
 SPECTRUM_DIMS = (4,)
@@ -37,11 +36,12 @@ def dev_init(device):
         asyncio.run(i.async_set_comm_client(device, device.test_client))
     device.test_client.start()
 
+
 class device_wrapper(Device, metaclass=DeviceMeta):
     @classmethod
     def attr_list(cls):
         """Return a list of all the AttributeWrapper members of this class."""
-        return [v for k, v in cls.__dict__.items() if type(v) == AttributeWrapper]
+        return [v for k, v in cls.__dict__.items() if isinstance(v, AttributeWrapper)]
 
     def off(self):
         self.set_state(DevState.OFF)
@@ -52,12 +52,11 @@ class device_wrapper(Device, metaclass=DeviceMeta):
     def initialise(self):
         self.set_state(DevState.INIT)
 
-class TestAttributeTypes(base.TestCase):
+
+class TestAttributeTypes():
     def setUp(self):
         # Avoid the device trying to access itself as a client
-        self.deviceproxy_patch = mock.patch.object(
-            Device, "DeviceProxy"
-        )
+        self.deviceproxy_patch = mock.patch.object(device_wrapper, "DeviceProxy")
         self.deviceproxy_patch.start()
         self.addCleanup(self.deviceproxy_patch.stop)
 
@@ -572,7 +571,6 @@ class TestAttributeTypes(base.TestCase):
     def read_R_test(self, dev, dtype, test_type):
         """Test device"""
         with DeviceTestContext(dev, process=True) as proxy:
-
             # initialise
             proxy.initialise()
             proxy.on()
@@ -589,7 +587,8 @@ class TestAttributeTypes(base.TestCase):
                     proxy.image_R
                 )  # is needed for STR since they act differently
 
-                # cant use all() for 2d arrays so instead compare the dimensions and then flatten to 2d
+                # cant use all() for 2d arrays so instead compare the dimensions and
+                # then flatten to 2d
                 self.assertEqual(
                     val.shape,
                     expected.shape,
@@ -632,13 +631,11 @@ class TestAttributeTypes(base.TestCase):
     def write_RW_test(self, dev, dtype, test_type):
         """Test device"""
         with DeviceTestContext(dev, process=True) as proxy:
-
             # initialise
             proxy.initialise()
             proxy.on()
 
             if test_type == "scalar":
-
                 if dtype is str:
                     val = STR_SCALAR_VAL
                 else:
@@ -678,7 +675,6 @@ class TestAttributeTypes(base.TestCase):
 
         try:
             with DeviceTestContext(dev, process=True) as proxy:
-
                 # initialise
                 proxy.initialise()
                 proxy.on()
@@ -695,7 +691,8 @@ class TestAttributeTypes(base.TestCase):
                         proxy.image_RW
                     )  # is needed for STR since they act differently
 
-                    # cant use all() for 2d arrays so instead compare the dimensions and then flatten to 2d
+                    # cant use all() for 2d arrays so instead compare the dimensions and
+                    # then flatten to 2d
                     self.assertEqual(
                         val.shape,
                         expected.shape,
@@ -792,7 +789,6 @@ class TestAttributeTypes(base.TestCase):
         """Test device"""
         try:
             with DeviceTestContext(dev, process=True) as proxy:
-
                 # initialise
                 proxy.initialise()
                 proxy.on()
@@ -1029,12 +1025,10 @@ class TestAttributeTypes(base.TestCase):
             )
 
 
-class TestAttributeAccess(base.TestCase):
+class TestAttributeAccess():
     def setUp(self):
         # Avoid the device trying to access itself as a client
-        self.deviceproxy_patch = mock.patch.object(
-            Device, "DeviceProxy"
-        )
+        self.deviceproxy_patch = mock.patch.object(Device, "DeviceProxy")
         self.deviceproxy_patch.start()
         self.addCleanup(self.deviceproxy_patch.stop)
 
diff --git a/tests/test_client.py b/tests/test_client.py
index 1b31de2..b1a0c98 100644
--- a/tests/test_client.py
+++ b/tests/test_client.py
@@ -6,13 +6,10 @@ import logging
 # External imports
 import numpy
 
-# Test imports
-from tangostationcontrol.clients.comms_client import CommClient
-
 logger = logging.getLogger()
 
 
-class TestClient(CommClient):
+class TestClient:
     """
     this class provides an example implementation of a comms_client.
     During initialisation it creates a correctly shaped zero filled value. on read that value is returned and on write its modified.
@@ -126,7 +123,8 @@ class TestClient(CommClient):
         # process the comms_annotation
         self._setup_annotation(annotation)
 
-        # get all the necessary data to set up the read/write functions from the AttributeWrapper
+        # get all the necessary data to set up the read/write functions from the
+        # AttributeWrapper
         dims, dtype = self._setup_value_conversion(attribute)
 
         # configure and return the read/write functions
diff --git a/tox.ini b/tox.ini
index d538894..10e61a9 100644
--- a/tox.ini
+++ b/tox.ini
@@ -14,6 +14,9 @@ setenv =
 deps =
     -r{toxinidir}/requirements.txt
     -r{toxinidir}/tests/requirements.txt
+commands_pre =
+    {envpython} --version
+    pip install --no-cache pytango
 commands =
     {envpython} --version
     {envpython} -m pytest
@@ -34,9 +37,9 @@ commands =
     black: {envpython} -m black --version
     black: {envpython} -m black --check --diff .
     pylint: {envpython} -m pylint --version
-    pylint: {envpython} -m pylint my_awesome_app tests
-    format: {envpython} -m autopep8 -v -aa --in-place --recursive my_awesome_app
-    format: {envpython} -m autopep8 -v -aa --in-place --recursive tests
+    pylint: {envpython} -m pylint AttributeWrapper tests
+    format: {envpython} -m autopep8 -v -aa --in-place --recursive Attribute_wrapper/
+    format: {envpython} -m autopep8 -v -aa --in-place --recursive tests/
     format: {envpython} -m black -v .
 
 
-- 
GitLab