From 74cac28311f19dd2d7d0ccff0e00ae149f036a0c Mon Sep 17 00:00:00 2001 From: nulltek Date: Sat, 20 May 2023 13:35:29 +1200 Subject: [PATCH] Adding ruff as a pre-commit linter. Adding a pre-commit hook to check the contents of pyproject.toml. --- .pre-commit-config.yaml | 71 +++++++++++++++++++-------------- docs/conf.py | 2 +- tests/test_abstractions.py | 3 +- uoshardware/abstractions.py | 24 ++++++----- uoshardware/api.py | 18 ++++++--- uoshardware/interface/serial.py | 5 +-- 6 files changed, 74 insertions(+), 49 deletions(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index b9af456..eaa775c 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -17,6 +17,12 @@ repos: - id: check-case-conflict - id: check-ast +# Verify the contents of pyproject.toml +- repo: https://github.com/abravalheri/validate-pyproject + rev: v0.13 + hooks: + - id: validate-pyproject + # Updating code to use modern python patterns where available. - repo: https://github.com/asottile/pyupgrade rev: v3.4.0 @@ -60,6 +66,42 @@ repos: '--exclude=conf.py' # Ignore the sphinx config as this is used by an external tool. ] +# Lint documentation source. +- repo: https://github.com/sphinx-contrib/sphinx-lint + # Make sure to also update the additional dependency pin + rev: v0.6.7 + hooks: + - id: sphinx-lint + +# lint documentation +- repo: https://github.com/PyCQA/doc8 + rev: v1.1.1 + hooks: + - id: doc8 + +# Lint docstrings. +- repo: https://github.com/PyCQA/pydocstyle + # Waiting for a 3.10 release on pypi + rev: "6.3.0" + hooks: + - id: pydocstyle + additional_dependencies: + # TOML support only added natively in python 3.11 + - toml + +# Static typehint linting. +- repo: https://github.com/pre-commit/mirrors-mypy + rev: v1.3.0 + hooks: + - id: mypy + +# A faster python linter +- repo: https://github.com/charliermarsh/ruff-pre-commit + # Ruff version. + rev: 'v0.0.269' + hooks: + - id: ruff + # Lint code using libs in project venv. - repo: local hooks: @@ -92,32 +134,3 @@ repos: - id: bandit # Assert is used exclusively in pytest. args: ['--skip=B101'] - -# Lint documentation source. -- repo: https://github.com/sphinx-contrib/sphinx-lint - # Make sure to also update the additional dependency pin - rev: v0.6.7 - hooks: - - id: sphinx-lint - -# lint documentation -- repo: https://github.com/PyCQA/doc8 - rev: v1.1.1 - hooks: - - id: doc8 - -# Lint docstrings. -- repo: https://github.com/PyCQA/pydocstyle - # Waiting for a 3.10 release on pypi - rev: "6.3.0" - hooks: - - id: pydocstyle - additional_dependencies: - # TOML support only added natively in python 3.11 - - toml - -# Static typehint linting. -- repo: https://github.com/pre-commit/mirrors-mypy - rev: v1.3.0 - hooks: - - id: mypy diff --git a/docs/conf.py b/docs/conf.py index d4b1151..4bcb6d7 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -12,7 +12,7 @@ sys.path.insert(0, os.path.abspath("../")) -from uoshardware import PROJECT, __author__, __copyright__, __version__ +from uoshardware import PROJECT, __author__, __copyright__, __version__ # noqa project = PROJECT # Copyright name shadowed by sphinx design. diff --git a/tests/test_abstractions.py b/tests/test_abstractions.py index e8169ef..f38f832 100644 --- a/tests/test_abstractions.py +++ b/tests/test_abstractions.py @@ -116,7 +116,8 @@ def test_get_npc_checksum(test_packet_data: tuple, expected_lrc: int): def test_get_npc_packet(test_packet: Packet): """Checks packets are formed correctly from some known data.""" print( - f"\n -> addr_to: {test_packet.address_to}, addr_from: {test_packet.address_from}, " + f"\n -> addr_to: {test_packet.address_to}, " + f"addr_from: {test_packet.address_from}, " f"payload: {test_packet.payload}, packet: {test_packet.binary!r}" ) assert ( diff --git a/uoshardware/abstractions.py b/uoshardware/abstractions.py index a7d6a7c..0fb2d89 100644 --- a/uoshardware/abstractions.py +++ b/uoshardware/abstractions.py @@ -190,7 +190,8 @@ def execute_instruction(self, packet: NPCPacket) -> ComResult: # dead: disable the action. """ raise UOSUnsupportedError( - f"UOSInterfaces must over-ride {UOSInterface.execute_instruction.__name__} prototype." + "UOSInterfaces must over-ride " + f"{UOSInterface.execute_instruction.__name__} prototype." ) @abstractmethod @@ -208,7 +209,8 @@ def read_response( the action. """ raise UOSUnsupportedError( - f"UOSInterfaces must over-ride {UOSInterface.read_response.__name__} prototype." + "UOSInterfaces must over-ride " + f"{UOSInterface.read_response.__name__} prototype." ) @abstractmethod @@ -222,7 +224,8 @@ def hard_reset(self) -> ComResult: the action. """ raise UOSUnsupportedError( - f"UOSInterfaces must over-ride {UOSInterface.hard_reset.__name__} prototype" + "UOSInterfaces must over-ride " + f"{UOSInterface.hard_reset.__name__} prototype" ) @abstractmethod @@ -235,7 +238,7 @@ def open(self): the action. """ raise UOSUnsupportedError( - f"UOSInterfaces must over-ride {UOSInterface.open.__name__} prototype." + "UOSInterfaces must over-ride " f"{UOSInterface.open.__name__} prototype." ) @abstractmethod @@ -248,7 +251,7 @@ def close(self): the action. """ raise UOSUnsupportedError( - f"UOSInterfaces must over-ride {UOSInterface.close.__name__} prototype." + "UOSInterfaces must over-ride " f"{UOSInterface.close.__name__} prototype." ) @abstractmethod @@ -260,7 +263,7 @@ def is_active(self) -> bool: correctly. """ raise UOSUnsupportedError( - f"UOSInterfaces must over-ride {UOSInterface.close.__name__} prototype." + "UOSInterfaces must over-ride " f"{UOSInterface.close.__name__} prototype." ) @staticmethod @@ -273,7 +276,8 @@ def enumerate_devices() -> list: correctly. """ raise UOSUnsupportedError( - f"UOSInterfaces must over-ride {UOSInterface.enumerate_devices.__name__} prototype." + "UOSInterfaces must over-ride " + f"{UOSInterface.enumerate_devices.__name__} prototype." ) @@ -363,7 +367,8 @@ def update_adc_samples(self, result: ComResult): for sample_index, pin in enumerate(result.tx_packet.payload): if pin not in self.pins: raise UOSRuntimeError( - f"Can't update ADC samples on pin {pin} as it's invalid for {self.name}." + f"Can't update ADC samples on pin {pin} " + f"as it's invalid for {self.name}." ) self.pins[pin].adc_reading = ADCSample( sample_values[sample_index * 2 : sample_index * 2 + 2], @@ -389,7 +394,8 @@ def update_gpio_samples(self, result: ComResult): pin = result.tx_packet.payload[2 * sample_index] if pin not in self.pins: raise UOSRuntimeError( - f"Can't update GPIO samples on pin {pin} as it's invalid for {self.name}." + f"Can't update GPIO samples on pin {pin} " + f"as it's invalid for {self.name}." ) self.pins[pin].gpio_reading = DigitalSample(sample_values[sample_index]) logger.debug( diff --git a/uoshardware/api.py b/uoshardware/api.py index 45f148d..599c0fe 100644 --- a/uoshardware/api.py +++ b/uoshardware/api.py @@ -28,7 +28,8 @@ def enumerate_system_devices( # dead: disable ) -> list: """Iterate through all interfaces and locates available devices. - :param interface_filter: Interface enum to limit the search to a single interface type. + :param interface_filter: Interface enum to limit the search to a + single interface type. :return: A list of uosinterface objects. """ system_devices = [] @@ -80,10 +81,12 @@ def __init__( """Instantiate a UOS device instance for communication. :param identity: Specify the type of device, this must exist in the device LUT. - :param address: Compliant connection string for identifying the device and interface. + :param address: Compliant connection string for identifying the device and + interface. :param interface: Set the type of interface to use for communication. loading: Alter the loading strategy for managing the communication. - :param kwargs: Additional optional connection parameters as defined in documentation. + :param kwargs: Additional optional connection parameters as defined in + documentation. """ self.address = address self.__kwargs = kwargs @@ -137,9 +140,11 @@ def set_gpio_output( ) -> ComResult: """Set a pin to digital output mode and sets a level on that pin. - :param pin: The numeric number of the pin as defined in the dictionary for that device. + :param pin: The numeric number of the pin as defined in the dictionary + for that device. :param level: The output level, 0 - low, 1 - High. - :param volatility: How volatile should the command be, use constants from uoshardware. + :param volatility: How volatile should the command be, use constants + from uoshardware. :return: ComResult object. """ return self.__execute_instruction( @@ -239,7 +244,8 @@ def open(self): def close(self): """Release connection, must be called explicitly if loading is eager. - :raises: UOSCommunicationError - Problem closing the connection to an active device. + :raises: UOSCommunicationError - Problem closing the connection + to an active device. """ self.__device_interface.close() diff --git a/uoshardware/interface/serial.py b/uoshardware/interface/serial.py index 10f5f0e..1e2c8b5 100644 --- a/uoshardware/interface/serial.py +++ b/uoshardware/interface/serial.py @@ -137,9 +137,8 @@ def read_response(self, expect_packets: int, timeout_s: float): byte_index = -1 # tracks the byte position index of the current packet packet_index = 0 # tracks the packet number being received 0 = ACK try: - while ( - timeout_s * 1000000000 - ) > time_ns() - start_ns and byte_index > -2: # read until packet or timeout + while (timeout_s * 1000000000) > time_ns() - start_ns and byte_index > -2: + # read until packet or timeout num_bytes = self._device.in_waiting for _ in range(num_bytes): byte_in = self._device.read(1)