- Add patch to allow docutils to read unicode source - Update specf38
parent
f4dd3e3464
commit
0f74bcca1b
@ -0,0 +1,33 @@
|
|||||||
|
diff -up nose-1.3.7/functional_tests/test_load_tests_from_test_case.py.py35 nose-1.3.7/functional_tests/test_load_tests_from_test_case.py
|
||||||
|
--- nose-1.3.7/functional_tests/test_load_tests_from_test_case.py.py35 2012-09-29 02:18:54.000000000 -0600
|
||||||
|
+++ nose-1.3.7/functional_tests/test_load_tests_from_test_case.py 2016-11-15 13:42:27.946707472 -0700
|
||||||
|
@@ -29,6 +29,7 @@ class NoFixturePlug(Plugin):
|
||||||
|
pass
|
||||||
|
def tearDown(self):
|
||||||
|
pass
|
||||||
|
+ Derived.__qualname__ = Derived.__name__
|
||||||
|
# must use nose loader here because the default loader in 2.3
|
||||||
|
# won't load tests from base classes
|
||||||
|
l = loader.TestLoader()
|
||||||
|
diff -up nose-1.3.7/nose/util.py.py35 nose-1.3.7/nose/util.py
|
||||||
|
--- nose-1.3.7/nose/util.py.py35 2015-04-04 02:52:52.000000000 -0600
|
||||||
|
+++ nose-1.3.7/nose/util.py 2016-11-15 13:42:27.946707472 -0700
|
||||||
|
@@ -643,6 +643,7 @@ def transplant_class(cls, module):
|
||||||
|
pass
|
||||||
|
C.__module__ = module
|
||||||
|
C.__name__ = cls.__name__
|
||||||
|
+ C.__qualname__ = cls.__name__
|
||||||
|
return C
|
||||||
|
|
||||||
|
|
||||||
|
diff -up nose-1.3.7/unit_tests/test_xunit.py.py35 nose-1.3.7/unit_tests/test_xunit.py
|
||||||
|
--- nose-1.3.7/unit_tests/test_xunit.py.py35 2015-04-04 02:52:52.000000000 -0600
|
||||||
|
+++ nose-1.3.7/unit_tests/test_xunit.py 2016-11-15 13:42:27.946707472 -0700
|
||||||
|
@@ -16,6 +16,7 @@ def mktest():
|
||||||
|
class TC(unittest.TestCase):
|
||||||
|
def runTest(self):
|
||||||
|
pass
|
||||||
|
+ TC.__qualname__ = TC.__name__
|
||||||
|
test = TC()
|
||||||
|
return test
|
||||||
|
|
@ -0,0 +1,20 @@
|
|||||||
|
diff -up nose-1.3.7/nose/plugins/doctests.py.readunicode nose-1.3.7/nose/plugins/doctests.py
|
||||||
|
--- nose-1.3.7/nose/plugins/doctests.py.readunicode 2015-04-04 02:52:52.000000000 -0600
|
||||||
|
+++ nose-1.3.7/nose/plugins/doctests.py 2016-11-15 14:24:54.298239018 -0700
|
||||||
|
@@ -49,6 +49,7 @@ test.
|
||||||
|
"""
|
||||||
|
from __future__ import generators
|
||||||
|
|
||||||
|
+import codecs
|
||||||
|
import logging
|
||||||
|
import os
|
||||||
|
import sys
|
||||||
|
@@ -259,7 +260,7 @@ class Doctest(Plugin):
|
||||||
|
"""
|
||||||
|
if self.extension and anyp(filename.endswith, self.extension):
|
||||||
|
name = os.path.basename(filename)
|
||||||
|
- dh = open(filename)
|
||||||
|
+ dh = codecs.open(filename, encoding='utf-8')
|
||||||
|
try:
|
||||||
|
doc = dh.read()
|
||||||
|
finally:
|
@ -0,0 +1,128 @@
|
|||||||
|
diff -up nose-1.3.7/AUTHORS.unicode nose-1.3.7/AUTHORS
|
||||||
|
diff -up nose-1.3.7/CHANGELOG.unicode nose-1.3.7/CHANGELOG
|
||||||
|
diff -up nose-1.3.7/nose/plugins/capture.py.unicode nose-1.3.7/nose/plugins/capture.py
|
||||||
|
--- nose-1.3.7/nose/plugins/capture.py.unicode 2015-04-04 02:52:52.000000000 -0600
|
||||||
|
+++ nose-1.3.7/nose/plugins/capture.py 2016-11-15 13:58:18.713025335 -0700
|
||||||
|
@@ -12,6 +12,7 @@ the options ``-s`` or ``--nocapture``.
|
||||||
|
import logging
|
||||||
|
import os
|
||||||
|
import sys
|
||||||
|
+import traceback
|
||||||
|
from nose.plugins.base import Plugin
|
||||||
|
from nose.pyversion import exc_to_unicode, force_unicode
|
||||||
|
from nose.util import ln
|
||||||
|
@@ -71,26 +72,56 @@ class Capture(Plugin):
|
||||||
|
def formatError(self, test, err):
|
||||||
|
"""Add captured output to error report.
|
||||||
|
"""
|
||||||
|
- test.capturedOutput = output = self.buffer
|
||||||
|
+ test.capturedOutput = output = ''
|
||||||
|
+ output_exc_info = None
|
||||||
|
+ try:
|
||||||
|
+ test.capturedOutput = output = self.buffer
|
||||||
|
+ except UnicodeError:
|
||||||
|
+ # python2's StringIO.StringIO [1] class has this warning:
|
||||||
|
+ #
|
||||||
|
+ # The StringIO object can accept either Unicode or 8-bit strings,
|
||||||
|
+ # but mixing the two may take some care. If both are used, 8-bit
|
||||||
|
+ # strings that cannot be interpreted as 7-bit ASCII (that use the
|
||||||
|
+ # 8th bit) will cause a UnicodeError to be raised when getvalue()
|
||||||
|
+ # is called.
|
||||||
|
+ #
|
||||||
|
+ # This exception handler is a protection against issue #816 [2].
|
||||||
|
+ # Capturing the exception info allows us to display it back to the
|
||||||
|
+ # user.
|
||||||
|
+ #
|
||||||
|
+ # [1] <https://github.com/python/cpython/blob/2.7/Lib/StringIO.py#L258>
|
||||||
|
+ # [2] <https://github.com/nose-devs/nose/issues/816>
|
||||||
|
+ output_exc_info = sys.exc_info()
|
||||||
|
self._buf = None
|
||||||
|
- if not output:
|
||||||
|
+ if (not output) and (not output_exc_info):
|
||||||
|
# Don't return None as that will prevent other
|
||||||
|
# formatters from formatting and remove earlier formatters
|
||||||
|
# formats, instead return the err we got
|
||||||
|
return err
|
||||||
|
ec, ev, tb = err
|
||||||
|
- return (ec, self.addCaptureToErr(ev, output), tb)
|
||||||
|
+ return (ec, self.addCaptureToErr(ev, output, output_exc_info=output_exc_info), tb)
|
||||||
|
|
||||||
|
def formatFailure(self, test, err):
|
||||||
|
"""Add captured output to failure report.
|
||||||
|
"""
|
||||||
|
return self.formatError(test, err)
|
||||||
|
|
||||||
|
- def addCaptureToErr(self, ev, output):
|
||||||
|
+ def addCaptureToErr(self, ev, output, output_exc_info=None):
|
||||||
|
+ # If given, output_exc_info should be a 3-tuple from sys.exc_info(),
|
||||||
|
+ # from an exception raised while trying to get the captured output.
|
||||||
|
ev = exc_to_unicode(ev)
|
||||||
|
output = force_unicode(output)
|
||||||
|
- return u'\n'.join([ev, ln(u'>> begin captured stdout <<'),
|
||||||
|
- output, ln(u'>> end captured stdout <<')])
|
||||||
|
+ error_text = [ev, ln(u'>> begin captured stdout <<'),
|
||||||
|
+ output, ln(u'>> end captured stdout <<')]
|
||||||
|
+ if output_exc_info:
|
||||||
|
+ error_text.extend([u'OUTPUT ERROR: Could not get captured output.',
|
||||||
|
+ # <https://github.com/python/cpython/blob/2.7/Lib/StringIO.py#L258>
|
||||||
|
+ # <https://github.com/nose-devs/nose/issues/816>
|
||||||
|
+ u"The test might've printed both 'unicode' strings and non-ASCII 8-bit 'str' strings.",
|
||||||
|
+ ln(u'>> begin captured stdout exception traceback <<'),
|
||||||
|
+ u''.join(traceback.format_exception(*output_exc_info)),
|
||||||
|
+ ln(u'>> end captured stdout exception traceback <<')])
|
||||||
|
+ return u'\n'.join(error_text)
|
||||||
|
|
||||||
|
def start(self):
|
||||||
|
self.stdout.append(sys.stdout)
|
||||||
|
diff -up nose-1.3.7/unit_tests/test_capture_plugin.py.unicode nose-1.3.7/unit_tests/test_capture_plugin.py
|
||||||
|
--- nose-1.3.7/unit_tests/test_capture_plugin.py.unicode 2012-09-29 02:18:54.000000000 -0600
|
||||||
|
+++ nose-1.3.7/unit_tests/test_capture_plugin.py 2016-11-15 13:58:18.714025330 -0700
|
||||||
|
@@ -4,6 +4,12 @@ import unittest
|
||||||
|
from optparse import OptionParser
|
||||||
|
from nose.config import Config
|
||||||
|
from nose.plugins.capture import Capture
|
||||||
|
+from nose.pyversion import force_unicode
|
||||||
|
+
|
||||||
|
+if sys.version_info[0] == 2:
|
||||||
|
+ py2 = True
|
||||||
|
+else:
|
||||||
|
+ py2 = False
|
||||||
|
|
||||||
|
class TestCapturePlugin(unittest.TestCase):
|
||||||
|
|
||||||
|
@@ -62,6 +68,35 @@ class TestCapturePlugin(unittest.TestCas
|
||||||
|
c.end()
|
||||||
|
self.assertEqual(c.buffer, "test 日本\n")
|
||||||
|
|
||||||
|
+ def test_does_not_crash_with_mixed_unicode_and_nonascii_str(self):
|
||||||
|
+ class Dummy:
|
||||||
|
+ pass
|
||||||
|
+ d = Dummy()
|
||||||
|
+ c = Capture()
|
||||||
|
+ c.start()
|
||||||
|
+ printed_nonascii_str = force_unicode("test 日本").encode('utf-8')
|
||||||
|
+ printed_unicode = force_unicode("Hello")
|
||||||
|
+ print printed_nonascii_str
|
||||||
|
+ print printed_unicode
|
||||||
|
+ try:
|
||||||
|
+ raise Exception("boom")
|
||||||
|
+ except:
|
||||||
|
+ err = sys.exc_info()
|
||||||
|
+ formatted = c.formatError(d, err)
|
||||||
|
+ _, fev, _ = formatted
|
||||||
|
+
|
||||||
|
+ if py2:
|
||||||
|
+ for string in [force_unicode(printed_nonascii_str, encoding='utf-8'), printed_unicode]:
|
||||||
|
+ assert string not in fev, "Output unexpectedly found in error message"
|
||||||
|
+ assert d.capturedOutput == '', "capturedOutput unexpectedly non-empty"
|
||||||
|
+ assert "OUTPUT ERROR" in fev
|
||||||
|
+ assert "captured stdout exception traceback" in fev
|
||||||
|
+ assert "UnicodeDecodeError" in fev
|
||||||
|
+ else:
|
||||||
|
+ for string in [repr(printed_nonascii_str), printed_unicode]:
|
||||||
|
+ assert string in fev, "Output not found in error message"
|
||||||
|
+ assert string in d.capturedOutput, "Output not attached to test"
|
||||||
|
+
|
||||||
|
def test_format_error(self):
|
||||||
|
class Dummy:
|
||||||
|
pass
|
Loading…
Reference in new issue