1717import shlex
1818import subprocess
1919import urllib .parse
20- from typing import Any , Optional
20+ from typing import TYPE_CHECKING , Any , Optional
21+
22+ if TYPE_CHECKING :
23+ import testinfra .host
2124
2225logger = logging .getLogger ("testinfra" )
2326
@@ -117,29 +120,29 @@ def __init__(
117120 self ,
118121 hostname : str ,
119122 sudo : bool = False ,
120- sudo_user : Optional [bool ] = None ,
123+ sudo_user : Optional [str ] = None ,
121124 * args : Any ,
122125 ** kwargs : Any ,
123126 ):
124- self ._encoding = None
125- self ._host = None
127+ self ._encoding : Optional [ str ] = None
128+ self ._host : Optional [ "testinfra.host.Host" ] = None
126129 self .hostname = hostname
127130 self .sudo = sudo
128131 self .sudo_user = sudo_user
129132 super ().__init__ ()
130133
131- def set_host (self , host ) :
134+ def set_host (self , host : "testinfra.host.Host" ) -> None :
132135 self ._host = host
133136
134137 @classmethod
135- def get_connection_type (cls ):
138+ def get_connection_type (cls ) -> str :
136139 """Return the connection backend used as string.
137140
138141 Can be local, paramiko, ssh, docker, salt or ansible
139142 """
140143 return cls .NAME
141144
142- def get_hostname (self ):
145+ def get_hostname (self ) -> str :
143146 """Return the hostname (for testinfra) of the remote or local system
144147
145148
@@ -166,11 +169,11 @@ def test(TestinfraBackend):
166169 """
167170 return self .hostname
168171
169- def get_pytest_id (self ):
172+ def get_pytest_id (self ) -> str :
170173 return self .get_connection_type () + "://" + self .get_hostname ()
171174
172175 @classmethod
173- def get_hosts (cls , host , ** kwargs ) :
176+ def get_hosts (cls , host : str , ** kwargs : Any ) -> list [ str ] :
174177 if host is None :
175178 raise RuntimeError (
176179 "One or more hosts is required with the {} backend" .format (
@@ -180,41 +183,41 @@ def get_hosts(cls, host, **kwargs):
180183 return [host ]
181184
182185 @staticmethod
183- def quote (command , * args ) :
186+ def quote (command : str , * args : str ) -> str :
184187 if args :
185188 return command % tuple (shlex .quote (a ) for a in args ) # noqa: S001
186189 return command
187190
188- def get_sudo_command (self , command , sudo_user ) :
191+ def get_sudo_command (self , command : str , sudo_user : Optional [ str ]) -> str :
189192 if sudo_user is None :
190193 return self .quote ("sudo /bin/sh -c %s" , command )
191194 return self .quote ("sudo -u %s /bin/sh -c %s" , sudo_user , command )
192195
193- def get_command (self , command , * args ) :
196+ def get_command (self , command : str , * args : str ) -> str :
194197 command = self .quote (command , * args )
195198 if self .sudo :
196199 command = self .get_sudo_command (command , self .sudo_user )
197200 return command
198201
199- def run (self , command , * args , ** kwargs ) :
202+ def run (self , command : str , * args : str , ** kwargs : Any ) -> CommandResult :
200203 raise NotImplementedError
201204
202- def run_local (self , command , * args ) :
205+ def run_local (self , command : str , * args : str ) -> CommandResult :
203206 command = self .quote (command , * args )
204- command = self .encode (command )
207+ cmd = self .encode (command )
205208 p = subprocess .Popen (
206- command ,
209+ cmd ,
207210 shell = True ,
208211 stdin = subprocess .PIPE ,
209212 stdout = subprocess .PIPE ,
210213 stderr = subprocess .PIPE ,
211214 )
212215 stdout , stderr = p .communicate ()
213- result = self .result (p .returncode , command , stdout , stderr )
216+ result = self .result (p .returncode , cmd , stdout , stderr )
214217 return result
215218
216219 @staticmethod
217- def parse_hostspec (hostspec ) :
220+ def parse_hostspec (hostspec : str ) -> HostSpec :
218221 name = hostspec
219222 port = None
220223 user = None
@@ -246,14 +249,14 @@ def parse_hostspec(hostspec):
246249 return HostSpec (name , port , user , password )
247250
248251 @staticmethod
249- def parse_containerspec (containerspec ) :
252+ def parse_containerspec (containerspec : str ) -> tuple [ str , Optional [ str ]] :
250253 name = containerspec
251254 user = None
252255 if "@" in name :
253256 user , name = name .split ("@" , 1 )
254257 return name , user
255258
256- def get_encoding (self ):
259+ def get_encoding (self ) -> str :
257260 encoding = None
258261 for python in ("python3" , "python" ):
259262 cmd = self .run (
@@ -274,7 +277,7 @@ def get_encoding(self):
274277 return encoding
275278
276279 @property
277- def encoding (self ):
280+ def encoding (self ) -> str :
278281 if self ._encoding is None :
279282 self ._encoding = self .get_encoding ()
280283 return self ._encoding
0 commit comments