1 new commit in pytest: https://bitbucket.org/hpk42/pytest/commits/c321b799400d/ Changeset: c321b799400d Branch: copy-in-cache User: RonnyPfannschmidt Date: 2015-02-19 21:58:11+00:00 Summary: use hook wrapping to separate logging for test, call, teardown Affected #: 3 files
diff -r 7c39287ab3d0b487a74f38930df27de1f17ade08 -r c321b799400db373e4f10b50cb6cb43961109c23 _pytest/cache.py --- a/_pytest/cache.py +++ b/_pytest/cache.py @@ -117,8 +117,12 @@ def pytest_addoption(parser): - outside_looponfail = 'xdist' in sys.modules and \ - 'looponfail.py' in pkg_resources.resource_listdir('xdist', '.') + try: + ls = pkg_resources.resource_listdir('xdist', '.') + except: + outside_looponfail = False + else: + outside_looponfail = 'looponfail.py' in ls group = parser.getgroup("general") group.addoption( diff -r 7c39287ab3d0b487a74f38930df27de1f17ade08 -r c321b799400db373e4f10b50cb6cb43961109c23 _pytest/capture_log.py --- a/_pytest/capture_log.py +++ b/_pytest/capture_log.py @@ -110,6 +110,7 @@ import py import logging +import pytest LOG_FORMAT = '%(filename)-25s %(lineno)4d %(levelname)-8s %(message)s' @@ -137,7 +138,7 @@ """Activate log capturing if appropriate.""" if config.getvalue('capturelog'): - config.pluginmanager.register(CaptureLogPlugin(config), '_capturelog') + config.pluginmanager.register(CaptureLogPlugin(config), 'capturelog') class CaptureLogPlugin(object): @@ -153,6 +154,7 @@ self.formatter = logging.Formatter(config.getvalue('log_format'), config.getvalue('log_date_format')) + @pytest.mark.hookwrapper def pytest_runtest_setup(self, item): """Start capturing log messages for this test. @@ -173,6 +175,11 @@ root_logger = logging.getLogger() root_logger.addHandler(item.capturelog_handler) root_logger.setLevel(logging.NOTSET) + yield + item.capturelog_handler.close() + root_logger.removeHandler(item.capturelog_handler) + + pytest_runtest_teardown = pytest_runtest_call = pytest_runtest_setup def pytest_runtest_makereport(self, __multicall__, item, call): """Add captured log messages for this report.""" @@ -182,23 +189,11 @@ # This fn called after setup, call and teardown. Only # interested in just after test call has finished. if call.when == 'call': - - # Detach the handler from the root logger to ensure no - # further access to the handler. - root_logger = logging.getLogger() - root_logger.removeHandler(item.capturelog_handler) - - # For failed tests that have captured log messages add a - # captured log section to the report. - if not report.passed: - longrepr = getattr(report, 'longrepr', None) - if hasattr(longrepr, 'addsection'): - log = item.capturelog_handler.stream.getvalue().strip() - if log: - longrepr.addsection('Captured log', log) - - # Release the handler resources. - item.capturelog_handler.close() + longrepr = getattr(report, 'longrepr', None) + if hasattr(longrepr, 'addsection'): + log = item.capturelog_handler.value.strip() + if log: + report.sections.append(('Captured log ' + call.when, log)) del item.capturelog_handler return report @@ -212,11 +207,19 @@ logging.StreamHandler.__init__(self) self.stream = py.io.TextIO() - self.records = [] + self.records = [] + self._value = None + + @property + def value(self): + if self._value is None: + return self.stream.getvalue() + else: + return self._value def close(self): """Close this log handler and its underlying stream.""" - + self._value = self.stream.getvalue() logging.StreamHandler.close(self) self.stream.close() @@ -230,15 +233,19 @@ class CaptureLogFuncArg(object): """Provides access and control of log capturing.""" - def __init__(self, handler): + def __init__(self, node): """Creates a new funcarg.""" - self.handler = handler + self.node = node + + @property + def handler(self): + return self.node.capturelog_handler def text(self): """Returns the log text.""" - return self.handler.stream.getvalue() + return self.handler.value def records(self): """Returns the list of log records.""" @@ -288,14 +295,8 @@ self.obj.setLevel(self.orig_level) - -def pytest_funcarg__caplog(request): +@pytest.fixture +def caplog(request): """Returns a funcarg to access and control log capturing.""" - return CaptureLogFuncArg(request._pyfuncitem.capturelog_handler) - - -def pytest_funcarg__capturelog(request): - """Returns a funcarg to access and control log capturing.""" - - return CaptureLogFuncArg(request._pyfuncitem.capturelog_handler) + return CaptureLogFuncArg(request.node) diff -r 7c39287ab3d0b487a74f38930df27de1f17ade08 -r c321b799400db373e4f10b50cb6cb43961109c23 _pytest/onchange.py --- a/_pytest/onchange.py +++ b/_pytest/onchange.py @@ -1,5 +1,5 @@ import py - +import subprocess SCRIPT = """ import pytest @@ -7,6 +7,14 @@ """ +def run_once(args, tw=None): + tw = py.io.TerminalWriter() + subprocess.call(args) + tw.line() + tw.sep('#', 'waiting for changes') + tw.line() + + def looponchange(config): newargs = config._origargs[:] if '--looponchange' in newargs: @@ -14,10 +22,8 @@ else: newargs.remove('-f') stats = StatRecorder(config.getini('looponchangeroots')) - command = py.std.functools.partial( - py.std.subprocess.call, [ - py.std.sys.executable, - '-c', SCRIPT % newargs]) + command = py.std.functools.partial(run_once, [ + py.std.sys.executable, '-c', SCRIPT % newargs]) command() loop_forever(stats, command) return 2 Repository URL: https://bitbucket.org/hpk42/pytest/ -- This is a commit notification from bitbucket.org. You are receiving this because you have the service enabled, addressing the recipient of this email. _______________________________________________ pytest-commit mailing list pytest-commit@python.org https://mail.python.org/mailman/listinfo/pytest-commit