Skip to content

Commit

Permalink
Introduce ToolkitError base exception class
Browse files Browse the repository at this point in the history
  • Loading branch information
markheik committed Feb 6, 2023
1 parent 9ef3ce8 commit 6a0327a
Show file tree
Hide file tree
Showing 8 changed files with 64 additions and 31 deletions.
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@
Unreleased

* Improved verbosity of the error message when invalid attributes of `CommandTable.header` and `CommandTable.table` are used.
* Introduced new base exception class `zhinst.toolkit.exceptions.ToolkitError`, deriving from `RuntimeError`.
* Changed some `RuntimeError` exceptions to `ToolkitError`.

## Version 0.5.1
* Added full support for the following LabOne modules (no need to fallback to zhinst.core):
Expand Down
24 changes: 13 additions & 11 deletions src/zhinst/toolkit/driver/devices/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,8 @@
from zhinst.toolkit.driver.parsers import node_parser
from zhinst.toolkit.nodetree import Node, NodeTree
from zhinst.toolkit.nodetree.helper import lazy_property
from zhinst.toolkit.exceptions import ToolkitError


logger = logging.getLogger(__name__)

Expand Down Expand Up @@ -129,23 +131,23 @@ def _check_python_versions(
zi_utils_version: zhinst.utils package version
Raises:
RuntimeError: If the zhinst.core version does not match the
ToolkitError: If the zhinst.core version does not match the
minimum requirements for zhinst.toolkit
RuntimeError: If the zhinst.utils version does not match the
ToolkitError: If the zhinst.utils version does not match the
minimum requirements for zhinst.toolkit
"""
if zi_python_version < BaseInstrument._version_string_to_tuple(
_MIN_LABONE_VERSION
):
raise RuntimeError(
raise ToolkitError(
"zhinst.core version does not match the minimum required version "
f"for zhinst.toolkit {zi_python_version} < {_MIN_LABONE_VERSION}. "
"Use `pip install --upgrade zhinst` to get the latest version."
)
if zi_utils_version < BaseInstrument._version_string_to_tuple(
_MIN_DEVICE_UTILS_VERSION
):
raise RuntimeError(
raise ToolkitError(
"zhinst.utils version does not match the minimum required "
f"version for zhinst.toolkit {zi_utils_version} < "
f"{_MIN_DEVICE_UTILS_VERSION}. Use `pip install "
Expand All @@ -164,18 +166,18 @@ def _check_labone_version(
labone_version: LabOne DataServer version
Raises:
RuntimeError: If the zhinst.core version does not match the
ToolkitError: If the zhinst.core version does not match the
version of the connected LabOne DataServer.
"""
if labone_version[:2] < zi_python_version[:2]:
raise RuntimeError(
raise ToolkitError(
"The LabOne version is smaller than the zhinst.core version. "
f"{labone_version} < {zi_python_version}. "
"Please install the latest/matching LabOne version from "
"https://www.zhinst.com/support/download-center."
)
if labone_version[:2] > zi_python_version[:2]:
raise RuntimeError(
raise ToolkitError(
"the zhinst.core version is smaller than the LabOne version "
f"{zi_python_version} < {labone_version}. "
"Please install the latest/matching version from pypi.org."
Expand All @@ -193,7 +195,7 @@ def _check_firmware_update_status(self) -> None:
Raises:
ConnectionError: If the device is currently updating
RuntimeError: If the firmware revision does not match to th
ToolkitError: If the firmware revision does not match to the
version of the connected LabOne DataServer.
"""
device_info = json.loads(self._session.daq_server.getString("/zi/devices"))[
Expand All @@ -206,12 +208,12 @@ def _check_firmware_update_status(self) -> None:
"process is complete"
)
if status_flag & 1 << 4 or status_flag & 1 << 5:
raise RuntimeError(
raise ToolkitError(
"The Firmware does not match the LabOne version. "
"Please update the firmware (e.g. in the LabOne UI)"
)
if status_flag & 1 << 6 or status_flag & 1 << 7:
raise RuntimeError(
raise ToolkitError(
"The Firmware does not match the LabOne version. "
"Please update LabOne to the latest version from "
"https://www.zhinst.com/support/download-center."
Expand All @@ -230,7 +232,7 @@ def check_compatibility(self) -> None:
Raises:
ConnectionError: If the device is currently updating
RuntimeError: If one of the above mentioned criterion is not
ToolkitError: If one of the above mentioned criterion is not
fulfilled
"""
self._check_python_versions(
Expand Down
16 changes: 14 additions & 2 deletions src/zhinst/toolkit/exceptions.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,17 @@
"""Global zhinst-toolkit exceptions."""


class ValidationError(Exception):
"""Data validation failed."""
class ToolkitError(RuntimeError):
"""Base class for `zhinst.toolkit` errors.
.. versionadded:: 0.5.2
"""


class ValidationError(ToolkitError):
"""Data validation failed.
.. versionchanged:: 0.5.2
Changed base class from `Exception` to `ToolkitError`.
"""
5 changes: 3 additions & 2 deletions src/zhinst/toolkit/nodetree/connection_dict.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
from numpy import array

from zhinst.toolkit.nodetree.helper import NodeDoc
from zhinst.toolkit.exceptions import ToolkitError


class ConnectionDict:
Expand Down Expand Up @@ -123,8 +124,8 @@ def setVector(self, path: str, value: t.Any = None) -> None:

def subscribe(self, path: str) -> None:
"""Mirrors the behavior of zhinst.core subscribe command."""
raise RuntimeError("Can not subscribe within the SHFQA_Sweeper")
raise ToolkitError("Can not subscribe within the SHFQA_Sweeper")

def unsubscribe(self, path: str) -> None:
"""Mirrors the behavior of zhinst.core unsubscribe command."""
raise RuntimeError("Can not subscribe within the SHFQA_Sweeper")
raise ToolkitError("Can not subscribe within the SHFQA_Sweeper")
5 changes: 3 additions & 2 deletions src/zhinst/toolkit/nodetree/nodetree.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@

from zhinst.toolkit.nodetree.helper import NodeDoc, _NodeInfo
from zhinst.toolkit.nodetree.node import Node
from zhinst.toolkit.exceptions import ToolkitError


class Connection(Protocol):
Expand Down Expand Up @@ -80,14 +81,14 @@ def start(
transaction.
Raises:
Runtime Error if the transaction is already in progress
ToolkitError: A transaction is already in progress.
.. versionchanged:: 0.4.0
add_callback added.
"""
if self.in_progress():
raise RuntimeError(
raise ToolkitError(
"A transaction is already in progress. Only one transaction is "
"possible at a time."
)
Expand Down
14 changes: 8 additions & 6 deletions src/zhinst/toolkit/session.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@

import zhinst.toolkit.driver.devices as tk_devices
import zhinst.toolkit.driver.modules as tk_modules
from zhinst.toolkit.exceptions import ToolkitError
from zhinst import core
from zhinst.toolkit.nodetree import Node, NodeTree
from zhinst.toolkit.nodetree.helper import lazy_property, NodeDict
Expand Down Expand Up @@ -149,6 +150,7 @@ def _create_device(self, serial: str) -> tk_devices.BaseInstrument:
Raises:
RuntimeError: If the device is not connected to the data server
ToolkitError: DataServer is HF2, but the device is not.
"""
try:
return super()._create_device(serial)
Expand All @@ -157,7 +159,7 @@ def _create_device(self, serial: str) -> tk_devices.BaseInstrument:
discovery = core.ziDiscovery()
discovery.find(serial)
dev_type = discovery.get(serial)["devicetype"]
raise RuntimeError(
raise ToolkitError(
"Can only connect HF2 devices to an HF2 data "
f"server. {serial} identifies itself as a {dev_type}."
) from error
Expand Down Expand Up @@ -189,10 +191,10 @@ def add_hf2_device(self, serial: str) -> None:
serial: Serial of the HF2 device
Raises:
RuntimeError: If the device was already added in that session.
ToolkitError: If the device was already added in that session.
"""
if serial in self._devices:
raise RuntimeError(f"Can only create one instance of {serial}.")
raise ToolkitError(f"Can only create one instance of {serial}.")
self._devices[serial] = self._create_device(serial)


Expand Down Expand Up @@ -666,12 +668,12 @@ def __init__(
if connection is not None:
self._is_hf2_server = "HF2" in connection.getString("/zi/about/dataserver")
if hf2 and not self._is_hf2_server:
raise RuntimeError(
raise ToolkitError(
"hf2 flag was set but the passed "
"DAQServer instance is not a HF2 data server."
)
if hf2 is False and self._is_hf2_server:
raise RuntimeError(
raise ToolkitError(
"hf2 flag was set but the passed "
"DAQServer instance is a HF2 data server."
)
Expand All @@ -697,7 +699,7 @@ def __init__(
1,
)
elif not hf2:
raise RuntimeError(
raise ToolkitError(
"hf2 Flag was reset but the specified "
f"server at {server_host}:{server_port} is a "
"HF2 data server."
Expand Down
17 changes: 9 additions & 8 deletions tests/test_base.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@

from zhinst.toolkit._min_version import _MIN_DEVICE_UTILS_VERSION, _MIN_LABONE_VERSION
from zhinst.toolkit.driver.devices.base import BaseInstrument
from zhinst.toolkit.exceptions import ToolkitError


@pytest.fixture()
Expand Down Expand Up @@ -114,7 +115,7 @@ def test_check_python_versions():
# zhinst.core heigher
BaseInstrument._check_python_versions(add(labone, (1, 0, 0)), device_utils)
# zhinst.core lower
with pytest.raises(RuntimeError):
with pytest.raises(ToolkitError):
BaseInstrument._check_python_versions(sub(labone, (1, 0, 0)), device_utils)
# utils heigher
BaseInstrument._check_python_versions(
Expand All @@ -125,7 +126,7 @@ def test_check_python_versions():
),
)
# utils lower
with pytest.raises(RuntimeError):
with pytest.raises(ToolkitError):
BaseInstrument._check_python_versions(labone, sub(device_utils, (1, 0, 0)))


Expand All @@ -134,10 +135,10 @@ def test_check_labone_version():
# matching version
BaseInstrument._check_labone_version((21, 8, 0), (21, 8, 0))
# zhinst.core heigher
with pytest.raises(RuntimeError):
with pytest.raises(ToolkitError):
BaseInstrument._check_labone_version((22, 2, 0), (21, 8, 0))
# zhinst.core lower
with pytest.raises(RuntimeError):
with pytest.raises(ToolkitError):
BaseInstrument._check_labone_version((21, 2, 0), (21, 8, 0))
# patchversion missmatch
with pytest.warns(RuntimeWarning):
Expand Down Expand Up @@ -168,7 +169,7 @@ def test_check_firmware_update_status(base_instrument, mock_connection):
"DEV1235": {},
}
mock_connection.return_value.getString.return_value = json.dumps(info)
with pytest.raises(RuntimeError):
with pytest.raises(ToolkitError):
base_instrument._check_firmware_update_status()
info = {
"DEV1111": {},
Expand All @@ -179,7 +180,7 @@ def test_check_firmware_update_status(base_instrument, mock_connection):
"DEV1235": {},
}
mock_connection.return_value.getString.return_value = json.dumps(info)
with pytest.raises(RuntimeError):
with pytest.raises(ToolkitError):
base_instrument._check_firmware_update_status()

# Downgrade available
Expand All @@ -192,7 +193,7 @@ def test_check_firmware_update_status(base_instrument, mock_connection):
"DEV1235": {},
}
mock_connection.return_value.getString.return_value = json.dumps(info)
with pytest.raises(RuntimeError):
with pytest.raises(ToolkitError):
base_instrument._check_firmware_update_status()
info = {
"DEV1111": {},
Expand All @@ -203,7 +204,7 @@ def test_check_firmware_update_status(base_instrument, mock_connection):
"DEV1235": {},
}
mock_connection.return_value.getString.return_value = json.dumps(info)
with pytest.raises(RuntimeError):
with pytest.raises(ToolkitError):
base_instrument._check_firmware_update_status()

# Update in progress
Expand Down
12 changes: 12 additions & 0 deletions tests/test_exceptions.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
import pytest

from zhinst.toolkit.exceptions import ToolkitError


def test_base_exception():
assert issubclass(ToolkitError, RuntimeError)


def test_base_exception_raises():
with pytest.raises(RuntimeError):
raise ToolkitError("message")

0 comments on commit 6a0327a

Please sign in to comment.