Merge ~cjwatson/lazr.delegates:rhinectomy into lazr.delegates:main

Proposed by Colin Watson
Status: Merged
Approved by: Colin Watson
Approved revision: 5e48801f78161f22fa360ec9ad46e2dd3b2f710a
Merged at revision: 5e48801f78161f22fa360ec9ad46e2dd3b2f710a
Proposed branch: ~cjwatson/lazr.delegates:rhinectomy
Merge into: lazr.delegates:main
Diff against target: 291 lines (+102/-26)
7 files modified
.gitignore (+1/-0)
NEWS.rst (+1/-0)
dev/null (+0/-9)
lazr/delegates/tests/test_docs.py (+67/-0)
lazr/delegates/tests/test_python2.py (+2/-9)
setup.py (+0/-6)
tox.ini (+31/-2)
Reviewer Review Type Date Requested Status
Jürgen Gmach Approve
Review via email: mp+412127@code.launchpad.net

Commit message

Test using zope.testrunner rather than nose

Description of the change

`nose` is unmaintained and doesn't work with Python 3.10. There's `nose2`, but using `zope.testrunner` brings this more into line with other lazr.* projects.

Coverage currently appears fairly terrible, but will improve dramatically once we drop Python 2 support. I could have done Python 2 and 3 runs and combined the coverage output, but it didn't seem worth the complexity when we're likely to be dropping Python 2 support from here soon anyway.

Pre-empting an obvious question: I don't necessarily object to using the `pytest` runner instead, but I thought it better to start by using the same thing as most other lazr.* projects, and we can consider switching them all over in one go later.

Python 2.6 support was already dropped in 2015, but apparently accidentally not removed from `setup.py`, and since I needed to adjust how tests are skipped as part of this work in a way that definitely wouldn't work with Python 2.6 I took the opportunity to update that.

To post a comment you must log in.
Revision history for this message
Jürgen Gmach (jugmac00) :
Revision history for this message
Jürgen Gmach (jugmac00) wrote :

LGTM

We can drop the very old Python 3 version in another MP.

I have created a MP based on yours with combined coverage - I never did that before, but I thought it would be fun to try out.

I will propose it once your's have landed.

review: Approve
Revision history for this message
Jürgen Gmach (jugmac00) wrote :

As you said, the coverage looks much better when combined.

Name Stmts Miss Cover Missing
------------------------------------------------------------------------
lazr/delegates/__init__.py 11 0 100%
lazr/delegates/_delegates.py 32 0 100%
lazr/delegates/_passthrough.py 22 0 100%
lazr/delegates/_python2.py 18 0 100%
lazr/delegates/_python3.py 15 0 100%
lazr/delegates/_version.py 1 0 100%
lazr/delegates/docs/__init__.py 0 0 100%
lazr/delegates/tests/__init__.py 0 0 100%
lazr/delegates/tests/test_api.py 12 3 75% 30-31, 35
lazr/delegates/tests/test_docs.py 19 0 100%
lazr/delegates/tests/test_passthrough.py 46 0 100%
lazr/delegates/tests/test_python2.py 94 4 96% 105, 154-155, 159
------------------------------------------------------------------------
TOTAL 270 7 97%

Missing % in test files usually is a sign of a bogus test setup. I think we should have a look once we drop Python 2.

Revision history for this message
Colin Watson (cjwatson) wrote :

Some of these are "else fail" kind of constructs, where I think "# pragma: no cover" would be suitable. But yes, let's check after dropping Python 2.

FYI you can propose MPs based on unlanded ones without having to wait for them to land, by using the "prerequisite branch" facility (this doesn't exist on GitHub so you may not be familiar with it). Though as I mentioned I wonder whether combined coverage is worth the complexity when we'll be dropping Python 2 support anyway?

Revision history for this message
Jürgen Gmach (jugmac00) wrote :

Thanks for the info about "MPs on unlanded ones" - this was indeed new.

I know it would not have been necessary to combine coverage, but as I never did that before, this was a nice fun "project" for the weekend.

Though it turned out it is not that complicated - once you know how it works :-)

This "knowledge" could come handy when we have to combine the coverage results for different Python 3 versions (I look at you Python 3.10 :-) ).

see https://code.launchpad.net/~jugmac00/lazr.delegates/+git/lazr.delegates/+merge/412213

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
diff --git a/.gitignore b/.gitignore
index daeb903..16ba64f 100644
--- a/.gitignore
+++ b/.gitignore
@@ -11,6 +11,7 @@ build
11dist11dist
12__pycache__12__pycache__
13.coverage13.coverage
14htmlcov
14.tox15.tox
15*.pyc16*.pyc
16lazr/delegates/docs/_build17lazr/delegates/docs/_build
diff --git a/NEWS.rst b/NEWS.rst
index 731cf96..476c1d4 100644
--- a/NEWS.rst
+++ b/NEWS.rst
@@ -5,6 +5,7 @@ NEWS for lazr.delegates
52.0.552.0.5
6=====6=====
7- Officially add support for Python 3.6, 3.7, and 3.8.7- Officially add support for Python 3.6, 3.7, and 3.8.
8- Test using ``zope.testrunner`` rather than ``nose``.
89
910
102.0.4 (2017-10-20)112.0.4 (2017-10-20)
diff --git a/lazr/delegates/docs/fixture.py b/lazr/delegates/docs/fixture.py
11deleted file mode 10064412deleted file mode 100644
index 1d4aced..0000000
--- a/lazr/delegates/docs/fixture.py
+++ /dev/null
@@ -1,34 +0,0 @@
1# Copyright 2009-2015 Canonical Ltd. All rights reserved.
2#
3# This file is part of lazr.delegates
4#
5# lazr.delegates is free software: you can redistribute it and/or modify it
6# under the terms of the GNU Lesser General Public License as published by
7# the Free Software Foundation, version 3 of the License.
8#
9# lazr.delegates is distributed in the hope that it will be useful, but WITHOUT
10# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11# FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
12# License for more details.
13#
14# You should have received a copy of the GNU Lesser General Public License
15# along with lazr.delegates. If not, see <http://www.gnu.org/licenses/>.
16
17"""Doctest fixtures for running under nose."""
18
19from __future__ import absolute_import, print_function, unicode_literals
20
21__metaclass__ = type
22__all__ = [
23 'globs',
24 ]
25
26
27def globs(globs):
28 """Set up globals for doctests."""
29 # Enable future statements to make Python 2 act more like Python 3.
30 globs['absolute_import'] = absolute_import
31 globs['print_function'] = print_function
32 globs['unicode_literals'] = unicode_literals
33 # Provide a convenient way to clean things up at the end of the test.
34 return globs
diff --git a/lazr/delegates/docs/usage_fixture.py b/lazr/delegates/docs/usage_fixture.py
35deleted file mode 1006440deleted file mode 100644
index 7012cf7..0000000
--- a/lazr/delegates/docs/usage_fixture.py
+++ /dev/null
@@ -1,27 +0,0 @@
1# Copyright 2009-2015 Canonical Ltd. All rights reserved.
2#
3# This file is part of lazr.delegates
4#
5# lazr.delegates is free software: you can redistribute it and/or modify it
6# under the terms of the GNU Lesser General Public License as published by
7# the Free Software Foundation, version 3 of the License.
8#
9# lazr.delegates is distributed in the hope that it will be useful, but WITHOUT
10# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11# FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
12# License for more details.
13#
14# You should have received a copy of the GNU Lesser General Public License
15# along with lazr.delegates. If not, see <http://www.gnu.org/licenses/>.
16
17"""Doctest fixtures for running under nose."""
18
19from __future__ import absolute_import, print_function, unicode_literals
20
21__metaclass__ = type
22__all__ = [
23 'globs',
24 ]
25
26
27from lazr.delegates.docs.fixture import globs
diff --git a/lazr/delegates/tests/test_docs.py b/lazr/delegates/tests/test_docs.py
28new file mode 1006440new file mode 100644
index 0000000..7ca6971
--- /dev/null
+++ b/lazr/delegates/tests/test_docs.py
@@ -0,0 +1,67 @@
1# Copyright 2009-2021 Canonical Ltd. All rights reserved.
2#
3# This file is part of lazr.delegates.
4#
5# lazr.delegates is free software: you can redistribute it and/or modify it
6# under the terms of the GNU Lesser General Public License as published by
7# the Free Software Foundation, version 3 of the License.
8#
9# lazr.delegates is distributed in the hope that it will be useful, but WITHOUT
10# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11# FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
12# License for more details.
13#
14# You should have received a copy of the GNU Lesser General Public License
15# along with lazr.delegates. If not, see <http://www.gnu.org/licenses/>.
16
17"""Test harness for doctests."""
18
19from __future__ import absolute_import, print_function, unicode_literals
20
21__metaclass__ = type
22__all__ = []
23
24import atexit
25import doctest
26import os
27
28from pkg_resources import (
29 resource_filename,
30 resource_exists,
31 resource_listdir,
32 cleanup_resources,
33)
34
35
36DOCTEST_FLAGS = (
37 doctest.ELLIPSIS | doctest.NORMALIZE_WHITESPACE | doctest.REPORT_NDIFF
38)
39
40
41def load_tests(loader, tests, pattern):
42 """Load the doc tests (docs/*, if any exist)."""
43 doctest_files = []
44 if resource_exists("lazr.delegates", "docs"):
45 for name in resource_listdir("lazr.delegates", "docs"):
46 if name.endswith(".rst"):
47 doctest_files.append(
48 os.path.abspath(
49 resource_filename("lazr.delegates", "docs/%s" % name)
50 )
51 )
52 atexit.register(cleanup_resources)
53 globs = {
54 "absolute_import": absolute_import,
55 "print_function": print_function,
56 "unicode_literals": unicode_literals,
57 }
58 tests.addTest(
59 doctest.DocFileSuite(
60 *doctest_files,
61 module_relative=False,
62 optionflags=DOCTEST_FLAGS,
63 globs=globs,
64 encoding="UTF-8"
65 )
66 )
67 return tests
diff --git a/lazr/delegates/tests/test_python2.py b/lazr/delegates/tests/test_python2.py
index 1cc873b..ad3de7e 100644
--- a/lazr/delegates/tests/test_python2.py
+++ b/lazr/delegates/tests/test_python2.py
@@ -63,14 +63,7 @@ class BaseOtherFoo(BaseFoo):
63 another = 'yes, another'63 another = 'yes, another'
6464
6565
66# Python 2.6 doesn't have skips.66@unittest.skipIf(sys.version_info[0] > 2, "only relevant in Python 2")
67def skip_python3(cls):
68 if sys.version_info[0] > 2:
69 return None
70 return cls
71
72
73@skip_python3
74class TestLegacyAPI(unittest.TestCase):67class TestLegacyAPI(unittest.TestCase):
75 def test_basic_usage(self):68 def test_basic_usage(self):
76 class SomeClass(object):69 class SomeClass(object):
@@ -146,7 +139,7 @@ class TestLegacyAPI(unittest.TestCase):
146 self.assertTrue(IOther.providedBy(foo_with_teapot))139 self.assertTrue(IOther.providedBy(foo_with_teapot))
147140
148141
149@skip_python3142@unittest.skipIf(sys.version_info[0] > 2, "only relevant in Python 2")
150class TestNewAPI(unittest.TestCase):143class TestNewAPI(unittest.TestCase):
151 """Test corner cases in Python 2.144 """Test corner cases in Python 2.
152145
diff --git a/setup.cfg b/setup.cfg
153deleted file mode 100644146deleted file mode 100644
index 0af9456..0000000
--- a/setup.cfg
+++ /dev/null
@@ -1,9 +0,0 @@
1[nosetests]
2verbosity=3
3with-coverage=1
4with-doctest=1
5doctest-extension=.rst
6doctest-options=+ELLIPSIS,+NORMALIZE_WHITESPACE,+REPORT_NDIFF
7doctest-fixtures=_fixture
8cover-package=lazr.delegates
9pdb=1
diff --git a/setup.py b/setup.py
index f0fe050..f8b5b24 100755
--- a/setup.py
+++ b/setup.py
@@ -37,7 +37,6 @@ delegating behavior.
37""",37""",
38 license='LGPL v3',38 license='LGPL v3',
39 install_requires=[39 install_requires=[
40 'nose',
41 'setuptools',40 'setuptools',
42 'zope.interface',41 'zope.interface',
43 ],42 ],
@@ -50,7 +49,6 @@ delegating behavior.
50 "Operating System :: OS Independent",49 "Operating System :: OS Independent",
51 'Programming Language :: Python',50 'Programming Language :: Python',
52 'Programming Language :: Python :: 2',51 'Programming Language :: Python :: 2',
53 'Programming Language :: Python :: 2.6',
54 'Programming Language :: Python :: 2.7',52 'Programming Language :: Python :: 2.7',
55 'Programming Language :: Python :: 3',53 'Programming Language :: Python :: 3',
56 'Programming Language :: Python :: 3.2',54 'Programming Language :: Python :: 3.2',
@@ -64,8 +62,4 @@ delegating behavior.
64 extras_require={62 extras_require={
65 "docs": ["Sphinx"],63 "docs": ["Sphinx"],
66 },64 },
67 # nose plugins don't really work with `python setup.py test` so use
68 # `python setup.py nosetests` instead, or just `tox`. Gosh, we really
69 # should switch to nose2. :/ - BAW 2014-08-20
70 #test_suite='nose.collector',
71 )65 )
diff --git a/tox.ini b/tox.ini
index 76a9117..f30fd94 100644
--- a/tox.ini
+++ b/tox.ini
@@ -1,8 +1,21 @@
1[tox]1[tox]
2envlist = py27,py32,py33,py34,py35,py36,py37,py382envlist =
3 py27
4 py32
5 py33
6 py34
7 py35
8 py36
9 py37
10 py38
11 coverage
312
4[testenv]13[testenv]
5commands = python setup.py nosetests14deps =
15 .
16 zope.testrunner
17commands =
18 zope-testrunner --test-path . --tests-pattern ^tests {posargs}
619
7[testenv:docs]20[testenv:docs]
8basepython =21basepython =
@@ -11,3 +24,19 @@ commands =
11 sphinx-build -b html -d lazr/delegates/docs/_build/doctrees lazr/delegates/docs lazr/delegates/docs/_build/html24 sphinx-build -b html -d lazr/delegates/docs/_build/doctrees lazr/delegates/docs lazr/delegates/docs/_build/html
12deps =25deps =
13 .[docs]26 .[docs]
27
28[testenv:coverage]
29basepython =
30 python3
31deps =
32 coverage
33 zope.testrunner
34commands =
35 coverage erase
36 coverage run -m zope.testrunner --test-path . --tests-pattern ^tests {posargs}
37 coverage html
38 coverage report -m --fail-under=56
39
40[coverage:run]
41source = lazr.delegates
42omit = */docs/conf.py

Subscribers

People subscribed via source and target branches

to all changes: