From 5ab02e686a30afa5ac7c9d28829fddb9137f5e64 Mon Sep 17 00:00:00 2001 From: Thomas Grainger Date: Fri, 13 Aug 2021 13:40:17 +0100 Subject: [PATCH 1/9] Update .pre-commit-config.yaml --- .pre-commit-config.yaml | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 67d55a68..98314202 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -18,3 +18,7 @@ repos: rev: 3.9.2 hooks: - id: flake8 + - repo: https://github.com/asottile/pyupgrade + rev: v2.23.3 + hooks: + - id: pyupgrade From 4a06aba59b50f3bdbe5e1fe3b23d3cab787c6823 Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Fri, 13 Aug 2021 22:53:07 +0000 Subject: [PATCH 2/9] [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci --- ci/bootstrap.py | 8 ++++---- docs/conf.py | 2 +- examples/adhoc-layout/example/__init__.py | 1 - examples/src-layout/src/example/__init__.py | 1 - setup.py | 2 +- src/pytest_cov/engine.py | 4 ++-- tests/test_pytest_cov.py | 6 +++--- 7 files changed, 11 insertions(+), 13 deletions(-) diff --git a/ci/bootstrap.py b/ci/bootstrap.py index 61747a15..6e9e75f2 100755 --- a/ci/bootstrap.py +++ b/ci/bootstrap.py @@ -30,7 +30,7 @@ def exec_in_env(): if not exists(env_path): import subprocess - print("Making bootstrap env in: {0} ...".format(env_path)) + print("Making bootstrap env in: {} ...".format(env_path)) try: check_call([sys.executable, "-m", "venv", env_path]) except subprocess.CalledProcessError: @@ -44,7 +44,7 @@ def exec_in_env(): if not os.path.exists(python_executable): python_executable += '.exe' - print("Re-executing with: {0}".format(python_executable)) + print("Re-executing with: {}".format(python_executable)) print("+ exec", python_executable, __file__, "--no-env") os.execv(python_executable, [python_executable, __file__, "--no-env"]) @@ -52,7 +52,7 @@ def exec_in_env(): def main(): import jinja2 - print("Project path: {0}".format(base_path)) + print("Project path: {}".format(base_path)) jinja = jinja2.Environment( loader=jinja2.FileSystemLoader(join(base_path, "ci", "templates")), @@ -89,5 +89,5 @@ def main(): elif not args: exec_in_env() else: - print("Unexpected arguments {0}".format(args), file=sys.stderr) + print("Unexpected arguments {}".format(args), file=sys.stderr) sys.exit(1) diff --git a/docs/conf.py b/docs/conf.py index 0668fdc2..d3c31081 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -47,7 +47,7 @@ html_sidebars = { '**': ['searchbox.html', 'globaltoc.html', 'sourcelink.html'], } -html_short_title = '%s-%s' % (project, version) +html_short_title = '{}-{}'.format(project, version) napoleon_use_ivar = True napoleon_use_rtype = False diff --git a/examples/adhoc-layout/example/__init__.py b/examples/adhoc-layout/example/__init__.py index 18080ac5..8a6dfd5e 100644 --- a/examples/adhoc-layout/example/__init__.py +++ b/examples/adhoc-layout/example/__init__.py @@ -1,4 +1,3 @@ - import sys PY2 = sys.version_info[0] == 2 diff --git a/examples/src-layout/src/example/__init__.py b/examples/src-layout/src/example/__init__.py index 18080ac5..8a6dfd5e 100644 --- a/examples/src-layout/src/example/__init__.py +++ b/examples/src-layout/src/example/__init__.py @@ -1,4 +1,3 @@ - import sys PY2 = sys.version_info[0] == 2 diff --git a/setup.py b/setup.py index 8cb1162b..631573ea 100755 --- a/setup.py +++ b/setup.py @@ -88,7 +88,7 @@ def run(self): version='2.12.1', license='MIT', description='Pytest plugin for measuring coverage.', - long_description='%s\n%s' % (read('README.rst'), re.sub(':[a-z]+:`~?(.*?)`', r'``\1``', read('CHANGELOG.rst'))), + long_description='{}\n{}'.format(read('README.rst'), re.sub(':[a-z]+:`~?(.*?)`', r'``\1``', read('CHANGELOG.rst'))), author='Marc Schlaich', author_email='marc.schlaich@gmail.com', url='https://github.com/pytest-dev/pytest-cov', diff --git a/src/pytest_cov/engine.py b/src/pytest_cov/engine.py index 084e92ea..ccdc99f1 100644 --- a/src/pytest_cov/engine.py +++ b/src/pytest_cov/engine.py @@ -116,7 +116,7 @@ def unset_env(): def get_node_desc(platform, version_info): """Return a description of this node.""" - return 'platform %s, python %s' % (platform, '%s.%s.%s-%s-%s' % version_info[:5]) + return 'platform {}, python {}'.format(platform, '%s.%s.%s-%s-%s' % version_info[:5]) @staticmethod def sep(stream, s, txt): @@ -126,7 +126,7 @@ def sep(stream, s, txt): sep_total = max((70 - 2 - len(txt)), 2) sep_len = sep_total // 2 sep_extra = sep_total % 2 - out = '%s %s %s\n' % (s * sep_len, txt, s * (sep_len + sep_extra)) + out = '{} {} {}\n'.format(s * sep_len, txt, s * (sep_len + sep_extra)) stream.write(out) @_ensure_topdir diff --git a/tests/test_pytest_cov.py b/tests/test_pytest_cov.py index 0d1b5a23..b4b9f534 100644 --- a/tests/test_pytest_cov.py +++ b/tests/test_pytest_cov.py @@ -780,13 +780,13 @@ def test_dist_not_collocated_coveragerc_source(testdir, prop): dir2 = testdir.mkdir('dir2') testdir.tmpdir.join('.coveragerc').write(''' [run] -%s -source = %s +{} +source = {} [paths] source = . dir1 - dir2''' % (prop.conf, script.dirpath())) + dir2'''.format(prop.conf, script.dirpath())) result = testdir.runpytest('-v', '--cov', From 3f9576caa68416a32e1b1458aa6a7e1f5b758663 Mon Sep 17 00:00:00 2001 From: Thomas Grainger Date: Fri, 13 Aug 2021 23:55:42 +0100 Subject: [PATCH 3/9] remove py2 compatibility syntax --- .pre-commit-config.yaml | 1 + 1 file changed, 1 insertion(+) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 98314202..e07f891b 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -22,3 +22,4 @@ repos: rev: v2.23.3 hooks: - id: pyupgrade + args: [--py36-plus] From b3a41c38f9bb5678a7c0ff8939f781ddaa8c8b5d Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Fri, 13 Aug 2021 22:55:49 +0000 Subject: [PATCH 4/9] [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci --- ci/bootstrap.py | 14 +++++--------- docs/conf.py | 7 ++----- setup.py | 5 +---- src/pytest_cov/compat.py | 2 +- src/pytest_cov/engine.py | 6 +++--- src/pytest_cov/plugin.py | 10 +++++----- tests/test_pytest_cov.py | 4 ++-- 7 files changed, 19 insertions(+), 29 deletions(-) diff --git a/ci/bootstrap.py b/ci/bootstrap.py index 6e9e75f2..77daad5b 100755 --- a/ci/bootstrap.py +++ b/ci/bootstrap.py @@ -1,8 +1,4 @@ #!/usr/bin/env python -# -*- coding: utf-8 -*- -from __future__ import absolute_import -from __future__ import print_function -from __future__ import unicode_literals import os import subprocess @@ -30,7 +26,7 @@ def exec_in_env(): if not exists(env_path): import subprocess - print("Making bootstrap env in: {} ...".format(env_path)) + print(f"Making bootstrap env in: {env_path} ...") try: check_call([sys.executable, "-m", "venv", env_path]) except subprocess.CalledProcessError: @@ -44,7 +40,7 @@ def exec_in_env(): if not os.path.exists(python_executable): python_executable += '.exe' - print("Re-executing with: {}".format(python_executable)) + print(f"Re-executing with: {python_executable}") print("+ exec", python_executable, __file__, "--no-env") os.execv(python_executable, [python_executable, __file__, "--no-env"]) @@ -52,7 +48,7 @@ def exec_in_env(): def main(): import jinja2 - print("Project path: {}".format(base_path)) + print(f"Project path: {base_path}") jinja = jinja2.Environment( loader=jinja2.FileSystemLoader(join(base_path, "ci", "templates")), @@ -78,7 +74,7 @@ def main(): 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("Wrote {}".format(name)) + print(f"Wrote {name}") print("DONE.") @@ -89,5 +85,5 @@ def main(): elif not args: exec_in_env() else: - print("Unexpected arguments {}".format(args), file=sys.stderr) + print(f"Unexpected arguments {args}", file=sys.stderr) sys.exit(1) diff --git a/docs/conf.py b/docs/conf.py index d3c31081..45da656c 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -1,6 +1,3 @@ -# -*- coding: utf-8 -*- -from __future__ import unicode_literals - import os import sphinx_py3doc_enhanced_theme @@ -25,7 +22,7 @@ project = 'pytest-cov' year = '2016' author = 'pytest-cov contributors' -copyright = '{}, {}'.format(year, author) +copyright = f'{year}, {author}' version = release = '2.12.1' pygments_style = 'trac' @@ -47,7 +44,7 @@ html_sidebars = { '**': ['searchbox.html', 'globaltoc.html', 'sourcelink.html'], } -html_short_title = '{}-{}'.format(project, version) +html_short_title = f'{project}-{version}' napoleon_use_ivar = True napoleon_use_rtype = False diff --git a/setup.py b/setup.py index 631573ea..0497db1d 100755 --- a/setup.py +++ b/setup.py @@ -1,7 +1,4 @@ #!/usr/bin/env python -# -*- encoding: utf-8 -*- -from __future__ import absolute_import -from __future__ import print_function import io import re @@ -22,7 +19,7 @@ def read(*names, **kwargs): - with io.open( + with open( join(dirname(__file__), *names), encoding=kwargs.get('encoding', 'utf8') ) as fh: diff --git a/src/pytest_cov/compat.py b/src/pytest_cov/compat.py index 5b4a0bfb..f422f25c 100644 --- a/src/pytest_cov/compat.py +++ b/src/pytest_cov/compat.py @@ -14,7 +14,7 @@ hookwrapper = pytest.mark.hookwrapper -class SessionWrapper(object): +class SessionWrapper: def __init__(self, session): self._session = session if hasattr(session, 'testsfailed'): diff --git a/src/pytest_cov/engine.py b/src/pytest_cov/engine.py index ccdc99f1..0303c2f1 100644 --- a/src/pytest_cov/engine.py +++ b/src/pytest_cov/engine.py @@ -14,7 +14,7 @@ from .embed import cleanup -class _NullFile(object): +class _NullFile: @staticmethod def write(v): pass @@ -49,7 +49,7 @@ def ensure_topdir_wrapper(self, *args, **kwargs): return ensure_topdir_wrapper -class CovController(object): +class CovController: """Base class for different plugin implementations.""" def __init__(self, cov_source, cov_report, cov_config, cov_append, cov_branch, config=None, nodeid=None): @@ -126,7 +126,7 @@ def sep(stream, s, txt): sep_total = max((70 - 2 - len(txt)), 2) sep_len = sep_total // 2 sep_extra = sep_total % 2 - out = '{} {} {}\n'.format(s * sep_len, txt, s * (sep_len + sep_extra)) + out = f'{s * sep_len} {txt} {s * (sep_len + sep_extra)}\n' stream.write(out) @_ensure_topdir diff --git a/src/pytest_cov/plugin.py b/src/pytest_cov/plugin.py index f5a00953..e214627c 100644 --- a/src/pytest_cov/plugin.py +++ b/src/pytest_cov/plugin.py @@ -36,7 +36,7 @@ def validate_report(arg): values = arg.split(":", 1) report_type = values[0] if report_type not in all_choices + ['']: - msg = 'invalid choice: "{}" (choose from "{}")'.format(arg, all_choices) + msg = f'invalid choice: "{arg}" (choose from "{all_choices}")' raise argparse.ArgumentTypeError(msg) if len(values) == 1: @@ -141,7 +141,7 @@ def pytest_load_initial_conftests(early_config, parser, args): early_config.pluginmanager.register(plugin, '_cov') -class CovPlugin(object): +class CovPlugin: """Use coverage package to produce code coverage reports. Delegates all work to a particular implementation based on whether @@ -196,7 +196,7 @@ def start(self, controller_cls, config=None, nodeid=None): if config is None: # fake config option for engine - class Config(object): + class Config: option = self.options config = Config() @@ -354,7 +354,7 @@ def pytest_runtest_call(self, item): yield -class TestContextPlugin(object): +class TestContextPlugin: def __init__(self, cov): self.cov = cov @@ -368,7 +368,7 @@ def pytest_runtest_call(self, item): self.switch_context(item, 'run') def switch_context(self, item, when): - context = "{item.nodeid}|{when}".format(item=item, when=when) + context = f"{item.nodeid}|{when}" self.cov.switch_context(context) os.environ['COV_CORE_CONTEXT'] = context diff --git a/tests/test_pytest_cov.py b/tests/test_pytest_cov.py index b4b9f534..670bfcdd 100644 --- a/tests/test_pytest_cov.py +++ b/tests/test_pytest_cov.py @@ -1964,7 +1964,7 @@ def bad_init(): monkeypatch.setattr(embed, 'init', bad_init) monkeypatch.setattr(sys, 'stderr', buff) monkeypatch.setitem(os.environ, 'COV_CORE_SOURCE', 'foobar') - exec_(payload) + exec(payload) assert buff.getvalue() == '''pytest-cov: Failed to setup subprocess coverage. Environ: {'COV_CORE_SOURCE': 'foobar'} Exception: SpecificError() ''' @@ -2087,7 +2087,7 @@ def test_contexts(testdir, opts): continue data.set_query_context(context) actual = set(data.lines(test_context_path)) - assert line_data[label] == actual, "Wrong lines for context {!r}".format(context) + assert line_data[label] == actual, f"Wrong lines for context {context!r}" @pytest.mark.skipif("coverage.version_info >= (5, 0)") From ce732093f16ca43e0fb8d7075e666bf0960146df Mon Sep 17 00:00:00 2001 From: Thomas Grainger Date: Fri, 13 Aug 2021 23:57:38 +0100 Subject: [PATCH 5/9] remove unused io import from setup.py --- setup.py | 1 - 1 file changed, 1 deletion(-) diff --git a/setup.py b/setup.py index 0497db1d..9508c16a 100755 --- a/setup.py +++ b/setup.py @@ -1,6 +1,5 @@ #!/usr/bin/env python -import io import re from distutils.command.build import build from glob import glob From fadb280413fc1a73ad83443a692f6aae086c1696 Mon Sep 17 00:00:00 2001 From: Thomas Grainger Date: Fri, 13 Aug 2021 23:59:28 +0100 Subject: [PATCH 6/9] remove unused six import --- tests/test_pytest_cov.py | 1 - 1 file changed, 1 deletion(-) diff --git a/tests/test_pytest_cov.py b/tests/test_pytest_cov.py index 670bfcdd..233058fd 100644 --- a/tests/test_pytest_cov.py +++ b/tests/test_pytest_cov.py @@ -16,7 +16,6 @@ from process_tests import TestProcess as _TestProcess from process_tests import dump_on_error from process_tests import wait_for_strings -from six import exec_ import pytest_cov.plugin From f17d8c524125497a5359842788ad9946a292f4ab Mon Sep 17 00:00:00 2001 From: Thomas Grainger Date: Wed, 18 Aug 2021 08:26:03 +0100 Subject: [PATCH 7/9] only exclude directories that need exluding --- .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 e07f891b..dc36fa2b 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -2,13 +2,13 @@ # pre-commit install # To update the pre-commit hooks run: # pre-commit install-hooks -exclude: '^(src/.*\.pth|\.tox|ci/templates|\.bumpversion\.cfg)(/|$)' repos: - repo: https://github.com/pre-commit/pre-commit-hooks rev: v4.0.1 hooks: - id: trailing-whitespace - id: end-of-file-fixer + exclude: '.*\.pth$' - id: debug-statements - repo: https://github.com/PyCQA/isort rev: 5.9.3 From c9f11ed7278ca2dc0a68df2010203ad363408e69 Mon Sep 17 00:00:00 2001 From: Thomas Grainger Date: Wed, 18 Aug 2021 08:27:44 +0100 Subject: [PATCH 8/9] remove unusupported python versions from ci/tox --- .appveyor.yml | 8 -------- tox.ini | 2 +- 2 files changed, 1 insertion(+), 9 deletions(-) diff --git a/.appveyor.yml b/.appveyor.yml index a0ffc795..9f176ee5 100644 --- a/.appveyor.yml +++ b/.appveyor.yml @@ -7,18 +7,13 @@ image: environment: matrix: - TOXENV: check - - TOXENV: 'py27-pytest46-xdist127-coverage55' - - TOXENV: 'py35-pytest46-xdist127-coverage55' - 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: 'pypy-pytest46-xdist127-coverage55' - TOXENV: 'pypy3-pytest46-xdist127-coverage55,pypy3-pytest46-xdist133-coverage55,pypy3-pytest54-xdist133-coverage55,pypy3-pytest62-xdist202-coverage55' matrix: exclude: - - image: Visual Studio 2019 - TOXENV: 'py27-pytest46-xdist127-coverage55' - 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 @@ -27,15 +22,12 @@ matrix: 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: 'pypy-pytest46-xdist127-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,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 diff --git a/tox.ini b/tox.ini index 6be986e9..490a5201 100644 --- a/tox.ini +++ b/tox.ini @@ -13,7 +13,7 @@ passenv = [tox] envlist = check - py{27,35,36,37,py,py3}-pytest46-xdist127-coverage{55} + 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,py3}-pytest{62}-xdist202-coverage{55} docs From 555fdcecc0da3d561b10a49a4b9333e4f8ec16b8 Mon Sep 17 00:00:00 2001 From: Thomas Grainger Date: Wed, 18 Aug 2021 12:57:16 +0100 Subject: [PATCH 9/9] update python_requires and trove classifiers --- setup.py | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/setup.py b/setup.py index 9508c16a..fa3e1a42 100755 --- a/setup.py +++ b/setup.py @@ -103,10 +103,8 @@ def run(self): 'Operating System :: POSIX', 'Operating System :: Unix', 'Programming Language :: Python', - 'Programming Language :: Python :: 2', - 'Programming Language :: Python :: 2.7', 'Programming Language :: Python :: 3', - 'Programming Language :: Python :: 3.5', + 'Programming Language :: Python :: 3 :: Only', 'Programming Language :: Python :: 3.6', 'Programming Language :: Python :: 3.7', 'Programming Language :: Python :: 3.8', @@ -122,7 +120,7 @@ def run(self): 'pytest>=4.6', 'coverage[toml]>=5.2.1' ], - python_requires='>=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*', + python_requires='>=3.6', extras_require={ 'testing': [ 'fields',