1111from collections .abc import Sequence
1212from fnmatch import fnmatch
1313from io import StringIO
14+ from typing import Union
1415from weakref import WeakKeyDictionary
1516
1617import py
@@ -362,9 +363,9 @@ class RunResult:
362363 :ivar duration: duration in seconds
363364 """
364365
365- def __init__ (self , ret , outlines , errlines , duration ):
366+ def __init__ (self , ret : Union [ int , ExitCode ], outlines , errlines , duration ) -> None :
366367 try :
367- self .ret = pytest .ExitCode (ret )
368+ self .ret = pytest .ExitCode (ret ) # type: Union[int, ExitCode]
368369 except ValueError :
369370 self .ret = ret
370371 self .outlines = outlines
@@ -483,11 +484,7 @@ def __init__(self, request, tmpdir_factory):
483484 self ._sys_modules_snapshot = self .__take_sys_modules_snapshot ()
484485 self .chdir ()
485486 self .request .addfinalizer (self .finalize )
486- method = self .request .config .getoption ("--runpytest" )
487- if method == "inprocess" :
488- self ._runpytest_method = self .runpytest_inprocess
489- elif method == "subprocess" :
490- self ._runpytest_method = self .runpytest_subprocess
487+ self ._method = self .request .config .getoption ("--runpytest" )
491488
492489 mp = self .monkeypatch = MonkeyPatch ()
493490 mp .setenv ("PYTEST_DEBUG_TEMPROOT" , str (self .test_tmproot ))
@@ -835,7 +832,7 @@ def pytest_configure(x, config):
835832 reprec = rec .pop ()
836833 else :
837834
838- class reprec :
835+ class reprec : # type: ignore
839836 pass
840837
841838 reprec .ret = ret
@@ -851,7 +848,7 @@ class reprec:
851848 for finalizer in finalizers :
852849 finalizer ()
853850
854- def runpytest_inprocess (self , * args , ** kwargs ):
851+ def runpytest_inprocess (self , * args , ** kwargs ) -> RunResult :
855852 """Return result of running pytest in-process, providing a similar
856853 interface to what self.runpytest() provides.
857854 """
@@ -866,15 +863,20 @@ def runpytest_inprocess(self, *args, **kwargs):
866863 try :
867864 reprec = self .inline_run (* args , ** kwargs )
868865 except SystemExit as e :
866+ ret = e .args [0 ]
867+ try :
868+ ret = ExitCode (e .args [0 ])
869+ except ValueError :
870+ pass
869871
870- class reprec :
871- ret = e . args [ 0 ]
872+ class reprec : # type: ignore
873+ ret = ret
872874
873875 except Exception :
874876 traceback .print_exc ()
875877
876- class reprec :
877- ret = 3
878+ class reprec : # type: ignore
879+ ret = ExitCode ( 3 )
878880
879881 finally :
880882 out , err = capture .readouterr ()
@@ -885,16 +887,20 @@ class reprec:
885887 res = RunResult (
886888 reprec .ret , out .splitlines (), err .splitlines (), time .time () - now
887889 )
888- res .reprec = reprec
890+ res .reprec = reprec # type: ignore
889891 return res
890892
891- def runpytest (self , * args , ** kwargs ):
893+ def runpytest (self , * args , ** kwargs ) -> RunResult :
892894 """Run pytest inline or in a subprocess, depending on the command line
893895 option "--runpytest" and return a :py:class:`RunResult`.
894896
895897 """
896898 args = self ._ensure_basetemp (args )
897- return self ._runpytest_method (* args , ** kwargs )
899+ if self ._method == "inprocess" :
900+ return self .runpytest_inprocess (* args , ** kwargs )
901+ elif self ._method == "subprocess" :
902+ return self .runpytest_subprocess (* args , ** kwargs )
903+ raise RuntimeError ("Unrecognized runpytest option: {}" .format (self ._method ))
898904
899905 def _ensure_basetemp (self , args ):
900906 args = list (args )
@@ -1051,7 +1057,7 @@ def popen(
10511057
10521058 return popen
10531059
1054- def run (self , * cmdargs , timeout = None , stdin = CLOSE_STDIN ):
1060+ def run (self , * cmdargs , timeout = None , stdin = CLOSE_STDIN ) -> RunResult :
10551061 """Run a command with arguments.
10561062
10571063 Run a process using subprocess.Popen saving the stdout and stderr.
@@ -1069,9 +1075,9 @@ def run(self, *cmdargs, timeout=None, stdin=CLOSE_STDIN):
10691075 """
10701076 __tracebackhide__ = True
10711077
1072- cmdargs = [
1078+ cmdargs = tuple (
10731079 str (arg ) if isinstance (arg , py .path .local ) else arg for arg in cmdargs
1074- ]
1080+ )
10751081 p1 = self .tmpdir .join ("stdout" )
10761082 p2 = self .tmpdir .join ("stderr" )
10771083 print ("running:" , * cmdargs )
@@ -1122,6 +1128,10 @@ def handle_timeout():
11221128 f2 .close ()
11231129 self ._dump_lines (out , sys .stdout )
11241130 self ._dump_lines (err , sys .stderr )
1131+ try :
1132+ ret = ExitCode (ret )
1133+ except ValueError :
1134+ pass
11251135 return RunResult (ret , out , err , time .time () - now )
11261136
11271137 def _dump_lines (self , lines , fp ):
@@ -1134,7 +1144,7 @@ def _dump_lines(self, lines, fp):
11341144 def _getpytestargs (self ):
11351145 return sys .executable , "-mpytest"
11361146
1137- def runpython (self , script ):
1147+ def runpython (self , script ) -> RunResult :
11381148 """Run a python script using sys.executable as interpreter.
11391149
11401150 Returns a :py:class:`RunResult`.
@@ -1146,7 +1156,7 @@ def runpython_c(self, command):
11461156 """Run python -c "command", return a :py:class:`RunResult`."""
11471157 return self .run (sys .executable , "-c" , command )
11481158
1149- def runpytest_subprocess (self , * args , timeout = None ):
1159+ def runpytest_subprocess (self , * args , timeout = None ) -> RunResult :
11501160 """Run pytest as a subprocess with given arguments.
11511161
11521162 Any plugins added to the :py:attr:`plugins` list will be added using the
0 commit comments