diff --git a/spinnman/board_test_configuration.py b/spinnman/board_test_configuration.py index 19ac94cd4..889038b10 100644 --- a/spinnman/board_test_configuration.py +++ b/spinnman/board_test_configuration.py @@ -24,11 +24,11 @@ class BoardTestConfiguration(object): Configuration to use for a test board """ - def __init__(self): - self.remotehost = None - self.auto_detect_bmp = None + def __init__(self) -> None: + self.remotehost: str = "UNSET" + self.auto_detect_bmp: bool = False - def set_up_remote_board(self, version: Optional[int] = None): + def set_up_remote_board(self, version: Optional[int] = None) -> None: """ Gets a remote board to test, returning the first that it finds. diff --git a/spinnman/connections/token_bucket.py b/spinnman/connections/token_bucket.py index b3da65280..65c0f3f81 100644 --- a/spinnman/connections/token_bucket.py +++ b/spinnman/connections/token_bucket.py @@ -27,7 +27,7 @@ class TokenBucket(object): """ __slots__ = ('_capacity', '_tokens', '_fill_rate', '_timestamp') - def __init__(self, tokens, fill_rate): + def __init__(self, tokens: int, fill_rate: float): """ :param int tokens: the total tokens in the bucket :param float fill_rate: @@ -38,7 +38,7 @@ def __init__(self, tokens, fill_rate): self._fill_rate = float(fill_rate) self._timestamp = time.time() - def consume(self, tokens, block=True): + def consume(self, tokens: int, block: bool = True) -> bool: """ Consume tokens from the bucket. Returns True if there were sufficient tokens. @@ -65,11 +65,10 @@ def consume(self, tokens, block=True): return False @property - def tokens(self): + def tokens(self) -> float: """ The number of tokens currently in the bucket. - :rtype: int """ if self._tokens < self._capacity: now = time.time() diff --git a/spinnman/connections/udp_packet_connections/utils.py b/spinnman/connections/udp_packet_connections/utils.py index 007dff016..f55f667e1 100644 --- a/spinnman/connections/udp_packet_connections/utils.py +++ b/spinnman/connections/udp_packet_connections/utils.py @@ -12,9 +12,12 @@ # See the License for the specific language governing permissions and # limitations under the License. +from spinnman.messages.sdp import SDPHeader + # Kept for spalloc_server to use -def update_sdp_header_for_udp_send(sdp_header, source_x, source_y): +def update_sdp_header_for_udp_send( + sdp_header: SDPHeader, source_x: int, source_y: int) -> None: """ Apply defaults to the SDP header for sending over UDP. diff --git a/spinnman/data/spinnman_data_view.py b/spinnman/data/spinnman_data_view.py index ebb9ab73c..ad467c952 100644 --- a/spinnman/data/spinnman_data_view.py +++ b/spinnman/data/spinnman_data_view.py @@ -251,7 +251,7 @@ def get_new_id(cls) -> int: return cls.__data._app_id_tracker.get_new_id() @classmethod - def free_id(cls, app_id: int): + def free_id(cls, app_id: int) -> None: """ Frees up an app_id. diff --git a/spinnman/exceptions.py b/spinnman/exceptions.py index 628bf8630..018ad71f9 100644 --- a/spinnman/exceptions.py +++ b/spinnman/exceptions.py @@ -14,7 +14,8 @@ from __future__ import annotations import traceback from types import TracebackType -from typing import Any, List, Optional, FrozenSet, Union, TYPE_CHECKING +from typing import ( + Any, Generic, List, Optional, FrozenSet, TYPE_CHECKING, TypeVar, Union) if TYPE_CHECKING: from spinnman.messages.scp.enums import SCPResult from spinnman.model.enums import CPUState @@ -22,6 +23,8 @@ from spinnman.messages.scp.abstract_messages import AbstractSCPRequest from spinnman.connections.udp_packet_connections import SCAMPConnection +T = TypeVar("T") + class SpinnmanException(Exception): """ @@ -64,13 +67,13 @@ def problem(self) -> str: return self._problem -class SpinnmanInvalidParameterException(SpinnmanException): +class SpinnmanInvalidParameterException(SpinnmanException, Generic[T]): """ An exception that indicates that the value of one of the parameters passed was invalid. """ - def __init__(self, parameter: str, value, problem: str): + def __init__(self, parameter: str, value: T, problem: str): """ :param str parameter: The name of the parameter that is invalid :param str value: The value of the parameter that is invalid @@ -93,7 +96,7 @@ def parameter(self) -> str: return self._parameter @property - def value(self): + def value(self) -> T: """ The value that is invalid. """ @@ -115,7 +118,7 @@ class SpinnmanInvalidParameterTypeException(SpinnmanException): passed was invalid. """ - def __init__(self, parameter: str, param_type, problem: str): + def __init__(self, parameter: str, param_type: str, problem: str): """ :param str parameter: The name of the parameter that is invalid :param str param_type: The type of the parameter that is invalid @@ -138,7 +141,7 @@ def parameter(self) -> str: return self._parameter @property - def type(self): + def type(self) -> str: """ The value that is invalid. """ @@ -186,13 +189,13 @@ def __init__(self) -> None: super().__init__("connection is closed") -class SpinnmanTimeoutException(SpinnmanException): +class SpinnmanTimeoutException(SpinnmanException, Generic[T]): """ An exception that indicates that a timeout occurred before an operation could finish. """ - def __init__(self, operation: Any, timeout: Optional[float], + def __init__(self, operation: T, timeout: Optional[float], msg: Optional[str] = None): """ :param operation: The operation being performed @@ -206,11 +209,10 @@ def __init__(self, operation: Any, timeout: Optional[float], self._timeout = timeout @property - def operation(self) -> str: + def operation(self) -> T: """ The operation that was performed. - :rtype: str """ return self._operation @@ -230,7 +232,7 @@ class SpinnmanUnexpectedResponseCodeException(SpinnmanException): for the current operation. """ - def __init__(self, operation: str, command, + def __init__(self, operation: str, command: str, response: Union[str, SCPResult]): """ :param str operation: The operation being performed @@ -254,7 +256,7 @@ def operation(self) -> str: return self._operation @property - def command(self): + def command(self) -> str: """ The command being executed. """ diff --git a/spinnman/messages/eieio/command_messages/eieio_command_message.py b/spinnman/messages/eieio/command_messages/eieio_command_message.py index b3ccc48b4..eb0bd61b4 100644 --- a/spinnman/messages/eieio/command_messages/eieio_command_message.py +++ b/spinnman/messages/eieio/command_messages/eieio_command_message.py @@ -101,8 +101,8 @@ def get_min_packet_length() -> int: """ return 2 - def __str__(self): + def __str__(self) -> str: return f"EIEIOCommandMessage:{self._eieio_command_header}" - def __repr__(self): + def __repr__(self) -> str: return self.__str__() diff --git a/spinnman/messages/eieio/command_messages/event_stop_request.py b/spinnman/messages/eieio/command_messages/event_stop_request.py index 46dc68ab0..b3be8e3ea 100644 --- a/spinnman/messages/eieio/command_messages/event_stop_request.py +++ b/spinnman/messages/eieio/command_messages/event_stop_request.py @@ -24,5 +24,5 @@ class EventStopRequest(EIEIOCommandMessage): """ __slots__ = () - def __init__(self): + def __init__(self) -> None: super().__init__(EIEIOCommandHeader(EIEIO_COMMAND_IDS.EVENT_STOP)) diff --git a/spinnman/messages/eieio/command_messages/notification_protocol_db_location.py b/spinnman/messages/eieio/command_messages/notification_protocol_db_location.py index 8e576d585..8ec60e258 100644 --- a/spinnman/messages/eieio/command_messages/notification_protocol_db_location.py +++ b/spinnman/messages/eieio/command_messages/notification_protocol_db_location.py @@ -13,6 +13,7 @@ # limitations under the License. from typing import Optional + from spinnman.constants import EIEIO_COMMAND_IDS from .eieio_command_message import EIEIOCommandMessage from .eieio_command_header import EIEIOCommandHeader @@ -29,9 +30,9 @@ class NotificationProtocolDatabaseLocation(EIEIOCommandMessage): """ __slots__ = "_database_path", - def __init__(self, database_path=None): + def __init__(self, database_path: Optional[str] = None): """ - :param str database_path: + :param database_path: The location of the database. If ``None``, this is an acknowledgement, stating that the database has now been read. """ @@ -55,15 +56,19 @@ def database_path(self) -> Optional[str]: return None @property - def bytestring(self): + def bytestring(self) -> bytes: data = super().bytestring if self._database_path is not None: data += self._database_path return data @staticmethod - def from_bytestring(command_header, data, offset): + def from_bytestring( + command_header: EIEIOCommandHeader, data: bytes, + offset: int) -> 'NotificationProtocolDatabaseLocation': database_path = None if len(data) - offset > 0: - database_path = data[offset:] + raise Exception( + "https://github.com/SpiNNakerManchester/SpiNNMan/issues/424") + # database_path = data[offset:] return NotificationProtocolDatabaseLocation(database_path) diff --git a/spinnman/messages/eieio/command_messages/notification_protocol_pause_stop.py b/spinnman/messages/eieio/command_messages/notification_protocol_pause_stop.py index 8f77c6738..ca0f56020 100644 --- a/spinnman/messages/eieio/command_messages/notification_protocol_pause_stop.py +++ b/spinnman/messages/eieio/command_messages/notification_protocol_pause_stop.py @@ -12,6 +12,7 @@ # See the License for the specific language governing permissions and # limitations under the License. +from spinn_utilities.overrides import overrides from spinnman.constants import EIEIO_COMMAND_IDS from .eieio_command_message import EIEIOCommandMessage from .eieio_command_header import EIEIOCommandHeader @@ -26,10 +27,12 @@ class NotificationProtocolPauseStop(EIEIOCommandMessage): """ __slots__ = () - def __init__(self): + def __init__(self) -> None: super().__init__(EIEIOCommandHeader( EIEIO_COMMAND_IDS.STOP_PAUSE_NOTIFICATION)) @staticmethod - def from_bytestring(command_header, data, offset): + @overrides(EIEIOCommandMessage.from_bytestring) + def from_bytestring(command_header: EIEIOCommandHeader, data: bytes, + offset: int) -> "NotificationProtocolPauseStop": return NotificationProtocolPauseStop() diff --git a/spinnman/messages/eieio/command_messages/notification_protocol_start_resume.py b/spinnman/messages/eieio/command_messages/notification_protocol_start_resume.py index 9a036da97..2558337e8 100644 --- a/spinnman/messages/eieio/command_messages/notification_protocol_start_resume.py +++ b/spinnman/messages/eieio/command_messages/notification_protocol_start_resume.py @@ -12,6 +12,7 @@ # See the License for the specific language governing permissions and # limitations under the License. +from spinn_utilities.overrides import overrides from spinnman.constants import EIEIO_COMMAND_IDS from .eieio_command_message import EIEIOCommandMessage from .eieio_command_header import EIEIOCommandHeader @@ -26,10 +27,12 @@ class NotificationProtocolStartResume(EIEIOCommandMessage): """ __slots__ = () - def __init__(self): + def __init__(self) -> None: super().__init__(EIEIOCommandHeader( EIEIO_COMMAND_IDS.START_RESUME_NOTIFICATION)) @staticmethod - def from_bytestring(command_header, data, offset): + @overrides(EIEIOCommandMessage.from_bytestring) + def from_bytestring(command_header: EIEIOCommandHeader, data: bytes, + offset: int) -> "NotificationProtocolStartResume": return NotificationProtocolStartResume() diff --git a/spinnman/messages/eieio/command_messages/padding_request.py b/spinnman/messages/eieio/command_messages/padding_request.py index 0fe179c0a..095783a6e 100644 --- a/spinnman/messages/eieio/command_messages/padding_request.py +++ b/spinnman/messages/eieio/command_messages/padding_request.py @@ -23,9 +23,9 @@ class PaddingRequest(EIEIOCommandMessage): """ __slots__ = () - def __init__(self): + def __init__(self) -> None: super().__init__(EIEIOCommandHeader(EIEIO_COMMAND_IDS.EVENT_PADDING)) @staticmethod - def get_min_packet_length(): + def get_min_packet_length() -> int: return 2 diff --git a/spinnman/messages/eieio/command_messages/spinnaker_request_read_data.py b/spinnman/messages/eieio/command_messages/spinnaker_request_read_data.py index 96fb1b9b0..ebdba1ef8 100644 --- a/spinnman/messages/eieio/command_messages/spinnaker_request_read_data.py +++ b/spinnman/messages/eieio/command_messages/spinnaker_request_read_data.py @@ -149,7 +149,7 @@ def channel(self, request_id: int) -> int: """ return self._requests.channel(request_id) - def region_id(self, request_id) -> int: + def region_id(self, request_id: int) -> int: """ The region_id for this request_id. @@ -159,7 +159,7 @@ def region_id(self, request_id) -> int: """ return self._requests.region_id(request_id) - def start_address(self, request_id) -> int: + def start_address(self, request_id: int) -> int: """ The start_address for this request_id. @@ -169,7 +169,7 @@ def start_address(self, request_id) -> int: """ return self._requests.start_address(request_id) - def space_to_be_read(self, request_id) -> int: + def space_to_be_read(self, request_id: int) -> int: """ The space_to_be_read for this request_id. @@ -356,7 +356,7 @@ def __init__(self, channel: Union[List[int], int], else: self._space_to_be_read = space_to_be_read - def channel(self, request_id) -> int: + def channel(self, request_id: int) -> int: """ Gets the channel for this request_id @@ -373,7 +373,7 @@ def channel(self, request_id) -> int: f"channel request needs to be comprised between 0 and " f"{len(self._channel) - 1:d}; current value: {request_id:d}") - def region_id(self, request_id) -> int: + def region_id(self, request_id: int) -> int: """ Gets the region_id for this request_id diff --git a/spinnman/messages/eieio/command_messages/start_requests.py b/spinnman/messages/eieio/command_messages/start_requests.py index 26340407e..3d8e60299 100644 --- a/spinnman/messages/eieio/command_messages/start_requests.py +++ b/spinnman/messages/eieio/command_messages/start_requests.py @@ -25,6 +25,6 @@ class StartRequests(EIEIOCommandMessage): """ __slots__ = () - def __init__(self): + def __init__(self) -> None: super().__init__(EIEIOCommandHeader( EIEIO_COMMAND_IDS.START_SENDING_REQUESTS)) diff --git a/spinnman/messages/eieio/command_messages/stop_requests.py b/spinnman/messages/eieio/command_messages/stop_requests.py index e7726eccf..9e6d1f942 100644 --- a/spinnman/messages/eieio/command_messages/stop_requests.py +++ b/spinnman/messages/eieio/command_messages/stop_requests.py @@ -25,6 +25,6 @@ class StopRequests(EIEIOCommandMessage): """ __slots__ = () - def __init__(self): + def __init__(self) -> None: super().__init__(EIEIOCommandHeader( EIEIO_COMMAND_IDS.STOP_SENDING_REQUESTS)) diff --git a/spinnman/messages/eieio/create_eieio_command.py b/spinnman/messages/eieio/create_eieio_command.py index 612dbd0d1..7a3638705 100644 --- a/spinnman/messages/eieio/create_eieio_command.py +++ b/spinnman/messages/eieio/create_eieio_command.py @@ -20,7 +20,8 @@ from spinnman.constants import EIEIO_COMMAND_IDS -def read_eieio_command_message(data, offset): +def read_eieio_command_message( + data: bytes, offset: int) -> EIEIOCommandMessage: """ Reads the content of an EIEIO command message and returns an object identifying the command which was contained in the packet, including diff --git a/spinnman/messages/eieio/create_eieio_data.py b/spinnman/messages/eieio/create_eieio_data.py index 9195787f4..a09478c8a 100644 --- a/spinnman/messages/eieio/create_eieio_data.py +++ b/spinnman/messages/eieio/create_eieio_data.py @@ -16,7 +16,7 @@ EIEIODataMessage, EIEIODataHeader) -def read_eieio_data_message(data, offset): +def read_eieio_data_message(data: bytes, offset: int) -> EIEIODataMessage: """ Reads the content of an EIEIO data message and returns an object identifying the data which was contained in the packet. diff --git a/spinnman/messages/eieio/data_messages/eieio_data_header.py b/spinnman/messages/eieio/data_messages/eieio_data_header.py index ecded471c..5eee2a74a 100644 --- a/spinnman/messages/eieio/data_messages/eieio_data_header.py +++ b/spinnman/messages/eieio/data_messages/eieio_data_header.py @@ -137,7 +137,7 @@ def count(self) -> int: return self._count @count.setter - def count(self, count: int): + def count(self, count: int) -> None: """ Sets the Count of the number of items in the packet @@ -157,7 +157,8 @@ def size(self) -> int: self._payload_base is not None) @staticmethod - def get_header_size(eieio_type, is_prefix=False, is_payload_base=False): + def get_header_size(eieio_type: EIEIOType, is_prefix: bool = False, + is_payload_base: bool = False) -> int: """ Get the size of a header with the given parameters. @@ -297,12 +298,12 @@ def from_bytestring(data: bytes, offset: int) -> 'EIEIODataHeader': prefix_type=prefix_type, payload_base=payload_prefix, is_time=bool(payload_is_timestamp), count=count) - def __str__(self): + def __str__(self) -> str: return (f"EIEIODataHeader:prefix={self._prefix}:" f"prefix_type={self._prefix_type}:" f"payload_base={self._payload_base}:" "is_time={self._is_time}:type={self._eieio_type.value}:" "tag={self._tag}:count={self._count}") - def __repr__(self): + def __repr__(self) -> str: return self.__str__() diff --git a/spinnman/messages/eieio/data_messages/eieio_data_message.py b/spinnman/messages/eieio/data_messages/eieio_data_message.py index 9da649a33..567d730e0 100644 --- a/spinnman/messages/eieio/data_messages/eieio_data_message.py +++ b/spinnman/messages/eieio/data_messages/eieio_data_message.py @@ -42,7 +42,8 @@ class EIEIODataMessage(AbstractEIEIOMessage): "_header", "_offset") - def __init__(self, eieio_header, data=None, offset=0): + def __init__(self, eieio_header: EIEIODataHeader, + data: Optional[bytes] = None, offset: int = 0): """ :param EIEIODataHeader eieio_header: The header of the message :param bytes data: Optional data contained within the packet @@ -61,9 +62,13 @@ def __init__(self, eieio_header, data=None, offset=0): @staticmethod def create( - eieio_type, count=0, data=None, offset=0, key_prefix=None, - payload_prefix=None, timestamp=None, - prefix_type=EIEIOPrefix.LOWER_HALF_WORD): + eieio_type: EIEIOType, count: int = 0, + data: Optional[bytes] = None, offset: int = 0, + key_prefix: Optional[int] = None, + payload_prefix: Optional[int] = None, + timestamp: Optional[int] = None, + prefix_type: EIEIOPrefix = EIEIOPrefix.LOWER_HALF_WORD + ) -> "EIEIODataMessage": """ Create a data message. @@ -98,8 +103,8 @@ def eieio_header(self) -> EIEIODataHeader: @staticmethod def min_packet_length( - eieio_type, is_prefix=False, is_payload_base=False, - is_timestamp=False): + eieio_type: EIEIOType, is_prefix: bool = False, + is_payload_base: bool = False, is_timestamp: bool = False) -> int: """ The minimum length of a message with the given header, in bytes. @@ -158,7 +163,7 @@ def size(self) -> int: return (self._header.size + (ty.key_bytes + ty.payload_bytes) * self._header.count) - def add_key_and_payload(self, key: int, payload: int): + def add_key_and_payload(self, key: int, payload: int) -> None: """ Adds a key and payload to the packet. @@ -180,7 +185,7 @@ def add_key_and_payload(self, key: int, payload: int): self.add_element(KeyPayloadDataElement( key, payload, self._header.is_time)) - def add_key(self, key: int): + def add_key(self, key: int) -> None: """ Add a key to the packet. @@ -195,7 +200,7 @@ def add_key(self, key: int): f"{self._header.eieio_type.max_value}") self.add_element(KeyDataElement(key)) - def add_element(self, element: AbstractDataElement): + def add_element(self, element: AbstractDataElement) -> None: """ Add an element to the message. The correct type of element must be added, depending on the header values. @@ -235,6 +240,7 @@ def next_element(self) -> Optional[AbstractDataElement]: return None self._elements_read += 1 payload: Optional[int] = None + assert self._data is not None if self._header.eieio_type == EIEIOType.KEY_16_BIT: key = _ONE_SHORT.unpack_from(self._data, self._offset)[0] self._offset += 2 @@ -272,10 +278,10 @@ def next_element(self) -> Optional[AbstractDataElement]: def bytestring(self) -> bytes: return self._header.bytestring + self._elements - def __str__(self): + def __str__(self) -> str: if self._data is not None: return f"EIEIODataMessage:{self._header}:{self._header.count}" - return f"EIEIODataMessage:{self._header}:{self._elements}" + return f"EIEIODataMessage:{self._header}:{self._elements!r}" - def __repr__(self): + def __repr__(self) -> str: return self.__str__() diff --git a/spinnman/messages/eieio/data_messages/key_data_element.py b/spinnman/messages/eieio/data_messages/key_data_element.py index 8ba2c6237..6d7c1f3f4 100644 --- a/spinnman/messages/eieio/data_messages/key_data_element.py +++ b/spinnman/messages/eieio/data_messages/key_data_element.py @@ -55,8 +55,8 @@ def get_bytestring(self, eieio_type: EIEIOType) -> bytes: raise SpinnmanInvalidParameterException( "eieio_type", eieio_type, "Unknown type") - def __str__(self): + def __str__(self) -> str: return f"KeyDataElement:0x{self._key:x}" - def __repr__(self): + def __repr__(self) -> str: return self.__str__() diff --git a/spinnman/messages/eieio/data_messages/key_payload_data_element.py b/spinnman/messages/eieio/data_messages/key_payload_data_element.py index 252cce6a7..2425c5dfd 100644 --- a/spinnman/messages/eieio/data_messages/key_payload_data_element.py +++ b/spinnman/messages/eieio/data_messages/key_payload_data_element.py @@ -79,8 +79,8 @@ def get_bytestring(self, eieio_type: EIEIOType) -> bytes: raise SpinnmanInvalidParameterException( "eieio_type", eieio_type, "Unknown type") - def __str__(self): + def __str__(self) -> str: return f"KeyPayloadDataElement:0x{self._key:x}:0x{self._payload:x}" - def __repr__(self): + def __repr__(self) -> str: return self.__str__() diff --git a/spinnman/messages/eieio/eieio_type.py b/spinnman/messages/eieio/eieio_type.py index 955357a49..76ba80ae1 100644 --- a/spinnman/messages/eieio/eieio_type.py +++ b/spinnman/messages/eieio/eieio_type.py @@ -29,9 +29,10 @@ class EIEIOType(Enum): #: Indicates that data is keys and payloads of 32 bits. KEY_PAYLOAD_32_BIT = (3, 4, 4) - def __new__(cls, *args) -> 'EIEIOType': + def __new__(cls, encoded_value: int, key_bytes: int, + payload_bytes: int) -> 'EIEIOType': obj = object.__new__(cls) - obj._value_ = args[0] + obj._value_ = encoded_value return obj def __init__(self, encoded_value: int, diff --git a/spinnman/messages/multicast_message.py b/spinnman/messages/multicast_message.py index 21451e456..022a04ea9 100644 --- a/spinnman/messages/multicast_message.py +++ b/spinnman/messages/multicast_message.py @@ -12,6 +12,8 @@ # See the License for the specific language governing permissions and # limitations under the License. +from typing import Optional + class MulticastMessage(object): """ @@ -22,16 +24,16 @@ class MulticastMessage(object): "_key", "_payload") - def __init__(self, key, payload=None): + def __init__(self, key: int, payload: Optional[int] = None): """ - :param int key: The key of the packet - :param int payload: The optional payload of the packet + :param key: The key of the packet + :param payload: The optional payload of the packet """ self._key = key self._payload = payload @property - def key(self): + def key(self) -> int: """ The key of the packet. @@ -40,7 +42,7 @@ def key(self): return self._key @property - def payload(self): + def payload(self) -> Optional[int]: """ The payload of the packet if there is one, or `None` if there is no payload. diff --git a/spinnman/messages/scp/abstract_messages/bmp_response.py b/spinnman/messages/scp/abstract_messages/bmp_response.py index aeaf96c7f..fc53f7ef1 100644 --- a/spinnman/messages/scp/abstract_messages/bmp_response.py +++ b/spinnman/messages/scp/abstract_messages/bmp_response.py @@ -49,7 +49,7 @@ def _value(self) -> T: return self.__value @overrides(AbstractSCPResponse.read_data_bytestring) - def read_data_bytestring(self, data: bytes, offset: int): + def read_data_bytestring(self, data: bytes, offset: int) -> None: result = self.scp_response_header.result if result != SCPResult.RC_OK: raise SpinnmanUnexpectedResponseCodeException( diff --git a/spinnman/messages/scp/abstract_messages/scp_request.py b/spinnman/messages/scp/abstract_messages/scp_request.py index 4fbae6a07..03f6a70fd 100644 --- a/spinnman/messages/scp/abstract_messages/scp_request.py +++ b/spinnman/messages/scp/abstract_messages/scp_request.py @@ -138,11 +138,11 @@ def bytestring(self) -> bytes: data += bytes(self._data) return data - def __repr__(self): + def __repr__(self) -> str: # Default is to return just the command, but can be overridden return str(self._scp_request_header.command) - def __str__(self): + def __str__(self) -> str: return self.__repr__() @abstractmethod diff --git a/spinnman/messages/scp/abstract_messages/scp_response.py b/spinnman/messages/scp/abstract_messages/scp_response.py index 7061910d6..d40ce2c2b 100644 --- a/spinnman/messages/scp/abstract_messages/scp_response.py +++ b/spinnman/messages/scp/abstract_messages/scp_response.py @@ -37,7 +37,7 @@ def __init__(self) -> None: self._sdp_header: Optional[SDPHeader] = None self._scp_response_header: Optional[SCPResponseHeader] = None - def read_bytestring(self, data: bytes, offset: int): + def read_bytestring(self, data: bytes, offset: int) -> None: """ Reads a packet from a byte-string of data. @@ -51,7 +51,7 @@ def read_bytestring(self, data: bytes, offset: int): self.read_data_bytestring(data, _SCP_DATA_OFFSET + offset) @abstractmethod - def read_data_bytestring(self, data: bytes, offset: int): + def read_data_bytestring(self, data: bytes, offset: int) -> None: """ Reads the remainder of the data following the header. diff --git a/spinnman/messages/scp/enums/signal.py b/spinnman/messages/scp/enums/signal.py index cd5a6f7e9..4eacaee79 100644 --- a/spinnman/messages/scp/enums/signal.py +++ b/spinnman/messages/scp/enums/signal.py @@ -43,9 +43,9 @@ class Signal(Enum): USER_2 = (12, SignalType.MULTICAST) USER_3 = (13, SignalType.MULTICAST) - def __new__(cls, *args) -> 'Signal': + def __new__(cls, value: int, signal_type: SignalType) -> 'Signal': obj = object.__new__(cls) - obj._value_ = args[0] + obj._value_ = value return obj def __init__(self, value: int, signal_type: SignalType) -> None: diff --git a/spinnman/messages/scp/impl/count_state_response.py b/spinnman/messages/scp/impl/count_state_response.py index ba3b4608f..d03f97169 100644 --- a/spinnman/messages/scp/impl/count_state_response.py +++ b/spinnman/messages/scp/impl/count_state_response.py @@ -12,6 +12,7 @@ # See the License for the specific language governing permissions and # limitations under the License. +from typing import Optional import struct from spinn_utilities.overrides import overrides from spinnman.messages.scp.abstract_messages import AbstractSCPResponse @@ -27,12 +28,12 @@ class CountStateResponse(AbstractSCPResponse): """ __slots__ = "_count", - def __init__(self): + def __init__(self) -> None: super().__init__() - self._count = None + self._count: Optional[int] = None @overrides(AbstractSCPResponse.read_data_bytestring) - def read_data_bytestring(self, data: bytes, offset: int): + def read_data_bytestring(self, data: bytes, offset: int) -> None: result = self.scp_response_header.result # We can accept a no-reply response here; that could just mean # that the count wasn't complete (but might be enough anyway) @@ -46,6 +47,6 @@ def count(self) -> int: """ The count of the number of cores with the requested state. - :rtype: int """ + assert self._count is not None return self._count diff --git a/spinnman/messages/scp/impl/fixed_route_read.py b/spinnman/messages/scp/impl/fixed_route_read.py index 5b31746c4..3c7dccf38 100644 --- a/spinnman/messages/scp/impl/fixed_route_read.py +++ b/spinnman/messages/scp/impl/fixed_route_read.py @@ -39,7 +39,7 @@ def __init__(self) -> None: self._route = 0 @overrides(AbstractSCPResponse.read_data_bytestring) - def read_data_bytestring(self, data: bytes, offset: int): + def read_data_bytestring(self, data: bytes, offset: int) -> None: result = self.scp_response_header.result if result != SCPResult.RC_OK: raise SpinnmanUnexpectedResponseCodeException( diff --git a/spinnman/messages/scp/impl/get_chip_info_response.py b/spinnman/messages/scp/impl/get_chip_info_response.py index 913adc654..6992f92a4 100644 --- a/spinnman/messages/scp/impl/get_chip_info_response.py +++ b/spinnman/messages/scp/impl/get_chip_info_response.py @@ -30,7 +30,7 @@ def __init__(self) -> None: self._chip_info: Optional[ChipSummaryInfo] = None @overrides(AbstractSCPResponse.read_data_bytestring) - def read_data_bytestring(self, data: bytes, offset: int): + def read_data_bytestring(self, data: bytes, offset: int) -> None: result = self.scp_response_header.result if result != SCPResult.RC_OK: raise SpinnmanUnexpectedResponseCodeException( diff --git a/spinnman/messages/scp/impl/get_version_response.py b/spinnman/messages/scp/impl/get_version_response.py index f8017c4d0..e0960ae65 100644 --- a/spinnman/messages/scp/impl/get_version_response.py +++ b/spinnman/messages/scp/impl/get_version_response.py @@ -30,7 +30,7 @@ def __init__(self) -> None: self._version_info: Optional[VersionInfo] = None @overrides(AbstractSCPResponse.read_data_bytestring) - def read_data_bytestring(self, data: bytes, offset: int): + def read_data_bytestring(self, data: bytes, offset: int) -> None: result = self.scp_response_header.result if result != SCPResult.RC_OK: raise SpinnmanUnexpectedResponseCodeException( diff --git a/spinnman/messages/scp/impl/iptag_get.py b/spinnman/messages/scp/impl/iptag_get.py index d6903982b..73529becb 100644 --- a/spinnman/messages/scp/impl/iptag_get.py +++ b/spinnman/messages/scp/impl/iptag_get.py @@ -60,7 +60,7 @@ def __init__(self) -> None: self._spin_port = 0 @overrides(AbstractSCPResponse.read_data_bytestring) - def read_data_bytestring(self, data: bytes, offset: int): + def read_data_bytestring(self, data: bytes, offset: int) -> None: result = self.scp_response_header.result if result != SCPResult.RC_OK: raise SpinnmanUnexpectedResponseCodeException( diff --git a/spinnman/messages/scp/impl/iptag_get_info_response.py b/spinnman/messages/scp/impl/iptag_get_info_response.py index 232caa7ad..98f3cd0a8 100644 --- a/spinnman/messages/scp/impl/iptag_get_info_response.py +++ b/spinnman/messages/scp/impl/iptag_get_info_response.py @@ -37,7 +37,7 @@ def __init__(self) -> None: self._fixed_size = 0 @overrides(AbstractSCPResponse.read_data_bytestring) - def read_data_bytestring(self, data: bytes, offset: int): + def read_data_bytestring(self, data: bytes, offset: int) -> None: result = self.scp_response_header.result if result != SCPResult.RC_OK: raise SpinnmanUnexpectedResponseCodeException( diff --git a/spinnman/messages/scp/impl/read_memory.py b/spinnman/messages/scp/impl/read_memory.py index 204f721e5..be1e4dbfa 100644 --- a/spinnman/messages/scp/impl/read_memory.py +++ b/spinnman/messages/scp/impl/read_memory.py @@ -43,7 +43,7 @@ def __init__(self, operation: str, command: str) -> None: self.__cmd = command @overrides(AbstractSCPResponse.read_data_bytestring) - def read_data_bytestring(self, data: bytes, offset: int): + def read_data_bytestring(self, data: bytes, offset: int) -> None: assert self._scp_response_header is not None if self._scp_response_header.result != SCPResult.RC_OK: raise SpinnmanUnexpectedResponseCodeException( diff --git a/spinnman/messages/scp/impl/router_alloc.py b/spinnman/messages/scp/impl/router_alloc.py index 26289308d..87765a832 100644 --- a/spinnman/messages/scp/impl/router_alloc.py +++ b/spinnman/messages/scp/impl/router_alloc.py @@ -37,7 +37,7 @@ def __init__(self) -> None: self._base_address: Optional[int] = None @overrides(AbstractSCPResponse.read_data_bytestring) - def read_data_bytestring(self, data: bytes, offset: int): + def read_data_bytestring(self, data: bytes, offset: int) -> None: result = self.scp_response_header.result if result != SCPResult.RC_OK: raise SpinnmanUnexpectedResponseCodeException( diff --git a/spinnman/messages/scp/impl/sdram_alloc.py b/spinnman/messages/scp/impl/sdram_alloc.py index 025908f28..ee775243b 100644 --- a/spinnman/messages/scp/impl/sdram_alloc.py +++ b/spinnman/messages/scp/impl/sdram_alloc.py @@ -42,7 +42,7 @@ def __init__(self, size: int): self._base_address: Optional[int] = None @overrides(AbstractSCPResponse.read_data_bytestring) - def read_data_bytestring(self, data: bytes, offset: int): + def read_data_bytestring(self, data: bytes, offset: int) -> None: result = self.scp_response_header.result if result != SCPResult.RC_OK: raise SpinnmanUnexpectedResponseCodeException( diff --git a/spinnman/messages/scp/impl/sdram_de_alloc.py b/spinnman/messages/scp/impl/sdram_de_alloc.py index 919dc7e38..6a9ff0b97 100644 --- a/spinnman/messages/scp/impl/sdram_de_alloc.py +++ b/spinnman/messages/scp/impl/sdram_de_alloc.py @@ -41,7 +41,7 @@ def __init__(self, read_n_blocks_freed: bool = False): self._read_n_blocks_freed = read_n_blocks_freed @overrides(AbstractSCPResponse.read_data_bytestring) - def read_data_bytestring(self, data: bytes, offset: int): + def read_data_bytestring(self, data: bytes, offset: int) -> None: result = self.scp_response_header.result if result != SCPResult.RC_OK: raise SpinnmanUnexpectedResponseCodeException( diff --git a/spinnman/messages/scp/impl/set_power.py b/spinnman/messages/scp/impl/set_power.py index 5051ffc90..e258b41da 100644 --- a/spinnman/messages/scp/impl/set_power.py +++ b/spinnman/messages/scp/impl/set_power.py @@ -32,7 +32,7 @@ class SetPower(BMPRequest[BMPOKResponse]): def __init__( self, power_command: PowerCommand, boards: Boards, *, - delay=0.0, board_to_send_to=0): + delay: float = 0.0, board_to_send_to: int = 0): """ .. note:: There is currently a bug in the BMP that means some boards don't diff --git a/spinnman/messages/scp/scp_request_header.py b/spinnman/messages/scp/scp_request_header.py index 6a3c4f662..2928e39ed 100644 --- a/spinnman/messages/scp/scp_request_header.py +++ b/spinnman/messages/scp/scp_request_header.py @@ -59,7 +59,7 @@ def sequence(self) -> int: return self._sequence @sequence.setter - def sequence(self, sequence: int): + def sequence(self, sequence: int) -> None: """ Set the sequence number of the SCP packet. diff --git a/spinnman/messages/scp/scp_response_header.py b/spinnman/messages/scp/scp_response_header.py index 55907e59f..97dbb9fce 100644 --- a/spinnman/messages/scp/scp_response_header.py +++ b/spinnman/messages/scp/scp_response_header.py @@ -26,7 +26,7 @@ class SCPResponseHeader(object): "_result", "_sequence") - def __init__(self, result, sequence): + def __init__(self, result: SCPResult, sequence: int): """ :param SCPResult result: :param int sequence: diff --git a/spinnman/messages/sdp/sdp_header.py b/spinnman/messages/sdp/sdp_header.py index 4afdb35d1..2f24b905c 100644 --- a/spinnman/messages/sdp/sdp_header.py +++ b/spinnman/messages/sdp/sdp_header.py @@ -98,7 +98,7 @@ def flags(self) -> SDPFlag: return self._flags @flags.setter - def flags(self, flags: SDPFlag): + def flags(self, flags: SDPFlag) -> None: """ Set the flags of the packet. @@ -117,7 +117,7 @@ def tag(self) -> int: return self._tag @tag.setter - def tag(self, tag: int): + def tag(self, tag: int) -> None: """ Set the tag of the packet. @@ -135,7 +135,7 @@ def destination_port(self) -> int: return self._destination_port @destination_port.setter - def destination_port(self, destination_port: int): + def destination_port(self, destination_port: int) -> None: """ Set the destination port of the packet. @@ -154,7 +154,7 @@ def destination_cpu(self) -> int: return self._destination_cpu @destination_cpu.setter - def destination_cpu(self, destination_cpu: int): + def destination_cpu(self, destination_cpu: int) -> None: """ Set the ID of the destination processor of the packet. @@ -174,7 +174,7 @@ def destination_chip_x(self) -> int: return self._destination_chip_x @destination_chip_x.setter - def destination_chip_x(self, destination_chip_x: int): + def destination_chip_x(self, destination_chip_x: int) -> None: """ Set the x-coordinate of the destination chip of the packet. @@ -194,7 +194,7 @@ def destination_chip_y(self) -> int: return self._destination_chip_y @destination_chip_y.setter - def destination_chip_y(self, destination_chip_y: int): + def destination_chip_y(self, destination_chip_y: int) -> None: """ Set the y-coordinate of the destination chip of the packet. @@ -214,7 +214,7 @@ def source_port(self) -> int: return self._source_port @source_port.setter - def source_port(self, source_port: int): + def source_port(self, source_port: int) -> None: """ Set the source port of the packet. @@ -233,7 +233,7 @@ def source_cpu(self) -> int: return self._source_cpu @source_cpu.setter - def source_cpu(self, source_cpu: int): + def source_cpu(self, source_cpu: int) -> None: """ Set the ID of the source processor of the packet. @@ -254,7 +254,7 @@ def source_chip_x(self) -> int: return self._source_chip_x @source_chip_x.setter - def source_chip_x(self, source_chip_x: int): + def source_chip_x(self, source_chip_x: int) -> None: """ Set the x-coordinate of the source chip of the packet. @@ -276,7 +276,7 @@ def source_chip_y(self) -> int: return self._source_chip_y @source_chip_y.setter - def source_chip_y(self, source_chip_y: int): + def source_chip_y(self, source_chip_y: int) -> None: """ Set the y-coordinate of the source chip of the packet. @@ -303,7 +303,7 @@ def bytestring(self) -> bytes: self.source_chip_y, self.source_chip_x) @staticmethod - def from_bytestring(data: bytes, offset: int): + def from_bytestring(data: bytes, offset: int) -> "SDPHeader": """ Read the header from a byte-string. @@ -334,7 +334,7 @@ def get_physical_cpu_id(self) -> str: (self._destination_chip_x, self._destination_chip_y), self._destination_cpu) - def update_for_send(self, source_x: int, source_y: int): + def update_for_send(self, source_x: int, source_y: int) -> None: """ Apply defaults to the header for sending over UDP. diff --git a/spinnman/model/cpu_info.py b/spinnman/model/cpu_info.py index fb726f959..4499ace68 100644 --- a/spinnman/model/cpu_info.py +++ b/spinnman/model/cpu_info.py @@ -377,8 +377,8 @@ def get_status_string(self) -> str: f"in state {self.__state.name}\n") @staticmethod - def mock_info( - x: int, y: int, p: int, physical_cpu_id: int, state: CPUState): + def mock_info(x: int, y: int, p: int, physical_cpu_id: int, + state: CPUState) -> "CPUInfo": """ Makes a CPU_info object for Testing purposes diff --git a/spinnman/model/cpu_infos.py b/spinnman/model/cpu_infos.py index 730ddf506..8a18a155d 100644 --- a/spinnman/model/cpu_infos.py +++ b/spinnman/model/cpu_infos.py @@ -13,6 +13,7 @@ # limitations under the License. from typing import Dict, Iterable, Iterator +from typing_extensions import Self from spinn_utilities.typing.coords import XYP from spinnman.model.enums import CPUState from .cpu_info import CPUInfo @@ -28,7 +29,7 @@ class CPUInfos(object): def __init__(self) -> None: self._cpu_infos: Dict[XYP, CPUInfo] = dict() - def add_info(self, cpu_info: CPUInfo): + def add_info(self, cpu_info: CPUInfo) -> None: """ Add a info on using its core coordinates. @@ -36,7 +37,7 @@ def add_info(self, cpu_info: CPUInfo): """ self._cpu_infos[cpu_info.x, cpu_info.y, cpu_info.p] = cpu_info - def add_infos(self, other, states: Iterable[CPUState]): + def add_infos(self, other: Self, states: Iterable[CPUState]) -> None: """ Adds all the infos in the other CPUInfos if the have one of the required states diff --git a/spinnman/model/enums/executable_type.py b/spinnman/model/enums/executable_type.py index dc4d67bf4..823f88089 100644 --- a/spinnman/model/enums/executable_type.py +++ b/spinnman/model/enums/executable_type.py @@ -13,7 +13,7 @@ # limitations under the License. from __future__ import annotations from enum import Enum -from typing import FrozenSet, Sequence +from typing import FrozenSet, Sequence, Tuple from spinnman.model.enums import CPUState @@ -67,10 +67,13 @@ class ExecutableType(Enum): True, "Runs immediately without waiting for barrier and never ends") - def __new__(cls, *args) -> 'ExecutableType': + def __new__(cls, value: int, start_state: Sequence[CPUState], + end_state: Sequence[CPUState], + supports_auto_pause_and_resume: bool, + doc: str = "") -> 'ExecutableType': obj = object.__new__(cls) - obj._value_ = args[0] - obj. __doc__ = args[-1] + obj._value_ = value + obj. __doc__ = doc return obj def __init__(self, value: int, start_state: Sequence[CPUState], diff --git a/spinnman/model/executable_targets.py b/spinnman/model/executable_targets.py index d50a0e694..8ad5900b8 100644 --- a/spinnman/model/executable_targets.py +++ b/spinnman/model/executable_targets.py @@ -43,7 +43,7 @@ def __init__(self) -> None: def add_subsets( self, binary: str, subsets: CoreSubsets, - executable_type: Optional[ExecutableType] = None): + executable_type: Optional[ExecutableType] = None) -> None: """ Add core subsets to a binary. @@ -66,7 +66,7 @@ def add_subsets( def add_processor( self, binary: str, chip_x: int, chip_y: int, chip_p: int, - executable_type: Optional[ExecutableType] = None): + executable_type: Optional[ExecutableType] = None) -> None: """ Add a processor to the executable targets @@ -160,7 +160,8 @@ def all_core_subsets(self) -> CoreSubsets: """ return self._all_core_subsets - def known(self, binary, chip_x, chip_y, chip_p) -> bool: + def known( + self, binary: str, chip_x: int, chip_y: int, chip_p: int) -> bool: """ :param str binary: :param int chip_x: diff --git a/spinnman/model/p2p_table.py b/spinnman/model/p2p_table.py index e40c04f75..7c6f689ab 100644 --- a/spinnman/model/p2p_table.py +++ b/spinnman/model/p2p_table.py @@ -13,7 +13,7 @@ # limitations under the License. import struct -from typing import Dict, List, Tuple +from typing import Dict, Iterable, List, Tuple from spinnman.model.enums import P2PTableRoute _ONE_WORD = struct.Struct(" int: """ return self._height - def iterchips(self): + def iterchips(self) -> Iterable[Tuple[int, int]]: """ Get an iterator of tuples of (x, y) coordinates in the table. @@ -95,7 +95,7 @@ def iterchips(self): """ return iter(self._routes.keys()) - def is_route(self, x, y): + def is_route(self, x: int, y: int) -> bool: """ Determines if there is a route in the P2P table to the given chip. @@ -118,7 +118,7 @@ def get_route(self, x: int, y: int) -> P2PTableRoute: return self._routes.get((x, y), P2PTableRoute.NONE) @property - def n_routes(self): + def n_routes(self) -> int: """ The number of routes in the table :rtype: int diff --git a/spinnman/utilities/appid_tracker.py b/spinnman/utilities/appid_tracker.py index 6ece8d458..2b9cfb257 100644 --- a/spinnman/utilities/appid_tracker.py +++ b/spinnman/utilities/appid_tracker.py @@ -53,7 +53,7 @@ def get_new_id(self) -> int: """ return self._free_ids.pop() - def allocate_id(self, allocated_id: int): + def allocate_id(self, allocated_id: int) -> None: """ Allocate a given ID. @@ -62,7 +62,7 @@ def allocate_id(self, allocated_id: int): """ self._free_ids.remove(allocated_id) - def free_id(self, id_to_free: int): + def free_id(self, id_to_free: int) -> None: """ Free a given ID. diff --git a/spinnman/utilities/socket_utils.py b/spinnman/utilities/socket_utils.py index 69463294a..c9d421551 100644 --- a/spinnman/utilities/socket_utils.py +++ b/spinnman/utilities/socket_utils.py @@ -53,7 +53,7 @@ def get_tcp_socket() -> socket.socket: # pylint: disable=wrong-spelling-in-docstring -def set_receive_buffer_size(sock: socket.socket, size: int): +def set_receive_buffer_size(sock: socket.socket, size: int) -> None: """ Wrapper round setsockopt() system call. """ @@ -66,7 +66,7 @@ def set_receive_buffer_size(sock: socket.socket, size: int): "receive buffer", exc_info=True) -def bind_socket(sock: socket.socket, host: str, port: int): +def bind_socket(sock: socket.socket, host: str, port: int) -> None: """ Wrapper round bind() system call. """ @@ -89,7 +89,8 @@ def resolve_host(host: str) -> str: f"Error getting IP address for {host}: {e}") from e -def connect_socket(sock: socket.socket, remote_address: str, remote_port: int): +def connect_socket( + sock: socket.socket, remote_address: str, remote_port: int) -> None: """ Wrapper round connect() system call. """ @@ -144,7 +145,7 @@ def receive_message_and_address( raise SpinnmanIOException(f"Error receiving: {e}") from e -def send_message(sock: socket.socket, data: bytes): +def send_message(sock: socket.socket, data: bytes) -> int: """ Wrapper round send() system call. """ @@ -155,7 +156,7 @@ def send_message(sock: socket.socket, data: bytes): def send_message_to_address( - sock: socket.socket, data: bytes, address: Tuple[str, int]): + sock: socket.socket, data: bytes, address: Tuple[str, int]) -> int: """ Wrapper round sendto() system call. """