@@ -173,12 +173,26 @@ def check_output(cmd, **popen_args):
173
173
return output .decode ('utf-8' )
174
174
175
175
176
- def try_to_run (cmd ):
176
+ def try_to_run (cmd , shell = True ):
177
177
try :
178
- return check_output (cmd , shell = True )
178
+ return check_output (cmd , shell = shell )
179
179
except subprocess .CalledProcessError as e :
180
180
write (' Error running `%s`: %s' % (cmd , str (getattr (e , 'output' , str (e )))))
181
181
182
+ def run_python_coverage (args ):
183
+ """Run the Python coverage tool
184
+
185
+ If it's importable in this Python, launch it using 'python -m'.
186
+ Otherwise, look it up on PATH like any other command.
187
+ """
188
+ try :
189
+ import coverage
190
+ except ImportError :
191
+ # Coverage is not installed on this Python. Hope it's on PATH.
192
+ try_to_run (['coverage' ] + args , shell = False )
193
+ else :
194
+ # Coverage is installed on this Python. Run it as a module.
195
+ try_to_run ([sys .executable , '-m' , 'coverage' ] + args , shell = False )
182
196
183
197
def remove_non_ascii (data ):
184
198
try :
@@ -666,12 +680,12 @@ def main(*argv, **kwargs):
666
680
# The `-a` option is mandatory here. If we
667
681
# have a `.coverage` in the current directory, calling
668
682
# without the option would delete the previous data
669
- try_to_run ( 'coverage combine -a' )
683
+ run_python_coverage ([ ' combine' , ' -a'] )
670
684
671
685
if os .path .exists (opj (os .getcwd (), '.coverage' )) and not os .path .exists (opj (os .getcwd (), 'coverage.xml' )):
672
686
write (' Generating coverage xml reports for Python' )
673
687
# using `-i` to ignore "No source for code" error
674
- try_to_run ( 'coverage xml -i' )
688
+ run_python_coverage ([ ' xml' , ' -i'] )
675
689
reports .append (read (opj (os .getcwd (), 'coverage.xml' )))
676
690
677
691
reports = list (filter (bool , reports ))
0 commit comments