nose: clean up, support Python 3.10. (#8825)

Due to changes in setuptools, we need to run 2to3 ourselves.
While we're at it, lets apply relevant patches from Debian.

https://salsa.debian.org/python-team/packages/nose/
This commit is contained in:
OscarL
2023-06-09 03:57:39 -03:00
committed by GitHub
parent e066a79237
commit 988d5a67e6
15 changed files with 771 additions and 55 deletions

View File

@@ -16,9 +16,25 @@ HOMEPAGE="https://readthedocs.io/docs/nose/
https://github.com/nose-devs/nose"
COPYRIGHT="2008-2010 anatoly techtonik"
LICENSE="GNU LGPL v2.1"
REVISION="4"
REVISION="5"
SOURCE_URI="https://pypi.io/packages/source/n/nose/nose-$portVersion.tar.gz"
CHECKSUM_SHA256="f1bffef9cbc82628f6e7d7b40d7e255aefaa1adb6a1b1d26c69a8b79e6208a98"
PATCHES="
debian/no-google-analytics.diff
debian/no-distribute_setup.diff
debian/disable-unstable-tests.diff
debian/coverage4.1.diff
debian/python3.6-modulenotfounderror.diff
debian/docs-sys.path.diff
debian/sphinx-html_sidebars.diff
debian/sphinx-body-max-width.diff
debian/no-versioned-entry-point.diff
debian/sphinx-class-directives.diff
debian/python3-conf-py.diff
debian/2to3-fixups.diff
debian/python3.11.diff
debian/python3.11-testcase-str.diff
"
ARCHITECTURES="any"
@@ -32,25 +48,33 @@ BUILD_REQUIRES="
haiku_devel
"
PYTHON_PACKAGES=(python38 python39)
PYTHON_VERSIONS=(3.8 3.9)
PYTHON_PACKAGES=(python38 python39 python310)
PYTHON_VERSIONS=(3.8 3.9 3.10)
defaultVersion=3.9
for i in "${!PYTHON_PACKAGES[@]}"; do
pythonPackage=${PYTHON_PACKAGES[i]}
pythonVersion=${PYTHON_VERSIONS[i]}
eval "PROVIDES_$pythonPackage=\"
nose_$pythonPackage = $portVersion
cmd:nosetests_$pythonVersion
\""
if [ $pythonVersion = $defaultVersion ]; then
eval "PROVIDES_${pythonPackage}+=\"
cmd:nosetests = $portVersion
\""
fi
eval "REQUIRES_$pythonPackage=\"
haiku
cmd:python$pythonVersion
\""
BUILD_REQUIRES="$BUILD_REQUIRES
setuptools_$pythonPackage
six_$pythonPackage
"
BUILD_PREREQUIRES="$BUILD_PREREQUIRES
cmd:python$pythonVersion"
BUILD_REQUIRES+="
setuptools_$pythonPackage
six_$pythonPackage
"
BUILD_PREREQUIRES+="
cmd:python$pythonVersion
"
done
PATCH()
@@ -58,58 +82,51 @@ PATCH()
sed -i "s|man/|$relativeManDir/|" setup.py
}
BUILD()
{
for i in "${!PYTHON_PACKAGES[@]}"; do
pythonPackage=${PYTHON_PACKAGES[i]}
pythonVersion=${PYTHON_VERSIONS[i]}
rm -rf "$sourceDir"-$pythonPackage
cp -a "$sourceDir" "$sourceDir"-$pythonPackage
cd "$sourceDir"-$pythonPackage
python=python$pythonVersion
$python setup.py build
done
}
INSTALL()
{
for i in "${!PYTHON_PACKAGES[@]}"; do
pythonPackage=${PYTHON_PACKAGES[i]}
pythonVersion=${PYTHON_VERSIONS[i]}
cd "$sourceDir"-$pythonPackage
python=python$pythonVersion
installLocation=$prefix/lib/$python/vendor-packages
export PYTHONPATH=$installLocation
mkdir -p "$installLocation"
$python setup.py install \
--root=/ --prefix="$prefix" --skip-build
rm $binDir/nosetests
packageEntries $pythonPackage \
"$binDir" \
"$prefix"/lib/$python
done
cd "$sourceDir"
mkdir -p "$docDir"
cp -rt "$docDir" \
README.txt CHANGELOG NEWS* doc/*
rm -f "$docDir"/Makefile
}
TEST()
{
for i in "${!PYTHON_PACKAGES[@]}"; do
pythonPackage=${PYTHON_PACKAGES[i]}
pythonVersion=${PYTHON_VERSIONS[$i]}
cd "$sourceDir"-$pythonPackage
python=python$pythonVersion
$python setup.py test || echo Tests failed with $python && true
installLocation=$prefix/lib/$python/vendor-packages/
export PYTHONPATH=$installLocation:$PYTHONPATH
mkdir -p $installLocation
rm -rf build
$python setup.py build
# Run 2to3 before install (newer setuptools doesn't doit for us anymore).
$python -m lib2to3 --write --nobackups --no-diffs build
$python setup.py install --skip-build --root=/ --prefix=$prefix
# Version suffix all the scripts
for f in $binDir/*; do
mv $f $f-$pythonVersion
done
# And provide suffix-less symlinks for the default version
if [ $pythonVersion = $defaultVersion ]; then
for f in $binDir/*; do
ln -sr $f ${f%-$pythonVersion}
done
fi
packageEntries $pythonPackage \
$prefix/lib/python* \
$binDir/* \
$manDir
done
}
TEST()
{
# We only test on the default Python version, for now at least.
python=python$defaultVersion
echo "Running 2to3 before running tests."
$python -m lib2to3 --write --nobackups --no-diffs .
echo "Run tests now."
$python setup.py test || echo "Tests failed with $python" && true
}

View File

@@ -0,0 +1,66 @@
From: Dmitry Shachnev <mitya57@debian.org>
Date: Sat, 30 Oct 2021 20:54:36 +0300
Subject: Remove code that relied on setuptools calling 2to3
Setuptools no longer runs that, we run 2to3 from debian/rules.
---
setup.cfg | 1 -
setup.py | 12 ------------
setup3lib.py | 2 +-
3 files changed, 1 insertion(+), 14 deletions(-)
diff --git a/setup.cfg b/setup.cfg
index 9e927a5..308e4de 100644
--- a/setup.cfg
+++ b/setup.cfg
@@ -2,7 +2,6 @@
with-doctest = 1
doctest-extension = .rst
doctest-fixtures = _fixtures
-py3where = build/tests
[bdist_rpm]
doc_files = README.txt
diff --git a/setup.py b/setup.py
index 29e29a8..9499468 100644
--- a/setup.py
+++ b/setup.py
@@ -6,17 +6,6 @@ py_vers_tag = '-%s.%s' % sys.version_info[:2]
test_dirs = ['functional_tests', 'unit_tests', os.path.join('doc','doc_tests'), 'nose']
-if sys.version_info >= (3,):
- import setuptools
-
- extra = {'use_2to3': True,
- 'test_dirs': test_dirs,
- 'test_build_dir': 'build/tests',
- 'pyversion_patching': True,
- }
-else:
- extra = {}
-
try:
from setup3lib import setup
from setuptools import find_packages
@@ -36,7 +25,6 @@ try:
if sys.version_info.major == 2:
addl_args['entry_points']['console_scripts'].append(
'nosetests%s = nose:run_exit' % py_vers_tag)
- addl_args.update(extra)
# This is required by multiprocess plugin; on Windows, if
# the launch script is not import-safe, spawned processes
diff --git a/setup3lib.py b/setup3lib.py
index 27bdb93..51164b8 100644
--- a/setup3lib.py
+++ b/setup3lib.py
@@ -3,7 +3,7 @@ from setuptools import setup as _setup
py3_args = ['use_2to3', 'convert_2to3_doctests', 'use_2to3_fixers', 'test_dirs', 'test_build_dir', 'doctest_exts', 'pyversion_patching']
-if sys.version_info < (3,):
+if True:
# Remove any Python-3.x-only arguments (so they don't generate complaints
# from 2.x setuptools) and then just pass through to the regular setup
# routine.

View File

@@ -0,0 +1,44 @@
From: Dmitry Shachnev <mitya57@gmail.com>
Date: Wed, 29 Jun 2016 13:15:16 +0300
Subject: 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
---
nose/plugins/cover.py | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/nose/plugins/cover.py b/nose/plugins/cover.py
index fbe2e30..b9bfc82 100644
--- a/nose/plugins/cover.py
+++ b/nose/plugins/cover.py
@@ -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}$')

View File

@@ -0,0 +1,49 @@
From: Dmitry Shachnev <mitya57@gmail.com>
Date: Thu, 8 Oct 2015 10:02:00 -0700
Subject: Disable some unstable tests in multiprocessing module
Forwarded: not-needed
Last-Update: 2014-05-04
---
functional_tests/test_multiprocessing/test_keyboardinterrupt.py | 2 ++
functional_tests/test_multiprocessing/test_process_timeout.py | 2 ++
2 files changed, 4 insertions(+)
diff --git a/functional_tests/test_multiprocessing/test_keyboardinterrupt.py b/functional_tests/test_multiprocessing/test_keyboardinterrupt.py
index 18c8af1..aead7e2 100644
--- a/functional_tests/test_multiprocessing/test_keyboardinterrupt.py
+++ b/functional_tests/test_multiprocessing/test_keyboardinterrupt.py
@@ -63,6 +63,7 @@ def get_log_content(logfile):
return content
def test_keyboardinterrupt():
+ raise nose.SkipTest('Disabled in Debian')
process, logfile, _ = keyboardinterrupt('keyboardinterrupt.py')
stdout, stderr = [s.decode('utf-8') for s in process.communicate(None)]
log = get_log_content(logfile)
@@ -83,6 +84,7 @@ def test_keyboardinterrupt():
def test_keyboardinterrupt_twice():
+ raise nose.SkipTest('Disabled in Debian')
process, logfile, killfile = keyboardinterrupt('keyboardinterrupt_twice.py')
waitForKillFile(killfile)
os.killpg(process.pid, signal.SIGINT)
diff --git a/functional_tests/test_multiprocessing/test_process_timeout.py b/functional_tests/test_multiprocessing/test_process_timeout.py
index 6b858f8..73b4e3b 100644
--- a/functional_tests/test_multiprocessing/test_process_timeout.py
+++ b/functional_tests/test_multiprocessing/test_process_timeout.py
@@ -1,4 +1,5 @@
import os
+import nose
from test_multiprocessing import MPTestBase
@@ -7,6 +8,7 @@ class TestMPTimeout(MPTestBase):
suitepath = os.path.join(os.path.dirname(__file__), 'support', 'timeout.py')
def runTest(self):
+ raise nose.SkipTest('Disabled in Debian')
assert "TimedOutException: 'timeout.test_timeout'" in self.output
assert "Ran 2 tests in" in self.output
assert "FAILED (errors=1)" in self.output

View File

@@ -0,0 +1,26 @@
From: Dmitry Shachnev <mitya57@debian.org>
Date: Sat, 8 Feb 2020 12:26:00 +0300
Subject: Use correct sys.path when building docs
The parent directory contains Python 2 nose, however we need the
Python 3 version, which we will pass via PYTHONPATH.
---
doc/conf.py | 5 +----
1 file changed, 1 insertion(+), 4 deletions(-)
diff --git a/doc/conf.py b/doc/conf.py
index 34ea147..ac7f0cb 100644
--- a/doc/conf.py
+++ b/doc/conf.py
@@ -20,10 +20,7 @@ import sys, os
# is relative to the documentation root, use os.path.abspath to make it
# absolute, like shown here.
-# need to be brutal because of easy_install's pth hacks:
-sys.path.insert(0,
- os.path.abspath(os.path.join(os.path.dirname(__file__), '..')))
-sys.path.insert(0, os.path.abspath('.'))
+sys.path[0] = os.path.abspath('.')
from nose import __versioninfo__ as nose_version
nose_version = tuple(str(x) for x in nose_version)

View File

@@ -0,0 +1,28 @@
From: Stefano Rivera <stefanor@debian.org>
Date: Thu, 8 Oct 2015 10:01:59 -0700
Subject: Don't even think about using distribute_setup to download things
during build
Forwarded: not-needed
Last-Update: 2012-02-03
---
setup.py | 6 +-----
1 file changed, 1 insertion(+), 5 deletions(-)
diff --git a/setup.py b/setup.py
index a710b30..765b7ae 100644
--- a/setup.py
+++ b/setup.py
@@ -7,11 +7,7 @@ py_vers_tag = '-%s.%s' % sys.version_info[:2]
test_dirs = ['functional_tests', 'unit_tests', os.path.join('doc','doc_tests'), 'nose']
if sys.version_info >= (3,):
- try:
- import setuptools
- except ImportError:
- from distribute_setup import use_setuptools
- use_setuptools()
+ import setuptools
extra = {'use_2to3': True,
'test_dirs': test_dirs,

View File

@@ -0,0 +1,31 @@
From: Stefano Rivera <stefanor@debian.org>
Date: Thu, 8 Oct 2015 10:01:58 -0700
Subject: Remove Google Analytics tracking JS
Forwarded: not-needed
Last-Update: 2013-03-04
---
doc/.templates/layout.html | 13 -------------
1 file changed, 13 deletions(-)
diff --git a/doc/.templates/layout.html b/doc/.templates/layout.html
index 2d961b0..4237ef7 100644
--- a/doc/.templates/layout.html
+++ b/doc/.templates/layout.html
@@ -3,16 +3,3 @@
{%- block relbar1 %}
{% if pagename != 'index' %}{{ super() }}{% endif %}
{% endblock %}
-
-{%- block footer %}
-{{ super() }}
-{% if not embedded %}
-<script src="http://www.google-analytics.com/urchin.js"
- type="text/javascript">
-</script>
-<script type="text/javascript">
- _uacct = "UA-2236166-1";
- urchinTracker();
-</script>
-{% endif %}
-{%- endblock %}

View File

@@ -0,0 +1,31 @@
From: Dmitry Shachnev <mitya57@debian.org>
Date: Sat, 8 Feb 2020 13:27:14 +0300
Subject: Remove setuptools-3.X entry point
It gets outdated with every new Python 3 default version, anyway.
---
setup.py | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/setup.py b/setup.py
index 765b7ae..29e29a8 100644
--- a/setup.py
+++ b/setup.py
@@ -26,7 +26,6 @@ try:
entry_points = {
'console_scripts': [
'nosetests = nose:run_exit',
- 'nosetests%s = nose:run_exit' % py_vers_tag,
],
'distutils.commands': [
' nosetests = nose.commands:nosetests',
@@ -34,6 +33,9 @@ try:
},
test_suite = 'nose.collector',
)
+ if sys.version_info.major == 2:
+ addl_args['entry_points']['console_scripts'].append(
+ 'nosetests%s = nose:run_exit' % py_vers_tag)
addl_args.update(extra)
# This is required by multiprocess plugin; on Windows, if

View File

@@ -0,0 +1,23 @@
From: Dmitry Shachnev <mitya57@debian.org>
Date: Sat, 30 Oct 2021 20:44:42 +0300
Subject: Fix syntax in doc/conf.py for Python 3
---
doc/conf.py | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/doc/conf.py b/doc/conf.py
index cccfd95..dab07bf 100644
--- a/doc/conf.py
+++ b/doc/conf.py
@@ -217,8 +217,8 @@ html_theme = 'default'
# Grouping the document tree into LaTeX files. List of tuples
# (source start file, target name, title, author, document class [howto/manual]).
latex_documents = [
- ('index', 'nose.tex', ur'nose Documentation',
- ur'Jason Pellerin', 'manual'),
+ ('index', 'nose.tex', u'nose Documentation',
+ u'Jason Pellerin', 'manual'),
]
# The name of an image file (relative to this directory) to place at the top of

View File

@@ -0,0 +1,167 @@
From: Dmitry Shachnev <mitya57@debian.org>
Date: Tue, 13 Dec 2022 15:08:11 +0300
Subject: Update tests to adapt for TestCase.__str__ change in Python 3.11
See https://github.com/python/cpython/issues/58473.
---
.../doc_tests/test_issue145/imported_tests.rst | 14 +++++++-------
.../doc_tests/test_selector_plugin/selector_plugin.rst | 10 +++++-----
functional_tests/test_attribute_plugin.py | 4 ++--
functional_tests/test_load_tests_from_test_case.py | 12 +++++++++---
functional_tests/test_xunit.py | 2 +-
nose/plugins/errorclass.py | 4 ++--
6 files changed, 26 insertions(+), 20 deletions(-)
diff --git a/functional_tests/doc_tests/test_issue145/imported_tests.rst b/functional_tests/doc_tests/test_issue145/imported_tests.rst
index c4eee78..8d0a7c6 100644
--- a/functional_tests/doc_tests/test_issue145/imported_tests.rst
+++ b/functional_tests/doc_tests/test_issue145/imported_tests.rst
@@ -40,13 +40,13 @@ below that the test names reflect the modules into which the tests are
imported, not the source modules.
>>> argv = [__file__, '-v', support]
- >>> run(argv=argv) # doctest: +REPORT_NDIFF
+ >>> run(argv=argv) # doctest: +REPORT_NDIFF, +ELLIPSIS
package1 setup
- test (package1.test_module.TestCase) ... ok
+ test (package1.test_module.TestCase...) ... 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...) ... ok
package2c.test_module.TestClass.test_class ... ok
package2f setup
package2f.test_module.test_function ... ok
@@ -69,9 +69,9 @@ packages are executed.
<BLANKLINE>
OK
>>> argv = [__file__, '-v', os.path.join(support, 'package2c')]
- >>> run(argv=argv) # doctest: +REPORT_NDIFF
+ >>> run(argv=argv) # doctest: +REPORT_NDIFF, +ELLIPSIS
package2c setup
- test (package2c.test_module.TestCase) ... ok
+ test (package2c.test_module.TestCase...) ... ok
package2c.test_module.TestClass.test_class ... ok
<BLANKLINE>
----------------------------------------------------------------------
@@ -96,9 +96,9 @@ command-line.
>>> argv = [__file__, '-v',
... os.path.join(support, 'package2c', 'test_module.py') +
... ':TestCase.test']
- >>> run(argv=argv) # doctest: +REPORT_NDIFF
+ >>> run(argv=argv) # doctest: +REPORT_NDIFF, +ELLIPSIS
package2c setup
- test (package2c.test_module.TestCase) ... ok
+ test (package2c.test_module.TestCase...) ... ok
<BLANKLINE>
----------------------------------------------------------------------
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..b01d665 100644
--- a/functional_tests/doc_tests/test_selector_plugin/selector_plugin.rst
+++ b/functional_tests/doc_tests/test_selector_plugin/selector_plugin.rst
@@ -107,11 +107,11 @@ the test loader.
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
+ >>> run(argv=argv, plugins=[UseMySelector()]) # doctest: +ELLIPSIS
+ test_add (basic.TestBasicMath...) ... ok
+ test_sub (basic.TestBasicMath...) ... ok
+ test_tuple_groups (my_function.MyFunction...) ... ok
+ test_cat (cat.StringsCat...) ... ok
<BLANKLINE>
----------------------------------------------------------------------
Ran 4 tests in ...s
diff --git a/functional_tests/test_attribute_plugin.py b/functional_tests/test_attribute_plugin.py
index c9bab66..5b0bf14 100644
--- a/functional_tests/test_attribute_plugin.py
+++ b/functional_tests/test_attribute_plugin.py
@@ -150,7 +150,7 @@ class TestClassAndMethodAttrs(AttributePluginTester):
args = ["-a", "meth_attr=method,cls_attr=class"]
def verify(self):
- assert '(test_attr.TestClassAndMethodAttrs) ... ok' in self.output
+ assert '(test_attr.TestClassAndMethodAttrs' 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 +166,7 @@ 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
+ assert 'test_a (test.TestBase' 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..d9db8c1 100644
--- a/functional_tests/test_xunit.py
+++ b/functional_tests/test_xunit.py
@@ -25,7 +25,7 @@ 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
+ assert "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/plugins/errorclass.py b/nose/plugins/errorclass.py
index d1540e0..8c11e0a 100644
--- a/nose/plugins/errorclass.py
+++ b/nose/plugins/errorclass.py
@@ -66,7 +66,7 @@ each step.
Now run the test. TODO is printed.
>>> _ = case(result) # doctest: +ELLIPSIS
- runTest (....TestTodo) ... TODO: I need to test something
+ runTest (....TestTodo...) ... TODO: I need to test something
Errors and failures are empty, but todo has our test:
@@ -79,7 +79,7 @@ Errors and failures are empty, but todo has our test:
>>> result.printErrors() # doctest: +ELLIPSIS
<BLANKLINE>
======================================================================
- TODO: runTest (....TestTodo)
+ TODO: runTest (....TestTodo...)
----------------------------------------------------------------------
Traceback (most recent call last):
...

View File

@@ -0,0 +1,79 @@
From 5221885fd4fea96edff3e7692cef4531e166e15c Mon Sep 17 00:00:00 2001
From: Thomas A Caswell <tcaswell@gmail.com>
Date: Sat, 26 Sep 2015 23:50:21 -0400
Subject: MNT: hide getargspec usage for 3.6 compatibility
Origin: other, https://github.com/nose-devs/nose/pull/1117
--- nose.orig/nose/plugins/manager.py
+++ nose/nose/plugins/manager.py
@@ -104,8 +104,19 @@
"""
meth = getattr(plugin, call, None)
if meth is not None:
- if call == 'loadTestsFromModule' and \
- len(inspect.getargspec(meth)[0]) == 2:
+ try:
+ sig = inspect.signature(meth)
+ bl = set([inspect.Parameter.VAR_KEYWORD,
+ inspect.Parameter.VAR_POSITIONAL,
+ inspect.Parameter.KEYWORD_ONLY])
+ args = [k for k, v in sig.parameters.items()
+ if v.kind not in bl]
+ arg_len = len(args)
+ if hasattr(meth, '__self__'):
+ arg_len += 1
+ except AttributeError:
+ arg_len = len(inspect.getargspec(meth)[0])
+ if call == 'loadTestsFromModule' and arg_len == 2:
orig_meth = meth
meth = lambda module, path, **kwargs: orig_meth(module)
self.plugins.append((plugin, meth))
@@ -153,6 +164,7 @@
if result is not None:
for r in result:
yield r
+
except (KeyboardInterrupt, SystemExit):
raise
except:
--- nose.orig/nose/util.py
+++ nose/nose/util.py
@@ -449,16 +449,34 @@
if type(obj) == types.ModuleType:
# py.test compatibility
if isinstance(func, types.FunctionType):
- args, varargs, varkw, defaults = \
- inspect.getargspec(func)
+ try:
+ sig = inspect.signature(func)
+ bl = set([inspect.Parameter.VAR_KEYWORD,
+ inspect.Parameter.VAR_POSITIONAL,
+ inspect.Parameter.KEYWORD_ONLY])
+ args = [k for k, v in sig.parameters.items()
+ if v.kind not in bl]
+ except AttributeError:
+ args, varargs, varkw, defaults = \
+ inspect.getargspec(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.pop(0) # pop the self off
+ try:
+ sig = inspect.signature(func)
+ bl = set([inspect.Parameter.VAR_KEYWORD,
+ inspect.Parameter.VAR_POSITIONAL,
+ inspect.Parameter.KEYWORD_ONLY])
+ args = [k for k, v in sig.parameters.items()
+ if v.kind not in bl]
+
+ except AttributeError:
+ args, varargs, varkw, defaults = \
+ inspect.getargspec(func)
+ args.pop(0) # pop the self off
except TypeError:
raise TypeError("Attribute %s of %r is not a python "
"function. Only functions or callables"

View File

@@ -0,0 +1,65 @@
From: Dmitry Shachnev <mitya57@gmail.com>
Date: Mon, 30 Oct 2017 23:40:34 +0300
Subject: Fix failures with Python 3.6 related to the new ModuleNotFoundError
class
---
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..1362c90 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: ...Error (No module ...apackagethatdoesntexist...) ... ERROR
#2 test_b.test ... ok
#3 test_b.test_fail ... FAIL
<BLANKLINE>
======================================================================
- ERROR: Failure: ImportError (No module ...apackagethatdoesntexist...)
+ ERROR: Failure: ...Error (No module ...apackagethatdoesntexist...)
----------------------------------------------------------------------
Traceback (most recent call last):
...
- ImportError: No module ...apackagethatdoesntexist...
+ ...Error: 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: ...Error (No module ...apackagethatdoesntexist...) ... ERROR
<BLANKLINE>
======================================================================
- ERROR: Failure: ImportError (No module ...apackagethatdoesntexist...)
+ ERROR: Failure: ...Error (No module ...apackagethatdoesntexist...)
----------------------------------------------------------------------
Traceback (most recent call last):
...
- ImportError: No module ...apackagethatdoesntexist...
+ ...Error: No module ...apackagethatdoesntexist...
<BLANKLINE>
----------------------------------------------------------------------
Ran 1 test in ...s

View File

@@ -0,0 +1,22 @@
From: Dmitry Shachnev <mitya57@debian.org>
Date: Sat, 8 Feb 2020 13:12:45 +0300
Subject: Unset body max-width option
Sphinx 1.7+ sets it to 800px by default, which does not play nice with
our right sidebar.
---
doc/conf.py | 1 +
1 file changed, 1 insertion(+)
diff --git a/doc/conf.py b/doc/conf.py
index 358414f..cccfd95 100644
--- a/doc/conf.py
+++ b/doc/conf.py
@@ -199,6 +199,7 @@ html_theme_options = {
'relbarbgcolor': '#fff',
'relbartextcolor': '#20435c',
'relbarlinkcolor': '#355f7c',
+ 'body_max_width': None,
}
# the css mostly overrides this:

View File

@@ -0,0 +1,39 @@
From: Dmitry Shachnev <mitya57@debian.org>
Date: Thu, 25 Jun 2020 11:58:34 +0300
Subject: Use class-based directives to fix build with Sphinx 3.x
---
nose/sphinx/pluginopts.py | 15 +++++++++++----
1 file changed, 11 insertions(+), 4 deletions(-)
diff --git a/nose/sphinx/pluginopts.py b/nose/sphinx/pluginopts.py
index d2b284a..033297b 100644
--- a/nose/sphinx/pluginopts.py
+++ b/nose/sphinx/pluginopts.py
@@ -34,7 +34,7 @@ import os
try:
from docutils import nodes, utils
from docutils.statemachine import ViewList
- from docutils.parsers.rst import directives
+ from docutils.parsers.rst import convert_directive_function, directives
except ImportError:
pass # won't run anyway
@@ -183,7 +183,14 @@ class Opt(object):
def setup(app):
+ autoplugin_directive.content = True
+ autoplugin_directive.arguments = (1, 0, True)
+ autoplugin_directive.options = {'plugin': directives.unchanged}
app.add_directive('autoplugin',
- autoplugin_directive, 1, (1, 0, 1),
- plugin=directives.unchanged)
- app.add_directive('autohelp', autohelp_directive, 0, (0, 0, 1))
+ convert_directive_function(autoplugin_directive))
+
+ autohelp_directive.content = False
+ autohelp_directive.arguments = (0, 0, True)
+ autohelp_directive.options = {}
+ app.add_directive('autohelp',
+ convert_directive_function(autohelp_directive))

View File

@@ -0,0 +1,29 @@
From: Dmitry Shachnev <mitya57@debian.org>
Date: Sat, 8 Feb 2020 12:47:10 +0300
Subject: html_sidebars values should be lists, not single strings
The single string values were deprecated in Sphinx 1.7 and removed
in Sphinx 2.0.
---
doc/conf.py | 8 +++++++-
1 file changed, 7 insertions(+), 1 deletion(-)
diff --git a/doc/conf.py b/doc/conf.py
index ac7f0cb..358414f 100644
--- a/doc/conf.py
+++ b/doc/conf.py
@@ -132,7 +132,13 @@ html_static_path = ['.static']
# Custom sidebar templates, maps document names to template names.
html_sidebars = {
- 'index': 'indexsidebar.html'
+ 'index': [
+ 'localtoc.html',
+ 'relations.html',
+ 'sourcelink.html',
+ 'indexsidebar.html',
+ 'searchbox.html',
+ ],
}
# Additional templates that should be rendered to pages, maps page names to