Skip to content

Commit 886a3ad

Browse files
committed
pytester: typing
1 parent cbc39dd commit 886a3ad

File tree

2 files changed

+52
-21
lines changed

2 files changed

+52
-21
lines changed

src/_pytest/pytester.py

Lines changed: 31 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
from collections.abc import Sequence
1212
from fnmatch import fnmatch
1313
from io import StringIO
14+
from typing import Union
1415
from weakref import WeakKeyDictionary
1516

1617
import 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

testing/test_pytester.py

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -395,6 +395,27 @@ def test_testdir_subprocess(testdir):
395395
assert testdir.runpytest_subprocess(testfile).ret == 0
396396

397397

398+
def test_testdir_subprocess_via_runpytest_arg(testdir) -> None:
399+
testfile = testdir.makepyfile(
400+
"""
401+
def test_testdir_subprocess(testdir):
402+
import os
403+
testfile = testdir.makepyfile(
404+
\"""
405+
import os
406+
def test_one():
407+
assert {} != os.getpid()
408+
\""".format(os.getpid())
409+
)
410+
assert testdir.runpytest(testfile).ret == 0
411+
"""
412+
)
413+
result = testdir.runpytest_subprocess(
414+
"-p", "pytester", "--runpytest", "subprocess", testfile
415+
)
416+
assert result.ret == 0
417+
418+
398419
def test_unicode_args(testdir):
399420
result = testdir.runpytest("-k", "💩")
400421
assert result.ret == ExitCode.NO_TESTS_COLLECTED

0 commit comments

Comments
 (0)