1010import logging
1111import time
1212import os
13- from typing import List , NamedTuple , Optional , Tuple , Sequence , Union
13+ from types import ModuleType
14+ from typing import (
15+ List ,
16+ NamedTuple ,
17+ Optional ,
18+ Tuple ,
19+ Sequence ,
20+ Union ,
21+ Any ,
22+ Dict ,
23+ Callable ,
24+ )
1425
26+ WaitForSingleObject : Optional [Callable [[int , int ], int ]]
27+ INFINITE : Optional [int ]
1528try :
1629 # Try builtin Python 3 Windows API
1730 from _winapi import WaitForSingleObject , INFINITE
1831
1932 HAS_EVENTS = True
2033except ImportError :
21- try :
22- # Try pywin32 package
23- from win32event import WaitForSingleObject , INFINITE
24-
25- HAS_EVENTS = True
26- except ImportError :
27- # Use polling instead
28- HAS_EVENTS = False
34+ WaitForSingleObject , INFINITE = None , None
35+ HAS_EVENTS = False
2936
3037# Import Modules
3138# ==============
3643 deprecated_args_alias ,
3744 time_perfcounter_correlation ,
3845)
39- from can .typechecking import AutoDetectedConfig , CanFilters
46+ from can .typechecking import AutoDetectedConfig , CanFilters , Channel
4047
4148# Define Module Logger
4249# ====================
4855from . import xldefine , xlclass
4956
5057# Import safely Vector API module for Travis tests
51- xldriver = None
58+ xldriver : Optional [ ModuleType ] = None
5259try :
5360 from . import xldriver
5461except Exception as exc :
@@ -74,19 +81,19 @@ def __init__(
7481 can_filters : Optional [CanFilters ] = None ,
7582 poll_interval : float = 0.01 ,
7683 receive_own_messages : bool = False ,
77- bitrate : int = None ,
84+ bitrate : Optional [ int ] = None ,
7885 rx_queue_size : int = 2 ** 14 ,
79- app_name : str = "CANalyzer" ,
80- serial : int = None ,
86+ app_name : Optional [ str ] = "CANalyzer" ,
87+ serial : Optional [ int ] = None ,
8188 fd : bool = False ,
82- data_bitrate : int = None ,
89+ data_bitrate : Optional [ int ] = None ,
8390 sjw_abr : int = 2 ,
8491 tseg1_abr : int = 6 ,
8592 tseg2_abr : int = 3 ,
8693 sjw_dbr : int = 2 ,
8794 tseg1_dbr : int = 6 ,
8895 tseg2_dbr : int = 3 ,
89- ** kwargs ,
96+ ** kwargs : Any ,
9097 ) -> None :
9198 """
9299 :param channel:
@@ -144,16 +151,18 @@ def __init__(
144151
145152 if xldriver is None :
146153 raise CanInterfaceNotImplementedError ("The Vector API has not been loaded" )
154+ self .xldriver = xldriver # keep reference so mypy knows it is not None
147155
148156 self .poll_interval = poll_interval
149157
150- if isinstance (channel , str ): # must be checked before generic Sequence
158+ self .channels : Sequence [int ]
159+ if isinstance (channel , int ):
160+ self .channels = [channel ]
161+ elif isinstance (channel , str ): # must be checked before generic Sequence
151162 # Assume comma separated string of channels
152163 self .channels = [int (ch .strip ()) for ch in channel .split ("," )]
153- elif isinstance (channel , int ):
154- self .channels = [channel ]
155164 elif isinstance (channel , Sequence ):
156- self .channels = channel
165+ self .channels = [ int ( ch ) for ch in channel ]
157166 else :
158167 raise TypeError (
159168 f"Invalid type for channels parameter: { type (channel ).__name__ } "
@@ -185,12 +194,12 @@ def __init__(
185194 "None of the configured channels could be found on the specified hardware."
186195 )
187196
188- xldriver .xlOpenDriver ()
197+ self . xldriver .xlOpenDriver ()
189198 self .port_handle = xlclass .XLportHandle (xldefine .XL_INVALID_PORTHANDLE )
190199 self .mask = 0
191200 self .fd = fd
192201 # Get channels masks
193- self .channel_masks = {}
202+ self .channel_masks : Dict [ Optional [ Channel ], int ] = {}
194203 self .index_to_channel = {}
195204
196205 for channel in self .channels :
@@ -200,7 +209,7 @@ def __init__(
200209 app_name , channel
201210 )
202211 LOG .debug ("Channel index %d found" , channel )
203- idx = xldriver .xlGetChannelIndex (hw_type , hw_index , hw_channel )
212+ idx = self . xldriver .xlGetChannelIndex (hw_type , hw_index , hw_channel )
204213 if idx < 0 :
205214 # Undocumented behavior! See issue #353.
206215 # If hardware is unavailable, this function returns -1.
@@ -224,7 +233,7 @@ def __init__(
224233 if bitrate or fd :
225234 permission_mask .value = self .mask
226235 if fd :
227- xldriver .xlOpenPort (
236+ self . xldriver .xlOpenPort (
228237 self .port_handle ,
229238 self ._app_name ,
230239 self .mask ,
@@ -234,7 +243,7 @@ def __init__(
234243 xldefine .XL_BusTypes .XL_BUS_TYPE_CAN ,
235244 )
236245 else :
237- xldriver .xlOpenPort (
246+ self . xldriver .xlOpenPort (
238247 self .port_handle ,
239248 self ._app_name ,
240249 self .mask ,
@@ -267,7 +276,7 @@ def __init__(
267276 self .canFdConf .tseg1Dbr = int (tseg1_dbr )
268277 self .canFdConf .tseg2Dbr = int (tseg2_dbr )
269278
270- xldriver .xlCanFdSetConfiguration (
279+ self . xldriver .xlCanFdSetConfiguration (
271280 self .port_handle , self .mask , self .canFdConf
272281 )
273282 LOG .info (
@@ -289,7 +298,7 @@ def __init__(
289298 )
290299 else :
291300 if bitrate :
292- xldriver .xlCanSetChannelBitrate (
301+ self . xldriver .xlCanSetChannelBitrate (
293302 self .port_handle , permission_mask , bitrate
294303 )
295304 LOG .info ("SetChannelBitrate: baudr.=%u" , bitrate )
@@ -298,16 +307,16 @@ def __init__(
298307
299308 # Enable/disable TX receipts
300309 tx_receipts = 1 if receive_own_messages else 0
301- xldriver .xlCanSetChannelMode (self .port_handle , self .mask , tx_receipts , 0 )
310+ self . xldriver .xlCanSetChannelMode (self .port_handle , self .mask , tx_receipts , 0 )
302311
303312 if HAS_EVENTS :
304313 self .event_handle = xlclass .XLhandle ()
305- xldriver .xlSetNotification (self .port_handle , self .event_handle , 1 )
314+ self . xldriver .xlSetNotification (self .port_handle , self .event_handle , 1 )
306315 else :
307316 LOG .info ("Install pywin32 to avoid polling" )
308317
309318 try :
310- xldriver .xlActivateChannel (
319+ self . xldriver .xlActivateChannel (
311320 self .port_handle , self .mask , xldefine .XL_BusTypes .XL_BUS_TYPE_CAN , 0
312321 )
313322 except VectorOperationError as error :
@@ -320,17 +329,17 @@ def __init__(
320329 if time .get_clock_info ("time" ).resolution > 1e-5 :
321330 ts , perfcounter = time_perfcounter_correlation ()
322331 try :
323- xldriver .xlGetSyncTime (self .port_handle , offset )
332+ self . xldriver .xlGetSyncTime (self .port_handle , offset )
324333 except VectorInitializationError :
325- xldriver .xlGetChannelTime (self .port_handle , self .mask , offset )
334+ self . xldriver .xlGetChannelTime (self .port_handle , self .mask , offset )
326335 current_perfcounter = time .perf_counter ()
327336 now = ts + (current_perfcounter - perfcounter )
328337 self ._time_offset = now - offset .value * 1e-9
329338 else :
330339 try :
331- xldriver .xlGetSyncTime (self .port_handle , offset )
340+ self . xldriver .xlGetSyncTime (self .port_handle , offset )
332341 except VectorInitializationError :
333- xldriver .xlGetChannelTime (self .port_handle , self .mask , offset )
342+ self . xldriver .xlGetChannelTime (self .port_handle , self .mask , offset )
334343 self ._time_offset = time .time () - offset .value * 1e-9
335344
336345 except VectorInitializationError :
@@ -339,7 +348,7 @@ def __init__(
339348 self ._is_filtered = False
340349 super ().__init__ (channel = channel , can_filters = can_filters , ** kwargs )
341350
342- def _apply_filters (self , filters ) -> None :
351+ def _apply_filters (self , filters : Optional [ CanFilters ] ) -> None :
343352 if filters :
344353 # Only up to one filter per ID type allowed
345354 if len (filters ) == 1 or (
@@ -348,7 +357,7 @@ def _apply_filters(self, filters) -> None:
348357 ):
349358 try :
350359 for can_filter in filters :
351- xldriver .xlCanSetChannelAcceptance (
360+ self . xldriver .xlCanSetChannelAcceptance (
352361 self .port_handle ,
353362 self .mask ,
354363 can_filter ["can_id" ],
@@ -370,14 +379,14 @@ def _apply_filters(self, filters) -> None:
370379 # fallback: reset filters
371380 self ._is_filtered = False
372381 try :
373- xldriver .xlCanSetChannelAcceptance (
382+ self . xldriver .xlCanSetChannelAcceptance (
374383 self .port_handle ,
375384 self .mask ,
376385 0x0 ,
377386 0x0 ,
378387 xldefine .XL_AcceptanceFilter .XL_CAN_EXT ,
379388 )
380- xldriver .xlCanSetChannelAcceptance (
389+ self . xldriver .xlCanSetChannelAcceptance (
381390 self .port_handle ,
382391 self .mask ,
383392 0x0 ,
@@ -417,14 +426,14 @@ def _recv_internal(
417426 else :
418427 time_left = end_time - time .time ()
419428 time_left_ms = max (0 , int (time_left * 1000 ))
420- WaitForSingleObject (self .event_handle .value , time_left_ms )
429+ WaitForSingleObject (self .event_handle .value , time_left_ms ) # type: ignore
421430 else :
422431 # Wait a short time until we try again
423432 time .sleep (self .poll_interval )
424433
425434 def _recv_canfd (self ) -> Optional [Message ]:
426435 xl_can_rx_event = xlclass .XLcanRxEvent ()
427- xldriver .xlCanReceive (self .port_handle , xl_can_rx_event )
436+ self . xldriver .xlCanReceive (self .port_handle , xl_can_rx_event )
428437
429438 if xl_can_rx_event .tag == xldefine .XL_CANFD_RX_EventTags .XL_CAN_EV_TAG_RX_OK :
430439 is_rx = True
@@ -470,7 +479,7 @@ def _recv_canfd(self) -> Optional[Message]:
470479 def _recv_can (self ) -> Optional [Message ]:
471480 xl_event = xlclass .XLevent ()
472481 event_count = ctypes .c_uint (1 )
473- xldriver .xlReceive (self .port_handle , event_count , xl_event )
482+ self . xldriver .xlReceive (self .port_handle , event_count , xl_event )
474483
475484 if xl_event .tag != xldefine .XL_EventTags .XL_RECEIVE_MSG :
476485 self .handle_can_event (xl_event )
@@ -523,7 +532,7 @@ def handle_canfd_event(self, event: xlclass.XLcanRxEvent) -> None:
523532 `XL_CAN_EV_TAG_TX_ERROR`, `XL_TIMER` or `XL_CAN_EV_TAG_CHIP_STATE` tag.
524533 """
525534
526- def send (self , msg : Message , timeout : Optional [float ] = None ):
535+ def send (self , msg : Message , timeout : Optional [float ] = None ) -> None :
527536 self ._send_sequence ([msg ])
528537
529538 def _send_sequence (self , msgs : Sequence [Message ]) -> int :
@@ -548,7 +557,9 @@ def _send_can_msg_sequence(self, msgs: Sequence[Message]) -> int:
548557 * map (self ._build_xl_event , msgs )
549558 )
550559
551- xldriver .xlCanTransmit (self .port_handle , mask , message_count , xl_event_array )
560+ self .xldriver .xlCanTransmit (
561+ self .port_handle , mask , message_count , xl_event_array
562+ )
552563 return message_count .value
553564
554565 @staticmethod
@@ -580,7 +591,7 @@ def _send_can_fd_msg_sequence(self, msgs: Sequence[Message]) -> int:
580591 )
581592
582593 msg_count_sent = ctypes .c_uint (0 )
583- xldriver .xlCanTransmitEx (
594+ self . xldriver .xlCanTransmitEx (
584595 self .port_handle , mask , message_count , msg_count_sent , xl_can_tx_event_array
585596 )
586597 return msg_count_sent .value
@@ -611,17 +622,17 @@ def _build_xl_can_tx_event(msg: Message) -> xlclass.XLcanTxEvent:
611622 return xl_can_tx_event
612623
613624 def flush_tx_buffer (self ) -> None :
614- xldriver .xlCanFlushTransmitQueue (self .port_handle , self .mask )
625+ self . xldriver .xlCanFlushTransmitQueue (self .port_handle , self .mask )
615626
616627 def shutdown (self ) -> None :
617628 super ().shutdown ()
618- xldriver .xlDeactivateChannel (self .port_handle , self .mask )
619- xldriver .xlClosePort (self .port_handle )
620- xldriver .xlCloseDriver ()
629+ self . xldriver .xlDeactivateChannel (self .port_handle , self .mask )
630+ self . xldriver .xlClosePort (self .port_handle )
631+ self . xldriver .xlCloseDriver ()
621632
622633 def reset (self ) -> None :
623- xldriver .xlDeactivateChannel (self .port_handle , self .mask )
624- xldriver .xlActivateChannel (
634+ self . xldriver .xlDeactivateChannel (self .port_handle , self .mask )
635+ self . xldriver .xlActivateChannel (
625636 self .port_handle , self .mask , xldefine .XL_BusTypes .XL_BUS_TYPE_CAN , 0
626637 )
627638
@@ -657,7 +668,7 @@ def _detect_available_configs() -> List[AutoDetectedConfig]:
657668 "vector_channel_config" : channel_config ,
658669 }
659670 )
660- return configs
671+ return configs # type: ignore
661672
662673 @staticmethod
663674 def popup_vector_hw_configuration (wait_for_finish : int = 0 ) -> None :
@@ -666,6 +677,9 @@ def popup_vector_hw_configuration(wait_for_finish: int = 0) -> None:
666677 :param wait_for_finish:
667678 Time to wait for user input in milliseconds.
668679 """
680+ if xldriver is None :
681+ raise CanInterfaceNotImplementedError ("The Vector API has not been loaded" )
682+
669683 xldriver .xlPopupHwConfig (ctypes .c_char_p (), ctypes .c_uint (wait_for_finish ))
670684
671685 @staticmethod
@@ -685,14 +699,17 @@ def get_application_config(
685699 :raises can.interfaces.vector.VectorInitializationError:
686700 If the application name does not exist in the Vector hardware configuration.
687701 """
702+ if xldriver is None :
703+ raise CanInterfaceNotImplementedError ("The Vector API has not been loaded" )
704+
688705 hw_type = ctypes .c_uint ()
689706 hw_index = ctypes .c_uint ()
690707 hw_channel = ctypes .c_uint ()
691- app_channel = ctypes .c_uint (app_channel )
708+ _app_channel = ctypes .c_uint (app_channel )
692709
693710 xldriver .xlGetApplConfig (
694711 app_name .encode (),
695- app_channel ,
712+ _app_channel ,
696713 hw_type ,
697714 hw_index ,
698715 hw_channel ,
@@ -707,7 +724,7 @@ def set_application_config(
707724 hw_type : xldefine .XL_HardwareType ,
708725 hw_index : int ,
709726 hw_channel : int ,
710- ** kwargs ,
727+ ** kwargs : Any ,
711728 ) -> None :
712729 """Modify the application settings in Vector Hardware Configuration.
713730
@@ -737,6 +754,9 @@ def set_application_config(
737754 :raises can.interfaces.vector.VectorInitializationError:
738755 If the application name does not exist in the Vector hardware configuration.
739756 """
757+ if xldriver is None :
758+ raise CanInterfaceNotImplementedError ("The Vector API has not been loaded" )
759+
740760 xldriver .xlSetApplConfig (
741761 app_name .encode (),
742762 app_channel ,
@@ -758,7 +778,7 @@ def set_timer_rate(self, timer_rate_ms: int) -> None:
758778 the timer events.
759779 """
760780 timer_rate_10us = timer_rate_ms * 100
761- xldriver .xlSetTimerRate (self .port_handle , timer_rate_10us )
781+ self . xldriver .xlSetTimerRate (self .port_handle , timer_rate_10us )
762782
763783
764784class VectorChannelConfig (NamedTuple ):
0 commit comments