[py-svn] pytest commit 057049589d52: fix skip reporting over distributed testing. if we have a "skip" report

commits-noreply at bitbucket.org commits-noreply at bitbucket.org
Sat Nov 13 21:04:24 CET 2010


# HG changeset patch -- Bitbucket.org
# Project pytest
# URL http://bitbucket.org/hpk42/pytest/overview
# User holger krekel <holger at merlinux.eu>
# Date 1289678608 -3600
# Node ID 057049589d52958d8561f45d88264ab3622ff70f
# Parent  01f97e561a1afcb664558a7fb6e5bb92fd6e9bcb
fix skip reporting over distributed testing.  if we have a "skip" report
rep.longrepr will now be a 3-tuple (path, lineno, message)

--- a/testing/test_skipping.py
+++ b/testing/test_skipping.py
@@ -366,11 +366,10 @@ def test_skipif_class(testdir):
 
 
 def test_skip_reasons_folding():
-    class longrepr:
-        class reprcrash:
-            path = 'xyz'
-            lineno = 3
-            message = "justso"
+    path = 'xyz'
+    lineno = 3
+    message = "justso"
+    longrepr = (path, lineno, message)
 
     class X:
         pass
@@ -387,9 +386,9 @@ def test_skip_reasons_folding():
     assert len(l) == 1
     num, fspath, lineno, reason = l[0]
     assert num == 2
-    assert fspath == longrepr.reprcrash.path
-    assert lineno == longrepr.reprcrash.lineno
-    assert reason == longrepr.reprcrash.message
+    assert fspath == path
+    assert lineno == lineno
+    assert reason == message
 
 def test_skipped_reasons_functional(testdir):
     testdir.makepyfile(

--- a/_pytest/runner.py
+++ b/_pytest/runner.py
@@ -111,9 +111,21 @@ class CallInfo:
             status = "result: %r" % (self.result,)
         return "<CallInfo when=%r %s>" % (self.when, status)
 
+def getslaveinfoline(node):
+    try:
+        return node._slaveinfocache
+    except AttributeError:
+        d = node.slaveinfo
+        ver = "%s.%s.%s" % d['version_info'][:3]
+        node._slaveinfocache = s = "[%s] %s -- Python %s %s" % (
+            d['id'], d['sysplatform'], ver, d['executable'])
+        return s
+
 class BaseReport(object):
     def toterminal(self, out):
         longrepr = self.longrepr
+        if hasattr(self, 'node'):
+            out.line(getslaveinfoline(self.node))
         if hasattr(longrepr, 'toterminal'):
             longrepr.toterminal(out)
         else:
@@ -140,7 +152,8 @@ def pytest_runtest_makereport(item, call
             longrepr = excinfo
         elif excinfo.errisinstance(py.test.skip.Exception):
             outcome = "skipped"
-            longrepr = item._repr_failure_py(excinfo)
+            r = item._repr_failure_py(excinfo, "line").reprcrash
+            longrepr = (str(r.path), r.lineno, r.message)
         else:
             outcome = "failed"
             if call.when == "call":
@@ -189,14 +202,14 @@ class TeardownErrorReport(BaseReport):
 
 def pytest_make_collect_report(collector):
     call = CallInfo(collector._memocollect, "memocollect")
-    reason = longrepr = None
+    longrepr = None
     if not call.excinfo:
         outcome = "passed"
     else:
         if call.excinfo.errisinstance(py.test.skip.Exception):
             outcome = "skipped"
-            reason = str(call.excinfo.value)
-            longrepr = collector._repr_failure_py(call.excinfo, "line")
+            r = collector._repr_failure_py(call.excinfo, "line").reprcrash
+            longrepr = (str(r.path), r.lineno, r.message)
         else:
             outcome = "failed"
             errorinfo = collector.repr_failure(call.excinfo)
@@ -204,15 +217,14 @@ def pytest_make_collect_report(collector
                 errorinfo = CollectErrorRepr(errorinfo)
             longrepr = errorinfo
     return CollectReport(collector.nodeid, outcome, longrepr,
-        getattr(call, 'result', None), reason)
+        getattr(call, 'result', None))
 
 class CollectReport(BaseReport):
-    def __init__(self, nodeid, outcome, longrepr, result, reason):
+    def __init__(self, nodeid, outcome, longrepr, result):
         self.nodeid = nodeid
         self.outcome = outcome
         self.longrepr = longrepr
         self.result = result or []
-        self.reason = reason
 
     @property
     def location(self):
@@ -355,6 +367,7 @@ def importorskip(modname, minversion=Non
     optionally specified 'minversion' - otherwise call py.test.skip()
     with a message detailing the mismatch.
     """
+    __tracebackhide__ = True
     compile(modname, '', 'eval') # to catch syntaxerrors
     try:
         mod = __import__(modname, None, None, ['__doc__'])

--- a/_pytest/terminal.py
+++ b/_pytest/terminal.py
@@ -389,7 +389,7 @@ class CollectonlyReporter:
                 msg = report.longrepr.reprcrash.message
             else:
                 # XXX unify (we have CollectErrorRepr here)
-                msg = str(report.longrepr.longrepr)
+                msg = str(report.longrepr[2])
             self.outindent("!!! %s !!!" % msg)
             #self.outindent("!!! error !!!")
             self._failed.append(report)

--- a/_pytest/skipping.py
+++ b/_pytest/skipping.py
@@ -186,8 +186,8 @@ def cached_eval(config, expr, d):
 def folded_skips(skipped):
     d = {}
     for event in skipped:
-        entry = event.longrepr.reprcrash
-        key = entry.path, entry.lineno, entry.message
+        key = event.longrepr
+        assert len(key) == 3, (event, key)
         d.setdefault(key, []).append(event)
     l = []
     for key, events in d.items():

--- a/pytest.py
+++ b/pytest.py
@@ -5,7 +5,7 @@ see http://pytest.org for documentation 
 
 (c) Holger Krekel and others, 2004-2010
 """
-__version__ = '2.0.0.dev27'
+__version__ = '2.0.0.dev28'
 __all__ = ['main']
 
 from _pytest.core import main, UsageError, _preloadplugins

--- a/setup.py
+++ b/setup.py
@@ -22,7 +22,7 @@ def main():
         name='pytest',
         description='py.test: simple powerful testing with Python',
         long_description = long_description,
-        version='2.0.0.dev27',
+        version='2.0.0.dev28',
         url='http://pytest.org',
         license='MIT license',
         platforms=['unix', 'linux', 'osx', 'cygwin', 'win32'],

--- a/_pytest/resultlog.py
+++ b/_pytest/resultlog.py
@@ -74,17 +74,18 @@ class ResultLog(object):
         elif report.failed:
             longrepr = str(report.longrepr)
         elif report.skipped:
-            longrepr = str(report.longrepr.reprcrash.message)
+            longrepr = str(report.longrepr[2])
         self.log_outcome(report, code, longrepr)
 
     def pytest_collectreport(self, report):
         if not report.passed:
             if report.failed:
                 code = "F"
+                longrepr = str(report.longrepr.reprcrash)
             else:
                 assert report.skipped
                 code = "S"
-            longrepr = str(report.longrepr.reprcrash)
+                longrepr = "%s:%d: %s" % report.longrepr
             self.log_outcome(report, code, longrepr)
 
     def pytest_internalerror(self, excrepr):

--- a/testing/test_runner.py
+++ b/testing/test_runner.py
@@ -344,13 +344,18 @@ def test_exception_printing_skip():
 
 def test_importorskip():
     importorskip = py.test.importorskip
+    def f():
+        importorskip("asdlkj")
     try:
         sys = importorskip("sys")
         assert sys == py.std.sys
         #path = py.test.importorskip("os.path")
         #assert path == py.std.os.path
-        py.test.raises(py.test.skip.Exception,
-            "py.test.importorskip('alskdj')")
+        excinfo = py.test.raises(py.test.skip.Exception, f)
+        path = py.path.local(excinfo.getrepr().reprcrash.path)
+        # check that importorskip reports the actual call
+        # in this test the test_runner.py file
+        assert path.purebasename == "test_runner"
         py.test.raises(SyntaxError, "py.test.importorskip('x y z')")
         py.test.raises(SyntaxError, "py.test.importorskip('x=y')")
         path = importorskip("py", minversion=".".join(py.__version__))



More information about the pytest-commit mailing list