commit 186acdbffcc508e7449b369883428b25ef9d8f4a Author: tigro Date: Sun Nov 19 22:59:27 2023 +0300 import python-nose-1.3.7-40.el9 diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..2cb3a71 --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +SOURCES/nose-1.3.7.tar.gz diff --git a/.python-nose.metadata b/.python-nose.metadata new file mode 100644 index 0000000..fe4012e --- /dev/null +++ b/.python-nose.metadata @@ -0,0 +1 @@ +97f2a04c9d43b29ddf4794a1a1d1ba803f1074c6 SOURCES/nose-1.3.7.tar.gz diff --git a/SOURCES/python-nose-coverage4.patch b/SOURCES/python-nose-coverage4.patch new file mode 100644 index 0000000..94d3f3c --- /dev/null +++ b/SOURCES/python-nose-coverage4.patch @@ -0,0 +1,21 @@ +diff -up nose-1.3.7/nose/plugins/cover.py.coverage4 nose-1.3.7/nose/plugins/cover.py +--- nose-1.3.7/nose/plugins/cover.py.coverage4 2015-04-04 03:28:20.000000000 -0600 ++++ nose-1.3.7/nose/plugins/cover.py 2016-11-09 16:16:32.832927855 -0700 +@@ -187,7 +187,7 @@ class Coverage(Plugin): + 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 @@ class Coverage(Plugin): + # 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/SOURCES/python-nose-no-use_2to3.patch b/SOURCES/python-nose-no-use_2to3.patch new file mode 100644 index 0000000..b2affab --- /dev/null +++ b/SOURCES/python-nose-no-use_2to3.patch @@ -0,0 +1,53 @@ +diff --git a/setup.py b/setup.py +index a2091c0..7e01bba 100644 +--- a/setup.py ++++ b/setup.py +@@ -13,8 +13,7 @@ if sys.version_info >= (3,): + from distribute_setup import use_setuptools + use_setuptools() + +- extra = {'use_2to3': True, +- 'test_dirs': test_dirs, ++ extra = {'test_dirs': test_dirs, + 'test_build_dir': 'build/tests', + 'pyversion_patching': True, + } +diff --git a/setup3lib.py b/setup3lib.py +index 27bdb93..761b74f 100644 +--- a/setup3lib.py ++++ b/setup3lib.py +@@ -18,7 +18,6 @@ else: + import logging + from setuptools import Distribution as _Distribution + from distutils.core import Command +- from setuptools.command.build_py import Mixin2to3 + from distutils import dir_util, file_util, log + import setuptools.command.test + from pkg_resources import normalize_path +@@ -68,7 +67,7 @@ else: + self.pyversion_patching = False + _Distribution.__init__(self, attrs) + +- class BuildTestsCommand (Command, Mixin2to3): ++ class BuildTestsCommand (Command): + # Create mirror copy of tests, convert all .py files using 2to3 + user_options = [] + +@@ -83,7 +82,6 @@ else: + self.test_base = test_base + + def run(self): +- use_2to3 = getattr(self.distribution, 'use_2to3', False) + test_dirs = getattr(self.distribution, 'test_dirs', []) + test_base = self.test_base + bpy_cmd = self.get_finalized_command("build_py") +@@ -112,9 +110,6 @@ else: + if fn.endswith(ext): + doc_modified.append(dstfile) + break +- if use_2to3: +- self.run_2to3(py_modified) +- self.run_2to3(doc_modified, True) + if self.distribution.pyversion_patching: + if patch is not None: + for file in modified: diff --git a/SOURCES/python-nose-py311-doctest.patch b/SOURCES/python-nose-py311-doctest.patch new file mode 100644 index 0000000..49da773 --- /dev/null +++ b/SOURCES/python-nose-py311-doctest.patch @@ -0,0 +1,56 @@ +diff --git a/functional_tests/doc_tests/test_issue145/imported_tests.rst b/functional_tests/doc_tests/test_issue145/imported_tests.rst +index c4eee78..caad752 100644 +--- a/functional_tests/doc_tests/test_issue145/imported_tests.rst ++++ b/functional_tests/doc_tests/test_issue145/imported_tests.rst +@@ -42,11 +42,11 @@ imported, not the source modules. + >>> argv = [__file__, '-v', support] + >>> run(argv=argv) # doctest: +REPORT_NDIFF + package1 setup +- test (package1.test_module.TestCase) ... ok ++ test (package1.test_module.TestCase.test) ... ok + package1.test_module.TestClass.test_class ... ok + package1.test_module.test_function ... ok + package2c setup +- test (package2c.test_module.TestCase) ... ok ++ test (package2c.test_module.TestCase.test) ... ok + package2c.test_module.TestClass.test_class ... ok + package2f setup + package2f.test_module.test_function ... ok +@@ -71,7 +71,7 @@ packages are executed. + >>> argv = [__file__, '-v', os.path.join(support, 'package2c')] + >>> run(argv=argv) # doctest: +REPORT_NDIFF + package2c setup +- test (package2c.test_module.TestCase) ... ok ++ test (package2c.test_module.TestCase.test) ... ok + package2c.test_module.TestClass.test_class ... ok + + ---------------------------------------------------------------------- +@@ -98,7 +98,7 @@ command-line. + ... ':TestCase.test'] + >>> run(argv=argv) # doctest: +REPORT_NDIFF + package2c setup +- test (package2c.test_module.TestCase) ... ok ++ test (package2c.test_module.TestCase.test) ... ok + + ---------------------------------------------------------------------- + Ran 1 test in ...s +diff --git a/functional_tests/doc_tests/test_selector_plugin/selector_plugin.rst b/functional_tests/doc_tests/test_selector_plugin/selector_plugin.rst +index f5f7913..5463cf1 100644 +--- a/functional_tests/doc_tests/test_selector_plugin/selector_plugin.rst ++++ b/functional_tests/doc_tests/test_selector_plugin/selector_plugin.rst +@@ -108,10 +108,10 @@ Now we can execute a test run using the custom selector, and the + project's tests will be collected. + + >>> run(argv=argv, plugins=[UseMySelector()]) +- test_add (basic.TestBasicMath) ... ok +- test_sub (basic.TestBasicMath) ... ok +- test_tuple_groups (my_function.MyFunction) ... ok +- test_cat (cat.StringsCat) ... ok ++ test_add (basic.TestBasicMath.test_add) ... ok ++ test_sub (basic.TestBasicMath.test_sub) ... ok ++ test_tuple_groups (my_function.MyFunction.test_tuple_groups) ... ok ++ test_cat (cat.StringsCat.test_cat) ... ok + + ---------------------------------------------------------------------- + Ran 4 tests in ...s + diff --git a/SOURCES/python-nose-py311.patch b/SOURCES/python-nose-py311.patch new file mode 100644 index 0000000..66ff345 --- /dev/null +++ b/SOURCES/python-nose-py311.patch @@ -0,0 +1,203 @@ +diff --git a/functional_tests/test_attribute_plugin.py b/functional_tests/test_attribute_plugin.py +index c9bab66..df2cfd3 100644 +--- a/functional_tests/test_attribute_plugin.py ++++ b/functional_tests/test_attribute_plugin.py +@@ -150,7 +150,10 @@ class TestClassAndMethodAttrs(AttributePluginTester): + args = ["-a", "meth_attr=method,cls_attr=class"] + + def verify(self): +- assert '(test_attr.TestClassAndMethodAttrs) ... ok' in self.output ++ if sys.version_info >= (3, 11): ++ assert '(test_attr.TestClassAndMethodAttrs.test_method) ... ok' in self.output ++ else: ++ assert '(test_attr.TestClassAndMethodAttrs) ... ok' in self.output + assert 'test_case_two' not in self.output + assert 'test_case_one' not in self.output + assert 'test_case_three' not in self.output +@@ -166,7 +169,10 @@ class TestTopLevelNotSelected(AttributePluginTester): + # rather than the attribute plugin, but the issue more easily manifests + # itself when using attributes. + assert 'test.test_b ... ok' in self.output +- assert 'test_a (test.TestBase) ... ok' in self.output ++ if sys.version_info >= (3, 11): ++ assert 'test_a (test.TestBase.test_a) ... ok' in self.output ++ else: ++ assert 'test_a (test.TestBase) ... ok' in self.output + assert 'TestDerived' not in self.output + + +diff --git a/functional_tests/test_load_tests_from_test_case.py b/functional_tests/test_load_tests_from_test_case.py +index 13d0c8a..934d43b 100644 +--- a/functional_tests/test_load_tests_from_test_case.py ++++ b/functional_tests/test_load_tests_from_test_case.py +@@ -2,6 +2,7 @@ + Tests that plugins can override loadTestsFromTestCase + """ + import os ++import sys + import unittest + from nose import loader + from nose.plugins import PluginTester +@@ -44,9 +45,14 @@ class TestLoadTestsFromTestCaseHook(PluginTester, unittest.TestCase): + suitepath = os.path.join(support, 'ltftc') + + def runTest(self): +- expect = [ +- 'test_value (%s.Derived) ... ERROR' % __name__, +- 'test_value (tests.Tests) ... ok'] ++ if sys.version_info >= (3, 11): ++ expect = [ ++ 'test_value (%s.Derived.test_value) ... ERROR' % __name__, ++ 'test_value (tests.Tests.test_value) ... ok'] ++ else: ++ expect = [ ++ 'test_value (%s.Derived) ... ERROR' % __name__, ++ 'test_value (tests.Tests) ... ok'] + print str(self.output) + for line in self.output: + if expect: +diff --git a/functional_tests/test_xunit.py b/functional_tests/test_xunit.py +index 6c2e99d..6e76a7d 100644 +--- a/functional_tests/test_xunit.py ++++ b/functional_tests/test_xunit.py +@@ -25,7 +25,10 @@ class TestXUnitPlugin(PluginTester, unittest.TestCase): + + assert "ERROR: test_error" in self.output + assert "FAIL: test_fail" in self.output +- assert "test_skip (test_xunit_as_suite.TestForXunit) ... SKIP: skipit" in self.output ++ if sys.version_info >= (3, 11): ++ assert "test_skip (test_xunit_as_suite.TestForXunit.test_skip) ... SKIP: skipit" in self.output ++ else: ++ assert "test_skip (test_xunit_as_suite.TestForXunit) ... SKIP: skipit" in self.output + assert "XML: %s" % xml_results_filename in self.output + + f = codecs.open(xml_results_filename,'r', encoding='utf8') +diff --git a/nose/config.py b/nose/config.py +index ad01e61..d9aec2d 100644 +--- a/nose/config.py ++++ b/nose/config.py +@@ -78,7 +78,7 @@ class ConfiguredDefaultsOptionParser(object): + except AttributeError: + filename = '' + try: +- cfg.readfp(fh) ++ cfg.read_file(fh) + except ConfigParser.Error, exc: + raise ConfigError("Error reading config file %r: %s" % + (filename, str(exc))) +diff --git a/nose/plugins/errorclass.py b/nose/plugins/errorclass.py +index d1540e0..38ecec9 100644 +--- a/nose/plugins/errorclass.py ++++ b/nose/plugins/errorclass.py +@@ -1,4 +1,15 @@ ++import sys ++ ++if sys.version_info >= (3, 11): ++ method = "TestTodo.runTest" ++ traceback = """ ++...Todo("I need to test something") ++... + """ ++else: ++ method = "TestTodo" ++ traceback = "" ++f""" + ErrorClass Plugins + ------------------ + +@@ -66,7 +77,7 @@ each step. + Now run the test. TODO is printed. + + >>> _ = case(result) # doctest: +ELLIPSIS +- runTest (....TestTodo) ... TODO: I need to test something ++ runTest (....{method}) ... TODO: I need to test something + + Errors and failures are empty, but todo has our test: + +@@ -79,10 +90,10 @@ Errors and failures are empty, but todo has our test: + >>> result.printErrors() # doctest: +ELLIPSIS + + ====================================================================== +- TODO: runTest (....TestTodo) ++ TODO: runTest (....{method}) + ---------------------------------------------------------------------- + Traceback (most recent call last): +- ... ++ ...{traceback} + ...Todo: I need to test something + + +diff --git a/nose/plugins/manager.py b/nose/plugins/manager.py +index 4d2ed22..daa9edb 100644 +--- a/nose/plugins/manager.py ++++ b/nose/plugins/manager.py +@@ -105,7 +105,7 @@ class PluginProxy(object): + meth = getattr(plugin, call, None) + if meth is not None: + if call == 'loadTestsFromModule' and \ +- len(inspect.getargspec(meth)[0]) == 2: ++ len(inspect.getfullargspec(meth)[0]) == 2: + orig_meth = meth + meth = lambda module, path, **kwargs: orig_meth(module) + self.plugins.append((plugin, meth)) +diff --git a/nose/result.py b/nose/result.py +index f974a14..228a42c 100644 +--- a/nose/result.py ++++ b/nose/result.py +@@ -13,7 +13,7 @@ try: + # 2.7+ + from unittest.runner import _TextTestResult + except ImportError: +- from unittest import _TextTestResult ++ from unittest import TextTestResult as _TextTestResult + from nose.config import Config + from nose.util import isclass, ln as _ln # backwards compat + +diff --git a/nose/util.py b/nose/util.py +index 80ab1d4..21770ae 100644 +--- a/nose/util.py ++++ b/nose/util.py +@@ -449,15 +449,15 @@ def try_run(obj, names): + if type(obj) == types.ModuleType: + # py.test compatibility + if isinstance(func, types.FunctionType): +- args, varargs, varkw, defaults = \ +- inspect.getargspec(func) ++ args, varargs, varkw, defaults, *_ = \ ++ inspect.getfullargspec(func) + else: + # Not a function. If it's callable, call it anyway + if hasattr(func, '__call__') and not inspect.ismethod(func): + func = func.__call__ + try: +- args, varargs, varkw, defaults = \ +- inspect.getargspec(func) ++ args, varargs, varkw, defaults, *_ = \ ++ inspect.getfullargspec(func) + args.pop(0) # pop the self off + except TypeError: + raise TypeError("Attribute %s of %r is not a python " +diff --git a/unit_tests/test_xunit.py b/unit_tests/test_xunit.py +index 2a9f69b..560b9c2 100644 +--- a/unit_tests/test_xunit.py ++++ b/unit_tests/test_xunit.py +@@ -134,7 +134,8 @@ class TestXMLOutputWithXML(unittest.TestCase): + err_lines = err.text.strip().split("\n") + eq_(err_lines[0], 'Traceback (most recent call last):') + eq_(err_lines[-1], 'AssertionError: one is not \'equal\' to two') +- eq_(err_lines[-2], ' raise AssertionError("one is not \'equal\' to two")') ++ r_line = -3 if '^' * 10 in err_lines[-2] else -2 ++ eq_(err_lines[r_line], ' raise AssertionError("one is not \'equal\' to two")') + else: + # this is a dumb test for 2.4- + assert '' in result +@@ -201,7 +202,8 @@ class TestXMLOutputWithXML(unittest.TestCase): + err_lines = err.text.strip().split("\n") + eq_(err_lines[0], 'Traceback (most recent call last):') + eq_(err_lines[-1], 'RuntimeError: some error happened') +- eq_(err_lines[-2], ' raise RuntimeError("some error happened")') ++ r_line = -3 if '^' * 10 in err_lines[-2] else -2 ++ eq_(err_lines[r_line], ' raise RuntimeError("some error happened")') + else: + # this is a dumb test for 2.4- + assert '' in result diff --git a/SOURCES/python-nose-py35.patch b/SOURCES/python-nose-py35.patch new file mode 100644 index 0000000..604f60e --- /dev/null +++ b/SOURCES/python-nose-py35.patch @@ -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 + diff --git a/SOURCES/python-nose-py36.patch b/SOURCES/python-nose-py36.patch new file mode 100644 index 0000000..75a47c0 --- /dev/null +++ b/SOURCES/python-nose-py36.patch @@ -0,0 +1,69 @@ +From acf7c4e073030a69712172b133076101e2b7d81f Mon Sep 17 00:00:00 2001 +From: Tomas Orsava +Date: Mon, 12 Dec 2016 12:09:47 +0100 +Subject: [PATCH] Patch for compatibility with Python 3.6 + +Python 3.6 returns a ModuleNotFoundError instead of the previous ImportError. +--- + functional_tests/test_loader.py | 2 +- + functional_tests/test_withid_failures.rst | 12 ++++++------ + 2 files changed, 7 insertions(+), 7 deletions(-) + +diff --git a/functional_tests/test_loader.py b/functional_tests/test_loader.py +index 81aaa7b..3f82122 100644 +--- a/functional_tests/test_loader.py ++++ b/functional_tests/test_loader.py +@@ -369,7 +369,7 @@ class TestNoseTestLoader(unittest.TestCase): + 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): +diff --git a/functional_tests/test_withid_failures.rst b/functional_tests/test_withid_failures.rst +index cf09d4f..cb20886 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 + + ====================================================================== +- ERROR: Failure: ImportError (No module ...apackagethatdoesntexist...) ++ ERROR: Failure: ... (No module ...apackagethatdoesntexist...) + ---------------------------------------------------------------------- + Traceback (most recent call last): + ... +- ImportError: No module ...apackagethatdoesntexist... ++ ...: No module ...apackagethatdoesntexist... + + ====================================================================== + 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 + + ====================================================================== +- ERROR: Failure: ImportError (No module ...apackagethatdoesntexist...) ++ ERROR: Failure: ... (No module ...apackagethatdoesntexist...) + ---------------------------------------------------------------------- + Traceback (most recent call last): + ... +- ImportError: No module ...apackagethatdoesntexist... ++ ...: No module ...apackagethatdoesntexist... + + ---------------------------------------------------------------------- + Ran 1 test in ...s +-- +2.11.0 + diff --git a/SOURCES/python-nose-py38.patch b/SOURCES/python-nose-py38.patch new file mode 100644 index 0000000..74bd9a8 --- /dev/null +++ b/SOURCES/python-nose-py38.patch @@ -0,0 +1,62 @@ +diff --git a/nose/config.py b/nose/config.py +index 125eb55..ad01e61 100644 +--- a/nose/config.py ++++ b/nose/config.py +@@ -139,7 +139,7 @@ class ConfiguredDefaultsOptionParser(object): + + + class Config(object): +- """nose configuration. ++ r"""nose configuration. + + Instances of Config are used throughout nose to configure + behavior, including plugin lists. Here are the default values for +diff --git a/nose/ext/dtcompat.py b/nose/ext/dtcompat.py +index 332cf08..b5698c5 100644 +--- a/nose/ext/dtcompat.py ++++ b/nose/ext/dtcompat.py +@@ -683,7 +683,7 @@ class DocTestParser: + + # This regular expression finds the indentation of every non-blank + # line in a string. +- _INDENT_RE = re.compile('^([ ]*)(?=\S)', re.MULTILINE) ++ _INDENT_RE = re.compile(r'^([ ]*)(?=\S)', re.MULTILINE) + + def _min_indent(self, s): + "Return the minimum indentation of any non-blank line in `s`" +@@ -1018,7 +1018,7 @@ class DocTestFinder: + if lineno is not None: + if source_lines is None: + return lineno+1 +- pat = re.compile('(^|.*:)\s*\w*("|\')') ++ pat = re.compile(r'(^|.*:)\s*\w*("|\')') + for lineno in range(lineno, len(source_lines)): + if pat.match(source_lines[lineno]): + return lineno +@@ -1427,11 +1427,11 @@ class OutputChecker: + # blank line, unless the DONT_ACCEPT_BLANKLINE flag is used. + if not (optionflags & DONT_ACCEPT_BLANKLINE): + # Replace in want with a blank line. +- want = re.sub('(?m)^%s\s*?$' % re.escape(BLANKLINE_MARKER), ++ want = re.sub(r'(?m)^%s\s*?$' % re.escape(BLANKLINE_MARKER), + '', want) + # If a line in got contains only spaces, then remove the + # spaces. +- got = re.sub('(?m)^\s*?$', '', got) ++ got = re.sub(r'(?m)^\s*?$', '', got) + if got == want: + return True + +diff --git a/nose/inspector.py b/nose/inspector.py +index a6c4a3e..ad22c0c 100644 +--- a/nose/inspector.py ++++ b/nose/inspector.py +@@ -107,7 +107,7 @@ def tbsource(tb, context=6): + + + def find_inspectable_lines(lines, pos): +- """Find lines in home that are inspectable. ++ r"""Find lines in home that are inspectable. + + Walk back from the err line up to 3 lines, but don't walk back over + changes in indent level. diff --git a/SOURCES/python-nose-readunicode.patch b/SOURCES/python-nose-readunicode.patch new file mode 100644 index 0000000..61d4cd2 --- /dev/null +++ b/SOURCES/python-nose-readunicode.patch @@ -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: diff --git a/SOURCES/python-nose-unicode.patch b/SOURCES/python-nose-unicode.patch new file mode 100644 index 0000000..a103da8 --- /dev/null +++ b/SOURCES/python-nose-unicode.patch @@ -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] ++ # [2] ++ 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.', ++ # ++ # ++ 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 diff --git a/SPECS/python-nose.spec b/SPECS/python-nose.spec new file mode 100644 index 0000000..56b1e75 --- /dev/null +++ b/SPECS/python-nose.spec @@ -0,0 +1,400 @@ +%global modname nose + +Name: python-%{modname} +Version: 1.3.7 +Release: 40%{?dist} +BuildArch: noarch + +License: LGPLv2+ and Public Domain +Summary: Deprecated test runner for Python +URL: https://nose.readthedocs.org/en/latest/ +Source0: http://pypi.python.org/packages/source/n/nose/nose-%{version}.tar.gz +# Make compatible with coverage 4.1 +# https://github.com/nose-devs/nose/pull/1004 +Patch0: python-nose-coverage4.patch +# Fix python 3.5 compat +# https://github.com/nose-devs/nose/pull/983 +Patch1: python-nose-py35.patch +# Fix UnicodeDecodeError with captured output +# https://github.com/nose-devs/nose/pull/988 +Patch2: python-nose-unicode.patch +# Allow docutils to read utf-8 source +Patch3: python-nose-readunicode.patch +# Fix Python 3.6 compatibility +# Python now returns ModuleNotFoundError instead of the previous ImportError +# https://github.com/nose-devs/nose/pull/1029 +Patch4: python-nose-py36.patch +# Remove a SyntaxWarning (other projects may treat it as error) +Patch5: python-nose-py38.patch +# Remove use_2to3 from setuptools.setup() call +# We call the command line tool in %%prep instead +# https://fedoraproject.org/wiki/Changes/Setuptools_58+ +Patch6: python-nose-no-use_2to3.patch +# Import unittest.TextTestResult instead of removed unittest._TextTestResult +# Use ConfigParser.read_file() instead of .readfp() +# Adapt test_xunit to tracebacks/exceptions with ^^^^^^^^ lines +# Migrate from removed inspect.getargspec() to inspect.getfullargspec() +Patch7: python-nose-py311.patch + +# Adapt doctest to new tracebacks/exceptions on Python 3.11+ +Patch311: python-nose-py311-doctest.patch + +BuildRequires: dos2unix + +%global _description %{expand: +A deprecated test runner for Python. + +See https://fedoraproject.org/wiki/Changes/DeprecateNose} + +%description %_description + +%package -n python3-%{modname} +Summary: %{summary} +BuildRequires: python3-devel +BuildRequires: /usr/bin/2to3 +BuildRequires: python3-setuptools +BuildRequires: python3-coverage >= 3.4-1 +Requires: python3-setuptools +%{?python_provide:%python_provide python3-%{modname}} +Conflicts: python-%{modname} < %{version}-%{release} +Obsoletes: python-%{modname}-docs < 1.3.7-30 + +# This package is deprecated, no new packages in Fedora can depend on it +# https://fedoraproject.org/wiki/Changes/DeprecateNose +# Contact the change owners for help migrating to pytest +Provides: deprecated() + +%description -n python3-%{modname} %_description + +%prep +%autosetup -N -n %{modname}-%{version} +# apply all patches up until number 300 +%autopatch -p1 -M 300 +%if v"0%{?python3_version}" >= v"3.11" +%patch311 -p1 +%endif + +dos2unix examples/attrib_plugin.py + +%build +2to3 %{?_smp_mflags} --write --nobackups --no-diffs . +2to3 %{?_smp_mflags} --write --nobackups --no-diffs -d $(find -name '*.rst') +%py3_build + +%install +mkdir -p %{buildroot}%{_mandir}/man1 +%py3_install +mv %{buildroot}%{_bindir}/nosetests{,-%{python3_version}} +ln -sf nosetests-%{python3_version} %{buildroot}%{_bindir}/nosetests-3 +mv %{buildroot}%{_prefix}/man/man1/nosetests.1 %{buildroot}%{_mandir}/man1/nosetests-%{python3_version}.1 +ln -sf nosetests-%{python3_version}.1 %{buildroot}%{_mandir}/man1/nosetests-3.1 +ln -sf nosetests-3 %{buildroot}%{_bindir}/nosetests +ln -sf nosetests-3.1 %{buildroot}%{_mandir}/man1/nosetests.1 + +%check +%{__python3} setup.py build_tests +%{__python3} selftest.py + +%files -n python3-%{modname} +%license lgpl.txt +%doc AUTHORS CHANGELOG NEWS README.txt +%{_bindir}/nosetests +%{_bindir}/nosetests-3 +%{_bindir}/nosetests-%{python3_version} +%{_mandir}/man1/nosetests.1* +%{_mandir}/man1/nosetests-3.1* +%{_mandir}/man1/nosetests-%{python3_version}.1* +%{python3_sitelib}/nose-*.egg-info/ +%{python3_sitelib}/nose/ + +%changelog +* Sun Nov 19 2023 Arkady L. Shane - 1.3.7-40 +- Rebuilt for MSVSphere 9.3 + +* Fri Jan 20 2023 Fedora Release Engineering - 1.3.7-40 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_38_Mass_Rebuild + +* Fri Jul 22 2022 Fedora Release Engineering - 1.3.7-39 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_37_Mass_Rebuild + +* Mon Jun 13 2022 Python Maint - 1.3.7-38 +- Rebuilt for Python 3.11 + +* Fri Jan 21 2022 Fedora Release Engineering - 1.3.7-37 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_36_Mass_Rebuild + +* Mon Nov 01 2021 Miro Hrončok - 1.3.7-36 +- Fix build with setuptools 58+ +- Fixes rhbz#2018972 + +* Fri Jul 23 2021 Fedora Release Engineering - 1.3.7-35 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_35_Mass_Rebuild + +* Wed Jun 02 2021 Python Maint - 1.3.7-34 +- Rebuilt for Python 3.10 + +* Wed Jan 27 2021 Fedora Release Engineering - 1.3.7-33 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_34_Mass_Rebuild + +* Wed Jul 29 2020 Fedora Release Engineering - 1.3.7-32 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_33_Mass_Rebuild + +* Fri May 22 2020 Miro Hrončok - 1.3.7-31 +- Rebuilt for Python 3.9 + +* Fri Jan 31 2020 Miro Hrončok - 1.3.7-30 +- Deprecate the package + https://fedoraproject.org/wiki/Changes/DeprecateNose +- Drop the docs subpackage + +* Thu Jan 30 2020 Fedora Release Engineering - 1.3.7-29 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_32_Mass_Rebuild + +* Fri Nov 15 2019 Miro Hrončok - 1.3.7-28 +- Subpackage python2-nose has been removed + See https://fedoraproject.org/wiki/Changes/Mass_Python_2_Package_Removal + +* Thu Oct 31 2019 Petr Viktorin - 1.3.7-27 +- Remove build dependency on python2-coverage + Don't test coverage plugin on Python 2 + +* Thu Oct 03 2019 Miro Hrončok - 1.3.7-26 +- Rebuilt for Python 3.8.0rc1 (#1748018) + +* Thu Aug 15 2019 Miro Hrončok - 1.3.7-25 +- Rebuilt for Python 3.8 + +* Fri Jul 26 2019 Fedora Release Engineering - 1.3.7-24 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_31_Mass_Rebuild + +* Mon Jul 22 2019 Miro Hrončok - 1.3.7-23 +- Make /usr/bin/nosetests Python 3 + +* Sat Feb 02 2019 Fedora Release Engineering - 1.3.7-22 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_30_Mass_Rebuild + +* Sat Jul 14 2018 Fedora Release Engineering - 1.3.7-21 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_29_Mass_Rebuild + +* Thu Jun 14 2018 Miro Hrončok - 1.3.7-20 +- Rebuilt for Python 3.7 + +* Fri Feb 09 2018 Fedora Release Engineering - 1.3.7-19 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_28_Mass_Rebuild + +* Tue Nov 07 2017 Igor Gnatenko - 1.3.7-18 +- Use better Obsoletes for platform-python + +* Sat Nov 04 2017 Igor Gnatenko - 1.3.7-17 +- Remove platform-python subpackage +- Cleanup spec + +* Fri Sep 29 2017 Troy Dawson - 1.3.7-16 +- Cleanup spec file conditionals + +* Thu Aug 10 2017 Miro Hrončok - 1.3.7-15 +- Add platform-python subpackage + +* Thu Jul 27 2017 Fedora Release Engineering - 1.3.7-14 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_27_Mass_Rebuild + +* Sat Feb 11 2017 Fedora Release Engineering - 1.3.7-13 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_26_Mass_Rebuild + +* Mon Dec 12 2016 Tomas Orsava - 1.3.7-12 +- Patched to fix compatibility with Python 3.6 + +* Mon Dec 05 2016 Randy Barlow - 1.3.7-11 +- Provide nosetests-3 (#1289820). +- Rename python-nose to python2-nose and use Python provides macro. +- Include the license with the -docs subpackage. +- Use symlinks to provide man pages for all the Python version variants of /usr/bin/nosetests. +- The -docs subpackage no longer requires python-nose since that doesn't make sense. + +* Tue Nov 15 2016 Orion Poplawski 1.3.7-10 +- Add upstream patch to fix python 3.5 compat +- Add patch to allow docutils to read unicode source +- Update spec + +* Wed Nov 9 2016 Orion Poplawski 1.3.7-9 +- Add patch to fix build with coverage 4.1 + +* Tue Jul 19 2016 Fedora Release Engineering - 1.3.7-8 +- https://fedoraproject.org/wiki/Changes/Automatic_Provides_for_Python_RPM_Packages + +* Tue Feb 2 2016 Orion Poplawski 1.3.7-7 +- Fix URL + +* Thu Sep 24 2015 Robert Kuska 1.3.7-6 +- Rebuilt for Python3.5 rebuild with disabled tests under python3 + +* Sun Aug 09 2015 Kevin Fenzi 1.3.7-5 +- Add conditional for python-sphinx buildrequires when with_docs is not set. +- Fixes bug #1251700 + +* Fri Jul 24 2015 Kevin Fenzi 1.3.7-4 +- Version provides correctly for python2-nose. + +* Fri Jul 17 2015 Kevin Fenzi 1.3.7-3 +- Add provides for python2-nose. Fixes bug #1241670 + +* Thu Jun 18 2015 Fedora Release Engineering - 1.3.7-2 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_23_Mass_Rebuild + +* Wed Jun 03 2015 Kevin Fenzi 1.3.7-1 +- Update to 1.3.7 (#1227345) + +* Sat Apr 04 2015 Ralph Bean - 1.3.6-1 +- new version + +* Wed Aug 27 2014 Luke Macken - 1.3.4-1 +- Update to 1.3.4 (#1094718) + +* Sat Jun 07 2014 Fedora Release Engineering - 1.3.2-3 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_21_Mass_Rebuild + +* Mon May 19 2014 Bohuslav Kabrda - 1.3.2-2 +- Add patch for issue https://github.com/nose-devs/nose/pull/811, +which makes tests of python-billiard and python-falcon fail with Python 3.4 + +* Sat May 03 2014 Orion Poplawski - 1.3.2-1 +- Update to 1.3.2 for Python 3.4 suport + +* Fri May 02 2014 Orion Poplawski - 1.3.1-2 +- Rebuild for Python 3.4 + +* Fri Mar 14 2014 Luke Macken - 1.3.1-1 +- Update to 1.3.1 (#1074971) + +* Sun Aug 04 2013 Fedora Release Engineering - 1.3.0-2 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_20_Mass_Rebuild + +* Tue Apr 9 2013 Toshio Kuratomi - 1.3.0-1 +- Update to 1.3.0 upstream with python-3.3 fixes + +* Thu Feb 14 2013 Fedora Release Engineering - 1.2.1-2 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_19_Mass_Rebuild + +* Wed Sep 12 2012 Toshio Kuratomi - 1.2.1-1 +- New upsream 1.2.1 that just bumps the version properly + +* Mon Sep 10 2012 Toshio Kuratomi - 1.2.0-1 +- Update to nose-1.2.0. +- Two less python3 test failures than 1.1.2 + +* Sat Aug 4 2012 David Malcolm - 1.1.2-5 +- rebuild for https://fedoraproject.org/wiki/Features/Python_3.3 +- disable selftests that fail under 3.3 + +* Fri Aug 3 2012 David Malcolm - 1.1.2-4 +- remove rhel logic from with_python3 conditional + +* Sat Jul 21 2012 Fedora Release Engineering - 1.1.2-3 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_18_Mass_Rebuild + +* Sat Jan 14 2012 Fedora Release Engineering - 1.1.2-2 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_17_Mass_Rebuild + +* Mon Aug 1 2011 Toshio Kuratomi - 1.1.2-1 +- Upstream bugfix release + +* Wed Jul 27 2011 Toshio Kuratomi - 1.1.1-1 +- Upstream bugfix release + +* Tue Feb 08 2011 Fedora Release Engineering - 1.0.0-2 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_15_Mass_Rebuild + +* Sun Dec 26 2010 Toshio Kuratomi - 1.0.0-1 +- Update to 1.0.0 +- Create the docs subpackage for text docs even if we don't create the html docs. +- Make python3 subpackage + +* Tue Dec 7 2010 Toshio Kuratomi - 0.11.4-2 +- Fix FTBFS with newer coverage + +* Thu Oct 21 2010 Luke Macken - 0.11.4-1 +- Update to 0.11.4 (#3630722) + +* Wed Jul 21 2010 David Malcolm - 0.11.3-5 +- add support for building without docs, to avoid a circular build-time +dependency between this and python-sphinx; disable docs subpackage for now +- add (apparently) missing BR on python-coverage (appears to be needed +for %%check) +- cherrypick upstream compatibility fixes for 2.7 + +* Wed Jul 21 2010 David Malcolm - 0.11.3-4 +- Rebuilt for https://fedoraproject.org/wiki/Features/Python_2.7/MassRebuild + +* Thu May 20 2010 Luke Macken - 0.11.3-3 +- Update URL to http://code.google.com/p/python-nose/ +- Align description to reflect that in setup.py +- Create a docs subpackage containing HTML & reST documentation +- Thanks to Gareth Armstrong at HP for the patch + +* Thu May 06 2010 Luke Macken - 0.11.3-2 +- Don't hardcode the python version + +* Thu May 06 2010 Luke Macken - 0.11.3-1 +- Update to 0.11.3 +- Enable the self tests + +* Mon Oct 05 2009 Luke Macken - 0.11.1-2 +- Include the new nosetests-2.6 script as well + +* Mon Oct 05 2009 Luke Macken - 0.11.1-1 +- Update to 0.11.1 + +* Sun Jul 26 2009 Fedora Release Engineering - 0.10.4-3 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_12_Mass_Rebuild + +* Thu Feb 26 2009 Fedora Release Engineering - 0.10.4-2 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_11_Mass_Rebuild + +* Sat Nov 29 2008 Ignacio Vazquez-Abrams - 0.10.4-1 +- Update to 0.10.4 to fix 2.6 issues + +* Sat Nov 29 2008 Ignacio Vazquez-Abrams - 0.10.3-2 +- Rebuild for Python 2.6 + +* Sat Aug 02 2008 Luke Macken 0.10.3-1 +- Update to 0.10.3 + +* Thu Feb 28 2008 Luke Macken 0.10.1-1 +- Update to 0.10.1 + +* Mon Dec 3 2007 Luke Macken 0.10.0-2 +- Add python-setuptools to Requires (Bug #408491) + +* Tue Nov 27 2007 Luke Macken 0.10.0-1 +- 0.10.0 + +* Sun Sep 2 2007 Luke Macken 0.10.0-0.3.b1 +- Update for python-setuptools changes in rawhide + +* Tue Aug 21 2007 Luke Macken 0.10.0-0.2.b1 +- 0.10.0b1 +- Update license tag to LGPLv2 + +* Wed Jun 20 2007 Luke Macken 0.10.0-0.1.a2 +- 0.10.0a2 + +* Sat Jun 2 2007 Luke Macken 0.9.3-1 +- Latest upstream release +- Remove python-nose-0.9.2-mandir.patch + +* Sat Mar 3 2007 Luke Macken 0.9.2-1 +- Add nosetests(1) manpage, and python-nose-0.9.2-mandir.patch to put it in + the correct location. +- 0.9.2 + +* Sat Dec 9 2006 Luke Macken 0.9.1-2 +- Rebuild for python 2.5 + +* Fri Nov 24 2006 Luke Macken 0.9.1-1 +- 0.9.1 + +* Fri Sep 8 2006 Luke Macken 0.9.0-1 +- 0.9.0 + +* Wed Apr 19 2006 Ignacio Vazquez-Abrams 0.8.7.2-1 +- Initial RPM release