diff --git a/python-nose-py311-doctest.patch b/python-nose-py311-doctest.patch new file mode 100644 index 0000000..49da773 --- /dev/null +++ b/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/python-nose-py311.patch b/python-nose-py311.patch index 1fcb6d9..66ff345 100644 --- a/python-nose-py311.patch +++ b/python-nose-py311.patch @@ -1,3 +1,77 @@ +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 @@ -11,43 +85,48 @@ index ad01e61..d9aec2d 100644 except ConfigParser.Error, exc: raise ConfigError("Error reading config file %r: %s" % (filename, str(exc))) -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/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/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/nose/plugins/manager.py b/nose/plugins/manager.py index 4d2ed22..daa9edb 100644 --- a/nose/plugins/manager.py @@ -61,6 +140,19 @@ index 4d2ed22..daa9edb 100644 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 @@ -85,3 +177,27 @@ index 80ab1d4..21770ae 100644 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/python-nose.spec b/python-nose.spec index cf6f728..168ee25 100644 --- a/python-nose.spec +++ b/python-nose.spec @@ -36,6 +36,9 @@ Patch6: python-nose-no-use_2to3.patch # 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: @@ -64,7 +67,13 @@ Provides: deprecated() %description -n python3-%{modname} %_description %prep -%autosetup -p1 -n %{modname}-%{version} +%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