From 37fbe31d8d1dfab7b9beb76812700fefd4a8e939 Mon Sep 17 00:00:00 2001 From: Greg Smethells <3286666+gsmethells@users.noreply.github.com> Date: Wed, 29 Sep 2021 16:21:12 -0500 Subject: [PATCH 01/42] Fix spelling error --- src/pytest_cov/embed.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/pytest_cov/embed.py b/src/pytest_cov/embed.py index 3adecdba..fe0575e9 100644 --- a/src/pytest_cov/embed.py +++ b/src/pytest_cov/embed.py @@ -100,9 +100,9 @@ def cleanup(): _active_cov = None _cleanup_in_progress = False if _pending_signal: - pending_singal = _pending_signal + pending_signal = _pending_signal _pending_signal = None - _signal_cleanup_handler(*pending_singal) + _signal_cleanup_handler(*pending_signal) multiprocessing_finish = cleanup # in case someone dared to use this internal From 5980fe2c22667891957e716e1047e4cd15e07898 Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Mon, 27 Sep 2021 19:44:17 +0000 Subject: [PATCH 02/42] [pre-commit.ci] pre-commit autoupdate MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit updates: - [github.com/asottile/pyupgrade: v2.23.3 → v2.28.0](https://github.com/asottile/pyupgrade/compare/v2.23.3...v2.28.0) --- .pre-commit-config.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index dc36fa2b..6af3f081 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -19,7 +19,7 @@ repos: hooks: - id: flake8 - repo: https://github.com/asottile/pyupgrade - rev: v2.23.3 + rev: v2.28.0 hooks: - id: pyupgrade args: [--py36-plus] From 574b5b5d30e663050910b0ae07f31bc7e45d2527 Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Mon, 27 Sep 2021 19:47:25 +0000 Subject: [PATCH 03/42] [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci --- setup.py | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/setup.py b/setup.py index 11e98a88..a43d0f07 100755 --- a/setup.py +++ b/setup.py @@ -27,7 +27,7 @@ def read(*names, **kwargs): class BuildWithPTH(build): def run(self, *args, **kwargs): - build.run(self, *args, **kwargs) + super().run(*args, **kwargs) path = join(dirname(__file__), 'src', 'pytest-cov.pth') dest = join(self.build_lib, basename(path)) self.copy_file(path, dest) @@ -35,7 +35,7 @@ def run(self, *args, **kwargs): class EasyInstallWithPTH(easy_install): def run(self, *args, **kwargs): - easy_install.run(self, *args, **kwargs) + super().run(*args, **kwargs) path = join(dirname(__file__), 'src', 'pytest-cov.pth') dest = join(self.install_dir, basename(path)) self.copy_file(path, dest) @@ -43,19 +43,19 @@ def run(self, *args, **kwargs): class InstallLibWithPTH(install_lib): def run(self, *args, **kwargs): - install_lib.run(self, *args, **kwargs) + super().run(*args, **kwargs) path = join(dirname(__file__), 'src', 'pytest-cov.pth') dest = join(self.install_dir, basename(path)) self.copy_file(path, dest) self.outputs = [dest] def get_outputs(self): - return chain(install_lib.get_outputs(self), self.outputs) + return chain(super().get_outputs(), self.outputs) class DevelopWithPTH(develop): def run(self, *args, **kwargs): - develop.run(self, *args, **kwargs) + super().run(*args, **kwargs) path = join(dirname(__file__), 'src', 'pytest-cov.pth') dest = join(self.install_dir, basename(path)) self.copy_file(path, dest) From e764047dd6cd2bed504e54232fc1b48c58724882 Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Mon, 4 Oct 2021 19:49:32 +0000 Subject: [PATCH 04/42] [pre-commit.ci] pre-commit autoupdate MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit updates: - [github.com/asottile/pyupgrade: v2.28.0 → v2.29.0](https://github.com/asottile/pyupgrade/compare/v2.28.0...v2.29.0) --- .pre-commit-config.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 6af3f081..e57766d6 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -19,7 +19,7 @@ repos: hooks: - id: flake8 - repo: https://github.com/asottile/pyupgrade - rev: v2.28.0 + rev: v2.29.0 hooks: - id: pyupgrade args: [--py36-plus] From e00d4a3ac5bc232a05ff909e51b0c6f510ff06a1 Mon Sep 17 00:00:00 2001 From: Arthur Rio Date: Thu, 7 Oct 2021 10:48:14 -0600 Subject: [PATCH 05/42] Update Changelog to reflect toml requirement change --- CHANGELOG.rst | 3 +++ 1 file changed, 3 insertions(+) diff --git a/CHANGELOG.rst b/CHANGELOG.rst index e6e47d95..014b2c67 100644 --- a/CHANGELOG.rst +++ b/CHANGELOG.rst @@ -24,6 +24,9 @@ Changelog `#488 `_. * Updated trove classifiers. Contributed by Michał Bielawski in `#481 `_. +* Reverted change for `toml` requirement. + Contributed by Thomas Grainger in + `#477 `_. 2.13.0 (2021-06-01) From 125f5188632340e25908ae4163d1a9dfa3ab8fe9 Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Mon, 22 Nov 2021 20:53:36 +0000 Subject: [PATCH 06/42] [pre-commit.ci] pre-commit autoupdate MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit updates: - [github.com/PyCQA/isort: 5.9.3 → 5.10.1](https://github.com/PyCQA/isort/compare/5.9.3...5.10.1) - [github.com/PyCQA/flake8: 3.9.2 → 4.0.1](https://github.com/PyCQA/flake8/compare/3.9.2...4.0.1) - [github.com/asottile/pyupgrade: v2.29.0 → v2.29.1](https://github.com/asottile/pyupgrade/compare/v2.29.0...v2.29.1) --- .pre-commit-config.yaml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index e57766d6..a0c352fb 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -11,15 +11,15 @@ repos: exclude: '.*\.pth$' - id: debug-statements - repo: https://github.com/PyCQA/isort - rev: 5.9.3 + rev: 5.10.1 hooks: - id: isort - repo: https://github.com/PyCQA/flake8 - rev: 3.9.2 + rev: 4.0.1 hooks: - id: flake8 - repo: https://github.com/asottile/pyupgrade - rev: v2.29.0 + rev: v2.29.1 hooks: - id: pyupgrade args: [--py36-plus] From 6925fcfbb2c96e01124840c46ebbda6719fbbbcd Mon Sep 17 00:00:00 2001 From: Zac-HD Date: Sun, 12 Dec 2021 00:59:38 +1100 Subject: [PATCH 07/42] --co disables --cov-fail-under --- AUTHORS.rst | 1 + CHANGELOG.rst | 8 ++++++++ src/pytest_cov/plugin.py | 2 +- tests/test_pytest_cov.py | 13 +++++++++++++ 4 files changed, 23 insertions(+), 1 deletion(-) diff --git a/AUTHORS.rst b/AUTHORS.rst index 6aa916a1..489903c2 100644 --- a/AUTHORS.rst +++ b/AUTHORS.rst @@ -50,3 +50,4 @@ Authors * Brian Rutledge - https://github.com/bhrutledge * Danilo Šegan - https://github.com/dsegan * Michał Bielawski - https://github.com/D3X +* Zac Hatfield-Dodds - https://github.com/Zac-HD diff --git a/CHANGELOG.rst b/CHANGELOG.rst index e6e47d95..684720ff 100644 --- a/CHANGELOG.rst +++ b/CHANGELOG.rst @@ -2,6 +2,14 @@ Changelog ========= +3.1.0 (future) +------------------- + +* `--cov-fail-under` no longer causes `pytest --collect-only` to fail + Contributed by Zac Hatfield-Dodds in + `#511 `_. + + 3.0.0 (2021-10-04) ------------------- diff --git a/src/pytest_cov/plugin.py b/src/pytest_cov/plugin.py index 94a1e494..e915246d 100644 --- a/src/pytest_cov/plugin.py +++ b/src/pytest_cov/plugin.py @@ -308,7 +308,7 @@ def pytest_runtestloop(self, session): warnings.warn(CovReportWarning(message)) self.cov_total = 0 assert self.cov_total is not None, 'Test coverage should never be `None`' - if self._failed_cov_total(): + if self._failed_cov_total() and not self.options.collectonly: # make sure we get the EXIT_TESTSFAILED exit code compat_session.testsfailed += 1 diff --git a/tests/test_pytest_cov.py b/tests/test_pytest_cov.py index e7f90668..f93d352f 100644 --- a/tests/test_pytest_cov.py +++ b/tests/test_pytest_cov.py @@ -389,6 +389,19 @@ def test_cov_min_100(testdir): ]) +def test_cov_min_100_passes_if_collectonly(testdir): + script = testdir.makepyfile(SCRIPT) + + result = testdir.runpytest('-v', + '--cov=%s' % script.dirpath(), + '--cov-report=term-missing', + '--cov-fail-under=100', + '--collect-only', + script) + + assert result.ret == 0 + + def test_cov_min_50(testdir): script = testdir.makepyfile(SCRIPT) From 2c23d3aa0761703617392a628e846afdad9e83cc Mon Sep 17 00:00:00 2001 From: "Kian-Meng, Ang" Date: Tue, 21 Dec 2021 13:13:09 +0800 Subject: [PATCH 08/42] Fix typos --- docs/config.rst | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/docs/config.rst b/docs/config.rst index 0ead66e8..e1e4c3d3 100644 --- a/docs/config.rst +++ b/docs/config.rst @@ -26,11 +26,11 @@ For full details refer to the `coverage config file`_ documentation. This plugin overrides the ``data_file`` and ``parallel`` options of coverage. Unless you also run coverage without pytest-cov it's pointless to set those options in your ``.coveragerc``. - If you use the ``--cov=something`` option (with a value) then coverage's ``source`` option will also get overriden. - If you have multiple sources it might be easier to set those in ``.coveragerc`` and always use ``--cov`` (wihout a value) + If you use the ``--cov=something`` option (with a value) then coverage's ``source`` option will also get overridden. + If you have multiple sources it might be easier to set those in ``.coveragerc`` and always use ``--cov`` (without a value) instead of having a long command line with ``--cov=pkg1 --cov=pkg2 --cov=pkg3 ...``. - If you use the ``--cov-branch`` option then coverage's ``branch`` option will also get overriden. + If you use the ``--cov-branch`` option then coverage's ``branch`` option will also get overridden. If you wish to always add pytest-cov with pytest, you can use ``addopts`` under ``pytest`` or ``tool:pytest`` section. For example: :: From 6d06678a76d9275beb48917d7653ea6a610c7717 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20G=C3=B3rny?= Date: Sun, 23 Jan 2022 15:03:35 +0100 Subject: [PATCH 09/42] Update test_invalid_coverage_source for coverage-6.2 Update test_invalid_coverage_source to make the "No data was collected" less strict, as the output has changed in coverage-6.2. This solution was suggested by Tom Callaway (@spotrh) on the linked bug. Fixes #509 --- tests/test_pytest_cov.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/test_pytest_cov.py b/tests/test_pytest_cov.py index f93d352f..6d979495 100644 --- a/tests/test_pytest_cov.py +++ b/tests/test_pytest_cov.py @@ -981,7 +981,7 @@ def test_invalid_coverage_source(testdir): '*10 passed*' ]) result.stderr.fnmatch_lines([ - 'Coverage.py warning: No data was collected.*' + '*No data was collected.*' ]) result.stdout.fnmatch_lines([ '*Failed to generate report: No data to report.', From 4870f997615c1ac40a996e296079454c003f9e91 Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Mon, 9 May 2022 20:57:16 +0000 Subject: [PATCH 10/42] [pre-commit.ci] pre-commit autoupdate MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit updates: - [github.com/pre-commit/pre-commit-hooks: v4.0.1 → v4.2.0](https://github.com/pre-commit/pre-commit-hooks/compare/v4.0.1...v4.2.0) - [github.com/asottile/pyupgrade: v2.29.1 → v2.32.1](https://github.com/asottile/pyupgrade/compare/v2.29.1...v2.32.1) --- .pre-commit-config.yaml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index a0c352fb..9bc7894f 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -4,7 +4,7 @@ # pre-commit install-hooks repos: - repo: https://github.com/pre-commit/pre-commit-hooks - rev: v4.0.1 + rev: v4.2.0 hooks: - id: trailing-whitespace - id: end-of-file-fixer @@ -19,7 +19,7 @@ repos: hooks: - id: flake8 - repo: https://github.com/asottile/pyupgrade - rev: v2.29.1 + rev: v2.32.1 hooks: - id: pyupgrade args: [--py36-plus] From e31f3e93802aa084d2e601667fa36be603d844d5 Mon Sep 17 00:00:00 2001 From: Colin O'Dell Date: Tue, 1 Mar 2022 17:14:23 -0500 Subject: [PATCH 11/42] Add sample error a user might encounter --- docs/debuggers.rst | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/docs/debuggers.rst b/docs/debuggers.rst index 15c83218..603119bb 100644 --- a/docs/debuggers.rst +++ b/docs/debuggers.rst @@ -7,7 +7,13 @@ Debuggers and PyCharm When it comes to TDD one obviously would like to debug tests. Debuggers in Python use mostly the sys.settrace function to gain access to context. Coverage uses the same technique to get access to the lines executed. Coverage does not play well with other tracers simultaneously running. This manifests itself in behaviour that PyCharm might not hit a -breakpoint no matter what the user does. Since it is common practice to have coverage configuration in the pytest.ini +breakpoint no matter what the user does, or encountering an error like this:: + + PYDEV DEBUGGER WARNING: + sys.settrace() should not be used when the debugger is being used. + This may cause the debugger to stop working correctly. + +Since it is common practice to have coverage configuration in the pytest.ini file and pytest does not support removeopts or similar the `--no-cov` flag can disable coverage completely. At the reporting part a warning message will show on screen:: From 6da2d308d1f6279c7016164e3b22842e2fe669f7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ionel=20Cristian=20M=C4=83rie=C8=99?= Date: Wed, 2 Feb 2022 18:49:23 +0200 Subject: [PATCH 12/42] Add extra envs. --- tox.ini | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/tox.ini b/tox.ini index 20a1561b..99e1fff6 100644 --- a/tox.ini +++ b/tox.ini @@ -15,7 +15,7 @@ envlist = check py{36,37,py,py3}-pytest46-xdist127-coverage{55} py{36,37,38,py3}-pytest{46,54}-xdist133-coverage{55} - py{36,37,38,39,310,py3}-pytest{62}-xdist202-coverage{55} + py{36,37,38,39,310,py3}-pytest{62}-xdist250-coverage{55,60,61,62,63} docs [testenv] @@ -40,6 +40,7 @@ setenv = xdist200: _DEP_PYTESTXDIST=pytest-xdist==2.0.0 xdist201: _DEP_PYTESTXDIST=pytest-xdist==2.1.0 xdist202: _DEP_PYTESTXDIST=pytest-xdist==2.2.0 + xdist250: _DEP_PYTESTXDIST=pytest-xdist==2.5.0 xdistdev: _DEP_PYTESTXDIST=git+https://github.com/pytest-dev/pytest-xdist.git#egg=pytest-xdist coverage45: _DEP_COVERAGE=coverage==4.5.4 @@ -49,6 +50,10 @@ setenv = coverage53: _DEP_COVERAGE=coverage==5.3.1 coverage54: _DEP_COVERAGE=coverage==5.4 coverage55: _DEP_COVERAGE=coverage==5.5 + coverage60: _DEP_COVERAGE=coverage==6.0.2 + coverage61: _DEP_COVERAGE=coverage==6.1.2 + coverage62: _DEP_COVERAGE=coverage==6.2 + coverage63: _DEP_COVERAGE=coverage==6.3 # For testing against a coverage.py working tree. coveragedev: _DEP_COVERAGE=-e{env:COVERAGE_HOME} passenv = From 3858888f670c80edeace519234fa251d7c0448a5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ionel=20Cristian=20M=C4=83rie=C8=99?= Date: Wed, 2 Feb 2022 19:34:59 +0200 Subject: [PATCH 13/42] Skip this on newer xdist. --- tests/test_pytest_cov.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/tests/test_pytest_cov.py b/tests/test_pytest_cov.py index 6d979495..32804bc0 100644 --- a/tests/test_pytest_cov.py +++ b/tests/test_pytest_cov.py @@ -994,6 +994,8 @@ def test_invalid_coverage_source(testdir): @pytest.mark.skipif("'dev' in pytest.__version__") @pytest.mark.skipif('sys.platform == "win32" and platform.python_implementation() == "PyPy"') +@pytest.mark.skipif('tuple(map(int, xdist.__version__.split("."))) >= (2, 3, 0)', + reason="Since pytest-xdist 2.3.0 the parent sys.path is copied in the child process") def test_dist_missing_data(testdir): """Test failure when using a worker without pytest-cov installed.""" venv_path = os.path.join(str(testdir.tmpdir), 'venv') From fa8ecf4ec198c3a29c979ae5be0f0b236c29bf4c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ionel=20Cristian=20M=C4=83rie=C8=99?= Date: Wed, 2 Feb 2022 19:36:42 +0200 Subject: [PATCH 14/42] Parametrize the spawn method. --- tests/test_pytest_cov.py | 60 ++++++++++++++++++++++++++-------------- 1 file changed, 39 insertions(+), 21 deletions(-) diff --git a/tests/test_pytest_cov.py b/tests/test_pytest_cov.py index 32804bc0..e94d59be 100644 --- a/tests/test_pytest_cov.py +++ b/tests/test_pytest_cov.py @@ -157,6 +157,15 @@ def test_foo(cov): pytest.param('-n 1', marks=pytest.mark.skipif('sys.platform == "win32" and platform.python_implementation() == "PyPy"')) ], ids=['nodist', 'xdist']) +skipif_multiprocessing_is_broken = pytest.mark.skipif( + 'sys.version_info[:2] >= (3, 8)', + reason="deadlocks on Python 3.8+, see: https://bugs.python.org/issue38227" +) +method_params = pytest.mark.parametrize('method', [ + pytest.param('fork', marks=skipif_multiprocessing_is_broken), + pytest.param('spawn', marks=skipif_multiprocessing_is_broken), +]) + @pytest.fixture(scope='session', autouse=True) def adjust_sys_path(): @@ -1025,7 +1034,7 @@ def test_dist_missing_data(testdir): '--dist=load', '--tx=popen//python=%s' % exe, max_worker_restart_0, - script) + str(script)) result.stdout.fnmatch_lines([ 'The following workers failed to return coverage data, ensure that pytest-cov is installed on these workers.' ]) @@ -1062,18 +1071,19 @@ def test_funcarg_not_active(testdir): @pytest.mark.skipif("sys.version_info[0] < 3", reason="no context manager api on Python 2") @pytest.mark.skipif('sys.platform == "win32"', reason="multiprocessing support is broken on Windows") @pytest.mark.skipif('platform.python_implementation() == "PyPy"', reason="often deadlocks on PyPy") -@pytest.mark.skipif('sys.version_info[:2] >= (3, 8)', reason="deadlocks on Python 3.8+, see: https://bugs.python.org/issue38227") -def test_multiprocessing_pool(testdir): +@method_params +def test_multiprocessing_pool(testdir, method): pytest.importorskip('multiprocessing.util') script = testdir.makepyfile(''' import multiprocessing def target_fn(a): - %sse: # pragma: nocover + {}se: # pragma: nocover return None def test_run_target(): + multiprocessing.set_start_method({!r}) from pytest_cov.embed import cleanup_on_sigterm cleanup_on_sigterm() @@ -1081,9 +1091,9 @@ def test_run_target(): with multiprocessing.Pool(3) as p: p.map(target_fn, [i * 3 + j for j in range(3)]) p.join() -''' % ''.join('''if a == %r: +'''.format(''.join('''if a == %r: return a - el''' % i for i in range(99))) + el''' % i for i in range(99)), method)) result = testdir.runpytest('-v', '--cov=%s' % script.dirpath(), @@ -1103,18 +1113,19 @@ def test_run_target(): @pytest.mark.skipif('sys.platform == "win32"', reason="multiprocessing support is broken on Windows") @pytest.mark.skipif('platform.python_implementation() == "PyPy"', reason="often deadlocks on PyPy") -@pytest.mark.skipif('sys.version_info[:2] >= (3, 8)', reason="deadlocks on Python 3.8, see: https://bugs.python.org/issue38227") -def test_multiprocessing_pool_terminate(testdir): +@method_params +def test_multiprocessing_pool_terminate(testdir, method): pytest.importorskip('multiprocessing.util') script = testdir.makepyfile(''' import multiprocessing def target_fn(a): - %sse: # pragma: nocover + {}se: # pragma: nocover return None def test_run_target(): + multiprocessing.set_start_method({!r}) from pytest_cov.embed import cleanup_on_sigterm cleanup_on_sigterm() @@ -1125,9 +1136,9 @@ def test_run_target(): finally: p.terminate() p.join() -''' % ''.join('''if a == %r: +'''.format(''.join('''if a == %r: return a - el''' % i for i in range(99))) + el''' % i for i in range(99)), method)) result = testdir.runpytest('-v', '--cov=%s' % script.dirpath(), @@ -1147,17 +1158,19 @@ def test_run_target(): @pytest.mark.skipif('sys.platform == "win32"', reason="multiprocessing support is broken on Windows") @pytest.mark.skipif('sys.version_info[0] > 2 and platform.python_implementation() == "PyPy"', reason="broken on PyPy3") -def test_multiprocessing_pool_close(testdir): +@method_params +def test_multiprocessing_pool_close(testdir, method): pytest.importorskip('multiprocessing.util') script = testdir.makepyfile(''' import multiprocessing def target_fn(a): - %sse: # pragma: nocover + {}se: # pragma: nocover return None def test_run_target(): + multiprocessing.set_start_method({!r}) for i in range(33): p = multiprocessing.Pool(3) try: @@ -1165,9 +1178,9 @@ def test_run_target(): finally: p.close() p.join() -''' % ''.join('''if a == %r: +'''.format(''.join('''if a == %r: return a - el''' % i for i in range(99))) + el''' % i for i in range(99)), method)) result = testdir.runpytest('-v', '--cov=%s' % script.dirpath(), @@ -1185,7 +1198,8 @@ def test_run_target(): @pytest.mark.skipif('sys.platform == "win32"', reason="multiprocessing support is broken on Windows") -def test_multiprocessing_process(testdir): +@method_params +def test_multiprocessing_process(testdir, method): pytest.importorskip('multiprocessing.util') script = testdir.makepyfile(''' @@ -1196,10 +1210,11 @@ def target_fn(): return a def test_run_target(): + multiprocessing.set_start_method({!r}) p = multiprocessing.Process(target=target_fn) p.start() p.join() -''') +'''.format(method)) result = testdir.runpytest('-v', '--cov=%s' % script.dirpath(), @@ -1215,7 +1230,8 @@ def test_run_target(): @pytest.mark.skipif('sys.platform == "win32"', reason="multiprocessing support is broken on Windows") -def test_multiprocessing_process_no_source(testdir): +@method_params +def test_multiprocessing_process_no_source(testdir, method): pytest.importorskip('multiprocessing.util') script = testdir.makepyfile(''' @@ -1245,7 +1261,8 @@ def test_run_target(): @pytest.mark.skipif('sys.platform == "win32"', reason="multiprocessing support is broken on Windows") -def test_multiprocessing_process_with_terminate(testdir): +@method_params +def test_multiprocessing_process_with_terminate(testdir, method): pytest.importorskip('multiprocessing.util') script = testdir.makepyfile(''' @@ -1783,6 +1800,7 @@ def test_not_started_plugin_does_not_fail(testdir): class ns: cov_source = [True] cov_report = '' + plugin = pytest_cov.plugin.CovPlugin(ns, None, start=False) plugin.pytest_runtestloop(None) plugin.pytest_terminal_summary(None) @@ -1900,7 +1918,7 @@ def test_append_coverage(testdir, opts, prop): result = testdir.runpytest('-v', '--cov=%s' % script.dirpath(), script, - *opts.split()+prop.args) + *opts.split() + prop.args) result.stdout.fnmatch_lines([ 'test_1* %s*' % prop.result, ]) @@ -1909,7 +1927,7 @@ def test_append_coverage(testdir, opts, prop): '--cov-append', '--cov=%s' % script2.dirpath(), script2, - *opts.split()+prop.args) + *opts.split() + prop.args) result.stdout.fnmatch_lines([ 'test_1* %s*' % prop.result, 'test_2* %s*' % prop.result2, From 47ad2d1da4516895bacb4c22a0f922f04457199c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ionel=20Cristian=20M=C4=83rie=C8=99?= Date: Wed, 2 Feb 2022 19:45:01 +0200 Subject: [PATCH 15/42] Remove appveyor and update various skel things. --- .appveyor.yml | 46 -- .cookiecutterrc | 14 +- .github/workflows/test.yml | 864 ++++++++++++++++++++++-- MANIFEST.in | 9 +- README.rst | 3 +- ci/appveyor-with-compiler.cmd | 23 - ci/bootstrap.py | 34 +- ci/requirements.txt | 1 + ci/templates/.appveyor.yml | 53 -- ci/templates/.github/workflows/test.yml | 65 ++ setup.py | 5 + tox.ini | 1 - 12 files changed, 893 insertions(+), 225 deletions(-) delete mode 100644 .appveyor.yml delete mode 100644 ci/appveyor-with-compiler.cmd delete mode 100644 ci/templates/.appveyor.yml create mode 100644 ci/templates/.github/workflows/test.yml diff --git a/.appveyor.yml b/.appveyor.yml deleted file mode 100644 index 9f176ee5..00000000 --- a/.appveyor.yml +++ /dev/null @@ -1,46 +0,0 @@ -# NOTE: this file is auto-generated via ci/bootstrap.py (ci/templates/.appveyor.yml). -version: '{branch}-{build}' -build: off -image: - - Visual Studio 2015 - - Visual Studio 2019 -environment: - matrix: - - TOXENV: check - - TOXENV: 'py36-pytest46-xdist127-coverage55,py36-pytest46-xdist133-coverage55,py36-pytest54-xdist133-coverage55,py36-pytest62-xdist202-coverage55' - - TOXENV: 'py37-pytest46-xdist127-coverage55,py37-pytest46-xdist133-coverage55,py37-pytest54-xdist133-coverage55,py37-pytest62-xdist202-coverage55' - - TOXENV: 'py38-pytest46-xdist133-coverage55,py38-pytest54-xdist133-coverage55,py38-pytest62-xdist202-coverage55' - - TOXENV: 'py39-pytest62-xdist202-coverage55' - - TOXENV: 'pypy3-pytest46-xdist127-coverage55,pypy3-pytest46-xdist133-coverage55,pypy3-pytest54-xdist133-coverage55,pypy3-pytest62-xdist202-coverage55' -matrix: - exclude: - - image: Visual Studio 2015 - TOXENV: 'py36-pytest46-xdist127-coverage55,py36-pytest46-xdist133-coverage55,py36-pytest54-xdist133-coverage55,py36-pytest62-xdist202-coverage55' - - image: Visual Studio 2015 - TOXENV: 'py37-pytest46-xdist127-coverage55,py37-pytest46-xdist133-coverage55,py37-pytest54-xdist133-coverage55,py37-pytest62-xdist202-coverage55' - - image: Visual Studio 2015 - TOXENV: 'py38-pytest46-xdist133-coverage55,py38-pytest54-xdist133-coverage55,py38-pytest62-xdist202-coverage55' - - image: Visual Studio 2015 - TOXENV: 'py39-pytest62-xdist202-coverage55' - - image: Visual Studio 2015 - TOXENV: 'pypy3-pytest46-xdist127-coverage55,pypy3-pytest46-xdist133-coverage55,pypy3-pytest54-xdist133-coverage55,pypy3-pytest62-xdist202-coverage55' -init: - - ps: echo $env:TOXENV - - ps: ls C:\Python* -install: - - IF "%TOXENV:~0,6%" == "pypy3-" choco install --no-progress pypy3 - - SET PATH=C:\tools\pypy\pypy;%PATH% - - C:\Python37\python -m pip install --progress-bar=off tox -rci/requirements.txt - -test_script: - - cmd /E:ON /V:ON /C .\ci\appveyor-with-compiler.cmd C:\Python37\python -m tox - -on_failure: - - ps: dir "env:" - - ps: get-content .tox\*\log\* -artifacts: - - path: dist\* - -### To enable remote debugging uncomment this (also, see: http://www.appveyor.com/docs/how-to/rdp-to-build-worker): -# on_finish: -# - ps: $blockRdp = $true; iex ((new-object net.webclient).DownloadString('https://raw.githubusercontent.com/appveyor/ci/master/scripts/enable-rdp.ps1')) diff --git a/.cookiecutterrc b/.cookiecutterrc index 9cad1178..49e9880e 100644 --- a/.cookiecutterrc +++ b/.cookiecutterrc @@ -2,7 +2,7 @@ default_context: allow_tests_inside_package: no - appveyor: yes + appveyor: no c_extension_function: '-' c_extension_module: '-' c_extension_optional: no @@ -16,10 +16,10 @@ default_context: command_line_interface: no command_line_interface_bin_name: '-' coveralls: no - coveralls_token: '[Required for Appveyor, take it from https://coveralls.io/github/ionelmc/pytest-cov]' distribution_name: pytest-cov email: contact@ionelmc.ro full_name: Ionel Cristian Mărieș + github_actions: yes legacy_python: yes license: MIT license linter: flake8 @@ -29,9 +29,10 @@ default_context: project_short_description: This plugin produces coverage reports. It supports centralised testing and distributed testing in both load and each modes. It also supports coverage of subprocesses. pypi_badge: yes pypi_disable_upload: no - release_date: '2020-06-12' + release_date: '2021-10-04' repo_hosting: github.com repo_hosting_domain: github.com + repo_main_branch: master repo_name: pytest-cov repo_username: pytest-dev requiresio: yes @@ -45,9 +46,10 @@ default_context: test_matrix_configurator: no test_matrix_separate_coverage: no test_runner: pytest - travis: yes + travis: no travis_osx: no - version: 2.10.1 + version: 3.0.0 + version_manager: bump2version website: http://blog.ionelmc.ro year_from: '2010' - year_to: '2020' + year_to: '2022' diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index b9f7c11c..18299c41 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -1,81 +1,797 @@ -name: Test - -on: [push, pull_request, workflow_dispatch] - -env: - FORCE_COLOR: 1 - +name: build +on: [push, pull_request] jobs: test: - runs-on: ubuntu-latest + name: ${{ matrix.name }} + runs-on: ${{ matrix.os }} + timeout-minutes: 30 strategy: fail-fast: false matrix: - python-version: ["pypy-3.6", "pypy-3.7", "3.6", "3.7", "3.8", "3.9", "3.10-dev"] - tox-extra-versions: [ - "pytest46-xdist127", - "pytest46-xdist133", - "pytest54-xdist133", - "pytest62-xdist202", - ] include: - # Add new helper variables to existing jobs - - {python-version: "pypy-3.6", tox-python-version: "pypy3"} - - {python-version: "pypy-3.7", tox-python-version: "pypy3"} - - {python-version: "3.6", tox-python-version: "py36"} - - {python-version: "3.7", tox-python-version: "py37"} - - {python-version: "3.8", tox-python-version: "py38"} - - {python-version: "3.9", tox-python-version: "py39"} - - {python-version: "3.10-dev", tox-python-version: "py310"} - exclude: - # Remove some jobs from the matrix - - {tox-extra-versions: "pytest46-xdist127", python-version: "3.8"} - - {tox-extra-versions: "pytest46-xdist127", python-version: "3.9"} - - {tox-extra-versions: "pytest46-xdist133", python-version: "3.9"} - - {tox-extra-versions: "pytest54-xdist133", python-version: "3.9"} - - {tox-extra-versions: "pytest46-xdist127", python-version: "3.10-dev"} - - {tox-extra-versions: "pytest46-xdist133", python-version: "3.10-dev"} - - {tox-extra-versions: "pytest54-xdist133", python-version: "3.10-dev"} - + - name: 'check' + python: '3.9' + toxpython: 'python3.9' + tox_env: 'check' + os: 'ubuntu-latest' + - name: 'docs' + python: '3.9' + toxpython: 'python3.9' + tox_env: 'docs' + os: 'ubuntu-latest' + - name: 'py36-pytest46-xdist127-coverage55 (ubuntu)' + python: '3.6' + toxpython: 'python3.6' + python_arch: 'x64' + tox_env: 'py36-pytest46-xdist127-coverage55' + os: 'ubuntu-latest' + - name: 'py36-pytest46-xdist127-coverage55 (windows)' + python: '3.6' + toxpython: 'python3.6' + python_arch: 'x64' + tox_env: 'py36-pytest46-xdist127-coverage55' + os: 'windows-latest' + - name: 'py36-pytest46-xdist127-coverage55 (macos)' + python: '3.6' + toxpython: 'python3.6' + python_arch: 'x64' + tox_env: 'py36-pytest46-xdist127-coverage55' + os: 'macos-latest' + - name: 'py37-pytest46-xdist127-coverage55 (ubuntu)' + python: '3.7' + toxpython: 'python3.7' + python_arch: 'x64' + tox_env: 'py37-pytest46-xdist127-coverage55' + os: 'ubuntu-latest' + - name: 'py37-pytest46-xdist127-coverage55 (windows)' + python: '3.7' + toxpython: 'python3.7' + python_arch: 'x64' + tox_env: 'py37-pytest46-xdist127-coverage55' + os: 'windows-latest' + - name: 'py37-pytest46-xdist127-coverage55 (macos)' + python: '3.7' + toxpython: 'python3.7' + python_arch: 'x64' + tox_env: 'py37-pytest46-xdist127-coverage55' + os: 'macos-latest' + - name: 'pypy-pytest46-xdist127-coverage55 (ubuntu)' + python: 'pypy-.' + toxpython: 'pypy.' + python_arch: 'x64' + tox_env: 'pypy-pytest46-xdist127-coverage55' + os: 'ubuntu-latest' + - name: 'pypy-pytest46-xdist127-coverage55 (windows)' + python: 'pypy-.' + toxpython: 'pypy.' + python_arch: 'x64' + tox_env: 'pypy-pytest46-xdist127-coverage55' + os: 'windows-latest' + - name: 'pypy-pytest46-xdist127-coverage55 (macos)' + python: 'pypy-.' + toxpython: 'pypy.' + python_arch: 'x64' + tox_env: 'pypy-pytest46-xdist127-coverage55' + os: 'macos-latest' + - name: 'pypy3-pytest46-xdist127-coverage55 (ubuntu)' + python: 'pypy-3.' + toxpython: 'pypy3.' + python_arch: 'x64' + tox_env: 'pypy3-pytest46-xdist127-coverage55' + os: 'ubuntu-latest' + - name: 'pypy3-pytest46-xdist127-coverage55 (windows)' + python: 'pypy-3.' + toxpython: 'pypy3.' + python_arch: 'x64' + tox_env: 'pypy3-pytest46-xdist127-coverage55' + os: 'windows-latest' + - name: 'pypy3-pytest46-xdist127-coverage55 (macos)' + python: 'pypy-3.' + toxpython: 'pypy3.' + python_arch: 'x64' + tox_env: 'pypy3-pytest46-xdist127-coverage55' + os: 'macos-latest' + - name: 'py36-pytest46-xdist133-coverage55 (ubuntu)' + python: '3.6' + toxpython: 'python3.6' + python_arch: 'x64' + tox_env: 'py36-pytest46-xdist133-coverage55' + os: 'ubuntu-latest' + - name: 'py36-pytest46-xdist133-coverage55 (windows)' + python: '3.6' + toxpython: 'python3.6' + python_arch: 'x64' + tox_env: 'py36-pytest46-xdist133-coverage55' + os: 'windows-latest' + - name: 'py36-pytest46-xdist133-coverage55 (macos)' + python: '3.6' + toxpython: 'python3.6' + python_arch: 'x64' + tox_env: 'py36-pytest46-xdist133-coverage55' + os: 'macos-latest' + - name: 'py36-pytest54-xdist133-coverage55 (ubuntu)' + python: '3.6' + toxpython: 'python3.6' + python_arch: 'x64' + tox_env: 'py36-pytest54-xdist133-coverage55' + os: 'ubuntu-latest' + - name: 'py36-pytest54-xdist133-coverage55 (windows)' + python: '3.6' + toxpython: 'python3.6' + python_arch: 'x64' + tox_env: 'py36-pytest54-xdist133-coverage55' + os: 'windows-latest' + - name: 'py36-pytest54-xdist133-coverage55 (macos)' + python: '3.6' + toxpython: 'python3.6' + python_arch: 'x64' + tox_env: 'py36-pytest54-xdist133-coverage55' + os: 'macos-latest' + - name: 'py37-pytest46-xdist133-coverage55 (ubuntu)' + python: '3.7' + toxpython: 'python3.7' + python_arch: 'x64' + tox_env: 'py37-pytest46-xdist133-coverage55' + os: 'ubuntu-latest' + - name: 'py37-pytest46-xdist133-coverage55 (windows)' + python: '3.7' + toxpython: 'python3.7' + python_arch: 'x64' + tox_env: 'py37-pytest46-xdist133-coverage55' + os: 'windows-latest' + - name: 'py37-pytest46-xdist133-coverage55 (macos)' + python: '3.7' + toxpython: 'python3.7' + python_arch: 'x64' + tox_env: 'py37-pytest46-xdist133-coverage55' + os: 'macos-latest' + - name: 'py37-pytest54-xdist133-coverage55 (ubuntu)' + python: '3.7' + toxpython: 'python3.7' + python_arch: 'x64' + tox_env: 'py37-pytest54-xdist133-coverage55' + os: 'ubuntu-latest' + - name: 'py37-pytest54-xdist133-coverage55 (windows)' + python: '3.7' + toxpython: 'python3.7' + python_arch: 'x64' + tox_env: 'py37-pytest54-xdist133-coverage55' + os: 'windows-latest' + - name: 'py37-pytest54-xdist133-coverage55 (macos)' + python: '3.7' + toxpython: 'python3.7' + python_arch: 'x64' + tox_env: 'py37-pytest54-xdist133-coverage55' + os: 'macos-latest' + - name: 'py38-pytest46-xdist133-coverage55 (ubuntu)' + python: '3.8' + toxpython: 'python3.8' + python_arch: 'x64' + tox_env: 'py38-pytest46-xdist133-coverage55' + os: 'ubuntu-latest' + - name: 'py38-pytest46-xdist133-coverage55 (windows)' + python: '3.8' + toxpython: 'python3.8' + python_arch: 'x64' + tox_env: 'py38-pytest46-xdist133-coverage55' + os: 'windows-latest' + - name: 'py38-pytest46-xdist133-coverage55 (macos)' + python: '3.8' + toxpython: 'python3.8' + python_arch: 'x64' + tox_env: 'py38-pytest46-xdist133-coverage55' + os: 'macos-latest' + - name: 'py38-pytest54-xdist133-coverage55 (ubuntu)' + python: '3.8' + toxpython: 'python3.8' + python_arch: 'x64' + tox_env: 'py38-pytest54-xdist133-coverage55' + os: 'ubuntu-latest' + - name: 'py38-pytest54-xdist133-coverage55 (windows)' + python: '3.8' + toxpython: 'python3.8' + python_arch: 'x64' + tox_env: 'py38-pytest54-xdist133-coverage55' + os: 'windows-latest' + - name: 'py38-pytest54-xdist133-coverage55 (macos)' + python: '3.8' + toxpython: 'python3.8' + python_arch: 'x64' + tox_env: 'py38-pytest54-xdist133-coverage55' + os: 'macos-latest' + - name: 'pypy3-pytest46-xdist133-coverage55 (ubuntu)' + python: 'pypy-3.' + toxpython: 'pypy3.' + python_arch: 'x64' + tox_env: 'pypy3-pytest46-xdist133-coverage55' + os: 'ubuntu-latest' + - name: 'pypy3-pytest46-xdist133-coverage55 (windows)' + python: 'pypy-3.' + toxpython: 'pypy3.' + python_arch: 'x64' + tox_env: 'pypy3-pytest46-xdist133-coverage55' + os: 'windows-latest' + - name: 'pypy3-pytest46-xdist133-coverage55 (macos)' + python: 'pypy-3.' + toxpython: 'pypy3.' + python_arch: 'x64' + tox_env: 'pypy3-pytest46-xdist133-coverage55' + os: 'macos-latest' + - name: 'pypy3-pytest54-xdist133-coverage55 (ubuntu)' + python: 'pypy-3.' + toxpython: 'pypy3.' + python_arch: 'x64' + tox_env: 'pypy3-pytest54-xdist133-coverage55' + os: 'ubuntu-latest' + - name: 'pypy3-pytest54-xdist133-coverage55 (windows)' + python: 'pypy-3.' + toxpython: 'pypy3.' + python_arch: 'x64' + tox_env: 'pypy3-pytest54-xdist133-coverage55' + os: 'windows-latest' + - name: 'pypy3-pytest54-xdist133-coverage55 (macos)' + python: 'pypy-3.' + toxpython: 'pypy3.' + python_arch: 'x64' + tox_env: 'pypy3-pytest54-xdist133-coverage55' + os: 'macos-latest' + - name: 'py36-pytest62-xdist250-coverage55 (ubuntu)' + python: '3.6' + toxpython: 'python3.6' + python_arch: 'x64' + tox_env: 'py36-pytest62-xdist250-coverage55' + os: 'ubuntu-latest' + - name: 'py36-pytest62-xdist250-coverage55 (windows)' + python: '3.6' + toxpython: 'python3.6' + python_arch: 'x64' + tox_env: 'py36-pytest62-xdist250-coverage55' + os: 'windows-latest' + - name: 'py36-pytest62-xdist250-coverage55 (macos)' + python: '3.6' + toxpython: 'python3.6' + python_arch: 'x64' + tox_env: 'py36-pytest62-xdist250-coverage55' + os: 'macos-latest' + - name: 'py36-pytest62-xdist250-coverage60 (ubuntu)' + python: '3.6' + toxpython: 'python3.6' + python_arch: 'x64' + tox_env: 'py36-pytest62-xdist250-coverage60' + os: 'ubuntu-latest' + - name: 'py36-pytest62-xdist250-coverage60 (windows)' + python: '3.6' + toxpython: 'python3.6' + python_arch: 'x64' + tox_env: 'py36-pytest62-xdist250-coverage60' + os: 'windows-latest' + - name: 'py36-pytest62-xdist250-coverage60 (macos)' + python: '3.6' + toxpython: 'python3.6' + python_arch: 'x64' + tox_env: 'py36-pytest62-xdist250-coverage60' + os: 'macos-latest' + - name: 'py36-pytest62-xdist250-coverage61 (ubuntu)' + python: '3.6' + toxpython: 'python3.6' + python_arch: 'x64' + tox_env: 'py36-pytest62-xdist250-coverage61' + os: 'ubuntu-latest' + - name: 'py36-pytest62-xdist250-coverage61 (windows)' + python: '3.6' + toxpython: 'python3.6' + python_arch: 'x64' + tox_env: 'py36-pytest62-xdist250-coverage61' + os: 'windows-latest' + - name: 'py36-pytest62-xdist250-coverage61 (macos)' + python: '3.6' + toxpython: 'python3.6' + python_arch: 'x64' + tox_env: 'py36-pytest62-xdist250-coverage61' + os: 'macos-latest' + - name: 'py36-pytest62-xdist250-coverage62 (ubuntu)' + python: '3.6' + toxpython: 'python3.6' + python_arch: 'x64' + tox_env: 'py36-pytest62-xdist250-coverage62' + os: 'ubuntu-latest' + - name: 'py36-pytest62-xdist250-coverage62 (windows)' + python: '3.6' + toxpython: 'python3.6' + python_arch: 'x64' + tox_env: 'py36-pytest62-xdist250-coverage62' + os: 'windows-latest' + - name: 'py36-pytest62-xdist250-coverage62 (macos)' + python: '3.6' + toxpython: 'python3.6' + python_arch: 'x64' + tox_env: 'py36-pytest62-xdist250-coverage62' + os: 'macos-latest' + - name: 'py36-pytest62-xdist250-coverage63 (ubuntu)' + python: '3.6' + toxpython: 'python3.6' + python_arch: 'x64' + tox_env: 'py36-pytest62-xdist250-coverage63' + os: 'ubuntu-latest' + - name: 'py36-pytest62-xdist250-coverage63 (windows)' + python: '3.6' + toxpython: 'python3.6' + python_arch: 'x64' + tox_env: 'py36-pytest62-xdist250-coverage63' + os: 'windows-latest' + - name: 'py36-pytest62-xdist250-coverage63 (macos)' + python: '3.6' + toxpython: 'python3.6' + python_arch: 'x64' + tox_env: 'py36-pytest62-xdist250-coverage63' + os: 'macos-latest' + - name: 'py37-pytest62-xdist250-coverage55 (ubuntu)' + python: '3.7' + toxpython: 'python3.7' + python_arch: 'x64' + tox_env: 'py37-pytest62-xdist250-coverage55' + os: 'ubuntu-latest' + - name: 'py37-pytest62-xdist250-coverage55 (windows)' + python: '3.7' + toxpython: 'python3.7' + python_arch: 'x64' + tox_env: 'py37-pytest62-xdist250-coverage55' + os: 'windows-latest' + - name: 'py37-pytest62-xdist250-coverage55 (macos)' + python: '3.7' + toxpython: 'python3.7' + python_arch: 'x64' + tox_env: 'py37-pytest62-xdist250-coverage55' + os: 'macos-latest' + - name: 'py37-pytest62-xdist250-coverage60 (ubuntu)' + python: '3.7' + toxpython: 'python3.7' + python_arch: 'x64' + tox_env: 'py37-pytest62-xdist250-coverage60' + os: 'ubuntu-latest' + - name: 'py37-pytest62-xdist250-coverage60 (windows)' + python: '3.7' + toxpython: 'python3.7' + python_arch: 'x64' + tox_env: 'py37-pytest62-xdist250-coverage60' + os: 'windows-latest' + - name: 'py37-pytest62-xdist250-coverage60 (macos)' + python: '3.7' + toxpython: 'python3.7' + python_arch: 'x64' + tox_env: 'py37-pytest62-xdist250-coverage60' + os: 'macos-latest' + - name: 'py37-pytest62-xdist250-coverage61 (ubuntu)' + python: '3.7' + toxpython: 'python3.7' + python_arch: 'x64' + tox_env: 'py37-pytest62-xdist250-coverage61' + os: 'ubuntu-latest' + - name: 'py37-pytest62-xdist250-coverage61 (windows)' + python: '3.7' + toxpython: 'python3.7' + python_arch: 'x64' + tox_env: 'py37-pytest62-xdist250-coverage61' + os: 'windows-latest' + - name: 'py37-pytest62-xdist250-coverage61 (macos)' + python: '3.7' + toxpython: 'python3.7' + python_arch: 'x64' + tox_env: 'py37-pytest62-xdist250-coverage61' + os: 'macos-latest' + - name: 'py37-pytest62-xdist250-coverage62 (ubuntu)' + python: '3.7' + toxpython: 'python3.7' + python_arch: 'x64' + tox_env: 'py37-pytest62-xdist250-coverage62' + os: 'ubuntu-latest' + - name: 'py37-pytest62-xdist250-coverage62 (windows)' + python: '3.7' + toxpython: 'python3.7' + python_arch: 'x64' + tox_env: 'py37-pytest62-xdist250-coverage62' + os: 'windows-latest' + - name: 'py37-pytest62-xdist250-coverage62 (macos)' + python: '3.7' + toxpython: 'python3.7' + python_arch: 'x64' + tox_env: 'py37-pytest62-xdist250-coverage62' + os: 'macos-latest' + - name: 'py37-pytest62-xdist250-coverage63 (ubuntu)' + python: '3.7' + toxpython: 'python3.7' + python_arch: 'x64' + tox_env: 'py37-pytest62-xdist250-coverage63' + os: 'ubuntu-latest' + - name: 'py37-pytest62-xdist250-coverage63 (windows)' + python: '3.7' + toxpython: 'python3.7' + python_arch: 'x64' + tox_env: 'py37-pytest62-xdist250-coverage63' + os: 'windows-latest' + - name: 'py37-pytest62-xdist250-coverage63 (macos)' + python: '3.7' + toxpython: 'python3.7' + python_arch: 'x64' + tox_env: 'py37-pytest62-xdist250-coverage63' + os: 'macos-latest' + - name: 'py38-pytest62-xdist250-coverage55 (ubuntu)' + python: '3.8' + toxpython: 'python3.8' + python_arch: 'x64' + tox_env: 'py38-pytest62-xdist250-coverage55' + os: 'ubuntu-latest' + - name: 'py38-pytest62-xdist250-coverage55 (windows)' + python: '3.8' + toxpython: 'python3.8' + python_arch: 'x64' + tox_env: 'py38-pytest62-xdist250-coverage55' + os: 'windows-latest' + - name: 'py38-pytest62-xdist250-coverage55 (macos)' + python: '3.8' + toxpython: 'python3.8' + python_arch: 'x64' + tox_env: 'py38-pytest62-xdist250-coverage55' + os: 'macos-latest' + - name: 'py38-pytest62-xdist250-coverage60 (ubuntu)' + python: '3.8' + toxpython: 'python3.8' + python_arch: 'x64' + tox_env: 'py38-pytest62-xdist250-coverage60' + os: 'ubuntu-latest' + - name: 'py38-pytest62-xdist250-coverage60 (windows)' + python: '3.8' + toxpython: 'python3.8' + python_arch: 'x64' + tox_env: 'py38-pytest62-xdist250-coverage60' + os: 'windows-latest' + - name: 'py38-pytest62-xdist250-coverage60 (macos)' + python: '3.8' + toxpython: 'python3.8' + python_arch: 'x64' + tox_env: 'py38-pytest62-xdist250-coverage60' + os: 'macos-latest' + - name: 'py38-pytest62-xdist250-coverage61 (ubuntu)' + python: '3.8' + toxpython: 'python3.8' + python_arch: 'x64' + tox_env: 'py38-pytest62-xdist250-coverage61' + os: 'ubuntu-latest' + - name: 'py38-pytest62-xdist250-coverage61 (windows)' + python: '3.8' + toxpython: 'python3.8' + python_arch: 'x64' + tox_env: 'py38-pytest62-xdist250-coverage61' + os: 'windows-latest' + - name: 'py38-pytest62-xdist250-coverage61 (macos)' + python: '3.8' + toxpython: 'python3.8' + python_arch: 'x64' + tox_env: 'py38-pytest62-xdist250-coverage61' + os: 'macos-latest' + - name: 'py38-pytest62-xdist250-coverage62 (ubuntu)' + python: '3.8' + toxpython: 'python3.8' + python_arch: 'x64' + tox_env: 'py38-pytest62-xdist250-coverage62' + os: 'ubuntu-latest' + - name: 'py38-pytest62-xdist250-coverage62 (windows)' + python: '3.8' + toxpython: 'python3.8' + python_arch: 'x64' + tox_env: 'py38-pytest62-xdist250-coverage62' + os: 'windows-latest' + - name: 'py38-pytest62-xdist250-coverage62 (macos)' + python: '3.8' + toxpython: 'python3.8' + python_arch: 'x64' + tox_env: 'py38-pytest62-xdist250-coverage62' + os: 'macos-latest' + - name: 'py38-pytest62-xdist250-coverage63 (ubuntu)' + python: '3.8' + toxpython: 'python3.8' + python_arch: 'x64' + tox_env: 'py38-pytest62-xdist250-coverage63' + os: 'ubuntu-latest' + - name: 'py38-pytest62-xdist250-coverage63 (windows)' + python: '3.8' + toxpython: 'python3.8' + python_arch: 'x64' + tox_env: 'py38-pytest62-xdist250-coverage63' + os: 'windows-latest' + - name: 'py38-pytest62-xdist250-coverage63 (macos)' + python: '3.8' + toxpython: 'python3.8' + python_arch: 'x64' + tox_env: 'py38-pytest62-xdist250-coverage63' + os: 'macos-latest' + - name: 'py39-pytest62-xdist250-coverage55 (ubuntu)' + python: '3.9' + toxpython: 'python3.9' + python_arch: 'x64' + tox_env: 'py39-pytest62-xdist250-coverage55' + os: 'ubuntu-latest' + - name: 'py39-pytest62-xdist250-coverage55 (windows)' + python: '3.9' + toxpython: 'python3.9' + python_arch: 'x64' + tox_env: 'py39-pytest62-xdist250-coverage55' + os: 'windows-latest' + - name: 'py39-pytest62-xdist250-coverage55 (macos)' + python: '3.9' + toxpython: 'python3.9' + python_arch: 'x64' + tox_env: 'py39-pytest62-xdist250-coverage55' + os: 'macos-latest' + - name: 'py39-pytest62-xdist250-coverage60 (ubuntu)' + python: '3.9' + toxpython: 'python3.9' + python_arch: 'x64' + tox_env: 'py39-pytest62-xdist250-coverage60' + os: 'ubuntu-latest' + - name: 'py39-pytest62-xdist250-coverage60 (windows)' + python: '3.9' + toxpython: 'python3.9' + python_arch: 'x64' + tox_env: 'py39-pytest62-xdist250-coverage60' + os: 'windows-latest' + - name: 'py39-pytest62-xdist250-coverage60 (macos)' + python: '3.9' + toxpython: 'python3.9' + python_arch: 'x64' + tox_env: 'py39-pytest62-xdist250-coverage60' + os: 'macos-latest' + - name: 'py39-pytest62-xdist250-coverage61 (ubuntu)' + python: '3.9' + toxpython: 'python3.9' + python_arch: 'x64' + tox_env: 'py39-pytest62-xdist250-coverage61' + os: 'ubuntu-latest' + - name: 'py39-pytest62-xdist250-coverage61 (windows)' + python: '3.9' + toxpython: 'python3.9' + python_arch: 'x64' + tox_env: 'py39-pytest62-xdist250-coverage61' + os: 'windows-latest' + - name: 'py39-pytest62-xdist250-coverage61 (macos)' + python: '3.9' + toxpython: 'python3.9' + python_arch: 'x64' + tox_env: 'py39-pytest62-xdist250-coverage61' + os: 'macos-latest' + - name: 'py39-pytest62-xdist250-coverage62 (ubuntu)' + python: '3.9' + toxpython: 'python3.9' + python_arch: 'x64' + tox_env: 'py39-pytest62-xdist250-coverage62' + os: 'ubuntu-latest' + - name: 'py39-pytest62-xdist250-coverage62 (windows)' + python: '3.9' + toxpython: 'python3.9' + python_arch: 'x64' + tox_env: 'py39-pytest62-xdist250-coverage62' + os: 'windows-latest' + - name: 'py39-pytest62-xdist250-coverage62 (macos)' + python: '3.9' + toxpython: 'python3.9' + python_arch: 'x64' + tox_env: 'py39-pytest62-xdist250-coverage62' + os: 'macos-latest' + - name: 'py39-pytest62-xdist250-coverage63 (ubuntu)' + python: '3.9' + toxpython: 'python3.9' + python_arch: 'x64' + tox_env: 'py39-pytest62-xdist250-coverage63' + os: 'ubuntu-latest' + - name: 'py39-pytest62-xdist250-coverage63 (windows)' + python: '3.9' + toxpython: 'python3.9' + python_arch: 'x64' + tox_env: 'py39-pytest62-xdist250-coverage63' + os: 'windows-latest' + - name: 'py39-pytest62-xdist250-coverage63 (macos)' + python: '3.9' + toxpython: 'python3.9' + python_arch: 'x64' + tox_env: 'py39-pytest62-xdist250-coverage63' + os: 'macos-latest' + - name: 'py310-pytest62-xdist250-coverage55 (ubuntu)' + python: '3.10' + toxpython: 'python3.10' + python_arch: 'x64' + tox_env: 'py310-pytest62-xdist250-coverage55' + os: 'ubuntu-latest' + - name: 'py310-pytest62-xdist250-coverage55 (windows)' + python: '3.10' + toxpython: 'python3.10' + python_arch: 'x64' + tox_env: 'py310-pytest62-xdist250-coverage55' + os: 'windows-latest' + - name: 'py310-pytest62-xdist250-coverage55 (macos)' + python: '3.10' + toxpython: 'python3.10' + python_arch: 'x64' + tox_env: 'py310-pytest62-xdist250-coverage55' + os: 'macos-latest' + - name: 'py310-pytest62-xdist250-coverage60 (ubuntu)' + python: '3.10' + toxpython: 'python3.10' + python_arch: 'x64' + tox_env: 'py310-pytest62-xdist250-coverage60' + os: 'ubuntu-latest' + - name: 'py310-pytest62-xdist250-coverage60 (windows)' + python: '3.10' + toxpython: 'python3.10' + python_arch: 'x64' + tox_env: 'py310-pytest62-xdist250-coverage60' + os: 'windows-latest' + - name: 'py310-pytest62-xdist250-coverage60 (macos)' + python: '3.10' + toxpython: 'python3.10' + python_arch: 'x64' + tox_env: 'py310-pytest62-xdist250-coverage60' + os: 'macos-latest' + - name: 'py310-pytest62-xdist250-coverage61 (ubuntu)' + python: '3.10' + toxpython: 'python3.10' + python_arch: 'x64' + tox_env: 'py310-pytest62-xdist250-coverage61' + os: 'ubuntu-latest' + - name: 'py310-pytest62-xdist250-coverage61 (windows)' + python: '3.10' + toxpython: 'python3.10' + python_arch: 'x64' + tox_env: 'py310-pytest62-xdist250-coverage61' + os: 'windows-latest' + - name: 'py310-pytest62-xdist250-coverage61 (macos)' + python: '3.10' + toxpython: 'python3.10' + python_arch: 'x64' + tox_env: 'py310-pytest62-xdist250-coverage61' + os: 'macos-latest' + - name: 'py310-pytest62-xdist250-coverage62 (ubuntu)' + python: '3.10' + toxpython: 'python3.10' + python_arch: 'x64' + tox_env: 'py310-pytest62-xdist250-coverage62' + os: 'ubuntu-latest' + - name: 'py310-pytest62-xdist250-coverage62 (windows)' + python: '3.10' + toxpython: 'python3.10' + python_arch: 'x64' + tox_env: 'py310-pytest62-xdist250-coverage62' + os: 'windows-latest' + - name: 'py310-pytest62-xdist250-coverage62 (macos)' + python: '3.10' + toxpython: 'python3.10' + python_arch: 'x64' + tox_env: 'py310-pytest62-xdist250-coverage62' + os: 'macos-latest' + - name: 'py310-pytest62-xdist250-coverage63 (ubuntu)' + python: '3.10' + toxpython: 'python3.10' + python_arch: 'x64' + tox_env: 'py310-pytest62-xdist250-coverage63' + os: 'ubuntu-latest' + - name: 'py310-pytest62-xdist250-coverage63 (windows)' + python: '3.10' + toxpython: 'python3.10' + python_arch: 'x64' + tox_env: 'py310-pytest62-xdist250-coverage63' + os: 'windows-latest' + - name: 'py310-pytest62-xdist250-coverage63 (macos)' + python: '3.10' + toxpython: 'python3.10' + python_arch: 'x64' + tox_env: 'py310-pytest62-xdist250-coverage63' + os: 'macos-latest' + - name: 'pypy3-pytest62-xdist250-coverage55 (ubuntu)' + python: 'pypy-3.' + toxpython: 'pypy3.' + python_arch: 'x64' + tox_env: 'pypy3-pytest62-xdist250-coverage55' + os: 'ubuntu-latest' + - name: 'pypy3-pytest62-xdist250-coverage55 (windows)' + python: 'pypy-3.' + toxpython: 'pypy3.' + python_arch: 'x64' + tox_env: 'pypy3-pytest62-xdist250-coverage55' + os: 'windows-latest' + - name: 'pypy3-pytest62-xdist250-coverage55 (macos)' + python: 'pypy-3.' + toxpython: 'pypy3.' + python_arch: 'x64' + tox_env: 'pypy3-pytest62-xdist250-coverage55' + os: 'macos-latest' + - name: 'pypy3-pytest62-xdist250-coverage60 (ubuntu)' + python: 'pypy-3.' + toxpython: 'pypy3.' + python_arch: 'x64' + tox_env: 'pypy3-pytest62-xdist250-coverage60' + os: 'ubuntu-latest' + - name: 'pypy3-pytest62-xdist250-coverage60 (windows)' + python: 'pypy-3.' + toxpython: 'pypy3.' + python_arch: 'x64' + tox_env: 'pypy3-pytest62-xdist250-coverage60' + os: 'windows-latest' + - name: 'pypy3-pytest62-xdist250-coverage60 (macos)' + python: 'pypy-3.' + toxpython: 'pypy3.' + python_arch: 'x64' + tox_env: 'pypy3-pytest62-xdist250-coverage60' + os: 'macos-latest' + - name: 'pypy3-pytest62-xdist250-coverage61 (ubuntu)' + python: 'pypy-3.' + toxpython: 'pypy3.' + python_arch: 'x64' + tox_env: 'pypy3-pytest62-xdist250-coverage61' + os: 'ubuntu-latest' + - name: 'pypy3-pytest62-xdist250-coverage61 (windows)' + python: 'pypy-3.' + toxpython: 'pypy3.' + python_arch: 'x64' + tox_env: 'pypy3-pytest62-xdist250-coverage61' + os: 'windows-latest' + - name: 'pypy3-pytest62-xdist250-coverage61 (macos)' + python: 'pypy-3.' + toxpython: 'pypy3.' + python_arch: 'x64' + tox_env: 'pypy3-pytest62-xdist250-coverage61' + os: 'macos-latest' + - name: 'pypy3-pytest62-xdist250-coverage62 (ubuntu)' + python: 'pypy-3.' + toxpython: 'pypy3.' + python_arch: 'x64' + tox_env: 'pypy3-pytest62-xdist250-coverage62' + os: 'ubuntu-latest' + - name: 'pypy3-pytest62-xdist250-coverage62 (windows)' + python: 'pypy-3.' + toxpython: 'pypy3.' + python_arch: 'x64' + tox_env: 'pypy3-pytest62-xdist250-coverage62' + os: 'windows-latest' + - name: 'pypy3-pytest62-xdist250-coverage62 (macos)' + python: 'pypy-3.' + toxpython: 'pypy3.' + python_arch: 'x64' + tox_env: 'pypy3-pytest62-xdist250-coverage62' + os: 'macos-latest' + - name: 'pypy3-pytest62-xdist250-coverage63 (ubuntu)' + python: 'pypy-3.' + toxpython: 'pypy3.' + python_arch: 'x64' + tox_env: 'pypy3-pytest62-xdist250-coverage63' + os: 'ubuntu-latest' + - name: 'pypy3-pytest62-xdist250-coverage63 (windows)' + python: 'pypy-3.' + toxpython: 'pypy3.' + python_arch: 'x64' + tox_env: 'pypy3-pytest62-xdist250-coverage63' + os: 'windows-latest' + - name: 'pypy3-pytest62-xdist250-coverage63 (macos)' + python: 'pypy-3.' + toxpython: 'pypy3.' + python_arch: 'x64' + tox_env: 'pypy3-pytest62-xdist250-coverage63' + os: 'macos-latest' steps: - - uses: actions/checkout@v2 - - - name: Set up Python ${{ matrix.python-version }} - uses: actions/setup-python@v2 - with: - python-version: ${{ matrix.python-version }} - - - name: Get pip cache dir - id: pip-cache - run: | - echo "::set-output name=dir::$(pip cache dir)" - - - name: Cache - uses: actions/cache@v2 - with: - path: ${{ steps.pip-cache.outputs.dir }} - key: - test-${{ matrix.python-version }}-v1-${{ hashFiles('**/requirements.txt') }} - restore-keys: | - test-${{ matrix.python-version }}-v1- - - - name: Install dependencies - run: | - python -m pip install -U pip - python -m pip install -U wheel - python -m pip install --progress-bar=off tox -rci/requirements.txt - virtualenv --version - pip --version - tox --version - - - name: Tox tests - run: | - tox -v -e ${{ matrix.tox-python-version }}-${{ matrix.tox-extra-versions }}-coverage55 - - allgood: - needs: test - runs-on: ubuntu-latest - name: Test successful - steps: - - name: Success - run: echo Test successful + - uses: actions/checkout@v2 + with: + fetch-depth: 0 + - uses: actions/setup-python@v2 + with: + python-version: ${{ matrix.python }} + architecture: ${{ matrix.python_arch }} + - name: install dependencies + run: | + python -mpip install --progress-bar=off -r ci/requirements.txt + virtualenv --version + pip --version + tox --version + pip list --format=freeze + - name: test + env: + TOXPYTHON: '${{ matrix.toxpython }}' + run: > + tox -e ${{ matrix.tox_env }} -v diff --git a/MANIFEST.in b/MANIFEST.in index af1581be..cbb88f74 100644 --- a/MANIFEST.in +++ b/MANIFEST.in @@ -12,16 +12,17 @@ graft ci graft tests include .bumpversion.cfg -include .coveragerc include .cookiecutterrc +include .coveragerc include .editorconfig - +include tox.ini +include .readthedocs.yml +include .pre-commit-config.yaml include AUTHORS.rst include CHANGELOG.rst include CONTRIBUTING.rst include LICENSE include README.rst -include tox.ini .appveyor.yml .readthedocs.yml .pre-commit-config.yaml -global-exclude *.py[cod] __pycache__/* *.so *.dylib .coverage .coverage.* +global-exclude *.py[cod] __pycache__/* *.so *.dylib diff --git a/README.rst b/README.rst index 508aff84..2137c118 100644 --- a/README.rst +++ b/README.rst @@ -10,7 +10,8 @@ Overview * - docs - |docs| * - tests - - | |github-actions| |appveyor| |requires| + - | |github-actions| |requires| + | * - package - | |version| |conda-forge| |wheel| |supported-versions| |supported-implementations| | |commits-since| diff --git a/ci/appveyor-with-compiler.cmd b/ci/appveyor-with-compiler.cmd deleted file mode 100644 index 289585fc..00000000 --- a/ci/appveyor-with-compiler.cmd +++ /dev/null @@ -1,23 +0,0 @@ -:: Very simple setup: -:: - if WINDOWS_SDK_VERSION is set then activate the SDK. -:: - disable the WDK if it's around. - -SET COMMAND_TO_RUN=%* -SET WIN_SDK_ROOT=C:\Program Files\Microsoft SDKs\Windows -SET WIN_WDK="c:\Program Files (x86)\Windows Kits\10\Include\wdf" -ECHO SDK: %WINDOWS_SDK_VERSION% ARCH: %PYTHON_ARCH% - -IF EXIST %WIN_WDK% ( - REM See: https://connect.microsoft.com/VisualStudio/feedback/details/1610302/ - REN %WIN_WDK% 0wdf -) -IF "%WINDOWS_SDK_VERSION%"=="" GOTO main - -SET DISTUTILS_USE_SDK=1 -SET MSSdk=1 -"%WIN_SDK_ROOT%\%WINDOWS_SDK_VERSION%\Setup\WindowsSdkVer.exe" -q -version:%WINDOWS_SDK_VERSION% -CALL "%WIN_SDK_ROOT%\%WINDOWS_SDK_VERSION%\Bin\SetEnv.cmd" /x64 /release - -:main -ECHO Executing: %COMMAND_TO_RUN% -CALL %COMMAND_TO_RUN% || EXIT 1 diff --git a/ci/bootstrap.py b/ci/bootstrap.py index 77daad5b..b0977495 100755 --- a/ci/bootstrap.py +++ b/ci/bootstrap.py @@ -3,13 +3,14 @@ import os import subprocess import sys -from collections import defaultdict from os.path import abspath from os.path import dirname from os.path import exists from os.path import join +from os.path import relpath base_path = dirname(dirname(abspath(__file__))) +templates_path = join(base_path, "ci", "templates") def check_call(args): @@ -51,7 +52,7 @@ def main(): print(f"Project path: {base_path}") jinja = jinja2.Environment( - loader=jinja2.FileSystemLoader(join(base_path, "ci", "templates")), + loader=jinja2.FileSystemLoader(templates_path), trim_blocks=True, lstrip_blocks=True, keep_trailing_newline=True @@ -59,22 +60,21 @@ def main(): tox_environments = [ line.strip() - # WARNING: 'tox' must be installed globally or in the project's virtualenv - for line in subprocess.check_output(['tox', '--listenvs'], universal_newlines=True).splitlines() + # 'tox' need not be installed globally, but must be importable + # by the Python that is running this script. + # This uses sys.executable the same way that the call in + # cookiecutter-pylibrary/hooks/post_gen_project.py + # invokes this bootstrap.py itself. + for line in subprocess.check_output([sys.executable, '-m', 'tox', '--listenvs'], universal_newlines=True).splitlines() ] - tox_environments = [line for line in tox_environments if line not in ['clean', 'report', 'docs', 'check']] - - template_vars = defaultdict(list) - template_vars['tox_environments'] = tox_environments - for env in tox_environments: - first, _ = env.split('-', 1) - template_vars['%s_environments' % first].append(env) - - for name in os.listdir(join("ci", "templates")): - with open(join(base_path, name), "w") as fh: - fh.write('# NOTE: this file is auto-generated via ci/bootstrap.py (ci/templates/%s).\n' % name) - fh.write(jinja.get_template(name).render(**template_vars)) - print(f"Wrote {name}") + tox_environments = [line for line in tox_environments if line.startswith('py')] + + for root, _, files in os.walk(templates_path): + for name in files: + relative = relpath(root, templates_path) + with open(join(base_path, relative, name), "w") as fh: + fh.write(jinja.get_template(join(relative, name)).render(tox_environments=tox_environments)) + print(f"Wrote {name}") print("DONE.") diff --git a/ci/requirements.txt b/ci/requirements.txt index d7f5177e..a0ef106f 100644 --- a/ci/requirements.txt +++ b/ci/requirements.txt @@ -2,3 +2,4 @@ virtualenv>=16.6.0 pip>=19.1.1 setuptools>=18.0.1 six>=1.14.0 +tox diff --git a/ci/templates/.appveyor.yml b/ci/templates/.appveyor.yml deleted file mode 100644 index 2b7e611c..00000000 --- a/ci/templates/.appveyor.yml +++ /dev/null @@ -1,53 +0,0 @@ -version: '{branch}-{build}' -build: off -image: - - Visual Studio 2015 - - Visual Studio 2019 -environment: - matrix: - - TOXENV: check - - TOXENV: '{{ py27_environments|join(",") }}' - - TOXENV: '{{ py35_environments|join(",") }}' - - TOXENV: '{{ py36_environments|join(",") }}' - - TOXENV: '{{ py37_environments|join(",") }}' - - TOXENV: '{{ py38_environments|join(",") }}' - - TOXENV: '{{ py39_environments|join(",") }}' - - TOXENV: '{{ pypy_environments|join(",") }}' - - TOXENV: '{{ pypy3_environments|join(",") }}' -matrix: - exclude: - - image: Visual Studio 2019 - TOXENV: '{{ py27_environments|join(",") }}' - - image: Visual Studio 2015 - TOXENV: '{{ py36_environments|join(",") }}' - - image: Visual Studio 2015 - TOXENV: '{{ py37_environments|join(",") }}' - - image: Visual Studio 2015 - TOXENV: '{{ py38_environments|join(",") }}' - - image: Visual Studio 2015 - TOXENV: '{{ py39_environments|join(",") }}' - - image: Visual Studio 2015 - TOXENV: '{{ pypy_environments|join(",") }}' - - image: Visual Studio 2015 - TOXENV: '{{ pypy3_environments|join(",") }}' -init: - - ps: echo $env:TOXENV - - ps: ls C:\Python* -install: - - IF "%TOXENV:~0,5%" == "pypy-" choco install --no-progress python.pypy - - IF "%TOXENV:~0,6%" == "pypy3-" choco install --no-progress pypy3 - - SET PATH=C:\tools\pypy\pypy;%PATH% - - C:\Python37\python -m pip install --progress-bar=off tox -rci/requirements.txt - -test_script: - - cmd /E:ON /V:ON /C .\ci\appveyor-with-compiler.cmd C:\Python37\python -m tox - -on_failure: - - ps: dir "env:" - - ps: get-content .tox\*\log\* -artifacts: - - path: dist\* - -### To enable remote debugging uncomment this (also, see: http://www.appveyor.com/docs/how-to/rdp-to-build-worker): -# on_finish: -# - ps: $blockRdp = $true; iex ((new-object net.webclient).DownloadString('https://raw.githubusercontent.com/appveyor/ci/master/scripts/enable-rdp.ps1')) diff --git a/ci/templates/.github/workflows/test.yml b/ci/templates/.github/workflows/test.yml new file mode 100644 index 00000000..96d24801 --- /dev/null +++ b/ci/templates/.github/workflows/test.yml @@ -0,0 +1,65 @@ +name: build +on: [push, pull_request] +jobs: + test: + name: {{ '${{ matrix.name }}' }} + runs-on: {{ '${{ matrix.os }}' }} + timeout-minutes: 30 + strategy: + fail-fast: false + matrix: + include: + - name: 'check' + python: '3.9' + toxpython: 'python3.9' + tox_env: 'check' + os: 'ubuntu-latest' + - name: 'docs' + python: '3.9' + toxpython: 'python3.9' + tox_env: 'docs' + os: 'ubuntu-latest' +{% for env in tox_environments %} +{% set prefix = env.split('-')[0] -%} +{% if prefix.startswith('pypy') %} +{% set python %}pypy-{{ prefix[4] }}.{{ prefix[5] }}{% endset %} +{% set cpython %}pp{{ prefix[4:5] }}{% endset %} +{% set toxpython %}pypy{{ prefix[4] }}.{{ prefix[5] }}{% endset %} +{% else %} +{% set python %}{{ prefix[2] }}.{{ prefix[3:] }}{% endset %} +{% set cpython %}cp{{ prefix[2:] }}{% endset %} +{% set toxpython %}python{{ prefix[2] }}.{{ prefix[3:] }}{% endset %} +{% endif %} +{% for os, python_arch in [ + ['ubuntu', 'x64'], + ['windows', 'x64'], + ['macos', 'x64'], +] %} + - name: '{{ env }} ({{ os }})' + python: '{{ python }}' + toxpython: '{{ toxpython }}' + python_arch: '{{ python_arch }}' + tox_env: '{{ env }}' + os: '{{ os }}-latest' +{% endfor %} +{% endfor %} + steps: + - uses: actions/checkout@v2 + with: + fetch-depth: 0 + - uses: actions/setup-python@v2 + with: + python-version: {{ '${{ matrix.python }}' }} + architecture: {{ '${{ matrix.python_arch }}' }} + - name: install dependencies + run: | + python -mpip install --progress-bar=off -r ci/requirements.txt + virtualenv --version + pip --version + tox --version + pip list --format=freeze + - name: test + env: + TOXPYTHON: '{{ '${{ matrix.toxpython }}' }}' + run: > + tox -e {{ '${{ matrix.tox_env }}' }} -v diff --git a/setup.py b/setup.py index 0748d12e..21681887 100755 --- a/setup.py +++ b/setup.py @@ -115,6 +115,11 @@ def run(self): 'Topic :: Software Development :: Testing', 'Topic :: Utilities', ], + project_urls={ + 'Documentation': 'https://pytest-cov.readthedocs.io/', + 'Changelog': 'https://pytest-cov.readthedocs.io/en/latest/changelog.html', + 'Issue Tracker': 'https://github.com/pytest-dev/pytest-cov/issues', + }, keywords=[ 'cover', 'coverage', 'pytest', 'py.test', 'distributed', 'parallel', ], diff --git a/tox.ini b/tox.ini index 99e1fff6..6d7ab6eb 100644 --- a/tox.ini +++ b/tox.ini @@ -1,7 +1,6 @@ [testenv:bootstrap] deps = jinja2 - matrix tox skip_install = true commands = From 3cf0631e771595838749f8005e4ff79e92879747 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ionel=20Cristian=20M=C4=83rie=C8=99?= Date: Thu, 3 Feb 2022 15:22:10 +0200 Subject: [PATCH 16/42] Remove unnecessary parametrization. Fix statement count. --- tests/test_pytest_cov.py | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/tests/test_pytest_cov.py b/tests/test_pytest_cov.py index e94d59be..33814ef4 100644 --- a/tests/test_pytest_cov.py +++ b/tests/test_pytest_cov.py @@ -1223,15 +1223,14 @@ def test_run_target(): result.stdout.fnmatch_lines([ '*- coverage: platform *, python * -*', - 'test_multiprocessing_process* 8 * 100%*', + 'test_multiprocessing_process* 9 * 100%*', '*1 passed*' ]) assert result.ret == 0 @pytest.mark.skipif('sys.platform == "win32"', reason="multiprocessing support is broken on Windows") -@method_params -def test_multiprocessing_process_no_source(testdir, method): +def test_multiprocessing_process_no_source(testdir): pytest.importorskip('multiprocessing.util') script = testdir.makepyfile(''' @@ -1261,8 +1260,7 @@ def test_run_target(): @pytest.mark.skipif('sys.platform == "win32"', reason="multiprocessing support is broken on Windows") -@method_params -def test_multiprocessing_process_with_terminate(testdir, method): +def test_multiprocessing_process_with_terminate(testdir): pytest.importorskip('multiprocessing.util') script = testdir.makepyfile(''' From 74f77d1c27ff6bfe71271cf647a9495807324b14 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ionel=20Cristian=20M=C4=83rie=C8=99?= Date: Thu, 21 Jul 2022 19:45:22 +0300 Subject: [PATCH 17/42] Bump deps and trim deps to strictly necessary. --- .github/workflows/test.yml | 720 ++----------------------------------- tox.ini | 10 +- 2 files changed, 42 insertions(+), 688 deletions(-) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 18299c41..0c182389 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -19,761 +19,113 @@ jobs: toxpython: 'python3.9' tox_env: 'docs' os: 'ubuntu-latest' - - name: 'py36-pytest46-xdist127-coverage55 (ubuntu)' + - name: 'py36-pytest70-xdist250-coverage62 (ubuntu)' python: '3.6' toxpython: 'python3.6' python_arch: 'x64' - tox_env: 'py36-pytest46-xdist127-coverage55' + tox_env: 'py36-pytest70-xdist250-coverage62' os: 'ubuntu-latest' - - name: 'py36-pytest46-xdist127-coverage55 (windows)' + - name: 'py36-pytest70-xdist250-coverage62 (windows)' python: '3.6' toxpython: 'python3.6' python_arch: 'x64' - tox_env: 'py36-pytest46-xdist127-coverage55' + tox_env: 'py36-pytest70-xdist250-coverage62' os: 'windows-latest' - - name: 'py36-pytest46-xdist127-coverage55 (macos)' + - name: 'py36-pytest70-xdist250-coverage62 (macos)' python: '3.6' toxpython: 'python3.6' python_arch: 'x64' - tox_env: 'py36-pytest46-xdist127-coverage55' + tox_env: 'py36-pytest70-xdist250-coverage62' os: 'macos-latest' - - name: 'py37-pytest46-xdist127-coverage55 (ubuntu)' + - name: 'py37-pytest71-xdist250-coverage64 (ubuntu)' python: '3.7' toxpython: 'python3.7' python_arch: 'x64' - tox_env: 'py37-pytest46-xdist127-coverage55' + tox_env: 'py37-pytest71-xdist250-coverage64' os: 'ubuntu-latest' - - name: 'py37-pytest46-xdist127-coverage55 (windows)' + - name: 'py37-pytest71-xdist250-coverage64 (windows)' python: '3.7' toxpython: 'python3.7' python_arch: 'x64' - tox_env: 'py37-pytest46-xdist127-coverage55' + tox_env: 'py37-pytest71-xdist250-coverage64' os: 'windows-latest' - - name: 'py37-pytest46-xdist127-coverage55 (macos)' + - name: 'py37-pytest71-xdist250-coverage64 (macos)' python: '3.7' toxpython: 'python3.7' python_arch: 'x64' - tox_env: 'py37-pytest46-xdist127-coverage55' + tox_env: 'py37-pytest71-xdist250-coverage64' os: 'macos-latest' - - name: 'pypy-pytest46-xdist127-coverage55 (ubuntu)' - python: 'pypy-.' - toxpython: 'pypy.' - python_arch: 'x64' - tox_env: 'pypy-pytest46-xdist127-coverage55' - os: 'ubuntu-latest' - - name: 'pypy-pytest46-xdist127-coverage55 (windows)' - python: 'pypy-.' - toxpython: 'pypy.' - python_arch: 'x64' - tox_env: 'pypy-pytest46-xdist127-coverage55' - os: 'windows-latest' - - name: 'pypy-pytest46-xdist127-coverage55 (macos)' - python: 'pypy-.' - toxpython: 'pypy.' - python_arch: 'x64' - tox_env: 'pypy-pytest46-xdist127-coverage55' - os: 'macos-latest' - - name: 'pypy3-pytest46-xdist127-coverage55 (ubuntu)' - python: 'pypy-3.' - toxpython: 'pypy3.' - python_arch: 'x64' - tox_env: 'pypy3-pytest46-xdist127-coverage55' - os: 'ubuntu-latest' - - name: 'pypy3-pytest46-xdist127-coverage55 (windows)' - python: 'pypy-3.' - toxpython: 'pypy3.' - python_arch: 'x64' - tox_env: 'pypy3-pytest46-xdist127-coverage55' - os: 'windows-latest' - - name: 'pypy3-pytest46-xdist127-coverage55 (macos)' - python: 'pypy-3.' - toxpython: 'pypy3.' - python_arch: 'x64' - tox_env: 'pypy3-pytest46-xdist127-coverage55' - os: 'macos-latest' - - name: 'py36-pytest46-xdist133-coverage55 (ubuntu)' - python: '3.6' - toxpython: 'python3.6' - python_arch: 'x64' - tox_env: 'py36-pytest46-xdist133-coverage55' - os: 'ubuntu-latest' - - name: 'py36-pytest46-xdist133-coverage55 (windows)' - python: '3.6' - toxpython: 'python3.6' - python_arch: 'x64' - tox_env: 'py36-pytest46-xdist133-coverage55' - os: 'windows-latest' - - name: 'py36-pytest46-xdist133-coverage55 (macos)' - python: '3.6' - toxpython: 'python3.6' - python_arch: 'x64' - tox_env: 'py36-pytest46-xdist133-coverage55' - os: 'macos-latest' - - name: 'py36-pytest54-xdist133-coverage55 (ubuntu)' - python: '3.6' - toxpython: 'python3.6' - python_arch: 'x64' - tox_env: 'py36-pytest54-xdist133-coverage55' - os: 'ubuntu-latest' - - name: 'py36-pytest54-xdist133-coverage55 (windows)' - python: '3.6' - toxpython: 'python3.6' - python_arch: 'x64' - tox_env: 'py36-pytest54-xdist133-coverage55' - os: 'windows-latest' - - name: 'py36-pytest54-xdist133-coverage55 (macos)' - python: '3.6' - toxpython: 'python3.6' - python_arch: 'x64' - tox_env: 'py36-pytest54-xdist133-coverage55' - os: 'macos-latest' - - name: 'py37-pytest46-xdist133-coverage55 (ubuntu)' - python: '3.7' - toxpython: 'python3.7' - python_arch: 'x64' - tox_env: 'py37-pytest46-xdist133-coverage55' - os: 'ubuntu-latest' - - name: 'py37-pytest46-xdist133-coverage55 (windows)' - python: '3.7' - toxpython: 'python3.7' - python_arch: 'x64' - tox_env: 'py37-pytest46-xdist133-coverage55' - os: 'windows-latest' - - name: 'py37-pytest46-xdist133-coverage55 (macos)' - python: '3.7' - toxpython: 'python3.7' - python_arch: 'x64' - tox_env: 'py37-pytest46-xdist133-coverage55' - os: 'macos-latest' - - name: 'py37-pytest54-xdist133-coverage55 (ubuntu)' - python: '3.7' - toxpython: 'python3.7' - python_arch: 'x64' - tox_env: 'py37-pytest54-xdist133-coverage55' - os: 'ubuntu-latest' - - name: 'py37-pytest54-xdist133-coverage55 (windows)' - python: '3.7' - toxpython: 'python3.7' - python_arch: 'x64' - tox_env: 'py37-pytest54-xdist133-coverage55' - os: 'windows-latest' - - name: 'py37-pytest54-xdist133-coverage55 (macos)' - python: '3.7' - toxpython: 'python3.7' - python_arch: 'x64' - tox_env: 'py37-pytest54-xdist133-coverage55' - os: 'macos-latest' - - name: 'py38-pytest46-xdist133-coverage55 (ubuntu)' - python: '3.8' - toxpython: 'python3.8' - python_arch: 'x64' - tox_env: 'py38-pytest46-xdist133-coverage55' - os: 'ubuntu-latest' - - name: 'py38-pytest46-xdist133-coverage55 (windows)' - python: '3.8' - toxpython: 'python3.8' - python_arch: 'x64' - tox_env: 'py38-pytest46-xdist133-coverage55' - os: 'windows-latest' - - name: 'py38-pytest46-xdist133-coverage55 (macos)' - python: '3.8' - toxpython: 'python3.8' - python_arch: 'x64' - tox_env: 'py38-pytest46-xdist133-coverage55' - os: 'macos-latest' - - name: 'py38-pytest54-xdist133-coverage55 (ubuntu)' - python: '3.8' - toxpython: 'python3.8' - python_arch: 'x64' - tox_env: 'py38-pytest54-xdist133-coverage55' - os: 'ubuntu-latest' - - name: 'py38-pytest54-xdist133-coverage55 (windows)' - python: '3.8' - toxpython: 'python3.8' - python_arch: 'x64' - tox_env: 'py38-pytest54-xdist133-coverage55' - os: 'windows-latest' - - name: 'py38-pytest54-xdist133-coverage55 (macos)' - python: '3.8' - toxpython: 'python3.8' - python_arch: 'x64' - tox_env: 'py38-pytest54-xdist133-coverage55' - os: 'macos-latest' - - name: 'pypy3-pytest46-xdist133-coverage55 (ubuntu)' - python: 'pypy-3.' - toxpython: 'pypy3.' - python_arch: 'x64' - tox_env: 'pypy3-pytest46-xdist133-coverage55' - os: 'ubuntu-latest' - - name: 'pypy3-pytest46-xdist133-coverage55 (windows)' - python: 'pypy-3.' - toxpython: 'pypy3.' - python_arch: 'x64' - tox_env: 'pypy3-pytest46-xdist133-coverage55' - os: 'windows-latest' - - name: 'pypy3-pytest46-xdist133-coverage55 (macos)' - python: 'pypy-3.' - toxpython: 'pypy3.' - python_arch: 'x64' - tox_env: 'pypy3-pytest46-xdist133-coverage55' - os: 'macos-latest' - - name: 'pypy3-pytest54-xdist133-coverage55 (ubuntu)' - python: 'pypy-3.' - toxpython: 'pypy3.' - python_arch: 'x64' - tox_env: 'pypy3-pytest54-xdist133-coverage55' - os: 'ubuntu-latest' - - name: 'pypy3-pytest54-xdist133-coverage55 (windows)' - python: 'pypy-3.' - toxpython: 'pypy3.' - python_arch: 'x64' - tox_env: 'pypy3-pytest54-xdist133-coverage55' - os: 'windows-latest' - - name: 'pypy3-pytest54-xdist133-coverage55 (macos)' - python: 'pypy-3.' - toxpython: 'pypy3.' - python_arch: 'x64' - tox_env: 'pypy3-pytest54-xdist133-coverage55' - os: 'macos-latest' - - name: 'py36-pytest62-xdist250-coverage55 (ubuntu)' - python: '3.6' - toxpython: 'python3.6' - python_arch: 'x64' - tox_env: 'py36-pytest62-xdist250-coverage55' - os: 'ubuntu-latest' - - name: 'py36-pytest62-xdist250-coverage55 (windows)' - python: '3.6' - toxpython: 'python3.6' - python_arch: 'x64' - tox_env: 'py36-pytest62-xdist250-coverage55' - os: 'windows-latest' - - name: 'py36-pytest62-xdist250-coverage55 (macos)' - python: '3.6' - toxpython: 'python3.6' - python_arch: 'x64' - tox_env: 'py36-pytest62-xdist250-coverage55' - os: 'macos-latest' - - name: 'py36-pytest62-xdist250-coverage60 (ubuntu)' - python: '3.6' - toxpython: 'python3.6' - python_arch: 'x64' - tox_env: 'py36-pytest62-xdist250-coverage60' - os: 'ubuntu-latest' - - name: 'py36-pytest62-xdist250-coverage60 (windows)' - python: '3.6' - toxpython: 'python3.6' - python_arch: 'x64' - tox_env: 'py36-pytest62-xdist250-coverage60' - os: 'windows-latest' - - name: 'py36-pytest62-xdist250-coverage60 (macos)' - python: '3.6' - toxpython: 'python3.6' - python_arch: 'x64' - tox_env: 'py36-pytest62-xdist250-coverage60' - os: 'macos-latest' - - name: 'py36-pytest62-xdist250-coverage61 (ubuntu)' - python: '3.6' - toxpython: 'python3.6' - python_arch: 'x64' - tox_env: 'py36-pytest62-xdist250-coverage61' - os: 'ubuntu-latest' - - name: 'py36-pytest62-xdist250-coverage61 (windows)' - python: '3.6' - toxpython: 'python3.6' - python_arch: 'x64' - tox_env: 'py36-pytest62-xdist250-coverage61' - os: 'windows-latest' - - name: 'py36-pytest62-xdist250-coverage61 (macos)' - python: '3.6' - toxpython: 'python3.6' - python_arch: 'x64' - tox_env: 'py36-pytest62-xdist250-coverage61' - os: 'macos-latest' - - name: 'py36-pytest62-xdist250-coverage62 (ubuntu)' - python: '3.6' - toxpython: 'python3.6' - python_arch: 'x64' - tox_env: 'py36-pytest62-xdist250-coverage62' - os: 'ubuntu-latest' - - name: 'py36-pytest62-xdist250-coverage62 (windows)' - python: '3.6' - toxpython: 'python3.6' - python_arch: 'x64' - tox_env: 'py36-pytest62-xdist250-coverage62' - os: 'windows-latest' - - name: 'py36-pytest62-xdist250-coverage62 (macos)' - python: '3.6' - toxpython: 'python3.6' - python_arch: 'x64' - tox_env: 'py36-pytest62-xdist250-coverage62' - os: 'macos-latest' - - name: 'py36-pytest62-xdist250-coverage63 (ubuntu)' - python: '3.6' - toxpython: 'python3.6' - python_arch: 'x64' - tox_env: 'py36-pytest62-xdist250-coverage63' - os: 'ubuntu-latest' - - name: 'py36-pytest62-xdist250-coverage63 (windows)' - python: '3.6' - toxpython: 'python3.6' - python_arch: 'x64' - tox_env: 'py36-pytest62-xdist250-coverage63' - os: 'windows-latest' - - name: 'py36-pytest62-xdist250-coverage63 (macos)' - python: '3.6' - toxpython: 'python3.6' - python_arch: 'x64' - tox_env: 'py36-pytest62-xdist250-coverage63' - os: 'macos-latest' - - name: 'py37-pytest62-xdist250-coverage55 (ubuntu)' - python: '3.7' - toxpython: 'python3.7' - python_arch: 'x64' - tox_env: 'py37-pytest62-xdist250-coverage55' - os: 'ubuntu-latest' - - name: 'py37-pytest62-xdist250-coverage55 (windows)' - python: '3.7' - toxpython: 'python3.7' - python_arch: 'x64' - tox_env: 'py37-pytest62-xdist250-coverage55' - os: 'windows-latest' - - name: 'py37-pytest62-xdist250-coverage55 (macos)' - python: '3.7' - toxpython: 'python3.7' - python_arch: 'x64' - tox_env: 'py37-pytest62-xdist250-coverage55' - os: 'macos-latest' - - name: 'py37-pytest62-xdist250-coverage60 (ubuntu)' - python: '3.7' - toxpython: 'python3.7' - python_arch: 'x64' - tox_env: 'py37-pytest62-xdist250-coverage60' - os: 'ubuntu-latest' - - name: 'py37-pytest62-xdist250-coverage60 (windows)' - python: '3.7' - toxpython: 'python3.7' - python_arch: 'x64' - tox_env: 'py37-pytest62-xdist250-coverage60' - os: 'windows-latest' - - name: 'py37-pytest62-xdist250-coverage60 (macos)' - python: '3.7' - toxpython: 'python3.7' - python_arch: 'x64' - tox_env: 'py37-pytest62-xdist250-coverage60' - os: 'macos-latest' - - name: 'py37-pytest62-xdist250-coverage61 (ubuntu)' - python: '3.7' - toxpython: 'python3.7' - python_arch: 'x64' - tox_env: 'py37-pytest62-xdist250-coverage61' - os: 'ubuntu-latest' - - name: 'py37-pytest62-xdist250-coverage61 (windows)' - python: '3.7' - toxpython: 'python3.7' - python_arch: 'x64' - tox_env: 'py37-pytest62-xdist250-coverage61' - os: 'windows-latest' - - name: 'py37-pytest62-xdist250-coverage61 (macos)' - python: '3.7' - toxpython: 'python3.7' - python_arch: 'x64' - tox_env: 'py37-pytest62-xdist250-coverage61' - os: 'macos-latest' - - name: 'py37-pytest62-xdist250-coverage62 (ubuntu)' - python: '3.7' - toxpython: 'python3.7' - python_arch: 'x64' - tox_env: 'py37-pytest62-xdist250-coverage62' - os: 'ubuntu-latest' - - name: 'py37-pytest62-xdist250-coverage62 (windows)' - python: '3.7' - toxpython: 'python3.7' - python_arch: 'x64' - tox_env: 'py37-pytest62-xdist250-coverage62' - os: 'windows-latest' - - name: 'py37-pytest62-xdist250-coverage62 (macos)' - python: '3.7' - toxpython: 'python3.7' - python_arch: 'x64' - tox_env: 'py37-pytest62-xdist250-coverage62' - os: 'macos-latest' - - name: 'py37-pytest62-xdist250-coverage63 (ubuntu)' - python: '3.7' - toxpython: 'python3.7' - python_arch: 'x64' - tox_env: 'py37-pytest62-xdist250-coverage63' - os: 'ubuntu-latest' - - name: 'py37-pytest62-xdist250-coverage63 (windows)' - python: '3.7' - toxpython: 'python3.7' - python_arch: 'x64' - tox_env: 'py37-pytest62-xdist250-coverage63' - os: 'windows-latest' - - name: 'py37-pytest62-xdist250-coverage63 (macos)' - python: '3.7' - toxpython: 'python3.7' - python_arch: 'x64' - tox_env: 'py37-pytest62-xdist250-coverage63' - os: 'macos-latest' - - name: 'py38-pytest62-xdist250-coverage55 (ubuntu)' - python: '3.8' - toxpython: 'python3.8' - python_arch: 'x64' - tox_env: 'py38-pytest62-xdist250-coverage55' - os: 'ubuntu-latest' - - name: 'py38-pytest62-xdist250-coverage55 (windows)' - python: '3.8' - toxpython: 'python3.8' - python_arch: 'x64' - tox_env: 'py38-pytest62-xdist250-coverage55' - os: 'windows-latest' - - name: 'py38-pytest62-xdist250-coverage55 (macos)' + - name: 'py38-pytest71-xdist250-coverage64 (ubuntu)' python: '3.8' toxpython: 'python3.8' python_arch: 'x64' - tox_env: 'py38-pytest62-xdist250-coverage55' - os: 'macos-latest' - - name: 'py38-pytest62-xdist250-coverage60 (ubuntu)' - python: '3.8' - toxpython: 'python3.8' - python_arch: 'x64' - tox_env: 'py38-pytest62-xdist250-coverage60' + tox_env: 'py38-pytest71-xdist250-coverage64' os: 'ubuntu-latest' - - name: 'py38-pytest62-xdist250-coverage60 (windows)' + - name: 'py38-pytest71-xdist250-coverage64 (windows)' python: '3.8' toxpython: 'python3.8' python_arch: 'x64' - tox_env: 'py38-pytest62-xdist250-coverage60' + tox_env: 'py38-pytest71-xdist250-coverage64' os: 'windows-latest' - - name: 'py38-pytest62-xdist250-coverage60 (macos)' + - name: 'py38-pytest71-xdist250-coverage64 (macos)' python: '3.8' toxpython: 'python3.8' python_arch: 'x64' - tox_env: 'py38-pytest62-xdist250-coverage60' + tox_env: 'py38-pytest71-xdist250-coverage64' os: 'macos-latest' - - name: 'py38-pytest62-xdist250-coverage61 (ubuntu)' - python: '3.8' - toxpython: 'python3.8' - python_arch: 'x64' - tox_env: 'py38-pytest62-xdist250-coverage61' - os: 'ubuntu-latest' - - name: 'py38-pytest62-xdist250-coverage61 (windows)' - python: '3.8' - toxpython: 'python3.8' - python_arch: 'x64' - tox_env: 'py38-pytest62-xdist250-coverage61' - os: 'windows-latest' - - name: 'py38-pytest62-xdist250-coverage61 (macos)' - python: '3.8' - toxpython: 'python3.8' - python_arch: 'x64' - tox_env: 'py38-pytest62-xdist250-coverage61' - os: 'macos-latest' - - name: 'py38-pytest62-xdist250-coverage62 (ubuntu)' - python: '3.8' - toxpython: 'python3.8' - python_arch: 'x64' - tox_env: 'py38-pytest62-xdist250-coverage62' - os: 'ubuntu-latest' - - name: 'py38-pytest62-xdist250-coverage62 (windows)' - python: '3.8' - toxpython: 'python3.8' - python_arch: 'x64' - tox_env: 'py38-pytest62-xdist250-coverage62' - os: 'windows-latest' - - name: 'py38-pytest62-xdist250-coverage62 (macos)' - python: '3.8' - toxpython: 'python3.8' - python_arch: 'x64' - tox_env: 'py38-pytest62-xdist250-coverage62' - os: 'macos-latest' - - name: 'py38-pytest62-xdist250-coverage63 (ubuntu)' - python: '3.8' - toxpython: 'python3.8' - python_arch: 'x64' - tox_env: 'py38-pytest62-xdist250-coverage63' - os: 'ubuntu-latest' - - name: 'py38-pytest62-xdist250-coverage63 (windows)' - python: '3.8' - toxpython: 'python3.8' - python_arch: 'x64' - tox_env: 'py38-pytest62-xdist250-coverage63' - os: 'windows-latest' - - name: 'py38-pytest62-xdist250-coverage63 (macos)' - python: '3.8' - toxpython: 'python3.8' - python_arch: 'x64' - tox_env: 'py38-pytest62-xdist250-coverage63' - os: 'macos-latest' - - name: 'py39-pytest62-xdist250-coverage55 (ubuntu)' - python: '3.9' - toxpython: 'python3.9' - python_arch: 'x64' - tox_env: 'py39-pytest62-xdist250-coverage55' - os: 'ubuntu-latest' - - name: 'py39-pytest62-xdist250-coverage55 (windows)' - python: '3.9' - toxpython: 'python3.9' - python_arch: 'x64' - tox_env: 'py39-pytest62-xdist250-coverage55' - os: 'windows-latest' - - name: 'py39-pytest62-xdist250-coverage55 (macos)' - python: '3.9' - toxpython: 'python3.9' - python_arch: 'x64' - tox_env: 'py39-pytest62-xdist250-coverage55' - os: 'macos-latest' - - name: 'py39-pytest62-xdist250-coverage60 (ubuntu)' + - name: 'py39-pytest71-xdist250-coverage64 (ubuntu)' python: '3.9' toxpython: 'python3.9' python_arch: 'x64' - tox_env: 'py39-pytest62-xdist250-coverage60' + tox_env: 'py39-pytest71-xdist250-coverage64' os: 'ubuntu-latest' - - name: 'py39-pytest62-xdist250-coverage60 (windows)' + - name: 'py39-pytest71-xdist250-coverage64 (windows)' python: '3.9' toxpython: 'python3.9' python_arch: 'x64' - tox_env: 'py39-pytest62-xdist250-coverage60' + tox_env: 'py39-pytest71-xdist250-coverage64' os: 'windows-latest' - - name: 'py39-pytest62-xdist250-coverage60 (macos)' + - name: 'py39-pytest71-xdist250-coverage64 (macos)' python: '3.9' toxpython: 'python3.9' python_arch: 'x64' - tox_env: 'py39-pytest62-xdist250-coverage60' + tox_env: 'py39-pytest71-xdist250-coverage64' os: 'macos-latest' - - name: 'py39-pytest62-xdist250-coverage61 (ubuntu)' - python: '3.9' - toxpython: 'python3.9' - python_arch: 'x64' - tox_env: 'py39-pytest62-xdist250-coverage61' - os: 'ubuntu-latest' - - name: 'py39-pytest62-xdist250-coverage61 (windows)' - python: '3.9' - toxpython: 'python3.9' - python_arch: 'x64' - tox_env: 'py39-pytest62-xdist250-coverage61' - os: 'windows-latest' - - name: 'py39-pytest62-xdist250-coverage61 (macos)' - python: '3.9' - toxpython: 'python3.9' - python_arch: 'x64' - tox_env: 'py39-pytest62-xdist250-coverage61' - os: 'macos-latest' - - name: 'py39-pytest62-xdist250-coverage62 (ubuntu)' - python: '3.9' - toxpython: 'python3.9' - python_arch: 'x64' - tox_env: 'py39-pytest62-xdist250-coverage62' - os: 'ubuntu-latest' - - name: 'py39-pytest62-xdist250-coverage62 (windows)' - python: '3.9' - toxpython: 'python3.9' - python_arch: 'x64' - tox_env: 'py39-pytest62-xdist250-coverage62' - os: 'windows-latest' - - name: 'py39-pytest62-xdist250-coverage62 (macos)' - python: '3.9' - toxpython: 'python3.9' - python_arch: 'x64' - tox_env: 'py39-pytest62-xdist250-coverage62' - os: 'macos-latest' - - name: 'py39-pytest62-xdist250-coverage63 (ubuntu)' - python: '3.9' - toxpython: 'python3.9' - python_arch: 'x64' - tox_env: 'py39-pytest62-xdist250-coverage63' - os: 'ubuntu-latest' - - name: 'py39-pytest62-xdist250-coverage63 (windows)' - python: '3.9' - toxpython: 'python3.9' - python_arch: 'x64' - tox_env: 'py39-pytest62-xdist250-coverage63' - os: 'windows-latest' - - name: 'py39-pytest62-xdist250-coverage63 (macos)' - python: '3.9' - toxpython: 'python3.9' - python_arch: 'x64' - tox_env: 'py39-pytest62-xdist250-coverage63' - os: 'macos-latest' - - name: 'py310-pytest62-xdist250-coverage55 (ubuntu)' - python: '3.10' - toxpython: 'python3.10' - python_arch: 'x64' - tox_env: 'py310-pytest62-xdist250-coverage55' - os: 'ubuntu-latest' - - name: 'py310-pytest62-xdist250-coverage55 (windows)' - python: '3.10' - toxpython: 'python3.10' - python_arch: 'x64' - tox_env: 'py310-pytest62-xdist250-coverage55' - os: 'windows-latest' - - name: 'py310-pytest62-xdist250-coverage55 (macos)' - python: '3.10' - toxpython: 'python3.10' - python_arch: 'x64' - tox_env: 'py310-pytest62-xdist250-coverage55' - os: 'macos-latest' - - name: 'py310-pytest62-xdist250-coverage60 (ubuntu)' - python: '3.10' - toxpython: 'python3.10' - python_arch: 'x64' - tox_env: 'py310-pytest62-xdist250-coverage60' - os: 'ubuntu-latest' - - name: 'py310-pytest62-xdist250-coverage60 (windows)' - python: '3.10' - toxpython: 'python3.10' - python_arch: 'x64' - tox_env: 'py310-pytest62-xdist250-coverage60' - os: 'windows-latest' - - name: 'py310-pytest62-xdist250-coverage60 (macos)' - python: '3.10' - toxpython: 'python3.10' - python_arch: 'x64' - tox_env: 'py310-pytest62-xdist250-coverage60' - os: 'macos-latest' - - name: 'py310-pytest62-xdist250-coverage61 (ubuntu)' - python: '3.10' - toxpython: 'python3.10' - python_arch: 'x64' - tox_env: 'py310-pytest62-xdist250-coverage61' - os: 'ubuntu-latest' - - name: 'py310-pytest62-xdist250-coverage61 (windows)' - python: '3.10' - toxpython: 'python3.10' - python_arch: 'x64' - tox_env: 'py310-pytest62-xdist250-coverage61' - os: 'windows-latest' - - name: 'py310-pytest62-xdist250-coverage61 (macos)' - python: '3.10' - toxpython: 'python3.10' - python_arch: 'x64' - tox_env: 'py310-pytest62-xdist250-coverage61' - os: 'macos-latest' - - name: 'py310-pytest62-xdist250-coverage62 (ubuntu)' - python: '3.10' - toxpython: 'python3.10' - python_arch: 'x64' - tox_env: 'py310-pytest62-xdist250-coverage62' - os: 'ubuntu-latest' - - name: 'py310-pytest62-xdist250-coverage62 (windows)' - python: '3.10' - toxpython: 'python3.10' - python_arch: 'x64' - tox_env: 'py310-pytest62-xdist250-coverage62' - os: 'windows-latest' - - name: 'py310-pytest62-xdist250-coverage62 (macos)' + - name: 'py310-pytest71-xdist250-coverage64 (ubuntu)' python: '3.10' toxpython: 'python3.10' python_arch: 'x64' - tox_env: 'py310-pytest62-xdist250-coverage62' - os: 'macos-latest' - - name: 'py310-pytest62-xdist250-coverage63 (ubuntu)' - python: '3.10' - toxpython: 'python3.10' - python_arch: 'x64' - tox_env: 'py310-pytest62-xdist250-coverage63' + tox_env: 'py310-pytest71-xdist250-coverage64' os: 'ubuntu-latest' - - name: 'py310-pytest62-xdist250-coverage63 (windows)' + - name: 'py310-pytest71-xdist250-coverage64 (windows)' python: '3.10' toxpython: 'python3.10' python_arch: 'x64' - tox_env: 'py310-pytest62-xdist250-coverage63' + tox_env: 'py310-pytest71-xdist250-coverage64' os: 'windows-latest' - - name: 'py310-pytest62-xdist250-coverage63 (macos)' + - name: 'py310-pytest71-xdist250-coverage64 (macos)' python: '3.10' toxpython: 'python3.10' python_arch: 'x64' - tox_env: 'py310-pytest62-xdist250-coverage63' - os: 'macos-latest' - - name: 'pypy3-pytest62-xdist250-coverage55 (ubuntu)' - python: 'pypy-3.' - toxpython: 'pypy3.' - python_arch: 'x64' - tox_env: 'pypy3-pytest62-xdist250-coverage55' - os: 'ubuntu-latest' - - name: 'pypy3-pytest62-xdist250-coverage55 (windows)' - python: 'pypy-3.' - toxpython: 'pypy3.' - python_arch: 'x64' - tox_env: 'pypy3-pytest62-xdist250-coverage55' - os: 'windows-latest' - - name: 'pypy3-pytest62-xdist250-coverage55 (macos)' - python: 'pypy-3.' - toxpython: 'pypy3.' - python_arch: 'x64' - tox_env: 'pypy3-pytest62-xdist250-coverage55' - os: 'macos-latest' - - name: 'pypy3-pytest62-xdist250-coverage60 (ubuntu)' - python: 'pypy-3.' - toxpython: 'pypy3.' - python_arch: 'x64' - tox_env: 'pypy3-pytest62-xdist250-coverage60' - os: 'ubuntu-latest' - - name: 'pypy3-pytest62-xdist250-coverage60 (windows)' - python: 'pypy-3.' - toxpython: 'pypy3.' - python_arch: 'x64' - tox_env: 'pypy3-pytest62-xdist250-coverage60' - os: 'windows-latest' - - name: 'pypy3-pytest62-xdist250-coverage60 (macos)' - python: 'pypy-3.' - toxpython: 'pypy3.' - python_arch: 'x64' - tox_env: 'pypy3-pytest62-xdist250-coverage60' - os: 'macos-latest' - - name: 'pypy3-pytest62-xdist250-coverage61 (ubuntu)' - python: 'pypy-3.' - toxpython: 'pypy3.' - python_arch: 'x64' - tox_env: 'pypy3-pytest62-xdist250-coverage61' - os: 'ubuntu-latest' - - name: 'pypy3-pytest62-xdist250-coverage61 (windows)' - python: 'pypy-3.' - toxpython: 'pypy3.' - python_arch: 'x64' - tox_env: 'pypy3-pytest62-xdist250-coverage61' - os: 'windows-latest' - - name: 'pypy3-pytest62-xdist250-coverage61 (macos)' - python: 'pypy-3.' - toxpython: 'pypy3.' - python_arch: 'x64' - tox_env: 'pypy3-pytest62-xdist250-coverage61' - os: 'macos-latest' - - name: 'pypy3-pytest62-xdist250-coverage62 (ubuntu)' - python: 'pypy-3.' - toxpython: 'pypy3.' - python_arch: 'x64' - tox_env: 'pypy3-pytest62-xdist250-coverage62' - os: 'ubuntu-latest' - - name: 'pypy3-pytest62-xdist250-coverage62 (windows)' - python: 'pypy-3.' - toxpython: 'pypy3.' - python_arch: 'x64' - tox_env: 'pypy3-pytest62-xdist250-coverage62' - os: 'windows-latest' - - name: 'pypy3-pytest62-xdist250-coverage62 (macos)' - python: 'pypy-3.' - toxpython: 'pypy3.' - python_arch: 'x64' - tox_env: 'pypy3-pytest62-xdist250-coverage62' + tox_env: 'py310-pytest71-xdist250-coverage64' os: 'macos-latest' - - name: 'pypy3-pytest62-xdist250-coverage63 (ubuntu)' + - name: 'pypy3-pytest71-xdist250-coverage64 (ubuntu)' python: 'pypy-3.' toxpython: 'pypy3.' python_arch: 'x64' - tox_env: 'pypy3-pytest62-xdist250-coverage63' + tox_env: 'pypy3-pytest71-xdist250-coverage64' os: 'ubuntu-latest' - - name: 'pypy3-pytest62-xdist250-coverage63 (windows)' + - name: 'pypy3-pytest71-xdist250-coverage64 (windows)' python: 'pypy-3.' toxpython: 'pypy3.' python_arch: 'x64' - tox_env: 'pypy3-pytest62-xdist250-coverage63' + tox_env: 'pypy3-pytest71-xdist250-coverage64' os: 'windows-latest' - - name: 'pypy3-pytest62-xdist250-coverage63 (macos)' + - name: 'pypy3-pytest71-xdist250-coverage64 (macos)' python: 'pypy-3.' toxpython: 'pypy3.' python_arch: 'x64' - tox_env: 'pypy3-pytest62-xdist250-coverage63' + tox_env: 'pypy3-pytest71-xdist250-coverage64' os: 'macos-latest' steps: - uses: actions/checkout@v2 diff --git a/tox.ini b/tox.ini index 6d7ab6eb..88a2b63a 100644 --- a/tox.ini +++ b/tox.ini @@ -12,9 +12,8 @@ passenv = [tox] envlist = check - py{36,37,py,py3}-pytest46-xdist127-coverage{55} - py{36,37,38,py3}-pytest{46,54}-xdist133-coverage{55} - py{36,37,38,39,310,py3}-pytest{62}-xdist250-coverage{55,60,61,62,63} + py{36}-pytest{70}-xdist250-coverage{62} + py{37,38,39,310,py3}-pytest{71}-xdist250-coverage{64} docs [testenv] @@ -29,6 +28,8 @@ setenv = pytest60: _DEP_PYTEST=pytest==6.0.2 pytest61: _DEP_PYTEST=pytest==6.1.2 pytest62: _DEP_PYTEST=pytest==6.2.5 + pytest70: _DEP_PYTEST=pytest==7.0.1 + pytest71: _DEP_PYTEST=pytest==7.1.2 xdist127: _DEP_PYTESTXDIST=pytest-xdist==1.27.0 xdist129: _DEP_PYTESTXDIST=pytest-xdist==1.29.0 @@ -52,7 +53,8 @@ setenv = coverage60: _DEP_COVERAGE=coverage==6.0.2 coverage61: _DEP_COVERAGE=coverage==6.1.2 coverage62: _DEP_COVERAGE=coverage==6.2 - coverage63: _DEP_COVERAGE=coverage==6.3 + coverage63: _DEP_COVERAGE=coverage==6.3.3 + coverage64: _DEP_COVERAGE=coverage==6.4.2 # For testing against a coverage.py working tree. coveragedev: _DEP_COVERAGE=-e{env:COVERAGE_HOME} passenv = From ef56546f0ae2add47bc9bed3734a096795fffcbe Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ionel=20Cristian=20M=C4=83rie=C8=99?= Date: Thu, 21 Jul 2022 19:52:47 +0300 Subject: [PATCH 18/42] Cleanup what can only be an accidental fatfinger copypasta. --- CHANGELOG.rst | 11 ----------- 1 file changed, 11 deletions(-) diff --git a/CHANGELOG.rst b/CHANGELOG.rst index 3087426b..1ec62380 100644 --- a/CHANGELOG.rst +++ b/CHANGELOG.rst @@ -36,17 +36,6 @@ Changelog Contributed by Thomas Grainger in `#477 `_. - -2.13.0 (2021-06-01) -------------------- - -* Changed the `toml` requirement to be always be directly required (instead of being required through a coverage extra). - This fixes issues with pip-compile (`pip-tools#1300 `_). - Contributed by Sorin Sbarnea in `#472 `_. -* Documented ``show_contexts``. - Contributed by Brian Rutledge in `#473 `_. - - 2.12.1 (2021-06-01) ------------------- From f1ee0461b1dd7b5ea530fae17dcdc758bfa2d5b1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ionel=20Cristian=20M=C4=83rie=C8=99?= Date: Thu, 21 Jul 2022 19:53:22 +0300 Subject: [PATCH 19/42] Remove another dupe entry. --- CHANGELOG.rst | 2 -- 1 file changed, 2 deletions(-) diff --git a/CHANGELOG.rst b/CHANGELOG.rst index 1ec62380..e559ebb4 100644 --- a/CHANGELOG.rst +++ b/CHANGELOG.rst @@ -185,8 +185,6 @@ Changelog `#272 `_, `#271 `_ and `#269 `_. -* Improved documentation regarding subprocess and multiprocessing. - Contributed in `#265 `_. * Improved ``pytest_cov.embed.cleanup_on_sigterm`` to be reentrant (signal deliveries while signal handling is running won't break stuff). * Added ``pytest_cov.embed.cleanup_on_signal`` for customized cleanup. From a5b07425cafab44dd956f02f3c096023db1cd6e1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ionel=20Cristian=20M=C4=83rie=C8=99?= Date: Thu, 21 Jul 2022 19:56:58 +0300 Subject: [PATCH 20/42] Fix `cannot import name 'environmentfilter' from 'jinja2'` issue. --- docs/requirements.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/docs/requirements.txt b/docs/requirements.txt index ccec79fd..6fdf26f9 100644 --- a/docs/requirements.txt +++ b/docs/requirements.txt @@ -1,4 +1,5 @@ sphinx==3.0.3 sphinx-py3doc-enhanced-theme==2.4.0 docutils==0.16 +jinja2<3.1 -e . From 16601bb93612f1b087452577fd63b99f9a894766 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ionel=20Cristian=20M=C4=83rie=C8=99?= Date: Thu, 21 Jul 2022 23:34:07 +0300 Subject: [PATCH 21/42] Remove our crummy multiprocessing hooks and work on some tests with the builtin mp support in coverage. --- src/pytest-cov.pth | 2 +- src/pytest_cov/embed.py | 18 ------- tests/test_pytest_cov.py | 103 ++++++++++++++++++--------------------- 3 files changed, 49 insertions(+), 74 deletions(-) diff --git a/src/pytest-cov.pth b/src/pytest-cov.pth index 91f2b7c7..8ed1a516 100644 --- a/src/pytest-cov.pth +++ b/src/pytest-cov.pth @@ -1 +1 @@ -import os, sys;exec('if \'COV_CORE_SOURCE\' in os.environ:\n try:\n from pytest_cov.embed import init\n init()\n except Exception as exc:\n sys.stderr.write(\n "pytest-cov: Failed to setup subprocess coverage. "\n "Environ: {0!r} "\n "Exception: {1!r}\\n".format(\n dict((k, v) for k, v in os.environ.items() if k.startswith(\'COV_CORE\')),\n exc\n )\n )\n') \ No newline at end of file +import os, sys;exec('if \'COV_CORE_SOURCE\' in os.environ:\n try:\n from pytest_cov.embed import init\n init()\n except Exception as exc:\n sys.stderr.write(\n "pytest-cov: Failed to setup subprocess coverage. "\n "Environ: {0!r} "\n "Exception: {1!r}\\n".format(\n dict((k, v) for k, v in os.environ.items() if k.startswith(\'COV_CORE\')),\n exc\n )\n )\n') diff --git a/src/pytest_cov/embed.py b/src/pytest_cov/embed.py index fe0575e9..f8a2749f 100644 --- a/src/pytest_cov/embed.py +++ b/src/pytest_cov/embed.py @@ -20,22 +20,6 @@ _active_cov = None -def multiprocessing_start(_): - global _active_cov - cov = init() - if cov: - _active_cov = cov - multiprocessing.util.Finalize(None, cleanup, exitpriority=1000) - - -try: - import multiprocessing.util -except ImportError: - pass -else: - multiprocessing.util.register_after_fork(multiprocessing_start, multiprocessing_start) - - def init(): # Only continue if ancestor process has set everything needed in # the env. @@ -105,8 +89,6 @@ def cleanup(): _signal_cleanup_handler(*pending_signal) -multiprocessing_finish = cleanup # in case someone dared to use this internal - _previous_handlers = {} _pending_signal = None _cleanup_in_progress = False diff --git a/tests/test_pytest_cov.py b/tests/test_pytest_cov.py index 33814ef4..edf0fe6e 100644 --- a/tests/test_pytest_cov.py +++ b/tests/test_pytest_cov.py @@ -157,15 +157,6 @@ def test_foo(cov): pytest.param('-n 1', marks=pytest.mark.skipif('sys.platform == "win32" and platform.python_implementation() == "PyPy"')) ], ids=['nodist', 'xdist']) -skipif_multiprocessing_is_broken = pytest.mark.skipif( - 'sys.version_info[:2] >= (3, 8)', - reason="deadlocks on Python 3.8+, see: https://bugs.python.org/issue38227" -) -method_params = pytest.mark.parametrize('method', [ - pytest.param('fork', marks=skipif_multiprocessing_is_broken), - pytest.param('spawn', marks=skipif_multiprocessing_is_broken), -]) - @pytest.fixture(scope='session', autouse=True) def adjust_sys_path(): @@ -203,7 +194,7 @@ def prop(request): ) -def test_central(testdir, prop): +def test_central(pytester, testdir, prop): script = testdir.makepyfile(prop.code) testdir.tmpdir.join('.coveragerc').write(prop.fullconf) @@ -470,7 +461,7 @@ def test_cov_min_no_report(testdir): ]) -def test_central_nonspecific(testdir, prop): +def test_central_nonspecific(pytester, testdir, prop): script = testdir.makepyfile(prop.code) testdir.tmpdir.join('.coveragerc').write(prop.fullconf) result = testdir.runpytest('-v', @@ -505,7 +496,7 @@ def test_cov_min_from_coveragerc(testdir): assert result.ret != 0 -def test_central_coveragerc(testdir, prop): +def test_central_coveragerc(pytester, testdir, prop): script = testdir.makepyfile(prop.code) testdir.tmpdir.join('.coveragerc').write(COVERAGERC_SOURCE + prop.conf) @@ -523,7 +514,7 @@ def test_central_coveragerc(testdir, prop): @xdist_params -def test_central_with_path_aliasing(testdir, monkeypatch, opts, prop): +def test_central_with_path_aliasing(pytester, testdir, monkeypatch, opts, prop): mod1 = testdir.mkdir('src').join('mod.py') mod1.write(SCRIPT) mod2 = testdir.mkdir('aliased').join('mod.py') @@ -557,7 +548,7 @@ def test_central_with_path_aliasing(testdir, monkeypatch, opts, prop): @xdist_params -def test_borken_cwd(testdir, monkeypatch, opts): +def test_borken_cwd(pytester, testdir, monkeypatch, opts): testdir.makepyfile(mod=''' def foobar(a, b): return a + b @@ -596,7 +587,7 @@ def test_foobar(bad): assert result.ret == 0 -def test_subprocess_with_path_aliasing(testdir, monkeypatch): +def test_subprocess_with_path_aliasing(pytester, testdir, monkeypatch): src = testdir.mkdir('src') src.join('parent_script.py').write(SCRIPT_PARENT) src.join('child_script.py').write(SCRIPT_CHILD) @@ -632,7 +623,7 @@ def test_subprocess_with_path_aliasing(testdir, monkeypatch): assert result.ret == 0 -def test_show_missing_coveragerc(testdir, prop): +def test_show_missing_coveragerc(pytester, testdir, prop): script = testdir.makepyfile(prop.code) testdir.tmpdir.join('.coveragerc').write(""" [run] @@ -675,7 +666,7 @@ def test_fail(): result.stdout.fnmatch_lines(['*1 failed*']) -def test_no_cov(testdir, monkeypatch): +def test_no_cov(pytester, testdir, monkeypatch): script = testdir.makepyfile(SCRIPT) testdir.makeini(""" [pytest] @@ -742,7 +733,7 @@ def test_foo(foo): @pytest.mark.skipif('sys.platform == "win32" and platform.python_implementation() == "PyPy"') -def test_dist_collocated(testdir, prop): +def test_dist_collocated(pytester, testdir, prop): script = testdir.makepyfile(prop.code) testdir.tmpdir.join('.coveragerc').write(prop.fullconf) result = testdir.runpytest('-v', @@ -762,7 +753,7 @@ def test_dist_collocated(testdir, prop): @pytest.mark.skipif('sys.platform == "win32" and platform.python_implementation() == "PyPy"') -def test_dist_not_collocated(testdir, prop): +def test_dist_not_collocated(pytester, testdir, prop): script = testdir.makepyfile(prop.code) dir1 = testdir.mkdir('dir1') dir2 = testdir.mkdir('dir2') @@ -795,7 +786,7 @@ def test_dist_not_collocated(testdir, prop): @pytest.mark.skipif('sys.platform == "win32" and platform.python_implementation() == "PyPy"') -def test_dist_not_collocated_coveragerc_source(testdir, prop): +def test_dist_not_collocated_coveragerc_source(pytester, testdir, prop): script = testdir.makepyfile(prop.code) dir1 = testdir.mkdir('dir1') dir2 = testdir.mkdir('dir2') @@ -870,7 +861,7 @@ def test_central_subprocess_change_cwd(testdir): assert result.ret == 0 -def test_central_subprocess_change_cwd_with_pythonpath(testdir, monkeypatch): +def test_central_subprocess_change_cwd_with_pythonpath(pytester, testdir, monkeypatch): stuff = testdir.mkdir('stuff') parent_script = stuff.join('parent_script.py') parent_script.write(SCRIPT_PARENT_CHANGE_CWD_IMPORT_CHILD) @@ -941,7 +932,7 @@ def test_dist_subprocess_collocated(testdir): @pytest.mark.skipif('sys.platform == "win32" and platform.python_implementation() == "PyPy"') -def test_dist_subprocess_not_collocated(testdir, tmpdir): +def test_dist_subprocess_not_collocated(pytester, testdir, tmpdir): scripts = testdir.makepyfile(parent_script=SCRIPT_PARENT, child_script=SCRIPT_CHILD) parent_script = scripts.dirpath().join('parent_script.py') @@ -1071,10 +1062,11 @@ def test_funcarg_not_active(testdir): @pytest.mark.skipif("sys.version_info[0] < 3", reason="no context manager api on Python 2") @pytest.mark.skipif('sys.platform == "win32"', reason="multiprocessing support is broken on Windows") @pytest.mark.skipif('platform.python_implementation() == "PyPy"', reason="often deadlocks on PyPy") -@method_params -def test_multiprocessing_pool(testdir, method): +@pytest.mark.parametrize('method', ['fork', 'spawn']) +@pytest.mark.xfail +def test_multiprocessing_pool(pytester, testdir, method): pytest.importorskip('multiprocessing.util') - + pytester.path.joinpath(".coveragerc").write_text(MP_COVERAGERC) script = testdir.makepyfile(''' import multiprocessing @@ -1084,9 +1076,6 @@ def target_fn(a): def test_run_target(): multiprocessing.set_start_method({!r}) - from pytest_cov.embed import cleanup_on_sigterm - cleanup_on_sigterm() - for i in range(33): with multiprocessing.Pool(3) as p: p.map(target_fn, [i * 3 + j for j in range(3)]) @@ -1102,21 +1091,21 @@ def test_run_target(): assert "Doesn't seem to be a coverage.py data file" not in result.stdout.str() assert "Doesn't seem to be a coverage.py data file" not in result.stderr.str() - assert not testdir.tmpdir.listdir(".coverage.*") result.stdout.fnmatch_lines([ '*- coverage: platform *, python * -*', 'test_multiprocessing_pool* 100%*', '*1 passed*' ]) + assert not testdir.tmpdir.listdir(".coverage.*") assert result.ret == 0 @pytest.mark.skipif('sys.platform == "win32"', reason="multiprocessing support is broken on Windows") @pytest.mark.skipif('platform.python_implementation() == "PyPy"', reason="often deadlocks on PyPy") -@method_params -def test_multiprocessing_pool_terminate(testdir, method): +@pytest.mark.parametrize('method', ['fork', 'spawn']) +def test_multiprocessing_pool_terminate(pytester, testdir, method): pytest.importorskip('multiprocessing.util') - + pytester.path.joinpath(".coveragerc").write_text(MP_COVERAGERC) script = testdir.makepyfile(''' import multiprocessing @@ -1126,8 +1115,6 @@ def target_fn(a): def test_run_target(): multiprocessing.set_start_method({!r}) - from pytest_cov.embed import cleanup_on_sigterm - cleanup_on_sigterm() for i in range(33): p = multiprocessing.Pool(3) @@ -1147,21 +1134,21 @@ def test_run_target(): assert "Doesn't seem to be a coverage.py data file" not in result.stdout.str() assert "Doesn't seem to be a coverage.py data file" not in result.stderr.str() - assert not testdir.tmpdir.listdir(".coverage.*") result.stdout.fnmatch_lines([ '*- coverage: platform *, python * -*', 'test_multiprocessing_pool* 100%*', '*1 passed*' ]) + assert not testdir.tmpdir.listdir(".coverage.*") assert result.ret == 0 @pytest.mark.skipif('sys.platform == "win32"', reason="multiprocessing support is broken on Windows") @pytest.mark.skipif('sys.version_info[0] > 2 and platform.python_implementation() == "PyPy"', reason="broken on PyPy3") -@method_params -def test_multiprocessing_pool_close(testdir, method): +@pytest.mark.parametrize('method', ['fork', 'spawn']) +def test_multiprocessing_pool_close(pytester, testdir, method): pytest.importorskip('multiprocessing.util') - + pytester.path.joinpath(".coveragerc").write_text(MP_COVERAGERC) script = testdir.makepyfile(''' import multiprocessing @@ -1188,20 +1175,20 @@ def test_run_target(): script) assert "Doesn't seem to be a coverage.py data file" not in result.stdout.str() assert "Doesn't seem to be a coverage.py data file" not in result.stderr.str() - assert not testdir.tmpdir.listdir(".coverage.*") result.stdout.fnmatch_lines([ '*- coverage: platform *, python * -*', 'test_multiprocessing_pool* 100%*', '*1 passed*' ]) + # assert not testdir.tmpdir.listdir(".coverage.*") assert result.ret == 0 @pytest.mark.skipif('sys.platform == "win32"', reason="multiprocessing support is broken on Windows") -@method_params -def test_multiprocessing_process(testdir, method): +@pytest.mark.parametrize('method', ['fork', 'spawn']) +def test_multiprocessing_process(pytester, testdir, method): pytest.importorskip('multiprocessing.util') - + pytester.path.joinpath(".coveragerc").write_text(MP_COVERAGERC) script = testdir.makepyfile(''' import multiprocessing @@ -1230,9 +1217,9 @@ def test_run_target(): @pytest.mark.skipif('sys.platform == "win32"', reason="multiprocessing support is broken on Windows") -def test_multiprocessing_process_no_source(testdir): +def test_multiprocessing_process_no_source(pytester, testdir): pytest.importorskip('multiprocessing.util') - + pytester.path.joinpath(".coveragerc").write_text(MP_COVERAGERC) script = testdir.makepyfile(''' import multiprocessing @@ -1260,9 +1247,9 @@ def test_run_target(): @pytest.mark.skipif('sys.platform == "win32"', reason="multiprocessing support is broken on Windows") -def test_multiprocessing_process_with_terminate(testdir): +def test_multiprocessing_process_with_terminate(pytester, testdir): pytest.importorskip('multiprocessing.util') - + pytester.path.joinpath(".coveragerc").write_text(MP_COVERAGERC) script = testdir.makepyfile(''' import multiprocessing import time @@ -1349,7 +1336,7 @@ def test_run(): ('cleanup_on_signal(signal.SIGBREAK)', '87% 21-22'), ('cleanup()', '73% 19-22'), ]) -def test_cleanup_on_sigterm_sig_break(testdir, setup): +def test_cleanup_on_sigterm_sig_break(pytester, testdir, setup): # worth a read: https://stefan.sofa-rockers.org/2013/08/15/handling-sub-process-hierarchies-python-linux-os-x/ script = testdir.makepyfile(''' import os, signal, subprocess, sys, time @@ -1395,7 +1382,7 @@ def test_run(): ('cleanup_on_sigterm()', '88% 18-19'), ('cleanup()', '75% 16-19'), ]) -def test_cleanup_on_sigterm_sig_dfl(testdir, setup): +def test_cleanup_on_sigterm_sig_dfl(pytester, testdir, setup): script = testdir.makepyfile(''' import os, signal, subprocess, sys, time @@ -1551,7 +1538,7 @@ def test_cover_conftest(testdir): @pytest.mark.skipif('sys.platform == "win32" and platform.python_implementation() == "PyPy"') -def test_cover_looponfail(testdir, monkeypatch): +def test_cover_looponfail(pytester, testdir, monkeypatch): testdir.makepyfile(mod=MODULE) testdir.makeconftest(CONFTEST) script = testdir.makepyfile(BASIC_TEST) @@ -1559,9 +1546,9 @@ def test_cover_looponfail(testdir, monkeypatch): def mock_run(*args, **kwargs): return _TestProcess(*map(str, args)) - monkeypatch.setattr(testdir, 'run', mock_run) + monkeypatch.setattr(pytester, testdir, 'run', mock_run) assert testdir.run is mock_run - if hasattr(testdir, '_pytester'): + if hasattr(pytester, testdir, '_pytester'): monkeypatch.setattr(testdir._pytester, 'run', mock_run) assert testdir._pytester.run is mock_run with testdir.runpytest('-v', @@ -1637,7 +1624,13 @@ def test_basic(no_cover): # Regexes for lines to exclude from consideration exclude_lines = raise NotImplementedError +''' +MP_COVERAGERC = ''' +[run] +concurrency = multiprocessing +parallel = true +sigterm = True ''' EXCLUDED_TEST = ''' @@ -1704,7 +1697,7 @@ def test_basic(): @pytest.mark.parametrize('report_option', [ 'term-missing:skip-covered', 'term:skip-covered']) -def test_skip_covered_cli(testdir, report_option): +def test_skip_covered_cli(pytester, testdir, report_option): testdir.makefile('', coveragerc=SKIP_COVERED_COVERAGERC) script = testdir.makepyfile(SKIP_COVERED_TEST) result = testdir.runpytest('-v', @@ -1910,7 +1903,7 @@ def test_external_data_file_negative(testdir): @xdist_params -def test_append_coverage(testdir, opts, prop): +def test_append_coverage(pytester, testdir, opts, prop): script = testdir.makepyfile(test_1=prop.code) testdir.tmpdir.join('.coveragerc').write(prop.fullconf) result = testdir.runpytest('-v', @@ -1933,7 +1926,7 @@ def test_append_coverage(testdir, opts, prop): @xdist_params -def test_do_not_append_coverage(testdir, opts, prop): +def test_do_not_append_coverage(pytester, testdir, opts, prop): script = testdir.makepyfile(test_1=prop.code) testdir.tmpdir.join('.coveragerc').write(prop.fullconf) result = testdir.runpytest('-v', @@ -2115,7 +2108,7 @@ def find_labels(text, pattern): @pytest.mark.skipif("coverage.version_info < (5, 0)") @xdist_params -def test_contexts(testdir, opts): +def test_contexts(pytester, testdir, opts): with open(os.path.join(os.path.dirname(__file__), "contextful.py")) as f: contextful_tests = f.read() script = testdir.makepyfile(contextful_tests) From 0c176298ffc44d8a64befc466e61dc74f2ac0745 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ionel=20Cristian=20M=C4=83rie=C8=99?= Date: Thu, 21 Jul 2022 23:34:45 +0300 Subject: [PATCH 22/42] Reveert this change that wastes me time typing up full paths. --- tox.ini | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tox.ini b/tox.ini index 88a2b63a..e283165c 100644 --- a/tox.ini +++ b/tox.ini @@ -65,7 +65,7 @@ deps = {env:_DEP_COVERAGE:coverage} pip_pre = true commands = - pytest {posargs:-vv} + {posargs:pytest -vv} [testenv:spell] setenv = From b0329585c6b0186715feb41f58071eefa36cdf0a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ionel=20Cristian=20M=C4=83rie=C8=99?= Date: Thu, 21 Jul 2022 23:36:52 +0300 Subject: [PATCH 23/42] Throwing in the towel. I don't care anymore. I don't see any workarounds for https://github.com/python/cpython/issues/82408. --- tests/test_pytest_cov.py | 226 --------------------------------------- 1 file changed, 226 deletions(-) diff --git a/tests/test_pytest_cov.py b/tests/test_pytest_cov.py index edf0fe6e..1cb68577 100644 --- a/tests/test_pytest_cov.py +++ b/tests/test_pytest_cov.py @@ -1059,232 +1059,6 @@ def test_funcarg_not_active(testdir): assert result.ret == 0 -@pytest.mark.skipif("sys.version_info[0] < 3", reason="no context manager api on Python 2") -@pytest.mark.skipif('sys.platform == "win32"', reason="multiprocessing support is broken on Windows") -@pytest.mark.skipif('platform.python_implementation() == "PyPy"', reason="often deadlocks on PyPy") -@pytest.mark.parametrize('method', ['fork', 'spawn']) -@pytest.mark.xfail -def test_multiprocessing_pool(pytester, testdir, method): - pytest.importorskip('multiprocessing.util') - pytester.path.joinpath(".coveragerc").write_text(MP_COVERAGERC) - script = testdir.makepyfile(''' -import multiprocessing - -def target_fn(a): - {}se: # pragma: nocover - return None - -def test_run_target(): - multiprocessing.set_start_method({!r}) - for i in range(33): - with multiprocessing.Pool(3) as p: - p.map(target_fn, [i * 3 + j for j in range(3)]) - p.join() -'''.format(''.join('''if a == %r: - return a - el''' % i for i in range(99)), method)) - - result = testdir.runpytest('-v', - '--cov=%s' % script.dirpath(), - '--cov-report=term-missing', - script) - - assert "Doesn't seem to be a coverage.py data file" not in result.stdout.str() - assert "Doesn't seem to be a coverage.py data file" not in result.stderr.str() - result.stdout.fnmatch_lines([ - '*- coverage: platform *, python * -*', - 'test_multiprocessing_pool* 100%*', - '*1 passed*' - ]) - assert not testdir.tmpdir.listdir(".coverage.*") - assert result.ret == 0 - - -@pytest.mark.skipif('sys.platform == "win32"', reason="multiprocessing support is broken on Windows") -@pytest.mark.skipif('platform.python_implementation() == "PyPy"', reason="often deadlocks on PyPy") -@pytest.mark.parametrize('method', ['fork', 'spawn']) -def test_multiprocessing_pool_terminate(pytester, testdir, method): - pytest.importorskip('multiprocessing.util') - pytester.path.joinpath(".coveragerc").write_text(MP_COVERAGERC) - script = testdir.makepyfile(''' -import multiprocessing - -def target_fn(a): - {}se: # pragma: nocover - return None - -def test_run_target(): - multiprocessing.set_start_method({!r}) - - for i in range(33): - p = multiprocessing.Pool(3) - try: - p.map(target_fn, [i * 3 + j for j in range(3)]) - finally: - p.terminate() - p.join() -'''.format(''.join('''if a == %r: - return a - el''' % i for i in range(99)), method)) - - result = testdir.runpytest('-v', - '--cov=%s' % script.dirpath(), - '--cov-report=term-missing', - script) - - assert "Doesn't seem to be a coverage.py data file" not in result.stdout.str() - assert "Doesn't seem to be a coverage.py data file" not in result.stderr.str() - result.stdout.fnmatch_lines([ - '*- coverage: platform *, python * -*', - 'test_multiprocessing_pool* 100%*', - '*1 passed*' - ]) - assert not testdir.tmpdir.listdir(".coverage.*") - assert result.ret == 0 - - -@pytest.mark.skipif('sys.platform == "win32"', reason="multiprocessing support is broken on Windows") -@pytest.mark.skipif('sys.version_info[0] > 2 and platform.python_implementation() == "PyPy"', reason="broken on PyPy3") -@pytest.mark.parametrize('method', ['fork', 'spawn']) -def test_multiprocessing_pool_close(pytester, testdir, method): - pytest.importorskip('multiprocessing.util') - pytester.path.joinpath(".coveragerc").write_text(MP_COVERAGERC) - script = testdir.makepyfile(''' -import multiprocessing - -def target_fn(a): - {}se: # pragma: nocover - return None - -def test_run_target(): - multiprocessing.set_start_method({!r}) - for i in range(33): - p = multiprocessing.Pool(3) - try: - p.map(target_fn, [i * 3 + j for j in range(3)]) - finally: - p.close() - p.join() -'''.format(''.join('''if a == %r: - return a - el''' % i for i in range(99)), method)) - - result = testdir.runpytest('-v', - '--cov=%s' % script.dirpath(), - '--cov-report=term-missing', - script) - assert "Doesn't seem to be a coverage.py data file" not in result.stdout.str() - assert "Doesn't seem to be a coverage.py data file" not in result.stderr.str() - result.stdout.fnmatch_lines([ - '*- coverage: platform *, python * -*', - 'test_multiprocessing_pool* 100%*', - '*1 passed*' - ]) - # assert not testdir.tmpdir.listdir(".coverage.*") - assert result.ret == 0 - - -@pytest.mark.skipif('sys.platform == "win32"', reason="multiprocessing support is broken on Windows") -@pytest.mark.parametrize('method', ['fork', 'spawn']) -def test_multiprocessing_process(pytester, testdir, method): - pytest.importorskip('multiprocessing.util') - pytester.path.joinpath(".coveragerc").write_text(MP_COVERAGERC) - script = testdir.makepyfile(''' -import multiprocessing - -def target_fn(): - a = True - return a - -def test_run_target(): - multiprocessing.set_start_method({!r}) - p = multiprocessing.Process(target=target_fn) - p.start() - p.join() -'''.format(method)) - - result = testdir.runpytest('-v', - '--cov=%s' % script.dirpath(), - '--cov-report=term-missing', - script) - - result.stdout.fnmatch_lines([ - '*- coverage: platform *, python * -*', - 'test_multiprocessing_process* 9 * 100%*', - '*1 passed*' - ]) - assert result.ret == 0 - - -@pytest.mark.skipif('sys.platform == "win32"', reason="multiprocessing support is broken on Windows") -def test_multiprocessing_process_no_source(pytester, testdir): - pytest.importorskip('multiprocessing.util') - pytester.path.joinpath(".coveragerc").write_text(MP_COVERAGERC) - script = testdir.makepyfile(''' -import multiprocessing - -def target_fn(): - a = True - return a - -def test_run_target(): - p = multiprocessing.Process(target=target_fn) - p.start() - p.join() -''') - - result = testdir.runpytest('-v', - '--cov', - '--cov-report=term-missing', - script) - - result.stdout.fnmatch_lines([ - '*- coverage: platform *, python * -*', - 'test_multiprocessing_process* 8 * 100%*', - '*1 passed*' - ]) - assert result.ret == 0 - - -@pytest.mark.skipif('sys.platform == "win32"', reason="multiprocessing support is broken on Windows") -def test_multiprocessing_process_with_terminate(pytester, testdir): - pytest.importorskip('multiprocessing.util') - pytester.path.joinpath(".coveragerc").write_text(MP_COVERAGERC) - script = testdir.makepyfile(''' -import multiprocessing -import time -from pytest_cov.embed import cleanup_on_sigterm -cleanup_on_sigterm() - -event = multiprocessing.Event() - -def target_fn(): - a = True - event.set() - time.sleep(5) - -def test_run_target(): - p = multiprocessing.Process(target=target_fn) - p.start() - time.sleep(0.5) - event.wait(1) - p.terminate() - p.join() -''') - - result = testdir.runpytest('-v', - '--cov=%s' % script.dirpath(), - '--cov-report=term-missing', - script) - - result.stdout.fnmatch_lines([ - '*- coverage: platform *, python * -*', - 'test_multiprocessing_process* 16 * 100%*', - '*1 passed*' - ]) - assert result.ret == 0 - - @pytest.mark.skipif('sys.platform == "win32"', reason="SIGTERM isn't really supported on Windows") def test_cleanup_on_sigterm(testdir): script = testdir.makepyfile(''' From a966694e88fdb76626cddfc8648da19d5a081874 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ionel=20Cristian=20M=C4=83rie=C8=99?= Date: Thu, 21 Jul 2022 23:51:29 +0300 Subject: [PATCH 24/42] Fix bad refactor. --- tests/test_pytest_cov.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/tests/test_pytest_cov.py b/tests/test_pytest_cov.py index 1cb68577..5bf7987c 100644 --- a/tests/test_pytest_cov.py +++ b/tests/test_pytest_cov.py @@ -1312,7 +1312,7 @@ def test_cover_conftest(testdir): @pytest.mark.skipif('sys.platform == "win32" and platform.python_implementation() == "PyPy"') -def test_cover_looponfail(pytester, testdir, monkeypatch): +def test_cover_looponfail(testdir, monkeypatch): testdir.makepyfile(mod=MODULE) testdir.makeconftest(CONFTEST) script = testdir.makepyfile(BASIC_TEST) @@ -1320,9 +1320,9 @@ def test_cover_looponfail(pytester, testdir, monkeypatch): def mock_run(*args, **kwargs): return _TestProcess(*map(str, args)) - monkeypatch.setattr(pytester, testdir, 'run', mock_run) + monkeypatch.setattr(testdir, 'run', mock_run) assert testdir.run is mock_run - if hasattr(pytester, testdir, '_pytester'): + if hasattr(testdir, '_pytester'): monkeypatch.setattr(testdir._pytester, 'run', mock_run) assert testdir._pytester.run is mock_run with testdir.runpytest('-v', From 404bc78ba06337735aab20bee4b63773414bf9fe Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ionel=20Cristian=20M=C4=83rie=C8=99?= Date: Thu, 21 Jul 2022 23:57:44 +0300 Subject: [PATCH 25/42] Update changelog and remove last cruft. --- CHANGELOG.rst | 15 ++++++++++++++- tests/test_pytest_cov.py | 7 ------- 2 files changed, 14 insertions(+), 8 deletions(-) diff --git a/CHANGELOG.rst b/CHANGELOG.rst index e559ebb4..6dbf514b 100644 --- a/CHANGELOG.rst +++ b/CHANGELOG.rst @@ -2,12 +2,25 @@ Changelog ========= -3.1.0 (future) +4.0.0 (future) ------------------- +**Note that this release drops support for multiprocessing.** + + * `--cov-fail-under` no longer causes `pytest --collect-only` to fail Contributed by Zac Hatfield-Dodds in `#511 `_. +* Dropped support for multiprocessing (mostly because `issue 82408 `_). This feature was + mostly working but made out test suite very flaky and slow. + + There is builtin multiprocessing support in coverage and you can switch to that if you feel lucky. All you need is this in your + ``.coveragerc``:: + + [run] + concurrency = multiprocessing + parallel = true + sigterm = true 3.0.0 (2021-10-04) diff --git a/tests/test_pytest_cov.py b/tests/test_pytest_cov.py index 5bf7987c..219dd868 100644 --- a/tests/test_pytest_cov.py +++ b/tests/test_pytest_cov.py @@ -1400,13 +1400,6 @@ def test_basic(no_cover): raise NotImplementedError ''' -MP_COVERAGERC = ''' -[run] -concurrency = multiprocessing -parallel = true -sigterm = True -''' - EXCLUDED_TEST = ''' def func(): From 94e3ffabcbbca402d3a77bb5083a031a44c37b1d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ionel=20Cristian=20M=C4=83rie=C8=99?= Date: Fri, 22 Jul 2022 00:08:47 +0300 Subject: [PATCH 26/42] Fix pypy envs. --- .github/workflows/test.yml | 42 +++++++++++++++++++++++++++----------- tox.ini | 2 +- 2 files changed, 31 insertions(+), 13 deletions(-) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 0c182389..42ef1b2b 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -109,23 +109,41 @@ jobs: python_arch: 'x64' tox_env: 'py310-pytest71-xdist250-coverage64' os: 'macos-latest' - - name: 'pypy3-pytest71-xdist250-coverage64 (ubuntu)' - python: 'pypy-3.' - toxpython: 'pypy3.' + - name: 'pypy37-pytest71-xdist250-coverage64 (ubuntu)' + python: 'pypy-3.7' + toxpython: 'pypy3.7' python_arch: 'x64' - tox_env: 'pypy3-pytest71-xdist250-coverage64' + tox_env: 'pypy37-pytest71-xdist250-coverage64' os: 'ubuntu-latest' - - name: 'pypy3-pytest71-xdist250-coverage64 (windows)' - python: 'pypy-3.' - toxpython: 'pypy3.' + - name: 'pypy37-pytest71-xdist250-coverage64 (windows)' + python: 'pypy-3.7' + toxpython: 'pypy3.7' python_arch: 'x64' - tox_env: 'pypy3-pytest71-xdist250-coverage64' + tox_env: 'pypy37-pytest71-xdist250-coverage64' os: 'windows-latest' - - name: 'pypy3-pytest71-xdist250-coverage64 (macos)' - python: 'pypy-3.' - toxpython: 'pypy3.' + - name: 'pypy37-pytest71-xdist250-coverage64 (macos)' + python: 'pypy-3.7' + toxpython: 'pypy3.7' python_arch: 'x64' - tox_env: 'pypy3-pytest71-xdist250-coverage64' + tox_env: 'pypy37-pytest71-xdist250-coverage64' + os: 'macos-latest' + - name: 'pypy38-pytest71-xdist250-coverage64 (ubuntu)' + python: 'pypy-3.8' + toxpython: 'pypy3.8' + python_arch: 'x64' + tox_env: 'pypy38-pytest71-xdist250-coverage64' + os: 'ubuntu-latest' + - name: 'pypy38-pytest71-xdist250-coverage64 (windows)' + python: 'pypy-3.8' + toxpython: 'pypy3.8' + python_arch: 'x64' + tox_env: 'pypy38-pytest71-xdist250-coverage64' + os: 'windows-latest' + - name: 'pypy38-pytest71-xdist250-coverage64 (macos)' + python: 'pypy-3.8' + toxpython: 'pypy3.8' + python_arch: 'x64' + tox_env: 'pypy38-pytest71-xdist250-coverage64' os: 'macos-latest' steps: - uses: actions/checkout@v2 diff --git a/tox.ini b/tox.ini index e283165c..282cd244 100644 --- a/tox.ini +++ b/tox.ini @@ -13,7 +13,7 @@ passenv = envlist = check py{36}-pytest{70}-xdist250-coverage{62} - py{37,38,39,310,py3}-pytest{71}-xdist250-coverage{64} + py{37,38,39,310,py37,py38}-pytest{71}-xdist250-coverage{64} docs [testenv] From 11a369809d69ee8a21d02369ad15293dff94c82f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ionel=20Cristian=20M=C4=83rie=C8=99?= Date: Fri, 22 Jul 2022 00:57:59 +0300 Subject: [PATCH 27/42] Add an xfail. --- tests/test_pytest_cov.py | 1 + 1 file changed, 1 insertion(+) diff --git a/tests/test_pytest_cov.py b/tests/test_pytest_cov.py index 219dd868..22991c9a 100644 --- a/tests/test_pytest_cov.py +++ b/tests/test_pytest_cov.py @@ -1060,6 +1060,7 @@ def test_funcarg_not_active(testdir): @pytest.mark.skipif('sys.platform == "win32"', reason="SIGTERM isn't really supported on Windows") +@pytest.mark.xfail('platform.python_implementation() == "PyPy"', reason="Interpreter seems buggy") def test_cleanup_on_sigterm(testdir): script = testdir.makepyfile(''' import os, signal, subprocess, sys, time From 93554cba8662c1076d8490a1b26738e3edf668e9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ionel=20Cristian=20M=C4=83rie=C8=99?= Date: Fri, 22 Jul 2022 00:58:05 +0300 Subject: [PATCH 28/42] Give proper name to workflow. --- .github/workflows/test.yml | 2 +- ci/templates/.github/workflows/test.yml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 42ef1b2b..3ad0bb49 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -1,4 +1,4 @@ -name: build +name: Tests on: [push, pull_request] jobs: test: diff --git a/ci/templates/.github/workflows/test.yml b/ci/templates/.github/workflows/test.yml index 96d24801..fda6886a 100644 --- a/ci/templates/.github/workflows/test.yml +++ b/ci/templates/.github/workflows/test.yml @@ -1,4 +1,4 @@ -name: build +name: Tests on: [push, pull_request] jobs: test: From 9ef92ffeb4fcb78254c4a42fe7b6dc5ca77522b1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ionel=20Cristian=20M=C4=83rie=C8=99?= Date: Fri, 22 Jul 2022 01:22:34 +0300 Subject: [PATCH 29/42] More xfails. --- tests/test_pytest_cov.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/tests/test_pytest_cov.py b/tests/test_pytest_cov.py index 22991c9a..6500fdec 100644 --- a/tests/test_pytest_cov.py +++ b/tests/test_pytest_cov.py @@ -1152,6 +1152,7 @@ def test_run(): @pytest.mark.skipif('sys.platform == "win32"', reason="SIGTERM isn't really supported on Windows") +@pytest.mark.xfail('sys.platform == "darwin"', reason="Something weird going on Macs...") @pytest.mark.parametrize('setup', [ ('signal.signal(signal.SIGTERM, signal.SIG_DFL); cleanup_on_sigterm()', '88% 18-19'), ('cleanup_on_sigterm()', '88% 18-19'), @@ -1195,6 +1196,7 @@ def test_run(): @pytest.mark.skipif('sys.platform == "win32"', reason="SIGINT is subtly broken on Windows") +@pytest.mark.xfail('sys.platform == "darwin"', reason="Something weird going on Macs...") def test_cleanup_on_sigterm_sig_dfl_sigint(testdir): script = testdir.makepyfile(''' import os, signal, subprocess, sys, time From 5899be3ff6cdab5d3e3af9e2b8180f05ed632b9d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ionel=20Cristian=20M=C4=83rie=C8=99?= Date: Fri, 22 Jul 2022 02:00:54 +0300 Subject: [PATCH 30/42] More xfails. --- tests/test_pytest_cov.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/tests/test_pytest_cov.py b/tests/test_pytest_cov.py index 6500fdec..fd544345 100644 --- a/tests/test_pytest_cov.py +++ b/tests/test_pytest_cov.py @@ -1153,6 +1153,7 @@ def test_run(): @pytest.mark.skipif('sys.platform == "win32"', reason="SIGTERM isn't really supported on Windows") @pytest.mark.xfail('sys.platform == "darwin"', reason="Something weird going on Macs...") +@pytest.mark.xfail('platform.python_implementation() == "PyPy"', reason="Interpreter seems buggy") @pytest.mark.parametrize('setup', [ ('signal.signal(signal.SIGTERM, signal.SIG_DFL); cleanup_on_sigterm()', '88% 18-19'), ('cleanup_on_sigterm()', '88% 18-19'), @@ -1236,6 +1237,7 @@ def test_run(): @pytest.mark.skipif('sys.platform == "win32"', reason="fork not available on Windows") +@pytest.mark.xfail('platform.python_implementation() == "PyPy"', reason="Interpreter seems buggy") def test_cleanup_on_sigterm_sig_ign(testdir): script = testdir.makepyfile(''' import os, signal, subprocess, sys, time From dbb20f6aafba4452c29fb77d88a78875d62502ec Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ionel=20Cristian=20M=C4=83rie=C8=99?= Date: Fri, 22 Jul 2022 08:44:18 +0300 Subject: [PATCH 31/42] Even more xfails. --- tests/test_pytest_cov.py | 1 + 1 file changed, 1 insertion(+) diff --git a/tests/test_pytest_cov.py b/tests/test_pytest_cov.py index fd544345..4402fc7b 100644 --- a/tests/test_pytest_cov.py +++ b/tests/test_pytest_cov.py @@ -1198,6 +1198,7 @@ def test_run(): @pytest.mark.skipif('sys.platform == "win32"', reason="SIGINT is subtly broken on Windows") @pytest.mark.xfail('sys.platform == "darwin"', reason="Something weird going on Macs...") +@pytest.mark.xfail('platform.python_implementation() == "PyPy"', reason="Interpreter seems buggy") def test_cleanup_on_sigterm_sig_dfl_sigint(testdir): script = testdir.makepyfile(''' import os, signal, subprocess, sys, time From 5503d74ac54ab4806cf4b3d9efe4c70922a75162 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ionel=20Cristian=20M=C4=83rie=C8=99?= Date: Fri, 22 Jul 2022 12:48:27 +0300 Subject: [PATCH 32/42] Remove dupe workflow. --- .github/workflows/lint.yml | 41 -------------------------------------- 1 file changed, 41 deletions(-) delete mode 100644 .github/workflows/lint.yml diff --git a/.github/workflows/lint.yml b/.github/workflows/lint.yml deleted file mode 100644 index 001ccfee..00000000 --- a/.github/workflows/lint.yml +++ /dev/null @@ -1,41 +0,0 @@ -name: Lint - -on: [push, pull_request, workflow_dispatch] - -env: - FORCE_COLOR: 1 - -jobs: - lint: - runs-on: ubuntu-latest - strategy: - fail-fast: false - matrix: - toxenv: ["check", "docs"] - - steps: - - uses: actions/checkout@v2 - - - name: Set up Python - uses: actions/setup-python@v2 - with: - python-version: 3.9 - - - name: Cache - uses: actions/cache@v2 - with: - path: ~/.cache/pip - key: - lint-v1-${{ hashFiles('**/tox.ini') }} - restore-keys: | - lint-v1- - - - name: Install dependencies - run: | - python -m pip install -U pip - python -m pip install -U wheel - python -m pip install --progress-bar=off tox -rci/requirements.txt - - - name: Lint ${{ matrix.toxenv }} - run: | - tox -v -e ${{ matrix.toxenv }} From 60b73ec673c60942a3cf052ee8a1fdc442840558 Mon Sep 17 00:00:00 2001 From: Ben Greiner Date: Sun, 17 Jul 2022 22:09:03 +0200 Subject: [PATCH 33/42] migrate build command from distutils to setuptools --- setup.py | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/setup.py b/setup.py index 21681887..421ec6b7 100755 --- a/setup.py +++ b/setup.py @@ -1,7 +1,6 @@ #!/usr/bin/env python import re -from distutils.command.build import build from glob import glob from itertools import chain from os.path import basename @@ -12,6 +11,11 @@ from setuptools import Command from setuptools import find_packages from setuptools import setup +try: + # https://setuptools.pypa.io/en/latest/deprecated/distutils-legacy.html + from setuptools.command.build import build +except ImportError: + from distutils.command.build import build from setuptools.command.develop import develop from setuptools.command.easy_install import easy_install from setuptools.command.install_lib import install_lib From 218419f665229d61356f1eea3ddc8e18aa21f87c Mon Sep 17 00:00:00 2001 From: Delgan <4193924+Delgan@users.noreply.github.com> Date: Sat, 18 Jun 2022 00:04:26 +0200 Subject: [PATCH 34/42] Prevent undesirable new lines to be displayed when report is disabled --- src/pytest_cov/plugin.py | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/pytest_cov/plugin.py b/src/pytest_cov/plugin.py index e915246d..252439ed 100644 --- a/src/pytest_cov/plugin.py +++ b/src/pytest_cov/plugin.py @@ -326,7 +326,11 @@ def pytest_terminal_summary(self, terminalreporter): # we shouldn't report, or report generation failed (error raised above) return - terminalreporter.write('\n' + self.cov_report.getvalue() + '\n') + report = self.cov_report.getvalue() + + # Avoid undesirable new lines when output is disabled with "--cov-report=". + if report: + terminalreporter.write('\n' + report + '\n') if self.options.cov_fail_under is not None and self.options.cov_fail_under > 0: failed = self.cov_total < self.options.cov_fail_under From b3dda36fddd3ca75689bb3645cd320aa8392aaf3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ionel=20Cristian=20M=C4=83rie=C8=99?= Date: Mon, 25 Jul 2022 11:28:10 +0300 Subject: [PATCH 35/42] Improve workflow with a collecting status check. (#548) * Improve workflow with a collecting status check. * Style fix. --- .github/workflows/examples.yml | 49 -------------------- .github/workflows/test.yml | 55 +++++++++++++++++++++- ci/templates/.github/workflows/test.yml | 61 ++++++++++++++++++++++++- setup.py | 2 + 4 files changed, 116 insertions(+), 51 deletions(-) delete mode 100644 .github/workflows/examples.yml diff --git a/.github/workflows/examples.yml b/.github/workflows/examples.yml deleted file mode 100644 index dbd62a6c..00000000 --- a/.github/workflows/examples.yml +++ /dev/null @@ -1,49 +0,0 @@ -name: Examples - -on: [push, pull_request, workflow_dispatch] - -env: - FORCE_COLOR: 1 - -jobs: - examples: - runs-on: ubuntu-latest - strategy: - fail-fast: false - matrix: - python-version: ["pypy-3.7", "3.9"] - target: [ - "src-layout", - "adhoc-layout", - ] - include: - # Add new helper variables to existing jobs - - {python-version: "pypy-3.7", tox-python-version: "pypy3"} - - {python-version: "3.9", tox-python-version: "py39"} - steps: - - uses: actions/checkout@v2 - - - name: Set up Python ${{ matrix.python-version }} - uses: actions/setup-python@v2 - with: - python-version: ${{ matrix.python-version }} - - - name: Cache - uses: actions/cache@v2 - with: - path: ~/.cache/pip - key: - examples-v1-${{ hashFiles('**/tox.ini') }} - restore-keys: | - examples-v1- - - - name: Install dependencies - run: | - python -m pip install -U pip - python -m pip install -U wheel - python -m pip install --progress-bar=off tox -rci/requirements.txt - - - name: Examples - run: | - cd examples/${{ matrix.target }} - tox -v -e ${{ matrix.tox-python-version }} diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 3ad0bb49..a85a1e03 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -1,6 +1,47 @@ name: Tests -on: [push, pull_request] +on: [push, pull_request, workflow_dispatch] jobs: + examples: + runs-on: ubuntu-latest + strategy: + fail-fast: false + matrix: + python-version: ["pypy-3.7", "3.9"] + target: [ + "src-layout", + "adhoc-layout", + ] + include: + # Add new helper variables to existing jobs + - {python-version: "pypy-3.7", tox-python-version: "pypy3"} + - {python-version: "3.9", tox-python-version: "py39"} + steps: + - uses: actions/checkout@v2 + + - name: Set up Python ${{ matrix.python-version }} + uses: actions/setup-python@v2 + with: + python-version: ${{ matrix.python-version }} + + - name: Cache + uses: actions/cache@v2 + with: + path: ~/.cache/pip + key: + examples-v1-${{ hashFiles('**/tox.ini') }} + restore-keys: | + examples-v1- + + - name: Install dependencies + run: | + python -m pip install -U pip + python -m pip install -U wheel + python -m pip install --progress-bar=off tox -rci/requirements.txt + + - name: Examples + run: | + cd examples/${{ matrix.target }} + tox -v -e ${{ matrix.tox-python-version }} test: name: ${{ matrix.name }} runs-on: ${{ matrix.os }} @@ -165,3 +206,15 @@ jobs: TOXPYTHON: '${{ matrix.toxpython }}' run: > tox -e ${{ matrix.tox_env }} -v + + check: + if: always() + needs: + - test + - examples + runs-on: ubuntu-latest + steps: + - name: Decide whether the needed jobs succeeded or failed + uses: re-actors/alls-green@release/v1 + with: + jobs: ${{ toJSON(needs) }} diff --git a/ci/templates/.github/workflows/test.yml b/ci/templates/.github/workflows/test.yml index fda6886a..3e99ef08 100644 --- a/ci/templates/.github/workflows/test.yml +++ b/ci/templates/.github/workflows/test.yml @@ -1,6 +1,50 @@ name: Tests -on: [push, pull_request] +on: [push, pull_request, workflow_dispatch] jobs: +{%- raw %} + examples: + runs-on: ubuntu-latest + strategy: + fail-fast: false + matrix: + python-version: ["pypy-3.7", "3.9"] + target: [ + "src-layout", + "adhoc-layout", + ] + include: + # Add new helper variables to existing jobs + - {python-version: "pypy-3.7", tox-python-version: "pypy3"} + - {python-version: "3.9", tox-python-version: "py39"} + steps: + - uses: actions/checkout@v2 + + - name: Set up Python ${{ matrix.python-version }} + uses: actions/setup-python@v2 + with: + python-version: ${{ matrix.python-version }} + + - name: Cache + uses: actions/cache@v2 + with: + path: ~/.cache/pip + key: + examples-v1-${{ hashFiles('**/tox.ini') }} + restore-keys: | + examples-v1- + + - name: Install dependencies + run: | + python -m pip install -U pip + python -m pip install -U wheel + python -m pip install --progress-bar=off tox -rci/requirements.txt + + - name: Examples + run: | + cd examples/${{ matrix.target }} + tox -v -e ${{ matrix.tox-python-version }} +{%- endraw %} + test: name: {{ '${{ matrix.name }}' }} runs-on: {{ '${{ matrix.os }}' }} @@ -63,3 +107,18 @@ jobs: TOXPYTHON: '{{ '${{ matrix.toxpython }}' }}' run: > tox -e {{ '${{ matrix.tox_env }}' }} -v +{% raw %} + successful: + # this provides a single status check for branch merge rules + # (use this in `Require status checks to pass before merging` in branch settings) + if: always() + needs: + - test + - examples + runs-on: ubuntu-latest + steps: + - name: Decide whether the needed jobs succeeded or failed + uses: re-actors/alls-green@release/v1 + with: + jobs: ${{ toJSON(needs) }} +{% endraw %} diff --git a/setup.py b/setup.py index 421ec6b7..8d20c134 100755 --- a/setup.py +++ b/setup.py @@ -11,11 +11,13 @@ from setuptools import Command from setuptools import find_packages from setuptools import setup + try: # https://setuptools.pypa.io/en/latest/deprecated/distutils-legacy.html from setuptools.command.build import build except ImportError: from distutils.command.build import build + from setuptools.command.develop import develop from setuptools.command.easy_install import easy_install from setuptools.command.install_lib import install_lib From 00713b3fec90cb8c98a9e4bfb3212e574c08e67b Mon Sep 17 00:00:00 2001 From: Andre Brisco Date: Sun, 26 Jun 2022 13:36:58 -0700 Subject: [PATCH 36/42] removed incorrect docs on `data_file`. --- docs/config.rst | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/config.rst b/docs/config.rst index e1e4c3d3..6712292b 100644 --- a/docs/config.rst +++ b/docs/config.rst @@ -23,8 +23,8 @@ For full details refer to the `coverage config file`_ documentation. .. note:: Important Note - This plugin overrides the ``data_file`` and ``parallel`` options of coverage. Unless you also run coverage without - pytest-cov it's pointless to set those options in your ``.coveragerc``. + This plugin overrides the ``parallel`` option of coverage. Unless you also run coverage without pytest-cov it's + pointless to set those options in your ``.coveragerc``. If you use the ``--cov=something`` option (with a value) then coverage's ``source`` option will also get overridden. If you have multiple sources it might be easier to set those in ``.coveragerc`` and always use ``--cov`` (without a value) From b077753f5d9d200815fe500d0ef23e306784e65b Mon Sep 17 00:00:00 2001 From: Bruno Oliveira Date: Sun, 31 Jul 2022 12:52:32 -0300 Subject: [PATCH 37/42] Use modern approach to specify hook options The old way using marks is being deprecated in pytest 7.2: https://github.com/pytest-dev/pytest/pull/9118 --- CHANGELOG.rst | 2 ++ src/pytest_cov/compat.py | 7 ------- src/pytest_cov/plugin.py | 10 +++++----- 3 files changed, 7 insertions(+), 12 deletions(-) diff --git a/CHANGELOG.rst b/CHANGELOG.rst index 6dbf514b..95c9eb9e 100644 --- a/CHANGELOG.rst +++ b/CHANGELOG.rst @@ -22,6 +22,8 @@ Changelog parallel = true sigterm = true +* Use modern way to specify hook options to avoid deprecation warnings with pytest >=7.2. + 3.0.0 (2021-10-04) ------------------- diff --git a/src/pytest_cov/compat.py b/src/pytest_cov/compat.py index f422f25c..614419cb 100644 --- a/src/pytest_cov/compat.py +++ b/src/pytest_cov/compat.py @@ -3,17 +3,10 @@ except ImportError: from io import StringIO -import pytest StringIO # pyflakes, this is for re-export -if hasattr(pytest, 'hookimpl'): - hookwrapper = pytest.hookimpl(hookwrapper=True) -else: - hookwrapper = pytest.mark.hookwrapper - - class SessionWrapper: def __init__(self, session): self._session = session diff --git a/src/pytest_cov/plugin.py b/src/pytest_cov/plugin.py index 252439ed..bf42971e 100644 --- a/src/pytest_cov/plugin.py +++ b/src/pytest_cov/plugin.py @@ -133,7 +133,7 @@ def _prepare_cov_source(cov_source): return None if True in cov_source else [path for path in cov_source if path is not True] -@pytest.mark.tryfirst +@pytest.hookimpl(tryfirst=True) def pytest_load_initial_conftests(early_config, parser, args): options = early_config.known_args_namespace no_cov = options.no_cov_should_warn = False @@ -253,6 +253,7 @@ def pytest_sessionstart(self, session): if self.options.cov_context == 'test': session.config.pluginmanager.register(TestContextPlugin(self.cov_controller.cov), '_cov_contexts') + @pytest.hookimpl(optionalhook=True) def pytest_configure_node(self, node): """Delegate to our implementation. @@ -260,8 +261,8 @@ def pytest_configure_node(self, node): """ if not self._disabled: self.cov_controller.configure_node(node) - pytest_configure_node.optionalhook = True + @pytest.hookimpl(optionalhook=True) def pytest_testnodedown(self, node, error): """Delegate to our implementation. @@ -269,7 +270,6 @@ def pytest_testnodedown(self, node, error): """ if not self._disabled: self.cov_controller.testnodedown(node, error) - pytest_testnodedown.optionalhook = True def _should_report(self): return not (self.failed and self.options.no_cov_on_fail) @@ -280,7 +280,7 @@ def _failed_cov_total(self): # we need to wrap pytest_runtestloop. by the time pytest_sessionfinish # runs, it's too late to set testsfailed - @compat.hookwrapper + @pytest.hookimpl(hookwrapper=True) def pytest_runtestloop(self, session): yield @@ -356,7 +356,7 @@ def pytest_runtest_setup(self, item): def pytest_runtest_teardown(self, item): embed.cleanup() - @compat.hookwrapper + @pytest.hookimpl(hookwrapper=True) def pytest_runtest_call(self, item): if (item.get_closest_marker('no_cover') or 'no_cover' in getattr(item, 'fixturenames', ())): From 1211d3134bb74abb7b00c3c2209091aaab440417 Mon Sep 17 00:00:00 2001 From: Bruno Oliveira Date: Sun, 31 Jul 2022 12:57:39 -0300 Subject: [PATCH 38/42] Fix flake8 error --- tests/test_pytest_cov.py | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/tests/test_pytest_cov.py b/tests/test_pytest_cov.py index 4402fc7b..10d2bd58 100644 --- a/tests/test_pytest_cov.py +++ b/tests/test_pytest_cov.py @@ -1761,8 +1761,11 @@ def bad_init(): monkeypatch.setattr(sys, 'stderr', buff) monkeypatch.setitem(os.environ, 'COV_CORE_SOURCE', 'foobar') exec(payload) - assert buff.getvalue() == '''pytest-cov: Failed to setup subprocess coverage. Environ: {'COV_CORE_SOURCE': 'foobar'} Exception: SpecificError() -''' + expected = ( + "pytest-cov: Failed to setup subprocess coverage. " + "Environ: {'COV_CORE_SOURCE': 'foobar'} Exception: SpecificError()\n" + ) + assert buff.getvalue() == expected def test_double_cov(testdir): From f7fced579e36b72b57e14768026467e4c4511a40 Mon Sep 17 00:00:00 2001 From: Christian Fetzer Date: Fri, 27 May 2022 11:41:46 +0200 Subject: [PATCH 39/42] Add support for LCOV output Coverage.py 6.3 gained support for the LCOV output format. Add support for this to pytest-cov via '--cov-report=lcov[:dest]'. Fix: #535 --- AUTHORS.rst | 1 + CHANGELOG.rst | 3 +++ docs/config.rst | 4 ++-- docs/reporting.rst | 8 +++++--- src/pytest_cov/engine.py | 12 ++++++++++++ src/pytest_cov/plugin.py | 9 ++++++--- tests/test_pytest_cov.py | 41 ++++++++++++++++++++++++++++++++++++---- 7 files changed, 66 insertions(+), 12 deletions(-) diff --git a/AUTHORS.rst b/AUTHORS.rst index 489903c2..d8271272 100644 --- a/AUTHORS.rst +++ b/AUTHORS.rst @@ -51,3 +51,4 @@ Authors * Danilo Šegan - https://github.com/dsegan * Michał Bielawski - https://github.com/D3X * Zac Hatfield-Dodds - https://github.com/Zac-HD +* Christian Fetzer - https://github.com/fetzerch diff --git a/CHANGELOG.rst b/CHANGELOG.rst index 95c9eb9e..1c1b524e 100644 --- a/CHANGELOG.rst +++ b/CHANGELOG.rst @@ -21,6 +21,9 @@ Changelog concurrency = multiprocessing parallel = true sigterm = true +* Added support for LCOV output format via `--cov-report=lcov`. Only works with coverage 6.3+. + Contributed by Christian Fetzer in + `#536 `_. * Use modern way to specify hook options to avoid deprecation warnings with pytest >=7.2. diff --git a/docs/config.rst b/docs/config.rst index 6712292b..fa257037 100644 --- a/docs/config.rst +++ b/docs/config.rst @@ -56,9 +56,9 @@ The complete list of command line options is: --cov=PATH Measure coverage for filesystem path. (multi-allowed) --cov-report=type Type of report to generate: term, term-missing, - annotate, html, xml (multi-allowed). term, term- + annotate, html, xml, lcov (multi-allowed). term, term- missing may be followed by ":skip-covered". annotate, - html and xml may be followed by ":DEST" where DEST + html, xml and lcov may be followed by ":DEST" where DEST specifies the output location. Use --cov-report= to not generate any output. --cov-config=path Config file for coverage. Default: .coveragerc diff --git a/docs/reporting.rst b/docs/reporting.rst index eaa99ad3..69191d48 100644 --- a/docs/reporting.rst +++ b/docs/reporting.rst @@ -3,7 +3,7 @@ Reporting It is possible to generate any combination of the reports for a single test run. -The available reports are terminal (with or without missing line numbers shown), HTML, XML and +The available reports are terminal (with or without missing line numbers shown), HTML, XML, LCOV and annotated source code. The terminal report without line numbers (default):: @@ -49,19 +49,21 @@ The terminal report with skip covered:: You can use ``skip-covered`` with ``term-missing`` as well. e.g. ``--cov-report term-missing:skip-covered`` -These three report options output to files without showing anything on the terminal:: +These four report options output to files without showing anything on the terminal:: pytest --cov-report html --cov-report xml + --cov-report lcov --cov-report annotate --cov=myproj tests/ -The output location for each of these reports can be specified. The output location for the XML +The output location for each of these reports can be specified. The output location for the XML and LCOV report is a file. Where as the output location for the HTML and annotated source code reports are directories:: pytest --cov-report html:cov_html --cov-report xml:cov.xml + --cov-report lcov:cov.info --cov-report annotate:cov_annotate --cov=myproj tests/ diff --git a/src/pytest_cov/engine.py b/src/pytest_cov/engine.py index 0303c2f1..bfede8c7 100644 --- a/src/pytest_cov/engine.py +++ b/src/pytest_cov/engine.py @@ -196,6 +196,18 @@ def summary(self, stream): total = self.cov.xml_report(ignore_errors=True, outfile=output) stream.write('Coverage XML written to file %s\n' % (self.cov.config.xml_output if output is None else output)) + # Produce lcov report if wanted. + if 'lcov' in self.cov_report: + output = self.cov_report['lcov'] + with _backup(self.cov, "config"): + self.cov.lcov_report(ignore_errors=True, outfile=output) + + # We need to call Coverage.report here, just to get the total + # Coverage.lcov_report doesn't return any total and we need it for --cov-fail-under. + total = self.cov.report(ignore_errors=True, file=_NullFile) + + stream.write('Coverage LCOV written to file %s\n' % (self.cov.config.lcov_output if output is None else output)) + return total diff --git a/src/pytest_cov/plugin.py b/src/pytest_cov/plugin.py index bf42971e..dd7b8c4e 100644 --- a/src/pytest_cov/plugin.py +++ b/src/pytest_cov/plugin.py @@ -29,7 +29,7 @@ class CovReportWarning(PytestCovWarning): def validate_report(arg): - file_choices = ['annotate', 'html', 'xml'] + file_choices = ['annotate', 'html', 'xml', 'lcov'] term_choices = ['term', 'term-missing'] term_modifier_choices = ['skip-covered'] all_choices = term_choices + file_choices @@ -39,6 +39,9 @@ def validate_report(arg): msg = f'invalid choice: "{arg}" (choose from "{all_choices}")' raise argparse.ArgumentTypeError(msg) + if report_type == 'lcov' and coverage.version_info <= (6, 3): + raise argparse.ArgumentTypeError('LCOV output is only supported with coverage.py >= 6.3') + if len(values) == 1: return report_type, None @@ -96,9 +99,9 @@ def pytest_addoption(parser): group.addoption('--cov-report', action=StoreReport, default={}, metavar='TYPE', type=validate_report, help='Type of report to generate: term, term-missing, ' - 'annotate, html, xml (multi-allowed). ' + 'annotate, html, xml, lcov (multi-allowed). ' 'term, term-missing may be followed by ":skip-covered". ' - 'annotate, html and xml may be followed by ":DEST" ' + 'annotate, html, xml and lcov may be followed by ":DEST" ' 'where DEST specifies the output location. ' 'Use --cov-report= to not generate any output.') group.addoption('--cov-config', action='store', default='.coveragerc', diff --git a/tests/test_pytest_cov.py b/tests/test_pytest_cov.py index 10d2bd58..84fe42ba 100644 --- a/tests/test_pytest_cov.py +++ b/tests/test_pytest_cov.py @@ -150,7 +150,8 @@ def test_foo(cov): CHILD_SCRIPT_RESULT = '[56] * 100%' PARENT_SCRIPT_RESULT = '9 * 100%' DEST_DIR = 'cov_dest' -REPORT_NAME = 'cov.xml' +XML_REPORT_NAME = 'cov.xml' +LCOV_REPORT_NAME = 'cov.info' xdist_params = pytest.mark.parametrize('opts', [ '', @@ -333,18 +334,50 @@ def test_xml_output_dir(testdir): result = testdir.runpytest('-v', '--cov=%s' % script.dirpath(), - '--cov-report=xml:' + REPORT_NAME, + '--cov-report=xml:' + XML_REPORT_NAME, script) result.stdout.fnmatch_lines([ '*- coverage: platform *, python * -*', - 'Coverage XML written to file ' + REPORT_NAME, + 'Coverage XML written to file ' + XML_REPORT_NAME, '*10 passed*', ]) - assert testdir.tmpdir.join(REPORT_NAME).check() + assert testdir.tmpdir.join(XML_REPORT_NAME).check() assert result.ret == 0 +@pytest.mark.skipif("coverage.version_info < (6, 3)") +def test_lcov_output_dir(testdir): + script = testdir.makepyfile(SCRIPT) + + result = testdir.runpytest('-v', + '--cov=%s' % script.dirpath(), + '--cov-report=lcov:' + LCOV_REPORT_NAME, + script) + + result.stdout.fnmatch_lines([ + '*- coverage: platform *, python * -*', + 'Coverage LCOV written to file ' + LCOV_REPORT_NAME, + '*10 passed*', + ]) + assert testdir.tmpdir.join(LCOV_REPORT_NAME).check() + assert result.ret == 0 + + +@pytest.mark.skipif("coverage.version_info >= (6, 3)") +def test_lcov_not_supported(testdir): + script = testdir.makepyfile("a = 1") + result = testdir.runpytest('-v', + '--cov=%s' % script.dirpath(), + '--cov-report=lcov', + script, + ) + result.stderr.fnmatch_lines([ + '*argument --cov-report: LCOV output is only supported with coverage.py >= 6.3', + ]) + assert result.ret != 0 + + def test_term_output_dir(testdir): script = testdir.makepyfile(SCRIPT) From 56b810b91c9ae15d1462633c6a8a1b522ebf8e65 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ionel=20Cristian=20M=C4=83rie=C8=99?= Date: Wed, 28 Sep 2022 18:04:11 +0300 Subject: [PATCH 40/42] Update chagelog. --- AUTHORS.rst | 1 + CHANGELOG.rst | 6 +++--- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/AUTHORS.rst b/AUTHORS.rst index d8271272..ae14600e 100644 --- a/AUTHORS.rst +++ b/AUTHORS.rst @@ -51,4 +51,5 @@ Authors * Danilo Šegan - https://github.com/dsegan * Michał Bielawski - https://github.com/D3X * Zac Hatfield-Dodds - https://github.com/Zac-HD +* Ronny Pfannschmidt - https://github.com/RonnyPfannschmidt * Christian Fetzer - https://github.com/fetzerch diff --git a/CHANGELOG.rst b/CHANGELOG.rst index 1c1b524e..479112ba 100644 --- a/CHANGELOG.rst +++ b/CHANGELOG.rst @@ -2,8 +2,8 @@ Changelog ========= -4.0.0 (future) -------------------- +4.0.0 (2022-09-28) +------------------ **Note that this release drops support for multiprocessing.** @@ -24,8 +24,8 @@ Changelog * Added support for LCOV output format via `--cov-report=lcov`. Only works with coverage 6.3+. Contributed by Christian Fetzer in `#536 `_. - * Use modern way to specify hook options to avoid deprecation warnings with pytest >=7.2. + Contributed by Ronny Pfannschmidt in `#550 `_. 3.0.0 (2021-10-04) From 57e9354a86f658556fe6f15f07625c4b9a9ddf53 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ionel=20Cristian=20M=C4=83rie=C8=99?= Date: Wed, 28 Sep 2022 18:19:04 +0300 Subject: [PATCH 41/42] Really update the changelog. --- AUTHORS.rst | 4 ++++ CHANGELOG.rst | 22 ++++++++++++++-------- 2 files changed, 18 insertions(+), 8 deletions(-) diff --git a/AUTHORS.rst b/AUTHORS.rst index ae14600e..2ad80a00 100644 --- a/AUTHORS.rst +++ b/AUTHORS.rst @@ -51,5 +51,9 @@ Authors * Danilo Šegan - https://github.com/dsegan * Michał Bielawski - https://github.com/D3X * Zac Hatfield-Dodds - https://github.com/Zac-HD +* Ben Greiner - https://github.com/bnavigator +* Delgan - https://github.com/Delgan +* Andre Brisco - https://github.com/abrisco +* Colin O'Dell - https://github.com/colinodell * Ronny Pfannschmidt - https://github.com/RonnyPfannschmidt * Christian Fetzer - https://github.com/fetzerch diff --git a/CHANGELOG.rst b/CHANGELOG.rst index 479112ba..c49683f5 100644 --- a/CHANGELOG.rst +++ b/CHANGELOG.rst @@ -9,23 +9,29 @@ Changelog * `--cov-fail-under` no longer causes `pytest --collect-only` to fail - Contributed by Zac Hatfield-Dodds in - `#511 `_. + Contributed by Zac Hatfield-Dodds in `#511 `_. * Dropped support for multiprocessing (mostly because `issue 82408 `_). This feature was - mostly working but made out test suite very flaky and slow. + mostly working but very broken in certain scenarios and made the test suite very flaky and slow. - There is builtin multiprocessing support in coverage and you can switch to that if you feel lucky. All you need is this in your + There is builtin multiprocessing support in coverage and you can migrate to that. All you need is this in your ``.coveragerc``:: [run] concurrency = multiprocessing parallel = true sigterm = true +* Fixed deprecation in ``setup.py`` by trying to import setuptools before distutils. + Contributed by Ben Greiner in `#545 `_. +* Removed undesirable new lines that were displayed while reporting was disabled. + Contributed by Delgan in `#540 `_. +* Documentation fixes. + Contributed by Andre Brisco in `#543 `_ + and Colin O'Dell in `#525 `_. * Added support for LCOV output format via `--cov-report=lcov`. Only works with coverage 6.3+. - Contributed by Christian Fetzer in - `#536 `_. -* Use modern way to specify hook options to avoid deprecation warnings with pytest >=7.2. - Contributed by Ronny Pfannschmidt in `#550 `_. + Contributed by Christian Fetzer in `#536 `_. +* Modernized pytest hook implementation. + Contributed by Bruno Oliveira in `#549 `_ + and Ronny Pfannschmidt in `#550 `_. 3.0.0 (2021-10-04) From 28db055bebbf3ee016a2144c8b69dd7b80b48cc5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ionel=20Cristian=20M=C4=83rie=C8=99?= Date: Wed, 28 Sep 2022 18:20:20 +0300 Subject: [PATCH 42/42] =?UTF-8?q?Bump=20version:=203.0.0=20=E2=86=92=204.0?= =?UTF-8?q?.0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .bumpversion.cfg | 2 +- README.rst | 4 ++-- docs/conf.py | 2 +- setup.py | 2 +- src/pytest_cov/__init__.py | 2 +- 5 files changed, 6 insertions(+), 6 deletions(-) diff --git a/.bumpversion.cfg b/.bumpversion.cfg index 27a843fb..09bfcde0 100644 --- a/.bumpversion.cfg +++ b/.bumpversion.cfg @@ -1,5 +1,5 @@ [bumpversion] -current_version = 3.0.0 +current_version = 4.0.0 commit = True tag = True diff --git a/README.rst b/README.rst index 2137c118..84a85786 100644 --- a/README.rst +++ b/README.rst @@ -39,9 +39,9 @@ Overview .. |conda-forge| image:: https://img.shields.io/conda/vn/conda-forge/pytest-cov.svg :target: https://anaconda.org/conda-forge/pytest-cov -.. |commits-since| image:: https://img.shields.io/github/commits-since/pytest-dev/pytest-cov/v3.0.0.svg +.. |commits-since| image:: https://img.shields.io/github/commits-since/pytest-dev/pytest-cov/v4.0.0.svg :alt: Commits since latest release - :target: https://github.com/pytest-dev/pytest-cov/compare/v3.0.0...master + :target: https://github.com/pytest-dev/pytest-cov/compare/v4.0.0...master .. |wheel| image:: https://img.shields.io/pypi/wheel/pytest-cov.svg :alt: PyPI Wheel diff --git a/docs/conf.py b/docs/conf.py index 5dd4e74b..d417ed00 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -23,7 +23,7 @@ year = '2016' author = 'pytest-cov contributors' copyright = f'{year}, {author}' -version = release = '3.0.0' +version = release = '4.0.0' pygments_style = 'trac' templates_path = ['.'] diff --git a/setup.py b/setup.py index 8d20c134..799d4699 100755 --- a/setup.py +++ b/setup.py @@ -87,7 +87,7 @@ def run(self): setup( name='pytest-cov', - version='3.0.0', + version='4.0.0', license='MIT', description='Pytest plugin for measuring coverage.', long_description='{}\n{}'.format(read('README.rst'), re.sub(':[a-z]+:`~?(.*?)`', r'``\1``', read('CHANGELOG.rst'))), diff --git a/src/pytest_cov/__init__.py b/src/pytest_cov/__init__.py index fba1d219..9dfd9823 100644 --- a/src/pytest_cov/__init__.py +++ b/src/pytest_cov/__init__.py @@ -1,2 +1,2 @@ """pytest-cov: avoid already-imported warning: PYTEST_DONT_REWRITE.""" -__version__ = '3.0.0' +__version__ = '4.0.0'