From 73b74c74c9674947c8383f657c3a78b1d73ffe1b Mon Sep 17 00:00:00 2001 From: Daniel Hahler Date: Thu, 9 May 2019 00:06:36 +0200 Subject: [PATCH] pdb: only use outcomes.exit via do_quit Fixes https://github.com/pytest-dev/pytest/issues/5235. --- changelog/5235.bugfix.rst | 1 + src/_pytest/debugging.py | 10 ++++++++-- testing/test_pdb.py | 32 ++++++++++++++++++++++++++++++-- 3 files changed, 39 insertions(+), 4 deletions(-) create mode 100644 changelog/5235.bugfix.rst diff --git a/changelog/5235.bugfix.rst b/changelog/5235.bugfix.rst new file mode 100644 index 000000000..87597a589 --- /dev/null +++ b/changelog/5235.bugfix.rst @@ -0,0 +1 @@ +``outcome.exit`` is not used with ``EOF`` in the pdb wrapper anymore, but only with ``quit``. diff --git a/src/_pytest/debugging.py b/src/_pytest/debugging.py index 7138fd2e1..52c6536f4 100644 --- a/src/_pytest/debugging.py +++ b/src/_pytest/debugging.py @@ -181,17 +181,23 @@ class pytestPDB(object): do_c = do_cont = do_continue - def set_quit(self): + def do_quit(self, arg): """Raise Exit outcome when quit command is used in pdb. This is a bit of a hack - it would be better if BdbQuit could be handled, but this would require to wrap the whole pytest run, and adjust the report etc. """ - super(PytestPdbWrapper, self).set_quit() + ret = super(PytestPdbWrapper, self).do_quit(arg) + if cls._recursive_debug == 0: outcomes.exit("Quitting debugger") + return ret + + do_q = do_quit + do_exit = do_quit + def setup(self, f, tb): """Suspend on setup(). diff --git a/testing/test_pdb.py b/testing/test_pdb.py index 0a72a2907..3b21bacd9 100644 --- a/testing/test_pdb.py +++ b/testing/test_pdb.py @@ -6,6 +6,8 @@ import os import platform import sys +import six + import _pytest._code import pytest from _pytest.debugging import _validate_usepdb_cls @@ -395,7 +397,7 @@ class TestPDB(object): child = testdir.spawn_pytest(str(p1)) child.expect("test_1") child.expect("Pdb") - child.sendeof() + child.sendline("q") rest = child.read().decode("utf8") assert "no tests ran" in rest assert "reading from stdin while output" not in rest @@ -957,7 +959,7 @@ class TestDebuggingBreakpoints(object): child = testdir.spawn_pytest(str(p1)) child.expect("test_1") child.expect("Pdb") - child.sendeof() + child.sendline("quit") rest = child.read().decode("utf8") assert "Quitting debugger" in rest assert "reading from stdin while output" not in rest @@ -1163,3 +1165,29 @@ def test_pdbcls_via_local_module(testdir): ) assert result.ret == 0 result.stdout.fnmatch_lines(["*runcall_called*", "* 1 passed in *"]) + + +def test_raises_bdbquit_with_eoferror(testdir): + """It is not guaranteed that DontReadFromInput's read is called.""" + if six.PY2: + builtin_module = "__builtin__" + input_func = "raw_input" + else: + builtin_module = "builtins" + input_func = "input" + p1 = testdir.makepyfile( + """ + def input_without_read(*args, **kwargs): + raise EOFError() + + def test(monkeypatch): + import {builtin_module} + monkeypatch.setattr({builtin_module}, {input_func!r}, input_without_read) + __import__('pdb').set_trace() + """.format( + builtin_module=builtin_module, input_func=input_func + ) + ) + result = testdir.runpytest(str(p1)) + result.stdout.fnmatch_lines(["E *BdbQuit", "*= 1 failed in*"]) + assert result.ret == 1