introduced pytest_keyboardinterrupt hook
removed optional argument from pytest_sessionfinish hook --HG-- branch : 1.0.x
This commit is contained in:
parent
04a98700d9
commit
8be0ea942a
|
@ -1,6 +1,9 @@
|
||||||
Changes between 1.0.0b7 and 1.0.0b8
|
Changes between 1.0.0b7 and 1.0.0b8
|
||||||
=====================================
|
=====================================
|
||||||
|
|
||||||
|
* introduced pytest_keyboardinterrupt hook and
|
||||||
|
refined pytest_sessionfinish hooked.
|
||||||
|
|
||||||
* workaround a buggy logging module interaction ("closing already closed
|
* workaround a buggy logging module interaction ("closing already closed
|
||||||
files"). Thanks to Sridhar Ratnakumar for triggering.
|
files"). Thanks to Sridhar Ratnakumar for triggering.
|
||||||
|
|
||||||
|
|
|
@ -75,7 +75,7 @@ class DSession(Session):
|
||||||
self.setup()
|
self.setup()
|
||||||
exitstatus = self.loop(colitems)
|
exitstatus = self.loop(colitems)
|
||||||
self.teardown()
|
self.teardown()
|
||||||
self.sessionfinishes()
|
self.sessionfinishes(exitstatus=exitstatus)
|
||||||
return exitstatus
|
return exitstatus
|
||||||
|
|
||||||
def loop_once(self, loopstate):
|
def loop_once(self, loopstate):
|
||||||
|
|
|
@ -94,11 +94,11 @@ def pytest_runtest_logreport(rep):
|
||||||
def pytest_sessionstart(session):
|
def pytest_sessionstart(session):
|
||||||
""" before session.main() is called. """
|
""" before session.main() is called. """
|
||||||
|
|
||||||
def pytest_sessionfinish(session, exitstatus, excrepr=None):
|
def pytest_sessionfinish(session, exitstatus):
|
||||||
""" whole test run finishes. """
|
""" whole test run finishes. """
|
||||||
|
|
||||||
# -------------------------------------------------------------------------
|
# -------------------------------------------------------------------------
|
||||||
# generic reporting hooks (invoked from pytest_terminal)
|
# hooks for influencing reporting (invoked from pytest_terminal)
|
||||||
# -------------------------------------------------------------------------
|
# -------------------------------------------------------------------------
|
||||||
|
|
||||||
def pytest_report_teststatus(rep):
|
def pytest_report_teststatus(rep):
|
||||||
|
@ -140,7 +140,7 @@ def pytest_looponfailinfo(failreports, rootdirs):
|
||||||
|
|
||||||
|
|
||||||
# -------------------------------------------------------------------------
|
# -------------------------------------------------------------------------
|
||||||
# internal debugging hooks
|
# error handling and internal debugging hooks
|
||||||
# -------------------------------------------------------------------------
|
# -------------------------------------------------------------------------
|
||||||
|
|
||||||
def pytest_plugin_registered(plugin):
|
def pytest_plugin_registered(plugin):
|
||||||
|
@ -152,5 +152,8 @@ def pytest_plugin_unregistered(plugin):
|
||||||
def pytest_internalerror(excrepr):
|
def pytest_internalerror(excrepr):
|
||||||
""" called for internal errors. """
|
""" called for internal errors. """
|
||||||
|
|
||||||
|
def pytest_keyboard_interrupt(excinfo):
|
||||||
|
""" called for keyboard interrupt. """
|
||||||
|
|
||||||
def pytest_trace(category, msg):
|
def pytest_trace(category, msg):
|
||||||
""" called for debug info. """
|
""" called for debug info. """
|
||||||
|
|
|
@ -24,7 +24,7 @@ class Execnetcleanup:
|
||||||
def pytest_sessionstart(self, session):
|
def pytest_sessionstart(self, session):
|
||||||
self._gateways = []
|
self._gateways = []
|
||||||
|
|
||||||
def pytest_sessionfinish(self, session, exitstatus, excrepr=None):
|
def pytest_sessionfinish(self, session, exitstatus):
|
||||||
l = []
|
l = []
|
||||||
for gw in self._gateways:
|
for gw in self._gateways:
|
||||||
gw.exit()
|
gw.exit()
|
||||||
|
|
|
@ -19,11 +19,10 @@ def pytest_addoption(parser):
|
||||||
def pytest_configure(config):
|
def pytest_configure(config):
|
||||||
config._setupstate = SetupState()
|
config._setupstate = SetupState()
|
||||||
|
|
||||||
def pytest_sessionfinish(session, exitstatus, excrepr=None):
|
def pytest_sessionfinish(session, exitstatus):
|
||||||
# XXX see above
|
# XXX see above
|
||||||
if hasattr(session.config, '_setupstate'):
|
if hasattr(session.config, '_setupstate'):
|
||||||
session.config._setupstate.teardown_all()
|
session.config._setupstate.teardown_all()
|
||||||
|
|
||||||
# prevent logging module atexit handler from choking on
|
# prevent logging module atexit handler from choking on
|
||||||
# its attempt to close already closed streams
|
# its attempt to close already closed streams
|
||||||
# see http://bugs.python.org/issue6333
|
# see http://bugs.python.org/issue6333
|
||||||
|
|
|
@ -231,20 +231,29 @@ class TerminalReporter:
|
||||||
for i, testarg in py.builtin.enumerate(self.config.args):
|
for i, testarg in py.builtin.enumerate(self.config.args):
|
||||||
self.write_line("test object %d: %s" %(i+1, testarg))
|
self.write_line("test object %d: %s" %(i+1, testarg))
|
||||||
|
|
||||||
def pytest_sessionfinish(self, __call__, session, exitstatus, excrepr=None):
|
def pytest_sessionfinish(self, __call__, session, exitstatus):
|
||||||
__call__.execute()
|
__call__.execute()
|
||||||
self._tw.line("")
|
self._tw.line("")
|
||||||
if exitstatus in (0, 1, 2):
|
if exitstatus in (0, 1, 2):
|
||||||
self.summary_failures()
|
self.summary_failures()
|
||||||
self.summary_skips()
|
self.summary_skips()
|
||||||
self.config.hook.pytest_terminal_summary(terminalreporter=self)
|
self.config.hook.pytest_terminal_summary(terminalreporter=self)
|
||||||
if excrepr is not None:
|
|
||||||
self.summary_final_exc(excrepr)
|
|
||||||
if exitstatus == 2:
|
if exitstatus == 2:
|
||||||
self.write_sep("!", "KEYBOARD INTERRUPT")
|
self._report_keyboardinterrupt()
|
||||||
self.summary_deselected()
|
self.summary_deselected()
|
||||||
self.summary_stats()
|
self.summary_stats()
|
||||||
|
|
||||||
|
def pytest_keyboard_interrupt(self, excinfo):
|
||||||
|
self._keyboardinterrupt_memo = excinfo.getrepr()
|
||||||
|
|
||||||
|
def _report_keyboardinterrupt(self):
|
||||||
|
self.write_sep("!", "KEYBOARD INTERRUPT")
|
||||||
|
excrepr = self._keyboardinterrupt_memo
|
||||||
|
if self.config.option.verbose:
|
||||||
|
excrepr.toterminal(self._tw)
|
||||||
|
else:
|
||||||
|
excrepr.reprcrash.toterminal(self._tw)
|
||||||
|
|
||||||
def pytest_looponfailinfo(self, failreports, rootdirs):
|
def pytest_looponfailinfo(self, failreports, rootdirs):
|
||||||
if failreports:
|
if failreports:
|
||||||
self.write_sep("#", "LOOPONFAILING", red=True)
|
self.write_sep("#", "LOOPONFAILING", red=True)
|
||||||
|
@ -334,14 +343,6 @@ class TerminalReporter:
|
||||||
for num, fspath, lineno, reason in fskips:
|
for num, fspath, lineno, reason in fskips:
|
||||||
self._tw.line("%s:%d: [%d] %s" %(fspath, lineno, num, reason))
|
self._tw.line("%s:%d: [%d] %s" %(fspath, lineno, num, reason))
|
||||||
|
|
||||||
def summary_final_exc(self, excrepr):
|
|
||||||
self.write_sep("!")
|
|
||||||
if self.config.option.verbose:
|
|
||||||
excrepr.toterminal(self._tw)
|
|
||||||
else:
|
|
||||||
excrepr.reprcrash.toterminal(self._tw)
|
|
||||||
|
|
||||||
|
|
||||||
class CollectonlyReporter:
|
class CollectonlyReporter:
|
||||||
INDENT = " "
|
INDENT = " "
|
||||||
|
|
||||||
|
@ -373,7 +374,7 @@ class CollectonlyReporter:
|
||||||
self._failed.append(rep)
|
self._failed.append(rep)
|
||||||
self.indent = self.indent[:-len(self.INDENT)]
|
self.indent = self.indent[:-len(self.INDENT)]
|
||||||
|
|
||||||
def pytest_sessionfinish(self, session, exitstatus, excrepr=None):
|
def pytest_sessionfinish(self, session, exitstatus):
|
||||||
if self._failed:
|
if self._failed:
|
||||||
self.out.sep("!", "collection failures")
|
self.out.sep("!", "collection failures")
|
||||||
for rep in self._failed:
|
for rep in self._failed:
|
||||||
|
|
|
@ -86,12 +86,11 @@ class Session(object):
|
||||||
self.shouldstop = True
|
self.shouldstop = True
|
||||||
pytest_collectreport = pytest_runtest_logreport
|
pytest_collectreport = pytest_runtest_logreport
|
||||||
|
|
||||||
def sessionfinishes(self, exitstatus=0, excinfo=None):
|
def sessionfinishes(self, exitstatus):
|
||||||
""" teardown any resources after a test run. """
|
""" teardown any resources after a test run. """
|
||||||
self.config.hook.pytest_sessionfinish(
|
self.config.hook.pytest_sessionfinish(
|
||||||
session=self,
|
session=self,
|
||||||
exitstatus=exitstatus,
|
exitstatus=exitstatus,
|
||||||
excrepr=excinfo and excinfo.getrepr() or None
|
|
||||||
)
|
)
|
||||||
|
|
||||||
def getinitialitems(self, colitems):
|
def getinitialitems(self, colitems):
|
||||||
|
@ -114,13 +113,14 @@ class Session(object):
|
||||||
if not self.config.option.collectonly:
|
if not self.config.option.collectonly:
|
||||||
item.config.hook.pytest_runtest_protocol(item=item)
|
item.config.hook.pytest_runtest_protocol(item=item)
|
||||||
except KeyboardInterrupt:
|
except KeyboardInterrupt:
|
||||||
captured_excinfo = py.code.ExceptionInfo()
|
excinfo = py.code.ExceptionInfo()
|
||||||
|
item.config.hook.pytest_keyboard_interrupt(excinfo=excinfo)
|
||||||
exitstatus = outcome.EXIT_INTERRUPTED
|
exitstatus = outcome.EXIT_INTERRUPTED
|
||||||
except:
|
except:
|
||||||
captured_excinfo = py.code.ExceptionInfo()
|
excinfo = py.code.ExceptionInfo()
|
||||||
self.config.pluginmanager.notify_exception(captured_excinfo)
|
self.config.pluginmanager.notify_exception(captured_excinfo)
|
||||||
exitstatus = outcome.EXIT_INTERNALERROR
|
exitstatus = outcome.EXIT_INTERNALERROR
|
||||||
if exitstatus == 0 and self._testsfailed:
|
if exitstatus == 0 and self._testsfailed:
|
||||||
exitstatus = outcome.EXIT_TESTSFAILED
|
exitstatus = outcome.EXIT_TESTSFAILED
|
||||||
self.sessionfinishes(exitstatus=exitstatus, excinfo=captured_excinfo)
|
self.sessionfinishes(exitstatus=exitstatus)
|
||||||
return exitstatus
|
return exitstatus
|
||||||
|
|
Loading…
Reference in New Issue