pytester: typing
This commit is contained in:
		
							parent
							
								
									cbc39dd86e
								
							
						
					
					
						commit
						886a3ad609
					
				| 
						 | 
					@ -11,6 +11,7 @@ import traceback
 | 
				
			||||||
from collections.abc import Sequence
 | 
					from collections.abc import Sequence
 | 
				
			||||||
from fnmatch import fnmatch
 | 
					from fnmatch import fnmatch
 | 
				
			||||||
from io import StringIO
 | 
					from io import StringIO
 | 
				
			||||||
 | 
					from typing import Union
 | 
				
			||||||
from weakref import WeakKeyDictionary
 | 
					from weakref import WeakKeyDictionary
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import py
 | 
					import py
 | 
				
			||||||
| 
						 | 
					@ -362,9 +363,9 @@ class RunResult:
 | 
				
			||||||
    :ivar duration: duration in seconds
 | 
					    :ivar duration: duration in seconds
 | 
				
			||||||
    """
 | 
					    """
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def __init__(self, ret, outlines, errlines, duration):
 | 
					    def __init__(self, ret: Union[int, ExitCode], outlines, errlines, duration) -> None:
 | 
				
			||||||
        try:
 | 
					        try:
 | 
				
			||||||
            self.ret = pytest.ExitCode(ret)
 | 
					            self.ret = pytest.ExitCode(ret)  # type: Union[int, ExitCode]
 | 
				
			||||||
        except ValueError:
 | 
					        except ValueError:
 | 
				
			||||||
            self.ret = ret
 | 
					            self.ret = ret
 | 
				
			||||||
        self.outlines = outlines
 | 
					        self.outlines = outlines
 | 
				
			||||||
| 
						 | 
					@ -483,11 +484,7 @@ class Testdir:
 | 
				
			||||||
        self._sys_modules_snapshot = self.__take_sys_modules_snapshot()
 | 
					        self._sys_modules_snapshot = self.__take_sys_modules_snapshot()
 | 
				
			||||||
        self.chdir()
 | 
					        self.chdir()
 | 
				
			||||||
        self.request.addfinalizer(self.finalize)
 | 
					        self.request.addfinalizer(self.finalize)
 | 
				
			||||||
        method = self.request.config.getoption("--runpytest")
 | 
					        self._method = self.request.config.getoption("--runpytest")
 | 
				
			||||||
        if method == "inprocess":
 | 
					 | 
				
			||||||
            self._runpytest_method = self.runpytest_inprocess
 | 
					 | 
				
			||||||
        elif method == "subprocess":
 | 
					 | 
				
			||||||
            self._runpytest_method = self.runpytest_subprocess
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
        mp = self.monkeypatch = MonkeyPatch()
 | 
					        mp = self.monkeypatch = MonkeyPatch()
 | 
				
			||||||
        mp.setenv("PYTEST_DEBUG_TEMPROOT", str(self.test_tmproot))
 | 
					        mp.setenv("PYTEST_DEBUG_TEMPROOT", str(self.test_tmproot))
 | 
				
			||||||
| 
						 | 
					@ -835,7 +832,7 @@ class Testdir:
 | 
				
			||||||
                reprec = rec.pop()
 | 
					                reprec = rec.pop()
 | 
				
			||||||
            else:
 | 
					            else:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                class reprec:
 | 
					                class reprec:  # type: ignore
 | 
				
			||||||
                    pass
 | 
					                    pass
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            reprec.ret = ret
 | 
					            reprec.ret = ret
 | 
				
			||||||
| 
						 | 
					@ -851,7 +848,7 @@ class Testdir:
 | 
				
			||||||
            for finalizer in finalizers:
 | 
					            for finalizer in finalizers:
 | 
				
			||||||
                finalizer()
 | 
					                finalizer()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def runpytest_inprocess(self, *args, **kwargs):
 | 
					    def runpytest_inprocess(self, *args, **kwargs) -> RunResult:
 | 
				
			||||||
        """Return result of running pytest in-process, providing a similar
 | 
					        """Return result of running pytest in-process, providing a similar
 | 
				
			||||||
        interface to what self.runpytest() provides.
 | 
					        interface to what self.runpytest() provides.
 | 
				
			||||||
        """
 | 
					        """
 | 
				
			||||||
| 
						 | 
					@ -866,15 +863,20 @@ class Testdir:
 | 
				
			||||||
            try:
 | 
					            try:
 | 
				
			||||||
                reprec = self.inline_run(*args, **kwargs)
 | 
					                reprec = self.inline_run(*args, **kwargs)
 | 
				
			||||||
            except SystemExit as e:
 | 
					            except SystemExit as e:
 | 
				
			||||||
 | 
					                ret = e.args[0]
 | 
				
			||||||
 | 
					                try:
 | 
				
			||||||
 | 
					                    ret = ExitCode(e.args[0])
 | 
				
			||||||
 | 
					                except ValueError:
 | 
				
			||||||
 | 
					                    pass
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                class reprec:
 | 
					                class reprec:  # type: ignore
 | 
				
			||||||
                    ret = e.args[0]
 | 
					                    ret = ret
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            except Exception:
 | 
					            except Exception:
 | 
				
			||||||
                traceback.print_exc()
 | 
					                traceback.print_exc()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                class reprec:
 | 
					                class reprec:  # type: ignore
 | 
				
			||||||
                    ret = 3
 | 
					                    ret = ExitCode(3)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        finally:
 | 
					        finally:
 | 
				
			||||||
            out, err = capture.readouterr()
 | 
					            out, err = capture.readouterr()
 | 
				
			||||||
| 
						 | 
					@ -885,16 +887,20 @@ class Testdir:
 | 
				
			||||||
        res = RunResult(
 | 
					        res = RunResult(
 | 
				
			||||||
            reprec.ret, out.splitlines(), err.splitlines(), time.time() - now
 | 
					            reprec.ret, out.splitlines(), err.splitlines(), time.time() - now
 | 
				
			||||||
        )
 | 
					        )
 | 
				
			||||||
        res.reprec = reprec
 | 
					        res.reprec = reprec  # type: ignore
 | 
				
			||||||
        return res
 | 
					        return res
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def runpytest(self, *args, **kwargs):
 | 
					    def runpytest(self, *args, **kwargs) -> RunResult:
 | 
				
			||||||
        """Run pytest inline or in a subprocess, depending on the command line
 | 
					        """Run pytest inline or in a subprocess, depending on the command line
 | 
				
			||||||
        option "--runpytest" and return a :py:class:`RunResult`.
 | 
					        option "--runpytest" and return a :py:class:`RunResult`.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        """
 | 
					        """
 | 
				
			||||||
        args = self._ensure_basetemp(args)
 | 
					        args = self._ensure_basetemp(args)
 | 
				
			||||||
        return self._runpytest_method(*args, **kwargs)
 | 
					        if self._method == "inprocess":
 | 
				
			||||||
 | 
					            return self.runpytest_inprocess(*args, **kwargs)
 | 
				
			||||||
 | 
					        elif self._method == "subprocess":
 | 
				
			||||||
 | 
					            return self.runpytest_subprocess(*args, **kwargs)
 | 
				
			||||||
 | 
					        raise RuntimeError("Unrecognized runpytest option: {}".format(self._method))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def _ensure_basetemp(self, args):
 | 
					    def _ensure_basetemp(self, args):
 | 
				
			||||||
        args = list(args)
 | 
					        args = list(args)
 | 
				
			||||||
| 
						 | 
					@ -1051,7 +1057,7 @@ class Testdir:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        return popen
 | 
					        return popen
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def run(self, *cmdargs, timeout=None, stdin=CLOSE_STDIN):
 | 
					    def run(self, *cmdargs, timeout=None, stdin=CLOSE_STDIN) -> RunResult:
 | 
				
			||||||
        """Run a command with arguments.
 | 
					        """Run a command with arguments.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        Run a process using subprocess.Popen saving the stdout and stderr.
 | 
					        Run a process using subprocess.Popen saving the stdout and stderr.
 | 
				
			||||||
| 
						 | 
					@ -1069,9 +1075,9 @@ class Testdir:
 | 
				
			||||||
        """
 | 
					        """
 | 
				
			||||||
        __tracebackhide__ = True
 | 
					        __tracebackhide__ = True
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        cmdargs = [
 | 
					        cmdargs = tuple(
 | 
				
			||||||
            str(arg) if isinstance(arg, py.path.local) else arg for arg in cmdargs
 | 
					            str(arg) if isinstance(arg, py.path.local) else arg for arg in cmdargs
 | 
				
			||||||
        ]
 | 
					        )
 | 
				
			||||||
        p1 = self.tmpdir.join("stdout")
 | 
					        p1 = self.tmpdir.join("stdout")
 | 
				
			||||||
        p2 = self.tmpdir.join("stderr")
 | 
					        p2 = self.tmpdir.join("stderr")
 | 
				
			||||||
        print("running:", *cmdargs)
 | 
					        print("running:", *cmdargs)
 | 
				
			||||||
| 
						 | 
					@ -1122,6 +1128,10 @@ class Testdir:
 | 
				
			||||||
            f2.close()
 | 
					            f2.close()
 | 
				
			||||||
        self._dump_lines(out, sys.stdout)
 | 
					        self._dump_lines(out, sys.stdout)
 | 
				
			||||||
        self._dump_lines(err, sys.stderr)
 | 
					        self._dump_lines(err, sys.stderr)
 | 
				
			||||||
 | 
					        try:
 | 
				
			||||||
 | 
					            ret = ExitCode(ret)
 | 
				
			||||||
 | 
					        except ValueError:
 | 
				
			||||||
 | 
					            pass
 | 
				
			||||||
        return RunResult(ret, out, err, time.time() - now)
 | 
					        return RunResult(ret, out, err, time.time() - now)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def _dump_lines(self, lines, fp):
 | 
					    def _dump_lines(self, lines, fp):
 | 
				
			||||||
| 
						 | 
					@ -1134,7 +1144,7 @@ class Testdir:
 | 
				
			||||||
    def _getpytestargs(self):
 | 
					    def _getpytestargs(self):
 | 
				
			||||||
        return sys.executable, "-mpytest"
 | 
					        return sys.executable, "-mpytest"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def runpython(self, script):
 | 
					    def runpython(self, script) -> RunResult:
 | 
				
			||||||
        """Run a python script using sys.executable as interpreter.
 | 
					        """Run a python script using sys.executable as interpreter.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        Returns a :py:class:`RunResult`.
 | 
					        Returns a :py:class:`RunResult`.
 | 
				
			||||||
| 
						 | 
					@ -1146,7 +1156,7 @@ class Testdir:
 | 
				
			||||||
        """Run python -c "command", return a :py:class:`RunResult`."""
 | 
					        """Run python -c "command", return a :py:class:`RunResult`."""
 | 
				
			||||||
        return self.run(sys.executable, "-c", command)
 | 
					        return self.run(sys.executable, "-c", command)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def runpytest_subprocess(self, *args, timeout=None):
 | 
					    def runpytest_subprocess(self, *args, timeout=None) -> RunResult:
 | 
				
			||||||
        """Run pytest as a subprocess with given arguments.
 | 
					        """Run pytest as a subprocess with given arguments.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        Any plugins added to the :py:attr:`plugins` list will be added using the
 | 
					        Any plugins added to the :py:attr:`plugins` list will be added using the
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -395,6 +395,27 @@ def test_testdir_subprocess(testdir):
 | 
				
			||||||
    assert testdir.runpytest_subprocess(testfile).ret == 0
 | 
					    assert testdir.runpytest_subprocess(testfile).ret == 0
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					def test_testdir_subprocess_via_runpytest_arg(testdir) -> None:
 | 
				
			||||||
 | 
					    testfile = testdir.makepyfile(
 | 
				
			||||||
 | 
					        """
 | 
				
			||||||
 | 
					        def test_testdir_subprocess(testdir):
 | 
				
			||||||
 | 
					            import os
 | 
				
			||||||
 | 
					            testfile = testdir.makepyfile(
 | 
				
			||||||
 | 
					                \"""
 | 
				
			||||||
 | 
					                import os
 | 
				
			||||||
 | 
					                def test_one():
 | 
				
			||||||
 | 
					                    assert {} != os.getpid()
 | 
				
			||||||
 | 
					                \""".format(os.getpid())
 | 
				
			||||||
 | 
					            )
 | 
				
			||||||
 | 
					            assert testdir.runpytest(testfile).ret == 0
 | 
				
			||||||
 | 
					        """
 | 
				
			||||||
 | 
					    )
 | 
				
			||||||
 | 
					    result = testdir.runpytest_subprocess(
 | 
				
			||||||
 | 
					        "-p", "pytester", "--runpytest", "subprocess", testfile
 | 
				
			||||||
 | 
					    )
 | 
				
			||||||
 | 
					    assert result.ret == 0
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
def test_unicode_args(testdir):
 | 
					def test_unicode_args(testdir):
 | 
				
			||||||
    result = testdir.runpytest("-k", "💩")
 | 
					    result = testdir.runpytest("-k", "💩")
 | 
				
			||||||
    assert result.ret == ExitCode.NO_TESTS_COLLECTED
 | 
					    assert result.ret == ExitCode.NO_TESTS_COLLECTED
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
		Reference in New Issue