11from contextlib import nullcontext
22from threading import RLock
3- from typing import Any
4-
5- from can import typechecking
6- from can .bus import BusABC , BusState , CanProtocol
7- from can .message import Message
3+ from typing import TYPE_CHECKING , Any , cast
84
5+ from . import typechecking
6+ from .bus import BusState , CanProtocol
97from .interface import Bus
8+ from .message import Message
9+
10+ if TYPE_CHECKING :
11+ from .bus import BusABC
1012
1113try :
1214 # Only raise an exception on instantiation but allow module
1517
1618 import_exc = None
1719except ImportError as exc :
18- ObjectProxy = object
20+ ObjectProxy = None # type: ignore[misc,assignment]
1921 import_exc = exc
2022
2123
22- class ThreadSafeBus (ObjectProxy ): # pylint: disable=abstract-method
24+ class ThreadSafeBus (
25+ ObjectProxy
26+ ): # pylint: disable=abstract-method # type: ignore[assignment]
2327 """
2428 Contains a thread safe :class:`can.BusABC` implementation that
2529 wraps around an existing interface instance. All public methods
@@ -36,8 +40,6 @@ class ThreadSafeBus(ObjectProxy): # pylint: disable=abstract-method
3640 instead of :meth:`~can.BusABC.recv` directly.
3741 """
3842
39- __wrapped__ : BusABC
40-
4143 def __init__ (
4244 self ,
4345 channel : typechecking .Channel | None = None ,
@@ -59,58 +61,61 @@ def __init__(
5961 )
6062 )
6163
64+ # store wrapped bus as a proxy-local attribute. Name it with the
65+ # `_self_` prefix so wrapt won't forward it onto the wrapped object.
66+ self ._self_wrapped = cast (
67+ "BusABC" , object .__getattribute__ (self , "__wrapped__" )
68+ )
69+
6270 # now, BusABC.send_periodic() does not need a lock anymore, but the
6371 # implementation still requires a context manager
64- self .__wrapped__ ._lock_send_periodic = nullcontext () # type: ignore[assignment]
72+ self ._self_wrapped ._lock_send_periodic = nullcontext () # type: ignore[assignment]
6573
6674 # init locks for sending and receiving separately
67- self ._lock_send = RLock ()
68- self ._lock_recv = RLock ()
75+ self ._self_lock_send = RLock ()
76+ self ._self_lock_recv = RLock ()
6977
7078 def recv (self , timeout : float | None = None ) -> Message | None :
71- with self ._lock_recv :
72- return self .__wrapped__ .recv (timeout = timeout )
79+ with self ._self_lock_recv :
80+ return self ._self_wrapped .recv (timeout = timeout )
7381
7482 def send (self , msg : Message , timeout : float | None = None ) -> None :
75- with self ._lock_send :
76- return self .__wrapped__ .send (msg = msg , timeout = timeout )
77-
78- # send_periodic does not need a lock, since the underlying
79- # `send` method is already synchronized
83+ with self ._self_lock_send :
84+ return self ._self_wrapped .send (msg = msg , timeout = timeout )
8085
8186 @property
8287 def filters (self ) -> typechecking .CanFilters | None :
83- with self ._lock_recv :
84- return self .__wrapped__ .filters
88+ with self ._self_lock_recv :
89+ return self ._self_wrapped .filters
8590
8691 @filters .setter
8792 def filters (self , filters : typechecking .CanFilters | None ) -> None :
88- with self ._lock_recv :
89- self .__wrapped__ .filters = filters
93+ with self ._self_lock_recv :
94+ self ._self_wrapped .filters = filters
9095
9196 def set_filters (self , filters : typechecking .CanFilters | None = None ) -> None :
92- with self ._lock_recv :
93- return self .__wrapped__ .set_filters (filters = filters )
97+ with self ._self_lock_recv :
98+ return self ._self_wrapped .set_filters (filters = filters )
9499
95100 def flush_tx_buffer (self ) -> None :
96- with self ._lock_send :
97- return self .__wrapped__ .flush_tx_buffer ()
101+ with self ._self_lock_send :
102+ return self ._self_wrapped .flush_tx_buffer ()
98103
99104 def shutdown (self ) -> None :
100- with self ._lock_send , self ._lock_recv :
101- return self .__wrapped__ .shutdown ()
105+ with self ._self_lock_send , self ._self_lock_recv :
106+ return self ._self_wrapped .shutdown ()
102107
103108 @property
104109 def state (self ) -> BusState :
105- with self ._lock_send , self ._lock_recv :
106- return self .__wrapped__ .state
110+ with self ._self_lock_send , self ._self_lock_recv :
111+ return self ._self_wrapped .state
107112
108113 @state .setter
109114 def state (self , new_state : BusState ) -> None :
110- with self ._lock_send , self ._lock_recv :
111- self .__wrapped__ .state = new_state
115+ with self ._self_lock_send , self ._self_lock_recv :
116+ self ._self_wrapped .state = new_state
112117
113118 @property
114119 def protocol (self ) -> CanProtocol :
115- with self ._lock_send , self ._lock_recv :
116- return self .__wrapped__ .protocol
120+ with self ._self_lock_send , self ._self_lock_recv :
121+ return self ._self_wrapped .protocol
0 commit comments