main: wrap_session: handle exit.Exception with notify_exception
Fixes https://github.com/pytest-dev/pytest/issues/6257. Via https://github.com/blueyed/pytest/pull/132.
This commit is contained in:
		
							parent
							
								
									63c9ad02f4
								
							
						
					
					
						commit
						2344982d7f
					
				| 
						 | 
					@ -0,0 +1 @@
 | 
				
			||||||
 | 
					Handle `exit.Exception` raised in `notify_exception` (via `pytest_internalerror`), e.g. when quitting pdb from post mortem.
 | 
				
			||||||
| 
						 | 
					@ -212,9 +212,15 @@ def wrap_session(config, doit):
 | 
				
			||||||
            config.hook.pytest_keyboard_interrupt(excinfo=excinfo)
 | 
					            config.hook.pytest_keyboard_interrupt(excinfo=excinfo)
 | 
				
			||||||
            session.exitstatus = exitstatus
 | 
					            session.exitstatus = exitstatus
 | 
				
			||||||
        except:  # noqa
 | 
					        except:  # noqa
 | 
				
			||||||
            excinfo = _pytest._code.ExceptionInfo.from_current()
 | 
					 | 
				
			||||||
            config.notify_exception(excinfo, config.option)
 | 
					 | 
				
			||||||
            session.exitstatus = ExitCode.INTERNAL_ERROR
 | 
					            session.exitstatus = ExitCode.INTERNAL_ERROR
 | 
				
			||||||
 | 
					            excinfo = _pytest._code.ExceptionInfo.from_current()
 | 
				
			||||||
 | 
					            try:
 | 
				
			||||||
 | 
					                config.notify_exception(excinfo, config.option)
 | 
				
			||||||
 | 
					            except exit.Exception as exc:
 | 
				
			||||||
 | 
					                if exc.returncode is not None:
 | 
				
			||||||
 | 
					                    session.exitstatus = exc.returncode
 | 
				
			||||||
 | 
					                sys.stderr.write("{}: {}\n".format(type(exc).__name__, exc))
 | 
				
			||||||
 | 
					            else:
 | 
				
			||||||
                if excinfo.errisinstance(SystemExit):
 | 
					                if excinfo.errisinstance(SystemExit):
 | 
				
			||||||
                    sys.stderr.write("mainloop: caught unexpected SystemExit!\n")
 | 
					                    sys.stderr.write("mainloop: caught unexpected SystemExit!\n")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -0,0 +1,52 @@
 | 
				
			||||||
 | 
					import pytest
 | 
				
			||||||
 | 
					from _pytest.main import ExitCode
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					@pytest.mark.parametrize(
 | 
				
			||||||
 | 
					    "ret_exc",
 | 
				
			||||||
 | 
					    (
 | 
				
			||||||
 | 
					        pytest.param((None, ValueError)),
 | 
				
			||||||
 | 
					        pytest.param((42, SystemExit)),
 | 
				
			||||||
 | 
					        pytest.param((False, SystemExit)),
 | 
				
			||||||
 | 
					    ),
 | 
				
			||||||
 | 
					)
 | 
				
			||||||
 | 
					def test_wrap_session_notify_exception(ret_exc, testdir):
 | 
				
			||||||
 | 
					    returncode, exc = ret_exc
 | 
				
			||||||
 | 
					    c1 = testdir.makeconftest(
 | 
				
			||||||
 | 
					        """
 | 
				
			||||||
 | 
					        import pytest
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        def pytest_sessionstart():
 | 
				
			||||||
 | 
					            raise {exc}("boom")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        def pytest_internalerror(excrepr, excinfo):
 | 
				
			||||||
 | 
					            returncode = {returncode!r}
 | 
				
			||||||
 | 
					            if returncode is not False:
 | 
				
			||||||
 | 
					                pytest.exit("exiting after %s..." % excinfo.typename, returncode={returncode!r})
 | 
				
			||||||
 | 
					    """.format(
 | 
				
			||||||
 | 
					            returncode=returncode, exc=exc.__name__
 | 
				
			||||||
 | 
					        )
 | 
				
			||||||
 | 
					    )
 | 
				
			||||||
 | 
					    result = testdir.runpytest()
 | 
				
			||||||
 | 
					    if returncode:
 | 
				
			||||||
 | 
					        assert result.ret == returncode
 | 
				
			||||||
 | 
					    else:
 | 
				
			||||||
 | 
					        assert result.ret == ExitCode.INTERNAL_ERROR
 | 
				
			||||||
 | 
					    assert result.stdout.lines[0] == "INTERNALERROR> Traceback (most recent call last):"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if exc == SystemExit:
 | 
				
			||||||
 | 
					        assert result.stdout.lines[-3:] == [
 | 
				
			||||||
 | 
					            'INTERNALERROR>   File "{}", line 4, in pytest_sessionstart'.format(c1),
 | 
				
			||||||
 | 
					            'INTERNALERROR>     raise SystemExit("boom")',
 | 
				
			||||||
 | 
					            "INTERNALERROR> SystemExit: boom",
 | 
				
			||||||
 | 
					        ]
 | 
				
			||||||
 | 
					    else:
 | 
				
			||||||
 | 
					        assert result.stdout.lines[-3:] == [
 | 
				
			||||||
 | 
					            'INTERNALERROR>   File "{}", line 4, in pytest_sessionstart'.format(c1),
 | 
				
			||||||
 | 
					            'INTERNALERROR>     raise ValueError("boom")',
 | 
				
			||||||
 | 
					            "INTERNALERROR> ValueError: boom",
 | 
				
			||||||
 | 
					        ]
 | 
				
			||||||
 | 
					    if returncode is False:
 | 
				
			||||||
 | 
					        assert result.stderr.lines == ["mainloop: caught unexpected SystemExit!"]
 | 
				
			||||||
 | 
					    else:
 | 
				
			||||||
 | 
					        assert result.stderr.lines == ["Exit: exiting after {}...".format(exc.__name__)]
 | 
				
			||||||
		Loading…
	
		Reference in New Issue