From 70135d4e08872c3481d79bd80ca8d19e79009119 Mon Sep 17 00:00:00 2001 From: Felix Kaschura Date: Fri, 26 Jan 2024 13:48:06 +0100 Subject: [PATCH 1/4] Fix deprecation message --- src/pysweepme/__init__.py | 2 +- src/pysweepme/_utils.py | 2 +- tests/test_utils.py | 12 ++++++------ 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/src/pysweepme/__init__.py b/src/pysweepme/__init__.py index 7b9c0ab..f5aaff3 100644 --- a/src/pysweepme/__init__.py +++ b/src/pysweepme/__init__.py @@ -21,7 +21,7 @@ # SOFTWARE. -__version__ = "1.5.6.7" +__version__ = "1.5.6.8" import sys diff --git a/src/pysweepme/_utils.py b/src/pysweepme/_utils.py index ccdc1ca..92feb0b 100644 --- a/src/pysweepme/_utils.py +++ b/src/pysweepme/_utils.py @@ -22,7 +22,7 @@ def _is_version_reached(version: str) -> bool: version_tuple = tuple(map(int, version.split("."))) # zip and un-zip the version tuples to make them same length version_tuple, compare = zip(*zip_longest(version_tuple, _pysweepme_version, fillvalue=0)) - if version_tuple < compare: + if version_tuple > compare: return False return True diff --git a/tests/test_utils.py b/tests/test_utils.py index 9bddbc0..1496e35 100644 --- a/tests/test_utils.py +++ b/tests/test_utils.py @@ -15,13 +15,13 @@ def test_tuple_extract(self) -> None: def test_version_compare(self) -> None: """Test that version strings are compared semantically.""" with patch("pysweepme._utils._pysweepme_version", new_callable=PropertyMock(return_value=(1, 2, 3, 4))): - assert _is_version_reached("1.2") is False - assert _is_version_reached("1.2.3.3.99") is False - - assert _is_version_reached("1.3") is True + assert _is_version_reached("1.2") is True + assert _is_version_reached("1.2.3.3.99") is True assert _is_version_reached("1.2.3.4") is True - assert _is_version_reached("1.2.3.4.1") is True - assert _is_version_reached("1.11.3.5") is True + + assert _is_version_reached("1.2.3.4.1") is False + assert _is_version_reached("1.3") is False + assert _is_version_reached("1.11.3.5") is False def test_deprecated_decorator_on_function(self) -> None: """Test deprecated decorator for simple function.""" From 558dd8d5a06dff8e97b1ca482e9fff56c9676a15 Mon Sep 17 00:00:00 2001 From: Felix Kaschura Date: Wed, 31 Jan 2024 16:32:21 +0100 Subject: [PATCH 2/4] Make device_communication a class variable of EmptyDevice that cannot be overwritten accidentally --- src/pysweepme/EmptyDeviceClass.py | 26 ++++++++++++++++++++++---- 1 file changed, 22 insertions(+), 4 deletions(-) diff --git a/src/pysweepme/EmptyDeviceClass.py b/src/pysweepme/EmptyDeviceClass.py index 338a4d8..f7ad4ad 100644 --- a/src/pysweepme/EmptyDeviceClass.py +++ b/src/pysweepme/EmptyDeviceClass.py @@ -28,7 +28,7 @@ import os from configparser import ConfigParser from copy import deepcopy -from typing import TYPE_CHECKING, Any +from typing import TYPE_CHECKING, Any, ClassVar from pysweepme.UserInterface import message_balloon, message_box, message_info, message_log @@ -42,10 +42,9 @@ class EmptyDevice: str ] = [] # static variable that can be used in a driver to define a list of function names that can be used as action - def __init__(self) -> None: - # here to make sure that it is known, later it is overwritten by SweepMe! - self.device_communication: dict[str, Any] = {} + _device_communication: ClassVar[dict[str, Any]] = {} + def __init__(self) -> None: self.variables: list[str] = [] self.units: list[str] = [] self.plottype: list[bool] = [] # True if plotted @@ -81,6 +80,25 @@ def __init__(self) -> None: # The ParameterStore can then be used to store and restore some parameters after re-instantiating. self._ParameterStore: dict[Any, Any] = {} + @property + def device_communication(self) -> dict[str, Any]: + """Single (global) dictionary where drivers can store their information that can be shared across instances.""" + return EmptyDevice._device_communication + + @device_communication.setter + def device_communication(self, _: object) -> None: + msg = ( + "Changing the device_communication dictionary is not allowed.\n" + "Please only work on specific indices, e.g. \n" + ">>> self.device_communication[] = " + ) + raise TypeError(msg) + + @staticmethod + def clear_device_communication() -> None: + """Clear all information that have been stored in the device_communication dictionary.""" + EmptyDevice._device_communication = {} + def list_functions(self): """Returns a list of all function names that are individually defined by the driver, e.g. get/set functions. From e6fcaa58d57d075ec17685208242b9cd2baf2bdb Mon Sep 17 00:00:00 2001 From: Felix Kaschura Date: Wed, 31 Jan 2024 16:57:28 +0100 Subject: [PATCH 3/4] Make ParameterStore a class variable of EmptyDevice that works in pysweepme --- src/pysweepme/EmptyDeviceClass.py | 37 ++++++++++++++++++++----------- 1 file changed, 24 insertions(+), 13 deletions(-) diff --git a/src/pysweepme/EmptyDeviceClass.py b/src/pysweepme/EmptyDeviceClass.py index f7ad4ad..e4f3169 100644 --- a/src/pysweepme/EmptyDeviceClass.py +++ b/src/pysweepme/EmptyDeviceClass.py @@ -43,6 +43,7 @@ class EmptyDevice: ] = [] # static variable that can be used in a driver to define a list of function names that can be used as action _device_communication: ClassVar[dict[str, Any]] = {} + _parameter_store: ClassVar[dict[str, Any]] = {} def __init__(self) -> None: self.variables: list[str] = [] @@ -74,12 +75,6 @@ def __init__(self) -> None: self._latest_parameters: dict[str, Any] | None = None - # ParameterStore - # needs to be defined here in case the device class is used standalone with pysweepme - # Otherwise, the object is handed over by the module during create_Device - # The ParameterStore can then be used to store and restore some parameters after re-instantiating. - self._ParameterStore: dict[Any, Any] = {} - @property def device_communication(self) -> dict[str, Any]: """Single (global) dictionary where drivers can store their information that can be shared across instances.""" @@ -109,14 +104,30 @@ def list_functions(self): return list(set(all_functions) - set(empty_device_functions)) - def store_parameter(self, key, value): - """Stores a value in the ParameterStore for a given key.""" - self._ParameterStore[key] = value + def store_parameter(self, key: str, value: object) -> None: + """Stores a value in the ParameterStore for a given key. + + Drivers can use the ParameterStore to store information and restore the same information later even in + a new instance. + + Args: + key: The key under which the information is stored. It should be unique and not conflicting with + other drivers. + value: The information to be stored. + """ + self._parameter_store[key] = value + + def restore_parameter(self, key: str) -> Any: # noqa: ANN401 # The type of the information is up to the user + """Restores a parameter from the ParameterStore for a given key. + + Args: + key: The key under which the information was stored before. - def restore_parameter(self, key): - """Restores a parameter from the ParameterStore for a given key.""" - if key in self._ParameterStore: - return self._ParameterStore[key] + Returns: + The stored information, or None if no information can be found under the given key. + """ + if key in self._parameter_store: + return self._parameter_store[key] return None def _on_run(self): From 18eb79c9bd158787b3dd7dab0417598e23c2da44 Mon Sep 17 00:00:00 2001 From: Felix Kaschura Date: Wed, 31 Jan 2024 17:43:36 +0100 Subject: [PATCH 4/4] Adjust some formatting --- src/pysweepme/Architecture.py | 2 +- src/pysweepme/pysweepme_types.py | 3 +++ 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/src/pysweepme/Architecture.py b/src/pysweepme/Architecture.py index 6429072..a8da787 100644 --- a/src/pysweepme/Architecture.py +++ b/src/pysweepme/Architecture.py @@ -21,7 +21,7 @@ def extract_information(self): "any", f"any-{self._python_bitness_str}", f"{self._python_version_str}-any", - f"{self._python_version_str}-{self._python_bitness_str}" + f"{self._python_version_str}-{self._python_bitness_str}", ] self._information_extracted = True diff --git a/src/pysweepme/pysweepme_types.py b/src/pysweepme/pysweepme_types.py index a42e8cd..197c42d 100644 --- a/src/pysweepme/pysweepme_types.py +++ b/src/pysweepme/pysweepme_types.py @@ -30,6 +30,7 @@ class FileIOContextProtocol(Protocol): """Protocol for a ContextManager for IO Operations.""" + def __enter__(self) -> IO[Any]: """Function to return a file descriptor.""" @@ -48,6 +49,7 @@ class FileIOProtocolWithoutModifiedCheck(Protocol): In contrast to Path's open(), this function does not return a file descriptor directly and instead always must be used in conjunction with a `with` statement that will return the file descriptor of the opened file. """ + def open( # noqa: A003, PLR0913 self, mode: str = "r", @@ -65,6 +67,7 @@ class FileIOProtocolWithModifiedCheck(FileIOProtocolWithoutModifiedCheck): In contrast to Path's open(), this function does not return a file descriptor directly and instead always must be used in conjunction with a `with` statement that will return the file descriptor of the opened file. """ + def set_full_read(self) -> None: """Function that shall be called when a file is read completely.