diff --git a/.github/workflows/python_actions.yml b/.github/workflows/python_actions.yml index ba2f9def..ab21b375 100644 --- a/.github/workflows/python_actions.yml +++ b/.github/workflows/python_actions.yml @@ -26,5 +26,6 @@ jobs: coverage-package: spinn_machine flake8-packages: spinn_machine unittests pylint-packages: spinn_machine - mypy-packages: spinn_machine unittests + mypy-packages: unittests + mypy-full_packages: spinn_machine secrets: inherit diff --git a/mypy.bash b/mypy.bash index d0d0eafc..a49673c5 100755 --- a/mypy.bash +++ b/mypy.bash @@ -21,4 +21,4 @@ utils="../SpiNNUtils/spinn_utilities" -mypy --python-version 3.8 $utils spinn_machine +mypy --python-version 3.8 $utils spinn_machine unittests diff --git a/mypyd.bash b/mypyd.bash new file mode 100755 index 00000000..e43e741c --- /dev/null +++ b/mypyd.bash @@ -0,0 +1,24 @@ +#!/bin/bash + +# Copyright (c) 2024 The University of Manchester +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# https://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# This bash assumes that other repositories are installed in paralled + +# requires the latest mypy +# pip install --upgrade mypy + +utils="../SpiNNUtils/spinn_utilities" + +mypy --python-version 3.8 --disallow-untyped-defs $utils spinn_machine diff --git a/spinn_machine/chip.py b/spinn_machine/chip.py index 75e98713..fd79ab18 100644 --- a/spinn_machine/chip.py +++ b/spinn_machine/chip.py @@ -13,6 +13,8 @@ # limitations under the License. from typing import (Iterable, Iterator, Optional, Tuple) +from typing_extensions import Self + from spinn_utilities.ordered_set import OrderedSet from spinn_utilities.typing.coords import XY @@ -33,7 +35,7 @@ def __new__(cls, x: int, y: int, scamp_processors: Iterable[int], sdram: int, nearest_ethernet_x: int, nearest_ethernet_y: int, ip_address: Optional[str] = None, tag_ids: Optional[Iterable[int]] = None, - parent_link: Optional[int] = None): + parent_link: Optional[int] = None) -> Self: return tuple.__new__(cls, (x, y)) # pylint: disable=too-many-arguments, wrong-spelling-in-docstring diff --git a/spinn_machine/core_subset.py b/spinn_machine/core_subset.py index 1420a3a7..cf0bfc5a 100644 --- a/spinn_machine/core_subset.py +++ b/spinn_machine/core_subset.py @@ -36,7 +36,7 @@ def __init__(self, x: int, y: int, processor_ids: Iterable[int]): for processor_id in processor_ids: self.add_processor(processor_id) - def add_processor(self, processor_id: int): + def add_processor(self, processor_id: int) -> None: """ Adds a processor ID to this subset diff --git a/spinn_machine/core_subsets.py b/spinn_machine/core_subsets.py index a93e6e5b..17ee7215 100644 --- a/spinn_machine/core_subsets.py +++ b/spinn_machine/core_subsets.py @@ -33,7 +33,7 @@ def __init__(self, core_subsets: Iterable[CoreSubset] = ()): for core_subset in core_subsets: self.add_core_subset(core_subset) - def add_core_subset(self, core_subset: CoreSubset): + def add_core_subset(self, core_subset: CoreSubset) -> None: """ Add a core subset to the set @@ -44,7 +44,7 @@ def add_core_subset(self, core_subset: CoreSubset): for processor_id in core_subset.processor_ids: self.add_processor(x, y, processor_id) - def add_core_subsets(self, core_subsets: Iterable[CoreSubset]): + def add_core_subsets(self, core_subsets: Iterable[CoreSubset]) -> None: """ Merges a core subsets into this one. @@ -53,7 +53,7 @@ def add_core_subsets(self, core_subsets: Iterable[CoreSubset]): for core_subset in core_subsets: self.add_core_subset(core_subset) - def add_processor(self, x: int, y: int, processor_id: int): + def add_processor(self, x: int, y: int, processor_id: int) -> None: """ Add a processor on a given chip to the set. diff --git a/spinn_machine/data/machine_data_view.py b/spinn_machine/data/machine_data_view.py index 6b48dfcd..dba80aef 100644 --- a/spinn_machine/data/machine_data_view.py +++ b/spinn_machine/data/machine_data_view.py @@ -277,7 +277,7 @@ def get_machine_version(cls) -> AbstractVersion: return cls.__data._machine_version @classmethod - def set_v_to_p_map(cls, v_to_p_map: Dict[XY, bytes]): + def set_v_to_p_map(cls, v_to_p_map: Dict[XY, bytes]) -> None: """ Registers the mapping from Virtual to int physical core ids diff --git a/spinn_machine/data/machine_data_writer.py b/spinn_machine/data/machine_data_writer.py index 94da3a3d..981e4aa3 100644 --- a/spinn_machine/data/machine_data_writer.py +++ b/spinn_machine/data/machine_data_writer.py @@ -72,7 +72,7 @@ def get_user_accessed_machine(self) -> bool: """ return self.__data._user_accessed_machine - def set_machine(self, machine: Machine): + def set_machine(self, machine: Machine) -> None: """ Sets the machine. @@ -94,19 +94,20 @@ def clear_machine(self) -> None: """ self.__data._machine = None - def set_machine_generator(self, machine_generator: Callable[[], None]): + def set_machine_generator( + self, machine_generator: Callable[[], None]) -> None: """ Registers a function that can be called to give a machine. Note that if the function does not actually register a machine when called, an exception will be thrown. - :param function machine_generator: + :param machine_generator: """ if not callable(machine_generator): raise TypeError("machine_generator must be callable") self.__data._machine_generator = machine_generator - def add_monitor_core(self, all_chips: bool): + def add_monitor_core(self, all_chips: bool) -> None: """ Accepts a simple of the monitor cores to be added. diff --git a/spinn_machine/exceptions.py b/spinn_machine/exceptions.py index 4b692080..48be0fed 100644 --- a/spinn_machine/exceptions.py +++ b/spinn_machine/exceptions.py @@ -12,6 +12,8 @@ # See the License for the specific language governing permissions and # limitations under the License. +from typing import Any + class SpinnMachineException(Exception): """ @@ -27,10 +29,10 @@ class SpinnMachineAlreadyExistsException(SpinnMachineException): "_item", "_value"] - def __init__(self, item: str, value): + def __init__(self, item: str, value: Any) -> None: """ - :param str item: The item of which there is already one of - :param str value: The value of the item + :param item: The item of which there is already one of + :param value: The value of the item """ super().__init__( f"There can only be one {item} with a value of {value}") @@ -45,7 +47,7 @@ def item(self) -> str: return self._item @property - def value(self): + def value(self) -> Any: """ The value of the item. """ @@ -61,12 +63,12 @@ class SpinnMachineInvalidParameterException(SpinnMachineException): "_problem", "_value"] - def __init__(self, parameter: str, value, problem: str): + def __init__(self, parameter: str, value: Any, problem: str) -> None: """ - :param str parameter: + :param parameter: The name of the parameter that has an invalid value - :param str value: The value of the parameter that is invalid - :param str problem: The reason for the exception + :param value: The value of the parameter that is invalid + :param problem: The reason for the exception """ super().__init__( f"It is invalid to set {parameter} to {value}: {problem}") @@ -82,7 +84,7 @@ def parameter(self) -> str: return self._parameter @property - def value(self): + def value(self) -> Any: """ The value of the parameter. """ diff --git a/spinn_machine/frozen_core_subsets.py b/spinn_machine/frozen_core_subsets.py index 7ee8e16f..7de1f073 100644 --- a/spinn_machine/frozen_core_subsets.py +++ b/spinn_machine/frozen_core_subsets.py @@ -35,13 +35,13 @@ def __init__(self, core_subsets: Iterable[CoreSubset] = ()): super().add_processor(x, y, processor_id) @overrides(CoreSubsets.add_core_subset) - def add_core_subset(self, core_subset: CoreSubset): + def add_core_subset(self, core_subset: CoreSubset) -> None: raise RuntimeError("This object is immutable") @overrides(CoreSubsets.add_core_subsets) - def add_core_subsets(self, core_subsets: Iterable[CoreSubset]): + def add_core_subsets(self, core_subsets: Iterable[CoreSubset]) -> None: raise RuntimeError("This object is immutable") @overrides(CoreSubsets.add_processor) - def add_processor(self, x: int, y: int, processor_id: int): + def add_processor(self, x: int, y: int, processor_id: int) -> None: raise RuntimeError("This object is immutable") diff --git a/spinn_machine/json_machine.py b/spinn_machine/json_machine.py index 38822dbd..adcce2a3 100644 --- a/spinn_machine/json_machine.py +++ b/spinn_machine/json_machine.py @@ -176,7 +176,7 @@ def _int_value(value: int) -> int: # pylint: disable=wrong-spelling-in-docstring -def _describe_chip(chip: Chip, standard, ethernet) -> JsonArray: +def _describe_chip(chip: Chip, standard: _Desc, ethernet: _Desc) -> JsonArray: """ Produce a JSON-suitable description of a single chip. diff --git a/spinn_machine/link_data_objects/spinnaker_link_data.py b/spinn_machine/link_data_objects/spinnaker_link_data.py index de932f66..ff8f4934 100644 --- a/spinn_machine/link_data_objects/spinnaker_link_data.py +++ b/spinn_machine/link_data_objects/spinnaker_link_data.py @@ -56,7 +56,7 @@ def __hash__(self) -> int: self.connected_chip_x, self.connected_chip_y, self.connected_link, self.board_address)) - def __str__(self): + def __str__(self) -> str: return (f"id:{self._spinnaker_link_id} x:{self.connected_chip_x} " f"y:{self.connected_chip_y} link:{self._spinnaker_link_id} " f"{self.board_address}") diff --git a/spinn_machine/machine.py b/spinn_machine/machine.py index 0ae114f8..b54b09cb 100644 --- a/spinn_machine/machine.py +++ b/spinn_machine/machine.py @@ -543,7 +543,7 @@ def wrap(self) -> str: """ raise NotImplementedError - def add_chip(self, chip: Chip): + def add_chip(self, chip: Chip) -> None: """ Add a chip to the machine. @@ -569,7 +569,7 @@ def add_chip(self, chip: Chip): if (chip == (0, 0)): self._boot_ethernet_address = chip.ip_address - def add_chips(self, chips: Iterable[Chip]): + def add_chips(self, chips: Iterable[Chip]) -> None: """ Add some chips to the machine. @@ -668,7 +668,7 @@ def is_link_at(self, x: int, y: int, link: int) -> bool: """ return (x, y) in self._chips and self._chips[x, y].router.is_link(link) - def __contains__(self, x_y_tuple: XY): + def __contains__(self, x_y_tuple: XY) -> bool: """ Determine if a chip exists at the given coordinates. @@ -862,7 +862,7 @@ def add_spinnaker_links(self) -> None: def _add_spinnaker_link( self, spinnaker_link_id: int, x: int, y: int, link: int, - board_address: str): + board_address: str) -> None: link_data = SpinnakerLinkData( spinnaker_link_id, x, y, link, board_address) self._spinnaker_links[board_address, spinnaker_link_id] = link_data @@ -888,7 +888,7 @@ def add_fpga_links(self) -> None: def _add_fpga_link( self, fpga_id: int, fpga_link: int, x: int, y: int, link: int, - board_address: str, ex: int, ey: int): + board_address: str, ex: int, ey: int) -> None: # pylint: disable=too-many-arguments link_data = FPGALinkData( fpga_link_id=fpga_link, fpga_id=fpga_id, diff --git a/spinn_machine/machine_factory.py b/spinn_machine/machine_factory.py index 10bd51fc..c920636b 100644 --- a/spinn_machine/machine_factory.py +++ b/spinn_machine/machine_factory.py @@ -121,7 +121,8 @@ def _generate_uni_direction_link_error( f"Please report this to spinnakerusers@googlegroups.com \n\n" -def machine_repair(original: Machine, removed_chips: Iterable[XY] = ()): +def machine_repair( + original: Machine, removed_chips: Iterable[XY] = ()) -> Machine: """ Remove chips that can't be reached or that can't reach other chips due to missing links. @@ -129,16 +130,13 @@ def machine_repair(original: Machine, removed_chips: Iterable[XY] = ()): Also remove any one way links. :param original: the original machine - :type original: Machine :param removed_chips: List of chips (x and y coordinates) that have been removed while the machine was being created. One-way links to these chip are expected repairs so always done and never logged - :type removed_chips: list(tuple(int,int)) :raises SpinnMachineException: if repair_machine is false and an unexpected repair is needed. :return: Either the original machine or a repaired replacement - :rtype: Machine """ repair_machine = get_config_bool("Machine", "repair_machine") dead_chips: Set[XY] = set() diff --git a/spinn_machine/router.py b/spinn_machine/router.py index c5b24fce..2958dab3 100644 --- a/spinn_machine/router.py +++ b/spinn_machine/router.py @@ -58,7 +58,7 @@ def __init__( self._n_available_multicast_entries = n_available_multicast_entries - def add_link(self, link: Link): + def add_link(self, link: Link) -> None: """ Add a link to the router of the chip. diff --git a/spinn_machine/spinnaker_triad_geometry.py b/spinn_machine/spinnaker_triad_geometry.py index 73f38bd0..a0b7c626 100644 --- a/spinn_machine/spinnaker_triad_geometry.py +++ b/spinn_machine/spinnaker_triad_geometry.py @@ -106,7 +106,7 @@ def __init__( for y, row in enumerate(nearest_ethernets)] @staticmethod - def __hexagonal_metric_distance(xy: XY, centre: _Centre): + def __hexagonal_metric_distance(xy: XY, centre: _Centre) -> float: """ Get the hexagonal metric distance of a point from the centre of the hexagon. @@ -138,7 +138,7 @@ def __hexagonal_metric_distance(xy: XY, centre: _Centre): return max(abs(dx), abs(dy), abs(dx - dy)) def __locate_nearest_ethernet( - self, xy: XY, ethernet_chips: Sequence[XY], centre: _Centre): + self, xy: XY, ethernet_chips: Sequence[XY], centre: _Centre) -> XY: """ Get the coordinate of the nearest Ethernet chip down and left from a given chip. diff --git a/spinn_machine/tags/abstract_tag.py b/spinn_machine/tags/abstract_tag.py index 266de010..28b9f084 100644 --- a/spinn_machine/tags/abstract_tag.py +++ b/spinn_machine/tags/abstract_tag.py @@ -29,37 +29,28 @@ class AbstractTag(object): "_port" ] - def __init__(self, board_address, tag, port): + def __init__(self, board_address: str, tag: int, port: int): self._board_address = board_address self._tag = tag self._port = port @property - def board_address(self): + def board_address(self) -> str: """ The board address of the tag. """ return self._board_address @property - def tag(self): + def tag(self) -> int: """ The tag ID of the tag. """ return self._tag @property - def port(self): + def port(self) -> int: """ The port of the tag. """ return self._port - - @port.setter - def port(self, port): - """ - Set the port; will fail if the port is already set. - """ - if self._port is not None: - raise RuntimeError("Port cannot be set more than once") - self._port = port diff --git a/spinn_machine/tags/iptag.py b/spinn_machine/tags/iptag.py index c7d1d5b7..7d4dd2bd 100644 --- a/spinn_machine/tags/iptag.py +++ b/spinn_machine/tags/iptag.py @@ -12,6 +12,7 @@ # See the License for the specific language governing permissions and # limitations under the License. +from typing import Any from .abstract_tag import AbstractTag @@ -31,23 +32,22 @@ class IPTag(AbstractTag): # pylint: disable=too-many-arguments def __init__( - self, board_address, destination_x, destination_y, tag, ip_address, - port=None, strip_sdp=False, traffic_identifier="DEFAULT"): + self, board_address: str, destination_x: int, + destination_y: int, tag: int, ip_address: str, + port: int, strip_sdp: bool = False, + traffic_identifier: str = "DEFAULT"): """ :param board_address: The IP address of the board on which the tag is allocated - :type board_address: str or None - :param int destination_x: + :param destination_x: The x-coordinate where users of this tag should send packets to - :param int destination_y: + :param destination_y: The y-coordinate where users of this tag should send packets to - :param int tag: The tag of the SDP packet + :param tag: The tag of the SDP packet :param str ip_address: The IP address to which SDP packets with the tag will be sent :param port: The port to which the SDP packets with the tag will be sent, or - ``None`` if not yet assigned - :type port: int or None :param bool strip_sdp: Indicates whether the SDP header should be removed :param str traffic_identifier: @@ -61,41 +61,41 @@ def __init__( self._destination_y = destination_y @property - def ip_address(self): + def ip_address(self) -> str: """ The IP address to which SDP packets with this tag will be sent. """ return self._ip_address @property - def strip_sdp(self): + def strip_sdp(self) -> bool: """ Whether the SDP header is to be stripped. """ return self._strip_sdp @property - def traffic_identifier(self): + def traffic_identifier(self) -> str: """ The identifier of traffic using this tag. """ return self._traffic_identifier @property - def destination_x(self): + def destination_x(self) -> int: """ The X-coordinate where users of this tag should send packets to. """ return self._destination_x @property - def destination_y(self): + def destination_y(self) -> int: """ The Y-coordinate where users of this tag should send packets to. """ return self._destination_y - def __repr__(self): + def __repr__(self) -> str: return ( f"IPTag(board_address={self.board_address}, " f"destination_x={self.destination_x}, " @@ -104,7 +104,7 @@ def __repr__(self): f"ip_address={self.ip_address}, strip_sdp={self.strip_sdp}, " f"traffic_identifier={self.traffic_identifier})") - def __eq__(self, other): + def __eq__(self, other: Any) -> bool: if not isinstance(other, IPTag): return False return (self._ip_address == other.ip_address and @@ -114,9 +114,9 @@ def __eq__(self, other): self._tag == other.tag and self._traffic_identifier == other.traffic_identifier) - def __hash__(self): + def __hash__(self) -> int: return hash((self._ip_address, self._strip_sdp, self._board_address, self._port, self._tag, self._traffic_identifier)) - def __ne__(self, other): + def __ne__(self, other: Any) -> bool: return not self.__eq__(other) diff --git a/spinn_machine/tags/reverse_iptag.py b/spinn_machine/tags/reverse_iptag.py index 54dd579c..a0f17c76 100644 --- a/spinn_machine/tags/reverse_iptag.py +++ b/spinn_machine/tags/reverse_iptag.py @@ -28,8 +28,9 @@ class ReverseIPTag(AbstractTag): ] # pylint: disable=too-many-arguments - def __init__(self, board_address, tag, port, destination_x, destination_y, - destination_p, sdp_port=1): + def __init__(self, board_address: str, tag: int, port: int, + destination_x: int, destination_y: int, destination_p: int, + sdp_port: int = 1): """ :param board_address: The IP address of the board on which the tag is allocated @@ -53,7 +54,7 @@ def __init__(self, board_address, tag, port, destination_x, destination_y, self._sdp_port = sdp_port @property - def sdp_port(self): + def sdp_port(self) -> int: """ The SDP port number of the tag that these packets are to be received on for the processor. @@ -61,7 +62,7 @@ def sdp_port(self): return self._sdp_port @property - def destination_x(self): + def destination_x(self) -> int: """ The destination x coordinate of a chip in the SpiNNaker machine that packets should be sent to for this reverse IP tag. @@ -69,7 +70,7 @@ def destination_x(self): return self._destination_x @property - def destination_y(self): + def destination_y(self) -> int: """ The destination y coordinate of a chip in the SpiNNaker machine that packets should be sent to for this reverse IP tag. @@ -77,14 +78,14 @@ def destination_y(self): return self._destination_y @property - def destination_p(self): + def destination_p(self) -> int: """ The destination processor ID for the chip at (x,y) that packets should be send to for this reverse IP tag. """ return self._destination_p - def __repr__(self): + def __repr__(self) -> str: return ( f"ReverseIPTag(board_address={self._board_address}, " f"tag={self._tag}, port={self._port}, " diff --git a/spinn_machine/version/abstract_version.py b/spinn_machine/version/abstract_version.py index fb53625d..659d3073 100644 --- a/spinn_machine/version/abstract_version.py +++ b/spinn_machine/version/abstract_version.py @@ -82,7 +82,7 @@ def __verify_config_width_height(self) -> None: else: self.verify_size(width, height) - def __set_max_cores_per_chip(self, max_cores_per_chip: int): + def __set_max_cores_per_chip(self, max_cores_per_chip: int) -> None: self._max_cores_per_chip = max_cores_per_chip max_machine_core = get_config_int_or_none( "Machine", "max_machine_core") @@ -99,7 +99,7 @@ def __set_max_cores_per_chip(self, max_cores_per_chip: int): f"due to cfg setting [Machine]max_machine_core") self._max_cores_per_chip = max_machine_core - def __set_max_sdram_per_chip(self, max_sdram_per_chip: int): + def __set_max_sdram_per_chip(self, max_sdram_per_chip: int) -> None: self._max_sdram_per_chip = max_sdram_per_chip max_sdram = get_config_int_or_none( "Machine", "max_sdram_allowed_per_chip") @@ -265,7 +265,7 @@ def get_potential_ethernet_chips( """ raise NotImplementedError - def verify_size(self, width: Optional[int], height: Optional[int]): + def verify_size(self, width: Optional[int], height: Optional[int]) -> None: """ Checks that the width and height are allowed for this version. @@ -284,7 +284,7 @@ def verify_size(self, width: Optional[int], height: Optional[int]): self._verify_size(width, height) @abstractmethod - def _verify_size(self, width: int, height: int): + def _verify_size(self, width: int, height: int) -> None: """ Implements the width and height checks that depend on the version. @@ -577,5 +577,5 @@ def get_router_report_packet_types(self) -> List[str]: """ raise NotImplementedError - def __hash__(self): + def __hash__(self) -> int: return self.number diff --git a/spinn_machine/version/version_201.py b/spinn_machine/version/version_201.py index ea84696d..e6f56f54 100644 --- a/spinn_machine/version/version_201.py +++ b/spinn_machine/version/version_201.py @@ -12,7 +12,7 @@ # See the License for the specific language governing permissions and # limitations under the License. -from typing import Dict, Final, List, Optional, Sequence, Tuple +from typing import Any, Dict, Final, List, Optional, Sequence, Tuple from spinn_utilities.typing.coords import XY from spinn_utilities.overrides import overrides @@ -61,7 +61,7 @@ def get_potential_ethernet_chips( return [(0, 0)] @overrides(VersionSpin2._verify_size) - def _verify_size(self, width: int, height: int): + def _verify_size(self, width: int, height: int) -> None: if width != 1: raise SpinnMachineException(f"Unexpected {width=}") if height != 1: @@ -90,5 +90,5 @@ def spinnaker_links(self) -> List[Tuple[int, int, int]]: def fpga_links(self) -> List[Tuple[int, int, int, int, int]]: return [] - def __eq__(self, other): + def __eq__(self, other: Any) -> bool: return isinstance(other, Version201) diff --git a/spinn_machine/version/version_248.py b/spinn_machine/version/version_248.py index 50bc4ad7..7de657c7 100644 --- a/spinn_machine/version/version_248.py +++ b/spinn_machine/version/version_248.py @@ -12,7 +12,7 @@ # See the License for the specific language governing permissions and # limitations under the License. -from typing import Dict, Final, List, Tuple +from typing import Any, Dict, Final, List, Tuple from spinn_utilities.typing.coords import XY from spinn_utilities.overrides import overrides @@ -69,5 +69,5 @@ def fpga_links(self) -> List[Tuple[int, int, int, int, int]]: # TODO return [] - def __eq__(self, other): + def __eq__(self, other: Any) -> bool: return isinstance(other, Version248) diff --git a/spinn_machine/version/version_3.py b/spinn_machine/version/version_3.py index 3c5c83a2..8e58a5c4 100644 --- a/spinn_machine/version/version_3.py +++ b/spinn_machine/version/version_3.py @@ -12,7 +12,7 @@ # See the License for the specific language governing permissions and # limitations under the License. -from typing import Dict, Final, List, Optional, Sequence, Tuple +from typing import Any, Dict, Final, List, Optional, Sequence, Tuple from spinn_utilities.overrides import overrides from spinn_utilities.typing.coords import XY from spinn_machine.exceptions import SpinnMachineException @@ -62,7 +62,7 @@ def get_potential_ethernet_chips( return [(0, 0)] @overrides(VersionSpin1._verify_size) - def _verify_size(self, width: int, height: int): + def _verify_size(self, width: int, height: int) -> None: if width != 2: raise SpinnMachineException(f"Unexpected {width=}") if height != 2: @@ -117,5 +117,5 @@ def get_active_energy( self._get_router_active_energy(router_packets) + self._get_core_active_energy(chip_active_time)) - def __eq__(self, other): + def __eq__(self, other: Any) -> bool: return isinstance(other, Version3) diff --git a/spinn_machine/version/version_48_chips.py b/spinn_machine/version/version_48_chips.py index c0dc6803..953d586a 100644 --- a/spinn_machine/version/version_48_chips.py +++ b/spinn_machine/version/version_48_chips.py @@ -47,7 +47,7 @@ def get_potential_ethernet_chips( return geometry.get_potential_ethernet_chips(width, height) @overrides(AbstractVersion._verify_size) - def _verify_size(self, width: int, height: int): + def _verify_size(self, width: int, height: int) -> None: if width <= 8: if width == 8 and height == 8: # 1 board diff --git a/spinn_machine/version/version_5.py b/spinn_machine/version/version_5.py index 94da5303..f7c522f0 100644 --- a/spinn_machine/version/version_5.py +++ b/spinn_machine/version/version_5.py @@ -12,7 +12,7 @@ # See the License for the specific language governing permissions and # limitations under the License. -from typing import Dict, Final, List, Tuple +from typing import Any, Dict, Final, List, Tuple from spinn_utilities.overrides import overrides from spinn_utilities.typing.coords import XY @@ -144,5 +144,5 @@ def get_active_energy( self._get_router_active_energy(router_packets) + self._get_core_active_energy(chip_active_time)) - def __eq__(self, other): + def __eq__(self, other: Any) -> bool: return isinstance(other, Version5) diff --git a/spinn_machine/version/version_factory.py b/spinn_machine/version/version_factory.py index fc19f07f..277c5a59 100644 --- a/spinn_machine/version/version_factory.py +++ b/spinn_machine/version/version_factory.py @@ -16,6 +16,9 @@ import logging import sys from typing import Optional, TYPE_CHECKING + +from typing_extensions import Never + from spinn_utilities.config_holder import ( get_config_bool, get_config_int_or_none, get_config_str_or_none) from spinn_utilities.log import FormatAdapter @@ -156,7 +159,7 @@ def _get_size_version() -> Optional[int]: return 5 -def _number_to_version(version: int): +def _number_to_version(version: int) -> AbstractVersion: # Delayed import to avoid circular imports # pylint: disable=import-outside-toplevel from .version_3 import Version3 @@ -179,7 +182,7 @@ def _number_to_version(version: int): raise SpinnMachineException(f"Unexpected cfg [Machine]version {version}") -def raise_version_error(error: str, version: Optional[int]): +def raise_version_error(error: str, version: Optional[int]) -> Never: """ Collects main cfg values and raises an exception diff --git a/spinn_machine/version/version_strings.py b/spinn_machine/version/version_strings.py index 336f0384..81578d34 100644 --- a/spinn_machine/version/version_strings.py +++ b/spinn_machine/version/version_strings.py @@ -13,7 +13,8 @@ # limitations under the License. from enum import Enum -from typing import List +from typing import List, Tuple +from typing_extensions import Self from spinn_machine.exceptions import SpinnMachineException @@ -35,17 +36,17 @@ class VersionStrings(Enum): # Tests for 8 by 8 boards with FPGAs defined WITH_FPGAS = (6, "with fpgas", [5]) - def __new__(cls, *args, **kwds): + def __new__(cls, *args: Tuple[int, str, List[int]], **kwds: None) -> Self: vs = object.__new__(cls) vs._value_ = args[0] return vs # ignore the first param since it's already set by __new__ - def __init__(self, _: str, text: str, versions: List[int]): + def __init__(self, _: int, text: str, versions: List[int]): self.text = text self._versions = versions - def __str__(self): + def __str__(self) -> str: return self.text @property diff --git a/spinn_machine/virtual_machine.py b/spinn_machine/virtual_machine.py index df3b6118..34db95fc 100644 --- a/spinn_machine/virtual_machine.py +++ b/spinn_machine/virtual_machine.py @@ -28,7 +28,7 @@ logger = FormatAdapter(logging.getLogger(__name__)) -def virtual_machine(width: int, height: int, validate: bool = True): +def virtual_machine(width: int, height: int, validate: bool = True) -> Machine: """ Create a virtual SpiNNaker machine, used for planning execution. @@ -44,7 +44,7 @@ def virtual_machine(width: int, height: int, validate: bool = True): def virtual_machine_by_min_size( - width: int, height: int, validate: bool = True): + width: int, height: int, validate: bool = True) -> Machine: """ Create a virtual SpiNNaker machine, used for planning execution. @@ -67,7 +67,7 @@ def virtual_machine_by_min_size( return virtual_machine(width, height, validate) -def virtual_machine_by_cores(n_cores: int, validate: bool = True): +def virtual_machine_by_cores(n_cores: int, validate: bool = True) -> Machine: """ Create a virtual SpiNNaker machine, used for planning execution. @@ -92,7 +92,7 @@ def virtual_machine_by_cores(n_cores: int, validate: bool = True): return virtual_machine(width, height, validate) -def virtual_machine_by_chips(n_chips: int, validate: bool = True): +def virtual_machine_by_chips(n_chips: int, validate: bool = True) -> Machine: """ Create a virtual SpiNNaker machine, used for planning execution. @@ -117,7 +117,7 @@ def virtual_machine_by_chips(n_chips: int, validate: bool = True): return virtual_machine(width, height, validate) -def virtual_machine_by_boards(n_boards: int, validate: bool = True): +def virtual_machine_by_boards(n_boards: int, validate: bool = True) -> Machine: """ Create a virtual SpiNNaker machine, used for planning execution. diff --git a/unittests/tag_tests/test_iptag.py b/unittests/tag_tests/test_iptag.py index 63141f88..87c5f4c7 100644 --- a/unittests/tag_tests/test_iptag.py +++ b/unittests/tag_tests/test_iptag.py @@ -102,13 +102,6 @@ def test_in_dict(self): assert d[iptag_2] == 10 assert len(d) == 2 - def test_set_port(self): - tag = IPTag("examplehost", 0, 0, 0, "") - tag.port = 1 - with self.assertRaises(RuntimeError) as e: - tag.port = 2 - self.assertIn("Port cannot be set more than once", str(e.exception)) - def test_no_equals(self): iptag = IPTag("", 0, 0, 0, "", 1) self.assertNotEqual(iptag, "foo")