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