aboutsummaryrefslogtreecommitdiffstats
path: root/main/py-nose
diff options
context:
space:
mode:
authorJakub Jirutka <jakub@jirutka.cz>2017-06-30 00:10:34 +0200
committerJakub Jirutka <jakub@jirutka.cz>2017-06-30 00:11:46 +0200
commit430209682f76651efadf255116830965ed295d5c (patch)
tree041158b686159e8f526b48afdaed323f2f8888a3 /main/py-nose
parentb16c1e47001d6a97b758ee5fb6fc47caa797d02c (diff)
downloadaports-430209682f76651efadf255116830965ed295d5c.tar.bz2
aports-430209682f76651efadf255116830965ed295d5c.tar.xz
main/py-nose: add py2/py3 subpackages and check
Patches are ported from Fedora.
Diffstat (limited to 'main/py-nose')
-rw-r--r--main/py-nose/APKBUILD80
-rw-r--r--main/py-nose/coverage4-compat.patch41
-rw-r--r--main/py-nose/fix-crashing-from-UnicodeDecodeError.patch152
-rw-r--r--main/py-nose/fix-doctests-unicode.patch21
-rw-r--r--main/py-nose/python3.5-compat.patch42
-rw-r--r--main/py-nose/python3.6-compat.patch61
6 files changed, 388 insertions, 9 deletions
diff --git a/main/py-nose/APKBUILD b/main/py-nose/APKBUILD
index d92a86ddbd..a8a2da4524 100644
--- a/main/py-nose/APKBUILD
+++ b/main/py-nose/APKBUILD
@@ -3,24 +3,86 @@
pkgname=py-nose
_pkgname=nose
pkgver=1.3.7
-pkgrel=0
+pkgrel=1
pkgdesc="A Python unittest module"
url="http://readthedocs.org/docs/nose/"
arch="noarch"
license="LGPL2+"
-depends="python2 py-setuptools"
-makedepends="python2-dev"
-source="https://files.pythonhosted.org/packages/source/${_pkgname:0:1}/$_pkgname/$_pkgname-$pkgver.tar.gz"
-builddir="$srcdir"/$_pkgname-$pkgver
+makedepends="python2-dev python3-dev py-setuptools"
+subpackages="$pkgname-doc py2-$_pkgname:_py2 py3-$_pkgname:_py3"
+source="https://files.pythonhosted.org/packages/source/${_pkgname:0:1}/$_pkgname/$_pkgname-$pkgver.tar.gz
+ coverage4-compat.patch
+ python3.5-compat.patch
+ fix-crashing-from-UnicodeDecodeError.patch
+ fix-doctests-unicode.patch
+ python3.6-compat.patch"
+builddir="$srcdir/$_pkgname-$pkgver"
+
+prepare() {
+ default_prepare
+
+ cd "$builddir"/examples
+ cat attrib_plugin.py | tr -d '\r' > attrib_plugin.py.fixed
+ mv attrib_plugin.py.fixed attrib_plugin.py
+
+ # Soure files are modified during build with 2to3 tool, so we cannot
+ # build it for both Python versions in the same location.
+ local python; for python in python2 python3; do
+ cp -r "$builddir" "$builddir-$python"
+ done
+}
build() {
- cd "$builddir"
- python2 setup.py build
+ local python; for python in python2 python3; do
+ cd "$builddir"-$python
+ $python setup.py build
+ done
+}
+
+check() {
+ msg "Testing on python2"
+ cd "$builddir-python2"
+ python2 selftest.py
+
+ msg "Testing on python3"
+ cd "$builddir-python3"
+ (
+ export PYTHONPATH="$(pwd)/build/lib"
+ python3 setup.py build_tests
+ python3 selftest.py
+ )
}
package() {
cd "$builddir"
- python2 setup.py install --prefix=/usr --root="$pkgdir"
+ install -D -m 644 nosetests.1 "$pkgdir"/usr/share/man/man1/nosetests.1
+}
+
+_py2() {
+ replaces="$pkgname"
+ _py python2
+ rm "$subpkgdir"/usr/bin/nosetests
+}
+
+_py3() {
+ _py python3
+}
+
+_py() {
+ local python="$1"
+ pkgdesc="$pkgdesc (for $python)"
+ depends="$python"
+ install_if="$pkgname=$pkgver-r$pkgrel $python"
+
+ cd "$builddir"-$python
+
+ $python setup.py install --prefix=/usr --root="$subpkgdir"
+ rm -rf "$subpkgdir"/usr/man
}
-sha512sums="e65c914f621f8da06b9ab11a0ff2763d6e29b82ce2aaed56da0e3773dc899d9deb1f20015789d44c65a5dad7214520f5b659b3f8d7695fb207ad3f78e5cf1b62 nose-1.3.7.tar.gz"
+sha512sums="e65c914f621f8da06b9ab11a0ff2763d6e29b82ce2aaed56da0e3773dc899d9deb1f20015789d44c65a5dad7214520f5b659b3f8d7695fb207ad3f78e5cf1b62 nose-1.3.7.tar.gz
+90238837b7d67a425c816e2160641aa55b8b0193d8b86c46efdd3d15b2d73880c8d6ad658bac40216bc9d8104de491bcec629cf7bfcf9f7a2022b7deec668f39 coverage4-compat.patch
+68693cda7a9d5787f56a26bd98949817e67d8795c324c968cb8af599e1e5f190531f80fc71de1233b88918f21f558f4d81f92dde529f908a0a66e5dd80b7ec21 python3.5-compat.patch
+741b97c6f8e33a8a712bb9db148cf869189065d0ea0c07b361356470b370a78e5075e6f631eb7fc714ace29c6904ee0324494b86cfe3414a6bb97193b5d77e52 fix-crashing-from-UnicodeDecodeError.patch
+bcc01fb8283ea097739db5d52be6c1835cbc6f8a14a235f921d1b2b1d70ac0d91a039781e40dba55d5b5380aa963409223cf79a636fce756fe100a37e500503b fix-doctests-unicode.patch
+9c47a73a16766e77d086c1a0bb1cc59064eb5755c0d46bfd1814b1aa90dc90c672dda03547abff389f5a05633eff7a3991e41c5e61c12cf51080a08a71f79199 python3.6-compat.patch"
diff --git a/main/py-nose/coverage4-compat.patch b/main/py-nose/coverage4-compat.patch
new file mode 100644
index 0000000000..e77a080f24
--- /dev/null
+++ b/main/py-nose/coverage4-compat.patch
@@ -0,0 +1,41 @@
+From: Dmitry Shachnev <mitya57@gmail.com>
+Date: Wed, 29 Jun 2016 13:15:16 +0300
+Subject: [PATCH] Make coverage plugin compatible with Coverage.py 4.1
+
+According to the Coverage.py 4.1 changelog:
+
+- The `Coverage.report` function had two parameters with non-None defaults,
+ which have been changed. `show_missing` used to default to True, but now
+ defaults to None. If you had been calling `Coverage.report` without
+ specifying `show_missing`, you'll need to explicitly set it to True to keep
+ the same behavior.
+
+Without that option, four tests in nose fail:
+
+- test_coverage_plugin.TestCoverageMinPercentagePlugin
+- test_coverage_plugin.TestCoverageMinPercentageSinglePackagePlugin
+- test_coverage_plugin.TestCoverageMinPercentageSinglePackageWithBranchesPlugin
+- test_coverage_plugin.TestCoveragePlugin
+
+Patch-Source: https://github.com/nose-devs/nose/pull/1004
+
+--- a/nose/plugins/cover.py
++++ b/nose/plugins/cover.py
+@@ -187,7 +187,7 @@
+ for name, module in sys.modules.items()
+ if self.wantModuleCoverage(name, module)]
+ log.debug("Coverage report will cover modules: %s", modules)
+- self.coverInstance.report(modules, file=stream)
++ self.coverInstance.report(modules, file=stream, show_missing=True)
+
+ import coverage
+ if self.coverHtmlDir:
+@@ -207,7 +207,7 @@
+ # make sure we have minimum required coverage
+ if self.coverMinPercentage:
+ f = StringIO.StringIO()
+- self.coverInstance.report(modules, file=f)
++ self.coverInstance.report(modules, file=f, show_missing=True)
+
+ multiPackageRe = (r'-------\s\w+\s+\d+\s+\d+(?:\s+\d+\s+\d+)?'
+ r'\s+(\d+)%\s+\d*\s{0,1}$')
diff --git a/main/py-nose/fix-crashing-from-UnicodeDecodeError.patch b/main/py-nose/fix-crashing-from-UnicodeDecodeError.patch
new file mode 100644
index 0000000000..9154ab0862
--- /dev/null
+++ b/main/py-nose/fix-crashing-from-UnicodeDecodeError.patch
@@ -0,0 +1,152 @@
+From: Jordan Moldow <jmoldow@box.com>
+Date: Wed, 23 Mar 2016 01:42:37 -0700
+Subject: [PATCH] Prevent crashing from UnicodeDecodeError
+
+On Python 2, `sys.stdout` and `print` can normally handle any
+combination of `str` and `unicode` objects. However,
+`StringIO.StringIO` can only safely handle one or the other. If
+the program writes both a `unicode` string, and a non-ASCII
+`str` string, then the `getvalue()` method will fail with
+`UnicodeDecodeError` [1].
+
+In nose, that causes the script to suddenly abort, with the
+cryptic `UnicodeDecodeError`.
+
+This fix catches `UnicodeError` when trying to get the captured
+output, and will replace the captured output with a warning
+message.
+
+Fixes #816
+
+[1] <https://github.com/python/cpython/blob/2.7/Lib/StringIO.py#L258>
+
+Patch-Source: https://github.com/nose-devs/nose/pull/988
+
+diff --git a/nose/plugins/capture.py b/nose/plugins/capture.py
+index c81f21ec..e7bbdd55 100644
+--- a/nose/plugins/capture.py
++++ b/nose/plugins/capture.py
+@@ -12,6 +12,7 @@
+ 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 @@ def beforeTest(self, test):
+ 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 --git a/unit_tests/test_capture_plugin.py b/unit_tests/test_capture_plugin.py
+index edab7de0..90125d3e 100644
+--- a/unit_tests/test_capture_plugin.py
++++ b/unit_tests/test_capture_plugin.py
+@@ -4,6 +4,12 @@
+ 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 @@ def test_captures_nonascii_stdout(self):
+ 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
diff --git a/main/py-nose/fix-doctests-unicode.patch b/main/py-nose/fix-doctests-unicode.patch
new file mode 100644
index 0000000000..a788ed9c43
--- /dev/null
+++ b/main/py-nose/fix-doctests-unicode.patch
@@ -0,0 +1,21 @@
+Patch-Source: https://src.fedoraproject.org/cgit/rpms/python-nose.git/tree/python-nose-coverage4.patch
+
+--- a/nose/plugins/doctests.py
++++ b/nose/plugins/doctests.py
+@@ -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:
diff --git a/main/py-nose/python3.5-compat.patch b/main/py-nose/python3.5-compat.patch
new file mode 100644
index 0000000000..2eb58e085c
--- /dev/null
+++ b/main/py-nose/python3.5-compat.patch
@@ -0,0 +1,42 @@
+From: Dmitry Shachnev <mitya57@gmail.com>
+Date: Mon, 1 Feb 2016 00:05:30 +0300
+Subject: [PATCH] Set __qualname__ equal to __name__ on derived classes
+
+To make output on Python ≥ 3.5 the same as on previous Python versions.
+
+This fixes #928.
+
+Patch-Source: https://github.com/nose-devs/nose/pull/983
+
+index 42f8563d..13d0c8a2 100644
+--- a/functional_tests/test_load_tests_from_test_case.py
++++ b/functional_tests/test_load_tests_from_test_case.py
+@@ -29,6 +29,7 @@ def setUp(self):
+ 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()
+index bfe16589..80ab1d4e 100644
+--- a/nose/util.py
++++ b/nose/util.py
+@@ -643,6 +643,7 @@ class C(cls):
+ pass
+ C.__module__ = module
+ C.__name__ = cls.__name__
++ C.__qualname__ = cls.__name__
+ return C
+
+
+index 944d2859..261436b0 100644
+--- a/unit_tests/test_xunit.py
++++ b/unit_tests/test_xunit.py
+@@ -16,6 +16,7 @@ def mktest():
+ class TC(unittest.TestCase):
+ def runTest(self):
+ pass
++ TC.__qualname__ = TC.__name__
+ test = TC()
+ return test
diff --git a/main/py-nose/python3.6-compat.patch b/main/py-nose/python3.6-compat.patch
new file mode 100644
index 0000000000..e6831bce80
--- /dev/null
+++ b/main/py-nose/python3.6-compat.patch
@@ -0,0 +1,61 @@
+From: Tomas Orsava <torsava@redhat.com>
+Date: Mon, 12 Dec 2016 14:35:50 +0100
+Subject: [PATCH] Fix compatibility with Python 3.6
+
+Python 3.6 returns ModuleNotFoundError instead of the previous ImportError.
+
+Patch-Source: https://github.com/nose-devs/nose/pull/1029
+
+index 104f2209..906e2ba2 100644
+--- a/functional_tests/test_loader.py
++++ b/functional_tests/test_loader.py
+@@ -372,7 +372,7 @@ def test_failed_import_module_name(self):
+ assert res.errors, "Expected errors but got none"
+ assert not res.failures, res.failures
+ err = res.errors[0][0].test.exc_class
+- assert err is ImportError, \
++ assert issubclass(err, ImportError), \
+ "Expected import error, got %s" % err
+
+ def test_load_nonsense_name(self):
+index cf09d4fb..cb20886b 100644
+--- a/functional_tests/test_withid_failures.rst
++++ b/functional_tests/test_withid_failures.rst
+@@ -7,16 +7,16 @@
+ >>> support = os.path.join(os.path.dirname(__file__), 'support', 'id_fails')
+ >>> argv = [__file__, '-v', '--with-id', '--id-file', idfile, support]
+ >>> run(argv=argv, plugins=[TestId()]) # doctest: +ELLIPSIS
+- #1 Failure: ImportError (No module ...apackagethatdoesntexist...) ... ERROR
++ #1 Failure: ... (No module ...apackagethatdoesntexist...) ... ERROR
+ #2 test_b.test ... ok
+ #3 test_b.test_fail ... FAIL
+ <BLANKLINE>
+ ======================================================================
+- ERROR: Failure: ImportError (No module ...apackagethatdoesntexist...)
++ ERROR: Failure: ... (No module ...apackagethatdoesntexist...)
+ ----------------------------------------------------------------------
+ Traceback (most recent call last):
+ ...
+- ImportError: No module ...apackagethatdoesntexist...
++ ...: No module ...apackagethatdoesntexist...
+ <BLANKLINE>
+ ======================================================================
+ FAIL: test_b.test_fail
+@@ -35,14 +35,14 @@ Addressing failures works (sometimes).
+ >>> argv.append('1')
+ >>> _junk = sys.modules.pop('test_a', None) # 2.3 requires
+ >>> run(argv=argv, plugins=[TestId()]) #doctest: +ELLIPSIS
+- #1 Failure: ImportError (No module ...apackagethatdoesntexist...) ... ERROR
++ #1 Failure: ... (No module ...apackagethatdoesntexist...) ... ERROR
+ <BLANKLINE>
+ ======================================================================
+- ERROR: Failure: ImportError (No module ...apackagethatdoesntexist...)
++ ERROR: Failure: ... (No module ...apackagethatdoesntexist...)
+ ----------------------------------------------------------------------
+ Traceback (most recent call last):
+ ...
+- ImportError: No module ...apackagethatdoesntexist...
++ ...: No module ...apackagethatdoesntexist...
+ <BLANKLINE>
+ ----------------------------------------------------------------------
+ Ran 1 test in ...s