diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index eaa775c..5e60fbe 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -4,7 +4,7 @@ ci: repos: - repo: https://github.com/pre-commit/pre-commit-hooks - rev: v4.4.0 + rev: v5.0.0 hooks: - id: check-yaml - id: check-toml @@ -19,39 +19,39 @@ repos: # Verify the contents of pyproject.toml - repo: https://github.com/abravalheri/validate-pyproject - rev: v0.13 + rev: v0.24.1 hooks: - id: validate-pyproject # Updating code to use modern python patterns where available. - repo: https://github.com/asottile/pyupgrade - rev: v3.4.0 + rev: v3.20.0 hooks: - id: pyupgrade # General Project code formatter. - repo: https://github.com/psf/black - rev: 23.3.0 + rev: 25.1.0 hooks: - id: black # Sorts python imports. - repo: https://github.com/PyCQA/isort # Note - on black update blacken-docs pin should also be updated. - rev: 5.12.0 + rev: 6.0.1 hooks: - id: isort args: ['--profile=black'] # Formats python docstrings. - repo: https://github.com/PyCQA/docformatter - rev: v1.7.1 + rev: v1.7.8-rc1 hooks: - id: docformatter # Formats code-blocks in documentation. - repo: https://github.com/asottile/blacken-docs - rev: 1.13.0 + rev: 1.19.1 hooks: - id: blacken-docs # Note - on black update blacken-docs pin should also be updated. @@ -59,7 +59,7 @@ repos: # Used to detect unintentionally unused code. - repo: https://github.com/asottile/dead - rev: v1.5.1 + rev: v2.1.0 hooks: - id: dead args: [ @@ -69,13 +69,13 @@ repos: # Lint documentation source. - repo: https://github.com/sphinx-contrib/sphinx-lint # Make sure to also update the additional dependency pin - rev: v0.6.7 + rev: v1.0.0 hooks: - id: sphinx-lint # lint documentation - repo: https://github.com/PyCQA/doc8 - rev: v1.1.1 + rev: v2.0.0 hooks: - id: doc8 @@ -91,14 +91,14 @@ repos: # Static typehint linting. - repo: https://github.com/pre-commit/mirrors-mypy - rev: v1.3.0 + rev: v1.17.1 hooks: - id: mypy # A faster python linter -- repo: https://github.com/charliermarsh/ruff-pre-commit +- repo: https://github.com/astral-sh/ruff-pre-commit # Ruff version. - rev: 'v0.0.269' + rev: 'v0.12.7' hooks: - id: ruff @@ -118,7 +118,7 @@ repos: # Lint code in pre-commit env, note: This ignores import checks. - repo: https://github.com/PyCQA/pylint - rev: v2.17.4 + rev: v3.3.7 hooks: # Pylint is also run from within pre-commit for CI purposes. - id: pylint @@ -129,7 +129,7 @@ repos: # Lint code for security flaws. - repo: https://github.com/PyCQA/bandit - rev: 1.7.5 + rev: 1.8.6 hooks: - id: bandit # Assert is used exclusively in pytest. diff --git a/docs/conf.py b/docs/conf.py index 4bcb6d7..3991107 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -6,6 +6,7 @@ -- Project information ----------------------------------------------------- https://www.sphinx-doc.org/en/master/usage/configuration.html#project-information """ + import os import sys from re import Match, match diff --git a/tests/__init__.py b/tests/__init__.py index 945005e..4c95c60 100644 --- a/tests/__init__.py +++ b/tests/__init__.py @@ -1,4 +1,5 @@ """Pytest package for testing uoshardware.""" + from dataclasses import dataclass diff --git a/tests/conftest.py b/tests/conftest.py index 683225a..7f2ca91 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -1,4 +1,5 @@ """Module for package test configuration, scope=session.""" + import pytest from uoshardware import Loading diff --git a/tests/interface/__init__.py b/tests/interface/__init__.py index 6b3b3ee..7e1c0a0 100644 --- a/tests/interface/__init__.py +++ b/tests/interface/__init__.py @@ -1 +1,2 @@ """Test Package for the low level interface backends.""" + diff --git a/tests/interface/conftest.py b/tests/interface/conftest.py index c24c719..c56d685 100644 --- a/tests/interface/conftest.py +++ b/tests/interface/conftest.py @@ -1,4 +1,5 @@ """Module used for fixture initialisation in interface tests.""" + import pytest diff --git a/tests/interface/test_package.py b/tests/interface/test_package.py index dbe2bfe..abeeb87 100644 --- a/tests/interface/test_package.py +++ b/tests/interface/test_package.py @@ -1,4 +1,5 @@ """Module for testing the interface package.""" + from time import sleep import pytest diff --git a/tests/test_abstractions.py b/tests/test_abstractions.py index f38f832..a88d1bc 100644 --- a/tests/test_abstractions.py +++ b/tests/test_abstractions.py @@ -1,4 +1,5 @@ """Unit tests for the `abstractions` module.""" + import pytest from tests import Packet diff --git a/tests/test_api.py b/tests/test_api.py index 9b4e9d1..30ddda4 100644 --- a/tests/test_api.py +++ b/tests/test_api.py @@ -1,4 +1,5 @@ """Unit tests for the api module.""" + from inspect import signature import pytest diff --git a/tests/test_devices.py b/tests/test_devices.py index 845759b..e7a04d5 100644 --- a/tests/test_devices.py +++ b/tests/test_devices.py @@ -1,4 +1,5 @@ """Tests for the devices module.""" + import pytest from uoshardware import UOSUnsupportedError diff --git a/uoshardware/__init__.py b/uoshardware/__init__.py index 7834f33..4e5b6f3 100644 --- a/uoshardware/__init__.py +++ b/uoshardware/__init__.py @@ -1,4 +1,5 @@ """The high level interface for communicating with UOS devices.""" + import logging from enum import Enum @@ -29,19 +30,14 @@ class Loading(Enum): class UOSError(Exception): """Base class exception for all UOS Interface Errors.""" - class UOSUnsupportedError(UOSError): """Exception for attempting an unknown / unsupported action.""" - class UOSCommunicationError(UOSError): """Exception while communicating with a UOS Device.""" - class UOSRuntimeError(UOSError): """General exception for runtime failure, usually indicates misuse.""" - - # Configures the global logger for the library # Note: Clients need to initialize logging otherwise no output will be visible. logger = logging.getLogger(__name__) diff --git a/uoshardware/abstractions.py b/uoshardware/abstractions.py index 0fb2d89..2d3f020 100644 --- a/uoshardware/abstractions.py +++ b/uoshardware/abstractions.py @@ -1,4 +1,5 @@ """Module defining the base class and static func for interfaces.""" + from abc import ABCMeta, abstractmethod from dataclasses import dataclass, field from datetime import datetime @@ -182,12 +183,13 @@ class UOSInterface(metaclass=ABCMeta): def execute_instruction(self, packet: NPCPacket) -> ComResult: # dead: disable """Abstract method for executing instructions on UOSInterfaces. - :param packet: A tuple containing the uint8 npc packet for the UOS instruction. + :param packet: A tuple containing the uint8 npc packet for the + UOS instruction. :returns: ComResult object. :raises: UOSUnsupportedError if the interface hasn't been built - correctly. + correctly. :raises: UOSCommunicationError if there is a problem completing - the action. + the action. """ raise UOSUnsupportedError( "UOSInterfaces must over-ride " @@ -201,12 +203,13 @@ def read_response( """Read ACK and Data packets from a UOSInterface. :param expect_packets: How many packets including ACK to expect - :param timeout_s: The maximum time this function will wait for data. + :param timeout_s: The maximum time this function will wait for + data. :return: COM Result object. :raises: UOSUnsupportedError if the interface hasn't been built - correctly. + correctly. :raises: UOSCommunicationError if there is a problem completing - the action. + the action. """ raise UOSUnsupportedError( "UOSInterfaces must over-ride " @@ -219,9 +222,9 @@ def hard_reset(self) -> ComResult: :return: COM Result object. :raises: UOSUnsupportedError if the interface hasn't been built - correctly. + correctly. :raises: UOSCommunicationError if there is a problem completing - the action. + the action. """ raise UOSUnsupportedError( "UOSInterfaces must over-ride " @@ -233,12 +236,12 @@ def open(self): """Abstract method for opening a connection to a UOSInterface. :raises: UOSUnsupportedError if the interface hasn't been built - correctly. + correctly. :raises: UOSCommunicationError if there is a problem completing - the action. + the action. """ raise UOSUnsupportedError( - "UOSInterfaces must over-ride " f"{UOSInterface.open.__name__} prototype." + "UOSInterfaces must over-ride " f"{UOSInterface.open.__name__} prototype." ) @abstractmethod @@ -246,12 +249,12 @@ def close(self): """Abstract method for closing a connection to a UOSInterface. :raises: UOSUnsupportedError if the interface hasn't been built - correctly. + correctly. :raises: UOSCommunicationError if there is a problem completing - the action. + the action. """ raise UOSUnsupportedError( - "UOSInterfaces must over-ride " f"{UOSInterface.close.__name__} prototype." + "UOSInterfaces must over-ride " f"{UOSInterface.close.__name__} prototype." ) @abstractmethod @@ -260,10 +263,10 @@ def is_active(self) -> bool: :return: Success boolean. :raises: UOSUnsupportedError if the interface hasn't been built - correctly. + correctly. """ raise UOSUnsupportedError( - "UOSInterfaces must over-ride " f"{UOSInterface.close.__name__} prototype." + "UOSInterfaces must over-ride " f"{UOSInterface.close.__name__} prototype." ) @staticmethod @@ -273,7 +276,7 @@ def enumerate_devices() -> list: :return: A list of possible UOSInterfaces on the server. :raises: UOSUnsupportedError if the interface hasn't been built - correctly. + correctly. """ raise UOSUnsupportedError( "UOSInterfaces must over-ride " diff --git a/uoshardware/api.py b/uoshardware/api.py index 599c0fe..81d2204 100644 --- a/uoshardware/api.py +++ b/uoshardware/api.py @@ -1,4 +1,5 @@ """Provides the HAL layer for communicating with the hardware.""" + from uoshardware import ( Loading, Persistence, @@ -29,7 +30,7 @@ def enumerate_system_devices( # dead: disable """Iterate through all interfaces and locates available devices. :param interface_filter: Interface enum to limit the search to a - single interface type. + single interface type. :return: A list of uosinterface objects. """ system_devices = [] @@ -44,7 +45,8 @@ def enumerate_system_devices( # dead: disable def get_device_definition(identity: str) -> Device | None: """Look up the system config dictionary for the defined device mappings. - :param identity: String containing the lookup key of the device in the dictionary. + :param identity: String containing the lookup key of the device in + the dictionary. :return: Device Object or None if not found """ if identity is not None and hasattr(Devices, identity): @@ -58,7 +60,8 @@ def get_device_definition(identity: str) -> Device | None: class UOSDevice: # dead: disable """Class for high level object-orientated control of UOS devices. - :ivar identity: The type of device, this is must have a valid device in the config. + :ivar identity: The type of device, this is must have a valid device + in the config. :ivar address: Compliant connection string for identifying the device and interface. """ @@ -165,10 +168,11 @@ def get_gpio_input( """Read a GPIO pins level from device and returns the value. :param pin: The numeric number of the pin as defined in the - dictionary for that device. - :param pull_up: Enable the internal pull-up resistor. Default is false. + dictionary for that device. + :param pull_up: Enable the internal pull-up resistor. Default is + false. :param volatility: How volatile should the command be, use - constants from uoshardware. + constants from uoshardware. :return: ComResult object. """ result = self.__execute_instruction( @@ -219,8 +223,9 @@ def reset_all_io(self, volatility=Persistence.RAM) -> ComResult: """Execute the reset IO at the defined volatility level. :param volatility: Where should the pins reset from, use - constants from uoshardware. - :return: ComResult object containing the result of the reset operation.. + constants from uoshardware. + :return: ComResult object containing the result of the reset + operation.. """ return self.__execute_instruction( UOSFunctions.reset_all_io, @@ -258,11 +263,13 @@ def __execute_instruction( """Execute a generic UOS function and get the result. :param function: The name of the function in the OOL. - :param instruction_data: device_functions from the LUT, payload ect. - :param retry: Allows the instruction to retry execution when fails. + :param instruction_data: device_functions from the LUT, payload + ect. + :param retry: Allows the instruction to retry execution when + fails. :return: ComResult object :raises: UOSUnsupportedError if function is not possible on the - loaded device. + loaded device. """ if ( function.name not in self.__device.functions_enabled @@ -373,7 +380,8 @@ def get_compatible_pins(self, function: UOSFunction) -> set: def get_functions_enabled(self) -> dict: # dead: disable """Return functions enabled for the device. - :return: Dictionary of function names to list of Persistence levels. + :return: Dictionary of function names to list of Persistence + levels. """ return self.__device.functions_enabled diff --git a/uoshardware/devices/__init__.py b/uoshardware/devices/__init__.py index fb8af49..565224a 100644 --- a/uoshardware/devices/__init__.py +++ b/uoshardware/devices/__init__.py @@ -1,4 +1,5 @@ """Packages used to define Devices supported by the library.""" + from dataclasses import dataclass from uoshardware.abstractions import Device diff --git a/uoshardware/devices/_arduino.py b/uoshardware/devices/_arduino.py index 1a7ad4e..afda857 100644 --- a/uoshardware/devices/_arduino.py +++ b/uoshardware/devices/_arduino.py @@ -1,4 +1,5 @@ """Module contains definitions for arduino devices.""" + from uoshardware import Persistence from uoshardware.abstractions import Device, Pin, UOSFunctions from uoshardware.interface import Interface diff --git a/uoshardware/interface/__init__.py b/uoshardware/interface/__init__.py index 4d8deb8..8102223 100644 --- a/uoshardware/interface/__init__.py +++ b/uoshardware/interface/__init__.py @@ -1,4 +1,5 @@ """Package defining io interfaces used for NPC Comms.""" + from enum import Enum from uoshardware.interface.serial import Serial diff --git a/uoshardware/interface/serial.py b/uoshardware/interface/serial.py index 1e2c8b5..433c42d 100644 --- a/uoshardware/interface/serial.py +++ b/uoshardware/interface/serial.py @@ -1,4 +1,5 @@ """Module defining the low level UOSImplementation for serial port devices.""" + import platform from time import sleep, time_ns @@ -16,11 +17,14 @@ class Serial(UOSInterface): """Pyserial class that handles reading / writing to ports. - :ivar _device: Holds the pyserial device once opened. None if not opened. + :ivar _device: Holds the pyserial device once opened. None if not + opened. :ivar _connection: Holds the standard connection string 'Interface'|'OS Connection String. - :ivar _port: Holds the port class, none type if device not instantiated. - :ivar _kwargs: Additional keyword arguments as defined in the documentation. + :ivar _port: Holds the port class, none type if device not + instantiated. + :ivar _kwargs: Additional keyword arguments as defined in the + documentation. """ _device = None @@ -100,9 +104,10 @@ def close(self): def execute_instruction(self, packet: NPCPacket): """Build and execute a new instruction packet. - :param packet: A tuple containing the uint8 npc packet for the UOS instruction. + :param packet: A tuple containing the uint8 npc packet for the + UOS instruction. :return: Tuple containing a status boolean and index 0 and a - result-set dict at index 1. + result-set dict at index 1. """ if self._device is None: raise UOSCommunicationError( @@ -124,7 +129,8 @@ def read_response(self, expect_packets: int, timeout_s: float): """Read ACK and response packets from the serial device. :param expect_packets: How many packets including ACK to expect. - :param timeout_s: The maximum time this function will wait for data. + :param timeout_s: The maximum time this function will wait for + data. :return: ComResult object. """ if self._device is None: @@ -173,7 +179,7 @@ def hard_reset(self): """Manually drive the DTR line low to reset the device. :return: Tuple containing a status boolean and index 0 and a - result-set dict at index 1. + result-set dict at index 1. """ if self._device is None: raise UOSCommunicationError("Connection must be open to hard reset device.") @@ -206,7 +212,8 @@ def decode_and_capture( :param byte_index: The index of the last 'valid' byte found. :param byte_in: The current byte for inspection. :param packet: The current packet of validated bytes. - :return: Tuple containing the updated byte index and updated packet. + :return: Tuple containing the updated byte index and updated + packet. """ if byte_index == -1: # start symbol if byte_in == b">": diff --git a/uoshardware/interface/stub.py b/uoshardware/interface/stub.py index 73429d4..6ac158e 100644 --- a/uoshardware/interface/stub.py +++ b/uoshardware/interface/stub.py @@ -1,4 +1,5 @@ """Package is used as a simulated UOSInterface for test purposes.""" + from uoshardware import UOSCommunicationError from uoshardware.abstractions import ComResult, NPCPacket, UOSInterface