Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
4 changes: 2 additions & 2 deletions can/bus.py
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand Down Expand Up @@ -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
):
Expand Down
31 changes: 22 additions & 9 deletions can/interfaces/virtual.py
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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()


Expand All @@ -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
)
Expand All @@ -62,18 +73,20 @@ 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.
"""
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)
Expand All @@ -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()
Expand All @@ -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

Expand Down