|
3 | 3 | """ |
4 | 4 |
|
5 | 5 | import asyncio |
| 6 | +import functools |
6 | 7 | import logging |
7 | 8 | import threading |
8 | 9 | import time |
9 | | -from typing import Awaitable, Callable, Iterable, List, Optional, Union |
| 10 | +from typing import Awaitable, Callable, Iterable, List, Optional, Union, cast |
10 | 11 |
|
11 | 12 | from can.bus import BusABC |
12 | 13 | from can.listener import Listener |
@@ -108,28 +109,33 @@ def stop(self, timeout: float = 5) -> None: |
108 | 109 | listener.stop() |
109 | 110 |
|
110 | 111 | def _rx_thread(self, bus: BusABC) -> None: |
111 | | - try: |
112 | | - while self._running: |
| 112 | + # determine message handling callable early, not inside while loop |
| 113 | + handle_message = cast( |
| 114 | + Callable[[Message], None], |
| 115 | + self._on_message_received |
| 116 | + if self._loop is None |
| 117 | + else functools.partial( |
| 118 | + self._loop.call_soon_threadsafe, self._on_message_received |
| 119 | + ), |
| 120 | + ) |
| 121 | + |
| 122 | + while self._running: |
| 123 | + try: |
113 | 124 | if msg := bus.recv(self.timeout): |
114 | 125 | with self._lock: |
115 | | - if self._loop is not None: |
116 | | - self._loop.call_soon_threadsafe( |
117 | | - self._on_message_received, msg |
118 | | - ) |
119 | | - else: |
120 | | - self._on_message_received(msg) |
121 | | - except Exception as exc: # pylint: disable=broad-except |
122 | | - self.exception = exc |
123 | | - if self._loop is not None: |
124 | | - self._loop.call_soon_threadsafe(self._on_error, exc) |
125 | | - # Raise anyway |
126 | | - raise |
127 | | - elif not self._on_error(exc): |
128 | | - # If it was not handled, raise the exception here |
129 | | - raise |
130 | | - else: |
131 | | - # It was handled, so only log it |
132 | | - logger.info("suppressed exception: %s", exc) |
| 126 | + handle_message(msg) |
| 127 | + except Exception as exc: # pylint: disable=broad-except |
| 128 | + self.exception = exc |
| 129 | + if self._loop is not None: |
| 130 | + self._loop.call_soon_threadsafe(self._on_error, exc) |
| 131 | + # Raise anyway |
| 132 | + raise |
| 133 | + elif not self._on_error(exc): |
| 134 | + # If it was not handled, raise the exception here |
| 135 | + raise |
| 136 | + else: |
| 137 | + # It was handled, so only log it |
| 138 | + logger.debug("suppressed exception: %s", exc) |
133 | 139 |
|
134 | 140 | def _on_message_available(self, bus: BusABC) -> None: |
135 | 141 | if msg := bus.recv(0): |
|
0 commit comments