[Pytest-commit] commit/pytest: RonnyPfannschmidt: use hook wrapping to separate logging for test, call, teardown

commits-noreply at bitbucket.org commits-noreply at bitbucket.org
Thu Feb 19 22:58:21 CET 2015


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):
+ at 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.


More information about the pytest-commit mailing list