1212import os
1313import struct
1414import sys
15- import types
15+
16+ from importlib .machinery import ModuleSpec
17+ from types import CodeType , ModuleType
18+ from typing import Any , List , Optional , Tuple
1619
1720from coverage import env
1821from coverage .exceptions import CoverageException , _ExceptionDuringRun , NoCode , NoSource
@@ -30,11 +33,13 @@ class DummyLoader:
3033
3134 Currently only implements the .fullname attribute
3235 """
33- def __init__ (self , fullname , * _args ) :
36+ def __init__ (self , fullname : str , * _args : Any ) -> None :
3437 self .fullname = fullname
3538
3639
37- def find_module (modulename ):
40+ def find_module (
41+ modulename : str ,
42+ ) -> Tuple [Optional [str ], str , ModuleSpec ]:
3843 """Find the module named `modulename`.
3944
4045 Returns the file path of the module, the name of the enclosing
@@ -68,18 +73,23 @@ class PyRunner:
6873 This is meant to emulate real Python execution as closely as possible.
6974
7075 """
71- def __init__ (self , args , as_module = False ):
76+ def __init__ (self , args : List [ str ] , as_module : bool = False ) -> None :
7277 self .args = args
7378 self .as_module = as_module
7479
7580 self .arg0 = args [0 ]
76- self .package = self .modulename = self .pathname = self .loader = self .spec = None
81+ self .package : Optional [str ] = None
82+ self .modulename : Optional [str ] = None
83+ self .pathname : Optional [str ] = None
84+ self .loader : Optional [DummyLoader ] = None
85+ self .spec : Optional [ModuleSpec ] = None
7786
78- def prepare (self ):
87+ def prepare (self ) -> None :
7988 """Set sys.path properly.
8089
8190 This needs to happen before any importing, and without importing anything.
8291 """
92+ path0 : Optional [str ]
8393 if self .as_module :
8494 path0 = os .getcwd ()
8595 elif os .path .isdir (self .arg0 ):
@@ -113,7 +123,7 @@ def prepare(self):
113123 if path0 is not None :
114124 sys .path [0 ] = python_reported_file (path0 )
115125
116- def _prepare2 (self ):
126+ def _prepare2 (self ) -> None :
117127 """Do more preparation to run Python code.
118128
119129 Includes finding the module to run and adjusting sys.argv[0].
@@ -126,6 +136,7 @@ def _prepare2(self):
126136 if self .spec is not None :
127137 self .modulename = self .spec .name
128138 self .loader = DummyLoader (self .modulename )
139+ assert pathname is not None
129140 self .pathname = os .path .abspath (pathname )
130141 self .args [0 ] = self .arg0 = self .pathname
131142 elif os .path .isdir (self .arg0 ):
@@ -155,25 +166,25 @@ def _prepare2(self):
155166
156167 self .arg0 = python_reported_file (self .arg0 )
157168
158- def run (self ):
169+ def run (self ) -> None :
159170 """Run the Python code!"""
160171
161172 self ._prepare2 ()
162173
163174 # Create a module to serve as __main__
164- main_mod = types . ModuleType ('__main__' )
175+ main_mod = ModuleType ('__main__' )
165176
166177 from_pyc = self .arg0 .endswith ((".pyc" , ".pyo" ))
167178 main_mod .__file__ = self .arg0
168179 if from_pyc :
169180 main_mod .__file__ = main_mod .__file__ [:- 1 ]
170181 if self .package is not None :
171182 main_mod .__package__ = self .package
172- main_mod .__loader__ = self .loader
183+ main_mod .__loader__ = self .loader # type: ignore[assignment]
173184 if self .spec is not None :
174185 main_mod .__spec__ = self .spec
175186
176- main_mod .__builtins__ = sys .modules ['builtins' ]
187+ main_mod .__builtins__ = sys .modules ['builtins' ] # type: ignore[attr-defined]
177188
178189 sys .modules ['__main__' ] = main_mod
179190
@@ -209,6 +220,9 @@ def run(self):
209220 # so that the coverage.py code doesn't appear in the final printed
210221 # traceback.
211222 typ , err , tb = sys .exc_info ()
223+ assert typ is not None
224+ assert err is not None
225+ assert tb is not None
212226
213227 # PyPy3 weirdness. If I don't access __context__, then somehow it
214228 # is non-None when the exception is reported at the upper layer,
@@ -218,6 +232,7 @@ def run(self):
218232
219233 # Call the excepthook.
220234 try :
235+ assert err .__traceback__ is not None
221236 err .__traceback__ = err .__traceback__ .tb_next
222237 sys .excepthook (typ , err , tb .tb_next )
223238 except SystemExit : # pylint: disable=try-except-raise
@@ -227,7 +242,11 @@ def run(self):
227242 # shenanigans is kind of involved.
228243 sys .stderr .write ("Error in sys.excepthook:\n " )
229244 typ2 , err2 , tb2 = sys .exc_info ()
245+ assert typ2 is not None
246+ assert err2 is not None
247+ assert tb2 is not None
230248 err2 .__suppress_context__ = True
249+ assert err2 .__traceback__ is not None
231250 err2 .__traceback__ = err2 .__traceback__ .tb_next
232251 sys .__excepthook__ (typ2 , err2 , tb2 .tb_next )
233252 sys .stderr .write ("\n Original exception was:\n " )
@@ -238,7 +257,7 @@ def run(self):
238257 os .chdir (cwd )
239258
240259
241- def run_python_module (args ) :
260+ def run_python_module (args : List [ str ]) -> None :
242261 """Run a Python module, as though with ``python -m name args...``.
243262
244263 `args` is the argument array to present as sys.argv, including the first
@@ -252,7 +271,7 @@ def run_python_module(args):
252271 runner .run ()
253272
254273
255- def run_python_file (args ) :
274+ def run_python_file (args : List [ str ]) -> None :
256275 """Run a Python file as if it were the main program on the command line.
257276
258277 `args` is the argument array to present as sys.argv, including the first
@@ -267,18 +286,18 @@ def run_python_file(args):
267286 runner .run ()
268287
269288
270- def make_code_from_py (filename ) :
289+ def make_code_from_py (filename : str ) -> CodeType :
271290 """Get source from `filename` and make a code object of it."""
272291 # Open the source file.
273292 try :
274293 source = get_python_source (filename )
275294 except (OSError , NoSource ) as exc :
276295 raise NoSource (f"No file to run: '{ filename } '" ) from exc
277296
278- return compile (source , filename , "exec" , dont_inherit = True )
297+ return compile (source , filename , "exec" , dont_inherit = True ) # type: ignore[no-any-return]
279298
280299
281- def make_code_from_pyc (filename ) :
300+ def make_code_from_pyc (filename : str ) -> CodeType :
282301 """Get a code object from a .pyc file."""
283302 try :
284303 fpyc = open (filename , "rb" )
@@ -303,5 +322,6 @@ def make_code_from_pyc(filename):
303322
304323 # The rest of the file is the code object we want.
305324 code = marshal .load (fpyc )
325+ assert isinstance (code , CodeType )
306326
307327 return code
0 commit comments