diff --git a/.travis.yml b/.travis.yml index 7b299feb7..76195ce51 100644 --- a/.travis.yml +++ b/.travis.yml @@ -105,6 +105,7 @@ jobs: can/bus.py can/interface.py can/interfaces/socketcan/**.py + can/interfaces/virtual.py can/listener.py can/logger.py can/message.py diff --git a/can/bus.py b/can/bus.py index 4ef5b5fd6..e315ee9d5 100644 --- a/can/bus.py +++ b/can/bus.py @@ -2,7 +2,7 @@ Contains the ABC bus implementation and its documentation. """ -from typing import cast, Iterator, List, Optional, Sequence, Tuple, Union +from typing import cast, Any, Iterator, List, Optional, Sequence, Tuple, Union import can.typechecking @@ -43,7 +43,7 @@ class BusABC(metaclass=ABCMeta): @abstractmethod def __init__( self, - channel: can.typechecking.Channel, + channel: Any, can_filters: Optional[can.typechecking.CanFilters] = None, **kwargs: object ): diff --git a/can/interfaces/virtual.py b/can/interfaces/virtual.py index e84fa5853..937084095 100644 --- a/can/interfaces/virtual.py +++ b/can/interfaces/virtual.py @@ -5,6 +5,8 @@ Any VirtualBus instances connecting to the same channel and reside in the same process will receive the same messages. """ +from typing import Any, Dict, List, Optional, Tuple, TYPE_CHECKING +from can import typechecking from copy import deepcopy import logging @@ -13,14 +15,19 @@ from threading import RLock from random import randint -from can.bus import BusABC from can import CanError +from can.bus import BusABC +from can.message import Message logger = logging.getLogger(__name__) # Channels are lists of queues, one for each connection -channels = {} +if TYPE_CHECKING: + # https://mypy.readthedocs.io/en/stable/common_issues.html#using-classes-that-are-generic-in-stubs-but-not-at-runtime + channels: Dict[Optional[Any], List[queue.Queue[Message]]] = {} +else: + channels = {} channels_lock = RLock() @@ -43,8 +50,12 @@ class VirtualBus(BusABC): """ def __init__( - self, channel=None, receive_own_messages=False, rx_queue_size=0, **kwargs - ): + self, + channel: Any = None, + receive_own_messages: bool = False, + rx_queue_size: int = 0, + **kwargs: Any + ) -> None: super().__init__( channel=channel, receive_own_messages=receive_own_messages, **kwargs ) @@ -62,10 +73,10 @@ def __init__( channels[self.channel_id] = [] self.channel = channels[self.channel_id] - self.queue = queue.Queue(rx_queue_size) + self.queue: queue.Queue[Message] = queue.Queue(rx_queue_size) self.channel.append(self.queue) - def _check_if_open(self): + def _check_if_open(self) -> None: """Raises CanError if the bus is not open. Has to be called in every method that accesses the bus. @@ -73,7 +84,9 @@ def _check_if_open(self): if not self._open: raise CanError("Operation on closed bus") - def _recv_internal(self, timeout): + def _recv_internal( + self, timeout: Optional[float] + ) -> Tuple[Optional[Message], bool]: self._check_if_open() try: msg = self.queue.get(block=True, timeout=timeout) @@ -82,7 +95,7 @@ def _recv_internal(self, timeout): else: return msg, False - def send(self, msg, timeout=None): + def send(self, msg: Message, timeout: Optional[float] = None) -> None: self._check_if_open() timestamp = time.time() @@ -102,7 +115,7 @@ def send(self, msg, timeout=None): if not all_sent: raise CanError("Could not send message to one or more recipients") - def shutdown(self): + def shutdown(self) -> None: self._check_if_open() self._open = False