2 new changesets in pytest:

http://bitbucket.org/hpk42/pytest/changeset/b9c849304237/
changeset:   r2193:b9c849304237
user:        flub
date:        2011-04-12 00:15:56
summary:     Allow unicode characters in testdir.makepyfile()

On python2.x text arguments where passed through str, which meant only
ascii-encodable strings could be used.  This uses
py.builting._totext() to keep unicode until it is written out to the
file, which was already UTF-8 encoded.
affected #:  2 files (265 bytes)

--- a/_pytest/pytester.py       Sat Mar 19 20:13:04 2011 +0100
+++ b/_pytest/pytester.py       Mon Apr 11 23:15:56 2011 +0100
@@ -236,13 +236,14 @@
     def _makefile(self, ext, args, kwargs):
         items = list(kwargs.items())
         if args:
-            source = "\n".join(map(str, args)) + "\n"
+            source = py.builtin._totext("\n").join(
+                map(py.builtin._totext, args)) + py.builtin._totext("\n")
             basename = self.request.function.__name__
             items.insert(0, (basename, source))
         ret = None
         for name, value in items:
             p = self.tmpdir.join(name).new(ext=ext)
-            source = str(py.code.Source(value)).lstrip()
+            source = py.builtin._totext(py.code.Source(value)).lstrip()
             p.write(source.encode("utf-8"), "wb")
             if ret is None:
                 ret = p


--- a/testing/test_pytester.py  Sat Mar 19 20:13:04 2011 +0100
+++ b/testing/test_pytester.py  Mon Apr 11 23:15:56 2011 +0100
@@ -1,3 +1,4 @@
+import py
 import pytest
 import os, sys
 from _pytest.pytester import LineMatcher, LineComp, HookRecorder
@@ -113,3 +114,12 @@
             assert res == [42]
     """)
     reprec.assertoutcome(passed=1)
+
+
+def test_makepyfile_unicode(testdir):
+    global unichr
+    try:
+        unichr(65)
+    except NameError:
+        unichr = chr
+    testdir.makepyfile(unichr(0xfffd))


http://bitbucket.org/hpk42/pytest/changeset/2a5219be3d3c/
changeset:   r2194:2a5219be3d3c
user:        flub
date:        2011-04-16 01:09:25
summary:     Prevent null-characters from appearing in junitxml's output

The Jenkins XML parser does not deal with null-characters inside the
XML.  This replaces any null character with nothing in the XML output,
which makes no visual difference.
affected #:  2 files (3.6 KB)

--- a/_pytest/junitxml.py       Mon Apr 11 23:15:56 2011 +0100
+++ b/_pytest/junitxml.py       Sat Apr 16 00:09:25 2011 +0100
@@ -5,8 +5,42 @@
 
 import py
 import os
+import re
+import sys
 import time
 
+
+# Python 2.X and 3.X compatibility
+try:
+    unichr(65)
+except NameError:
+    unichr = chr
+try:
+    unicode('A')
+except NameError:
+    unicode = str
+try:
+    long(1)
+except NameError:
+    long = int
+
+
+# We need to get the subset of the invalid unicode ranges according to
+# XML 1.0 which are valid in this python build.  Hence we calculate
+# this dynamically instead of hardcoding it.  The spec range of valid
+# chars is: Char ::= #x9 | #xA | #xD | [#x20-#xD7FF] | [#xE000-#xFFFD]
+#                    | [#x10000-#x10FFFF]
+_illegal_unichrs = [(0x00, 0x08), (0x0B, 0x0C), (0x0E, 0x19),
+                   (0xD800, 0xDFFF), (0xFDD0, 0xFFFF)]
+_illegal_ranges = [unicode("%s-%s") % (unichr(low), unichr(high))
+                  for (low, high) in _illegal_unichrs
+                  if low < sys.maxunicode]
+illegal_xml_re = re.compile(unicode('[%s]') %
+                            unicode('').join(_illegal_ranges))
+del _illegal_unichrs
+del _illegal_ranges
+
+
 def pytest_addoption(parser):
     group = parser.getgroup("terminal reporting")
     group.addoption('--junitxml', action="store", dest="xmlpath",
@@ -28,6 +62,7 @@
         del config._xml
         config.pluginmanager.unregister(xml)
 
+
 class LogXML(object):
     def __init__(self, logfile, prefix):
         self.logfile = logfile
@@ -55,7 +90,14 @@
         self.test_logs.append("</testcase>")
 
     def appendlog(self, fmt, *args):
-        args = tuple([py.xml.escape(arg) for arg in args])
+        def repl(matchobj):
+            i = ord(matchobj.group())
+            if i <= 0xFF:
+                return unicode('#x%02X') % i
+            else:
+                return unicode('#x%04X') % i
+        args = tuple([illegal_xml_re.sub(repl, py.xml.escape(arg))
+                      for arg in args])
         self.test_logs.append(fmt % args)
 
     def append_pass(self, report):


--- a/testing/test_junitxml.py  Mon Apr 11 23:15:56 2011 +0100
+++ b/testing/test_junitxml.py  Sat Apr 16 00:09:25 2011 +0100
@@ -283,3 +283,71 @@
         assert_attr(fnode, message="test failure")
         assert "custom item runtest failed" in fnode.toxml()
 
+
+def test_nullbyte(testdir):
+    # A null byte can not occur in XML (see section 2.2 of the spec)
+    testdir.makepyfile("""
+        import sys
+        def test_print_nullbyte():
+            sys.stdout.write('Here the null -->' + chr(0) + '<--')
+            sys.stdout.write('In repr form -->' + repr(chr(0)) + '<--')
+            assert False
+    """)
+    xmlf = testdir.tmpdir.join('junit.xml')
+    result = testdir.runpytest('--junitxml=%s' % xmlf)
+    text = xmlf.read()
+    assert '\x00' not in text
+    assert '#x00' in text
+
+
+def test_nullbyte_replace(testdir):
+    # Check if the null byte gets replaced
+    testdir.makepyfile("""
+        import sys
+        def test_print_nullbyte():
+            sys.stdout.write('Here the null -->' + chr(0) + '<--')
+            sys.stdout.write('In repr form -->' + repr(chr(0)) + '<--')
+            assert False
+    """)
+    xmlf = testdir.tmpdir.join('junit.xml')
+    result = testdir.runpytest('--junitxml=%s' % xmlf)
+    text = xmlf.read()
+    assert '#x0' in text
+
+
+def test_invalid_xml_escape(testdir):
+    # Test some more invalid xml chars, the full range should be
+    # tested really but let's just thest the edges of the ranges
+    # intead.
+    # XXX This only tests low unicode character points for now as
+    #     there are some issues with the testing infrastructure for
+    #     the higher ones.
+    # XXX Testing 0xD (\r) is tricky as it overwrites the just written
+    #     line in the output, so we skip it too.
+    global unichr
+    try:
+        unichr(65)
+    except NameError:
+        unichr = chr
+    u = py.builtin._totext
+    invalid = (0x1, 0xB, 0xC, 0xE, 0x19,)
+               # 0xD800, 0xDFFF, 0xFFFE, 0x0FFFF) #, 0x110000)
+    valid = (0x9, 0xA, 0x20,) # 0xD, 0xD7FF, 0xE000, 0xFFFD, 0x10000, 0x10FFFF)
+    all = invalid + valid
+    prints = [u("    sys.stdout.write('''0x%X-->%s<--''')") % (i, unichr(i))
+              for i in all]
+    testdir.makepyfile(u("# -*- coding: UTF-8 -*-"),
+                       u("import sys"),
+                       u("def test_print_bytes():"),
+                       u("\n").join(prints),
+                       u("    assert False"))
+    xmlf = testdir.tmpdir.join('junit.xml')
+    result = testdir.runpytest('--junitxml=%s' % xmlf)
+    text = xmlf.read()
+    for i in invalid:
+        if i <= 0xFF:
+            assert '#x%02X' % i in text
+        else:
+            assert '#x%04X' % i in text
+    for i in valid:
+        assert chr(i) in text

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.
_______________________________________________
py-svn mailing list
py-svn@codespeak.net
http://codespeak.net/mailman/listinfo/py-svn

Reply via email to