88import  re 
99import  tempfile 
1010import  time 
11+ from  typing  import  List , Optional , Dict , Tuple , Any , Callable , Union 
1112
1213import  attr 
1314from  pexpect  import  TIMEOUT 
@@ -95,18 +96,18 @@ class QEMUDriver(ConsoleExpectMixin, Driver, PowerProtocol, ConsoleProtocol):
9596        default = None ,
9697        validator = attr .validators .optional (attr .validators .instance_of (str )))
9798
98-     def  __attrs_post_init__ (self ):
99+     def  __attrs_post_init__ (self )  ->   None :
99100        super ().__attrs_post_init__ ()
100-         self .status  =  0 
101-         self .txdelay  =  None 
102-         self ._child  =  None 
103-         self ._tempdir  =  None 
104-         self ._socket  =  None 
105-         self ._clientsocket  =  None 
106-         self ._forwarded_ports  =  {}
101+         self .status :  int  =  0 
102+         self .txdelay :  Optional [ float ]  =  None 
103+         self ._child :  Optional [ subprocess . Popen ]  =  None 
104+         self ._tempdir :  Optional [ str ]  =  None 
105+         self ._socket :  Optional [ socket . socket ]  =  None 
106+         self ._clientsocket :  Optional [ socket . socket ]  =  None 
107+         self ._forwarded_ports :  Dict [ Tuple [ str ,  str ,  int ],  Tuple [ str ,  str ,  int ,  str ,  int ]]  =  {}
107108        atexit .register (self ._atexit )
108109
109-     def  _atexit (self ):
110+     def  _atexit (self )  ->   None :
110111        if  not  self ._child :
111112            return 
112113        self ._child .terminate ()
@@ -116,7 +117,7 @@ def _atexit(self):
116117            self ._child .kill ()
117118            self ._child .communicate (timeout = 1 )
118119
119-     def  get_qemu_version (self , qemu_bin ) :
120+     def  get_qemu_version (self , qemu_bin :  str )  ->   Tuple [ int ,  int ,  int ] :
120121        p  =  subprocess .run ([qemu_bin , "-version" ], stdout = subprocess .PIPE , encoding = "utf-8" )
121122        if  p .returncode  !=  0 :
122123            raise  ExecutionError (f"Unable to get QEMU version. QEMU exited with: { p .returncode }  )
@@ -127,7 +128,7 @@ def get_qemu_version(self, qemu_bin):
127128
128129        return  (int (m .group ('major' )), int (m .group ('minor' )), int (m .group ('micro' )))
129130
130-     def  get_qemu_base_args (self ):
131+     def  get_qemu_base_args (self )  ->   List [ str ] :
131132        """Returns the base command line used for Qemu without the options 
132133        related to QMP. These options can be used to start an interactive 
133134        Qemu manually for debugging tests 
@@ -230,7 +231,7 @@ def get_qemu_base_args(self):
230231
231232        return  cmd 
232233
233-     def  on_activate (self ):
234+     def  on_activate (self )  ->   None :
234235        self ._tempdir  =  tempfile .mkdtemp (prefix = "labgrid-qemu-tmp-" )
235236        sockpath  =  f"{ self ._tempdir }  
236237        self ._socket  =  socket .socket (socket .AF_UNIX , socket .SOCK_STREAM )
@@ -248,7 +249,7 @@ def on_activate(self):
248249        self ._cmd .append ("-serial" )
249250        self ._cmd .append ("chardev:serialsocket" )
250251
251-     def  on_deactivate (self ):
252+     def  on_deactivate (self )  ->   None :
252253        if  self .status :
253254            self .off ()
254255        if  self ._clientsocket :
@@ -259,7 +260,7 @@ def on_deactivate(self):
259260        shutil .rmtree (self ._tempdir )
260261
261262    @step () 
262-     def  on (self , pre_start_hook = None ):
263+     def  on (self , pre_start_hook :  Optional [ Callable [[],  None ]]  =   None )  ->   None :
263264        """Start the QEMU subprocess, accept the unix socket connection, run the 
264265        pre_start_hook if applicable and start the emulator using a QMP Command""" 
265266        if  self .status :
@@ -295,7 +296,7 @@ def on(self, pre_start_hook=None):
295296        self .monitor_command ("cont" )
296297
297298    @step () 
298-     def  off (self ):
299+     def  off (self )  ->   None :
299300        """Stop the emulator using a monitor command and await the exitcode""" 
300301        if  not  self .status :
301302            return 
@@ -306,37 +307,38 @@ def off(self):
306307        self ._child  =  None 
307308        self .status  =  0 
308309
309-     def  cycle (self ):
310+     def  cycle (self )  ->   None :
310311        """Cycle the emulator by restarting it""" 
311312        self .off ()
312313        self .on ()
313314
314315    @step (result = True , args = ['command' , 'arguments' ]) 
315-     def  monitor_command (self , command , arguments = {}):
316+     def  monitor_command (self , command :  str , arguments :  Dict [ str ,  Any ]  =   {})  ->   Any :
316317        """Execute a monitor_command via the QMP""" 
317318        if  not  self .status :
318319            raise  ExecutionError (
319320                "Can't use monitor command on non-running target" )
320321        return  self .qmp .execute (command , arguments )
321322
322-     def  _add_port_forward (self , proto , local_address , local_port , remote_address , remote_port ) :
323+     def  _add_port_forward (self , proto :  str , local_address :  str , local_port :  int , remote_address :  str , remote_port :  int )  ->   None :
323324        self .monitor_command (
324325            "human-monitor-command" ,
325326            {"command-line" : f"hostfwd_add { proto } { local_address } { local_port } { remote_address } { remote_port }  },
326327        )
327328
328-     def  add_port_forward (self , proto , local_address , local_port , remote_address , remote_port ) :
329+     def  add_port_forward (self , proto :  str , local_address :  str , local_port :  int , remote_address :  str , remote_port :  int )  ->   None :
329330        self ._add_port_forward (proto , local_address , local_port , remote_address , remote_port )
330-         self ._forwarded_ports [(proto , local_address , local_port )] =  (proto , local_address , local_port , remote_address , remote_port )
331+         self ._forwarded_ports [(proto , local_address , local_port )] =  (
332+             proto , local_address , local_port , remote_address , remote_port )
331333
332-     def  remove_port_forward (self , proto , local_address , local_port ) :
334+     def  remove_port_forward (self , proto :  str , local_address :  str , local_port :  int )  ->   None :
333335        del  self ._forwarded_ports [(proto , local_address , local_port )]
334336        self .monitor_command (
335337            "human-monitor-command" ,
336338            {"command-line" : f"hostfwd_remove { proto } { local_address } { local_port }  },
337339        )
338340
339-     def  _read (self , size = 1 , timeout = 10 , max_size = None ):
341+     def  _read (self , size :  int   =   1 , timeout :  float   =   10 , max_size :  Optional [ int ]  =   None )  ->   bytes :
340342        ready , _ , _  =  select .select ([self ._clientsocket ], [], [], timeout )
341343        if  ready :
342344            # Collect some more data 
@@ -349,8 +351,8 @@ def _read(self, size=1, timeout=10, max_size=None):
349351            raise  TIMEOUT (f"Timeout of { timeout :.2f}  )
350352        return  res 
351353
352-     def  _write (self , data ) :
354+     def  _write (self , data :  bytes )  ->   int :
353355        return  self ._clientsocket .send (data )
354356
355-     def  __str__ (self ):
357+     def  __str__ (self )  ->   str :
356358        return  f"QemuDriver({ self .target .name }  
0 commit comments