Merge master into features (#6111)
This commit is contained in:
		
						commit
						b268463243
					
				| 
						 | 
					@ -60,7 +60,7 @@ jobs:
 | 
				
			||||||
    - env: TOXENV=py37-freeze
 | 
					    - env: TOXENV=py37-freeze
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    - env: TOXENV=py38-xdist
 | 
					    - env: TOXENV=py38-xdist
 | 
				
			||||||
      python: '3.8-dev'
 | 
					      python: '3.8'
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    - stage: baseline
 | 
					    - stage: baseline
 | 
				
			||||||
      env: TOXENV=py36-xdist
 | 
					      env: TOXENV=py36-xdist
 | 
				
			||||||
| 
						 | 
					@ -94,11 +94,6 @@ jobs:
 | 
				
			||||||
          tags: true
 | 
					          tags: true
 | 
				
			||||||
          repo: pytest-dev/pytest
 | 
					          repo: pytest-dev/pytest
 | 
				
			||||||
 | 
					
 | 
				
			||||||
matrix:
 | 
					 | 
				
			||||||
  allow_failures:
 | 
					 | 
				
			||||||
    - python: '3.8-dev'
 | 
					 | 
				
			||||||
      env: TOXENV=py38-xdist
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
before_script:
 | 
					before_script:
 | 
				
			||||||
  - |
 | 
					  - |
 | 
				
			||||||
    # Do not (re-)upload coverage with cron runs.
 | 
					    # Do not (re-)upload coverage with cron runs.
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -13,7 +13,7 @@ with advance notice in the **Deprecations** section of releases.
 | 
				
			||||||
    file is managed by towncrier. You *may* edit previous change logs to
 | 
					    file is managed by towncrier. You *may* edit previous change logs to
 | 
				
			||||||
    fix problems like typo corrections or such.
 | 
					    fix problems like typo corrections or such.
 | 
				
			||||||
    To add a new change log entry, please see
 | 
					    To add a new change log entry, please see
 | 
				
			||||||
    https://pip.pypa.io/en/latest/development/#adding-a-news-entry
 | 
					    https://pip.pypa.io/en/latest/development/contributing/#news-entries
 | 
				
			||||||
    we named the news folder changelog
 | 
					    we named the news folder changelog
 | 
				
			||||||
 | 
					
 | 
				
			||||||
.. towncrier release notes start
 | 
					.. towncrier release notes start
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -0,0 +1 @@
 | 
				
			||||||
 | 
					Fix ``--trace`` when used with parametrized functions.
 | 
				
			||||||
| 
						 | 
					@ -137,7 +137,7 @@ class Frame:
 | 
				
			||||||
    def exec_(self, code, **vars):
 | 
					    def exec_(self, code, **vars):
 | 
				
			||||||
        """ exec 'code' in the frame
 | 
					        """ exec 'code' in the frame
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            'vars' are optiona; additional local variables
 | 
					            'vars' are optional; additional local variables
 | 
				
			||||||
        """
 | 
					        """
 | 
				
			||||||
        f_locals = self.f_locals.copy()
 | 
					        f_locals = self.f_locals.copy()
 | 
				
			||||||
        f_locals.update(vars)
 | 
					        f_locals.update(vars)
 | 
				
			||||||
| 
						 | 
					@ -207,7 +207,7 @@ class TracebackEntry:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    @property
 | 
					    @property
 | 
				
			||||||
    def locals(self):
 | 
					    def locals(self):
 | 
				
			||||||
        """ locals of underlaying frame """
 | 
					        """ locals of underlying frame """
 | 
				
			||||||
        return self.frame.f_locals
 | 
					        return self.frame.f_locals
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def getfirstlinesource(self):
 | 
					    def getfirstlinesource(self):
 | 
				
			||||||
| 
						 | 
					@ -274,7 +274,7 @@ class TracebackEntry:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    @property
 | 
					    @property
 | 
				
			||||||
    def name(self):
 | 
					    def name(self):
 | 
				
			||||||
        """ co_name of underlaying code """
 | 
					        """ co_name of underlying code """
 | 
				
			||||||
        return self.frame.code.raw.co_name
 | 
					        return self.frame.code.raw.co_name
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -302,7 +302,7 @@ class Traceback(list):
 | 
				
			||||||
    def cut(self, path=None, lineno=None, firstlineno=None, excludepath=None):
 | 
					    def cut(self, path=None, lineno=None, firstlineno=None, excludepath=None):
 | 
				
			||||||
        """ return a Traceback instance wrapping part of this Traceback
 | 
					        """ return a Traceback instance wrapping part of this Traceback
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            by provding any combination of path, lineno and firstlineno, the
 | 
					            by providing any combination of path, lineno and firstlineno, the
 | 
				
			||||||
            first frame to start the to-be-returned traceback is determined
 | 
					            first frame to start the to-be-returned traceback is determined
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            this allows cutting the first part of a Traceback instance e.g.
 | 
					            this allows cutting the first part of a Traceback instance e.g.
 | 
				
			||||||
| 
						 | 
					@ -1008,7 +1008,7 @@ class ReprFileLocation(TerminalRepr):
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def toterminal(self, tw) -> None:
 | 
					    def toterminal(self, tw) -> None:
 | 
				
			||||||
        # filename and lineno output for each entry,
 | 
					        # filename and lineno output for each entry,
 | 
				
			||||||
        # using an output format that most editors unterstand
 | 
					        # using an output format that most editors understand
 | 
				
			||||||
        msg = self.message
 | 
					        msg = self.message
 | 
				
			||||||
        i = msg.find("\n")
 | 
					        i = msg.find("\n")
 | 
				
			||||||
        if i != -1:
 | 
					        if i != -1:
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -38,7 +38,6 @@ def format_explanation(explanation: str) -> str:
 | 
				
			||||||
    for when one explanation needs to span multiple lines, e.g. when
 | 
					    for when one explanation needs to span multiple lines, e.g. when
 | 
				
			||||||
    displaying diffs.
 | 
					    displaying diffs.
 | 
				
			||||||
    """
 | 
					    """
 | 
				
			||||||
    explanation = explanation
 | 
					 | 
				
			||||||
    lines = _split_explanation(explanation)
 | 
					    lines = _split_explanation(explanation)
 | 
				
			||||||
    result = _format_lines(lines)
 | 
					    result = _format_lines(lines)
 | 
				
			||||||
    return "\n".join(result)
 | 
					    return "\n".join(result)
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1,5 +1,6 @@
 | 
				
			||||||
""" interactive debugging with PDB, the Python Debugger. """
 | 
					""" interactive debugging with PDB, the Python Debugger. """
 | 
				
			||||||
import argparse
 | 
					import argparse
 | 
				
			||||||
 | 
					import functools
 | 
				
			||||||
import sys
 | 
					import sys
 | 
				
			||||||
 | 
					
 | 
				
			||||||
from _pytest import outcomes
 | 
					from _pytest import outcomes
 | 
				
			||||||
| 
						 | 
					@ -278,13 +279,16 @@ class PdbTrace:
 | 
				
			||||||
def _test_pytest_function(pyfuncitem):
 | 
					def _test_pytest_function(pyfuncitem):
 | 
				
			||||||
    _pdb = pytestPDB._init_pdb("runcall")
 | 
					    _pdb = pytestPDB._init_pdb("runcall")
 | 
				
			||||||
    testfunction = pyfuncitem.obj
 | 
					    testfunction = pyfuncitem.obj
 | 
				
			||||||
    pyfuncitem.obj = _pdb.runcall
 | 
					
 | 
				
			||||||
    if "func" in pyfuncitem._fixtureinfo.argnames:  # pragma: no branch
 | 
					    # we can't just return `partial(pdb.runcall, testfunction)` because (on
 | 
				
			||||||
        raise ValueError("--trace can't be used with a fixture named func!")
 | 
					    # python < 3.7.4) runcall's first param is `func`, which means we'd get
 | 
				
			||||||
    pyfuncitem.funcargs["func"] = testfunction
 | 
					    # an exception if one of the kwargs to testfunction was called `func`
 | 
				
			||||||
    new_list = list(pyfuncitem._fixtureinfo.argnames)
 | 
					    @functools.wraps(testfunction)
 | 
				
			||||||
    new_list.append("func")
 | 
					    def wrapper(*args, **kwargs):
 | 
				
			||||||
    pyfuncitem._fixtureinfo.argnames = tuple(new_list)
 | 
					        func = functools.partial(testfunction, *args, **kwargs)
 | 
				
			||||||
 | 
					        _pdb.runcall(func)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    pyfuncitem.obj = wrapper
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
def _enter_pdb(node, excinfo, rep):
 | 
					def _enter_pdb(node, excinfo, rep):
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -513,7 +513,7 @@ class LogXML:
 | 
				
			||||||
        key = nodeid, slavenode
 | 
					        key = nodeid, slavenode
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        if key in self.node_reporters:
 | 
					        if key in self.node_reporters:
 | 
				
			||||||
            # TODO: breasks for --dist=each
 | 
					            # TODO: breaks for --dist=each
 | 
				
			||||||
            return self.node_reporters[key]
 | 
					            return self.node_reporters[key]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        reporter = _NodeReporter(nodeid, self)
 | 
					        reporter = _NodeReporter(nodeid, self)
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -437,7 +437,7 @@ class Session(nodes.FSCollector):
 | 
				
			||||||
            # one or more conftests are not in use at this fspath
 | 
					            # one or more conftests are not in use at this fspath
 | 
				
			||||||
            proxy = FSHookProxy(fspath, pm, remove_mods)
 | 
					            proxy = FSHookProxy(fspath, pm, remove_mods)
 | 
				
			||||||
        else:
 | 
					        else:
 | 
				
			||||||
            # all plugis are active for this fspath
 | 
					            # all plugins are active for this fspath
 | 
				
			||||||
            proxy = self.config.hook
 | 
					            proxy = self.config.hook
 | 
				
			||||||
        return proxy
 | 
					        return proxy
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -28,7 +28,7 @@ class MarkEvaluator:
 | 
				
			||||||
        self._mark_name = name
 | 
					        self._mark_name = name
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def __bool__(self):
 | 
					    def __bool__(self):
 | 
				
			||||||
        # dont cache here to prevent staleness
 | 
					        # don't cache here to prevent staleness
 | 
				
			||||||
        return bool(self._get_marks())
 | 
					        return bool(self._get_marks())
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    __nonzero__ = __bool__
 | 
					    __nonzero__ = __bool__
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1,6 +1,6 @@
 | 
				
			||||||
"""
 | 
					"""
 | 
				
			||||||
this is a place where we put datastructures used by legacy apis
 | 
					this is a place where we put datastructures used by legacy apis
 | 
				
			||||||
we hope ot remove
 | 
					we hope to remove
 | 
				
			||||||
"""
 | 
					"""
 | 
				
			||||||
import keyword
 | 
					import keyword
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -211,8 +211,8 @@ def pytest_pycollect_makeitem(collector, name, obj):
 | 
				
			||||||
        # mock seems to store unbound methods (issue473), normalize it
 | 
					        # mock seems to store unbound methods (issue473), normalize it
 | 
				
			||||||
        obj = getattr(obj, "__func__", obj)
 | 
					        obj = getattr(obj, "__func__", obj)
 | 
				
			||||||
        # We need to try and unwrap the function if it's a functools.partial
 | 
					        # We need to try and unwrap the function if it's a functools.partial
 | 
				
			||||||
        # or a funtools.wrapped.
 | 
					        # or a functools.wrapped.
 | 
				
			||||||
        # We musn't if it's been wrapped with mock.patch (python 2 only)
 | 
					        # We mustn't if it's been wrapped with mock.patch (python 2 only)
 | 
				
			||||||
        if not (inspect.isfunction(obj) or inspect.isfunction(get_real_func(obj))):
 | 
					        if not (inspect.isfunction(obj) or inspect.isfunction(get_real_func(obj))):
 | 
				
			||||||
            filename, lineno = getfslineno(obj)
 | 
					            filename, lineno = getfslineno(obj)
 | 
				
			||||||
            warnings.warn_explicit(
 | 
					            warnings.warn_explicit(
 | 
				
			||||||
| 
						 | 
					@ -596,7 +596,7 @@ class Package(Module):
 | 
				
			||||||
            # one or more conftests are not in use at this fspath
 | 
					            # one or more conftests are not in use at this fspath
 | 
				
			||||||
            proxy = FSHookProxy(fspath, pm, remove_mods)
 | 
					            proxy = FSHookProxy(fspath, pm, remove_mods)
 | 
				
			||||||
        else:
 | 
					        else:
 | 
				
			||||||
            # all plugis are active for this fspath
 | 
					            # all plugins are active for this fspath
 | 
				
			||||||
            proxy = self.config.hook
 | 
					            proxy = self.config.hook
 | 
				
			||||||
        return proxy
 | 
					        return proxy
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -122,7 +122,7 @@ def pytest_runtest_makereport(item, call):
 | 
				
			||||||
    outcome = yield
 | 
					    outcome = yield
 | 
				
			||||||
    rep = outcome.get_result()
 | 
					    rep = outcome.get_result()
 | 
				
			||||||
    evalxfail = getattr(item, "_evalxfail", None)
 | 
					    evalxfail = getattr(item, "_evalxfail", None)
 | 
				
			||||||
    # unitttest special case, see setting of _unexpectedsuccess
 | 
					    # unittest special case, see setting of _unexpectedsuccess
 | 
				
			||||||
    if hasattr(item, "_unexpectedsuccess") and rep.when == "call":
 | 
					    if hasattr(item, "_unexpectedsuccess") and rep.when == "call":
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        if item._unexpectedsuccess:
 | 
					        if item._unexpectedsuccess:
 | 
				
			||||||
| 
						 | 
					@ -132,7 +132,7 @@ def pytest_runtest_makereport(item, call):
 | 
				
			||||||
        rep.outcome = "failed"
 | 
					        rep.outcome = "failed"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    elif item.config.option.runxfail:
 | 
					    elif item.config.option.runxfail:
 | 
				
			||||||
        pass  # don't interefere
 | 
					        pass  # don't interfere
 | 
				
			||||||
    elif call.excinfo and call.excinfo.errisinstance(xfail.Exception):
 | 
					    elif call.excinfo and call.excinfo.errisinstance(xfail.Exception):
 | 
				
			||||||
        rep.wasxfail = "reason: " + call.excinfo.value.msg
 | 
					        rep.wasxfail = "reason: " + call.excinfo.value.msg
 | 
				
			||||||
        rep.outcome = "skipped"
 | 
					        rep.outcome = "skipped"
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -15,7 +15,7 @@ class TestMetafunc:
 | 
				
			||||||
    def Metafunc(self, func, config=None):
 | 
					    def Metafunc(self, func, config=None):
 | 
				
			||||||
        # the unit tests of this class check if things work correctly
 | 
					        # the unit tests of this class check if things work correctly
 | 
				
			||||||
        # on the funcarg level, so we don't need a full blown
 | 
					        # on the funcarg level, so we don't need a full blown
 | 
				
			||||||
        # initiliazation
 | 
					        # initialization
 | 
				
			||||||
        class FixtureInfo:
 | 
					        class FixtureInfo:
 | 
				
			||||||
            name2fixturedefs = None
 | 
					            name2fixturedefs = None
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -482,7 +482,7 @@ class TestFunctional:
 | 
				
			||||||
        items, rec = testdir.inline_genitems(p)
 | 
					        items, rec = testdir.inline_genitems(p)
 | 
				
			||||||
        base_item, sub_item, sub_item_other = items
 | 
					        base_item, sub_item, sub_item_other = items
 | 
				
			||||||
        print(items, [x.nodeid for x in items])
 | 
					        print(items, [x.nodeid for x in items])
 | 
				
			||||||
        # new api seregates
 | 
					        # new api segregates
 | 
				
			||||||
        assert not list(base_item.iter_markers(name="b"))
 | 
					        assert not list(base_item.iter_markers(name="b"))
 | 
				
			||||||
        assert not list(sub_item_other.iter_markers(name="b"))
 | 
					        assert not list(sub_item_other.iter_markers(name="b"))
 | 
				
			||||||
        assert list(sub_item.iter_markers(name="b"))
 | 
					        assert list(sub_item.iter_markers(name="b"))
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -229,7 +229,7 @@ def test_nose_setup_ordering(testdir):
 | 
				
			||||||
 | 
					
 | 
				
			||||||
def test_apiwrapper_problem_issue260(testdir):
 | 
					def test_apiwrapper_problem_issue260(testdir):
 | 
				
			||||||
    # this would end up trying a call an optional teardown on the class
 | 
					    # this would end up trying a call an optional teardown on the class
 | 
				
			||||||
    # for plain unittests we dont want nose behaviour
 | 
					    # for plain unittests we don't want nose behaviour
 | 
				
			||||||
    testdir.makepyfile(
 | 
					    testdir.makepyfile(
 | 
				
			||||||
        """
 | 
					        """
 | 
				
			||||||
        import unittest
 | 
					        import unittest
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -304,7 +304,7 @@ def test_argcomplete(testdir, monkeypatch):
 | 
				
			||||||
                shlex.quote(sys.executable)
 | 
					                shlex.quote(sys.executable)
 | 
				
			||||||
            )
 | 
					            )
 | 
				
			||||||
        )
 | 
					        )
 | 
				
			||||||
    # alternative would be exteneded Testdir.{run(),_run(),popen()} to be able
 | 
					    # alternative would be extended Testdir.{run(),_run(),popen()} to be able
 | 
				
			||||||
    # to handle a keyword argument env that replaces os.environ in popen or
 | 
					    # to handle a keyword argument env that replaces os.environ in popen or
 | 
				
			||||||
    # extends the copy, advantage: could not forget to restore
 | 
					    # extends the copy, advantage: could not forget to restore
 | 
				
			||||||
    monkeypatch.setenv("_ARGCOMPLETE", "1")
 | 
					    monkeypatch.setenv("_ARGCOMPLETE", "1")
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -603,7 +603,7 @@ class TestPDB:
 | 
				
			||||||
        # No extra newline.
 | 
					        # No extra newline.
 | 
				
			||||||
        assert child.before.endswith(b"c\r\nprint_from_foo\r\n")
 | 
					        assert child.before.endswith(b"c\r\nprint_from_foo\r\n")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        # set_debug should not raise outcomes.Exit, if used recrursively.
 | 
					        # set_debug should not raise outcomes. Exit, if used recursively.
 | 
				
			||||||
        child.sendline("debug 42")
 | 
					        child.sendline("debug 42")
 | 
				
			||||||
        child.sendline("q")
 | 
					        child.sendline("q")
 | 
				
			||||||
        child.expect("LEAVING RECURSIVE DEBUGGER")
 | 
					        child.expect("LEAVING RECURSIVE DEBUGGER")
 | 
				
			||||||
| 
						 | 
					@ -1047,6 +1047,51 @@ class TestTraceOption:
 | 
				
			||||||
        assert "Exit: Quitting debugger" not in child.before.decode("utf8")
 | 
					        assert "Exit: Quitting debugger" not in child.before.decode("utf8")
 | 
				
			||||||
        TestPDB.flush(child)
 | 
					        TestPDB.flush(child)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def test_trace_with_parametrize_handles_shared_fixtureinfo(self, testdir):
 | 
				
			||||||
 | 
					        p1 = testdir.makepyfile(
 | 
				
			||||||
 | 
					            """
 | 
				
			||||||
 | 
					            import pytest
 | 
				
			||||||
 | 
					            @pytest.mark.parametrize('myparam', [1,2])
 | 
				
			||||||
 | 
					            def test_1(myparam, request):
 | 
				
			||||||
 | 
					                assert myparam in (1, 2)
 | 
				
			||||||
 | 
					                assert request.function.__name__ == "test_1"
 | 
				
			||||||
 | 
					            @pytest.mark.parametrize('func', [1,2])
 | 
				
			||||||
 | 
					            def test_func(func, request):
 | 
				
			||||||
 | 
					                assert func in (1, 2)
 | 
				
			||||||
 | 
					                assert request.function.__name__ == "test_func"
 | 
				
			||||||
 | 
					            @pytest.mark.parametrize('myparam', [1,2])
 | 
				
			||||||
 | 
					            def test_func_kw(myparam, request, func="func_kw"):
 | 
				
			||||||
 | 
					                assert myparam in (1, 2)
 | 
				
			||||||
 | 
					                assert func == "func_kw"
 | 
				
			||||||
 | 
					                assert request.function.__name__ == "test_func_kw"
 | 
				
			||||||
 | 
					            """
 | 
				
			||||||
 | 
					        )
 | 
				
			||||||
 | 
					        child = testdir.spawn_pytest("--trace " + str(p1))
 | 
				
			||||||
 | 
					        for func, argname in [
 | 
				
			||||||
 | 
					            ("test_1", "myparam"),
 | 
				
			||||||
 | 
					            ("test_func", "func"),
 | 
				
			||||||
 | 
					            ("test_func_kw", "myparam"),
 | 
				
			||||||
 | 
					        ]:
 | 
				
			||||||
 | 
					            child.expect_exact("> PDB runcall (IO-capturing turned off) >")
 | 
				
			||||||
 | 
					            child.expect_exact(func)
 | 
				
			||||||
 | 
					            child.expect_exact("Pdb")
 | 
				
			||||||
 | 
					            child.sendline("args")
 | 
				
			||||||
 | 
					            child.expect_exact("{} = 1\r\n".format(argname))
 | 
				
			||||||
 | 
					            child.expect_exact("Pdb")
 | 
				
			||||||
 | 
					            child.sendline("c")
 | 
				
			||||||
 | 
					            child.expect_exact("Pdb")
 | 
				
			||||||
 | 
					            child.sendline("args")
 | 
				
			||||||
 | 
					            child.expect_exact("{} = 2\r\n".format(argname))
 | 
				
			||||||
 | 
					            child.expect_exact("Pdb")
 | 
				
			||||||
 | 
					            child.sendline("c")
 | 
				
			||||||
 | 
					            child.expect_exact("> PDB continue (IO-capturing resumed) >")
 | 
				
			||||||
 | 
					        rest = child.read().decode("utf8")
 | 
				
			||||||
 | 
					        assert "= \x1b[32m\x1b[1m6 passed\x1b[0m\x1b[32m in" in rest
 | 
				
			||||||
 | 
					        assert "reading from stdin while output" not in rest
 | 
				
			||||||
 | 
					        # Only printed once - not on stderr.
 | 
				
			||||||
 | 
					        assert "Exit: Quitting debugger" not in child.before.decode("utf8")
 | 
				
			||||||
 | 
					        TestPDB.flush(child)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
def test_trace_after_runpytest(testdir):
 | 
					def test_trace_after_runpytest(testdir):
 | 
				
			||||||
    """Test that debugging's pytest_configure is re-entrant."""
 | 
					    """Test that debugging's pytest_configure is re-entrant."""
 | 
				
			||||||
| 
						 | 
					@ -1172,7 +1217,6 @@ def test_pdbcls_via_local_module(testdir):
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                def runcall(self, *args, **kwds):
 | 
					                def runcall(self, *args, **kwds):
 | 
				
			||||||
                    print("runcall_called", args, kwds)
 | 
					                    print("runcall_called", args, kwds)
 | 
				
			||||||
                    assert "func" in kwds
 | 
					 | 
				
			||||||
        """,
 | 
					        """,
 | 
				
			||||||
    )
 | 
					    )
 | 
				
			||||||
    result = testdir.runpytest(
 | 
					    result = testdir.runpytest(
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -4,7 +4,7 @@ import pytest
 | 
				
			||||||
@pytest.fixture
 | 
					@pytest.fixture
 | 
				
			||||||
def stepwise_testdir(testdir):
 | 
					def stepwise_testdir(testdir):
 | 
				
			||||||
    # Rather than having to modify our testfile between tests, we introduce
 | 
					    # Rather than having to modify our testfile between tests, we introduce
 | 
				
			||||||
    # a flag for wether or not the second test should fail.
 | 
					    # a flag for whether or not the second test should fail.
 | 
				
			||||||
    testdir.makeconftest(
 | 
					    testdir.makeconftest(
 | 
				
			||||||
        """
 | 
					        """
 | 
				
			||||||
def pytest_addoption(parser):
 | 
					def pytest_addoption(parser):
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
		Reference in New Issue