[py-svn] py-trunk commit 4f00006a2434: fix issue94 make reporting more robust against bogus source code

commits-noreply at bitbucket.org commits-noreply at bitbucket.org
Fri May 21 16:43:37 CEST 2010


# HG changeset patch -- Bitbucket.org
# Project py-trunk
# URL http://bitbucket.org/hpk42/py-trunk/overview
# User holger krekel <holger at merlinux.eu>
# Date 1274452966 -7200
# Node ID 4f00006a24344b9e763e92d3558d18fc89fff456
# Parent  9eb1cef24b56e4f61772da8776025475ca903ac9
fix issue94 make reporting more robust against bogus source code
(and internally be more careful when presenting unexpected byte sequences)
also make py.code.Source accept a list of lines directly.

--- a/py/_plugin/pytest_pytester.py
+++ b/py/_plugin/pytest_pytester.py
@@ -110,7 +110,7 @@ class TmpTestdir:
     def _makefile(self, ext, args, kwargs):
         items = list(kwargs.items())
         if args:
-            source = "\n".join(map(str, args))
+            source = "\n".join(map(str, args)) + "\n"
             basename = self.request.function.__name__
             items.insert(0, (basename, source))
         ret = None
@@ -294,8 +294,10 @@ class TmpTestdir:
         ret = popen.wait()
         f1.close()
         f2.close()
-        out = p1.read("rb").decode("utf-8").splitlines()
-        err = p2.read("rb").decode("utf-8").splitlines()
+        out = p1.read("rb")
+        out = getdecoded(out).splitlines()
+        err = p2.read("rb")
+        err = getdecoded(err).splitlines()
         def dump_lines(lines, fp):
             try:
                 for line in lines:
@@ -360,6 +362,13 @@ class TmpTestdir:
         child.timeout = expect_timeout
         return child
 
+def getdecoded(out):
+        try:
+            return out.decode("utf-8")
+        except UnicodeDecodeError:
+            return "INTERNAL not-utf8-decodeable, truncated string:\n%s" % (
+                    py.io.saferepr(out),)
+
 class PseudoPlugin:
     def __init__(self, vars):
         self.__dict__.update(vars) 

--- a/testing/code/test_source.py
+++ b/testing/code/test_source.py
@@ -36,6 +36,19 @@ def test_source_from_function():
     source = py.code.Source(test_source_str_function)
     assert str(source).startswith('def test_source_str_function():')
 
+def test_source_from_method():
+    class TestClass:
+        def test_method(self):
+            pass
+    source = py.code.Source(TestClass().test_method)
+    assert source.lines == ["def test_method(self):",
+                            "    pass"]
+
+def test_source_from_lines():
+    lines = ["a \n", "b\n", "c"]
+    source = py.code.Source(lines)
+    assert source.lines == ['a ', 'b', 'c']
+
 def test_source_from_inner_function():
     def f():
         pass
@@ -92,6 +105,7 @@ def test_isparseable():
     assert Source(" \nif 1:\n  pass").isparseable()
     assert not Source("if 1:\n").isparseable() 
     assert not Source(" \nif 1:\npass").isparseable()
+    assert not Source(chr(0)).isparseable()
 
 class TestAccesses:
     source = Source("""\

--- a/py/_code/source.py
+++ b/py/_code/source.py
@@ -26,6 +26,8 @@ class Source(object):
                 partlines = []
             if isinstance(part, Source):
                 partlines = part.lines
+            elif isinstance(part, (tuple, list)):
+                partlines = [x.rstrip("\n") for x in part]
             elif isinstance(part, py.builtin._basestring):
                 partlines = part.split('\n')
                 if rstrip:
@@ -172,7 +174,9 @@ class Source(object):
         try:
             #compile(source+'\n', "x", "exec")
             syntax_checker(source+'\n')
-        except SyntaxError:
+        except KeyboardInterrupt:
+            raise
+        except Exception:
             return False
         else:
             return True

--- a/CHANGELOG
+++ b/CHANGELOG
@@ -17,6 +17,9 @@ Changes between 1.3.0 and 1.3.1
   declarative approach with the @py.test.mark.xfail cannot
   be used as it would mark all configurations as xfail. 
 
+- fix issue94: make reporting more robust against bogus source code
+  (and internally be more careful when presenting unexpected byte sequences)
+
 - improve and refine letter reporting in the progress bar:
   .  pass
   f  failed test



More information about the pytest-commit mailing list