diff options
author | Jakub Jirutka <jakub@jirutka.cz> | 2017-06-30 00:10:34 +0200 |
---|---|---|
committer | Jakub Jirutka <jakub@jirutka.cz> | 2017-06-30 00:11:46 +0200 |
commit | 430209682f76651efadf255116830965ed295d5c (patch) | |
tree | 041158b686159e8f526b48afdaed323f2f8888a3 /main/py-nose | |
parent | b16c1e47001d6a97b758ee5fb6fc47caa797d02c (diff) | |
download | aports-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/APKBUILD | 80 | ||||
-rw-r--r-- | main/py-nose/coverage4-compat.patch | 41 | ||||
-rw-r--r-- | main/py-nose/fix-crashing-from-UnicodeDecodeError.patch | 152 | ||||
-rw-r--r-- | main/py-nose/fix-doctests-unicode.patch | 21 | ||||
-rw-r--r-- | main/py-nose/python3.5-compat.patch | 42 | ||||
-rw-r--r-- | main/py-nose/python3.6-compat.patch | 61 |
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 |