diff --git a/.travis.yml b/.travis.yml
index d529d9a8..19c7b825 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -17,15 +17,6 @@ jobs:
directories:
- $HOME/.cache/pre-commit
- -
- python: 2.7
- env: TOXENV=py27
-
- -
- python: 2.7
- env: TOXENV=py27-ansi2html
-
- -
python: 3.6
env: TOXENV=py36
@@ -45,14 +36,6 @@ jobs:
sudo: required
env: TOXENV=py37-ansi2html
- -
- python: pypy
- env: TOXENV=pypy
-
- -
- python: pypy
- env: TOXENV=pypy-ansi2html
-
-
python: pypy3
env: TOXENV=pypy3
diff --git a/README.rst b/README.rst
index 02dad39b..c4ccb1f1 100644
--- a/README.rst
+++ b/README.rst
@@ -28,7 +28,7 @@ Requirements
You will need the following prerequisites in order to use pytest-html:
-- Python 2.7, 3.6, PyPy, or PyPy3
+- Python 3.6+ or PyPy3
Installation
------------
diff --git a/appveyor.yml b/appveyor.yml
index 3b3b413f..66236325 100644
--- a/appveyor.yml
+++ b/appveyor.yml
@@ -9,11 +9,7 @@ environment:
- TOXENV: py36-pytest29
PYTHON_HOME: C:\Python36
- TOXENV: flake8
- PYTHON_HOME: C:\Python27
- - TOXENV: py27-pytest30
- PYTHON_HOME: C:\Python27
- - TOXENV: py27-pytest29
- PYTHON_HOME: C:\Python27
+ PYTHON_HOME: C:\Python37
install:
- '%PYTHON_HOME%\Scripts\pip --version'
- '%PYTHON_HOME%\Scripts\pip install tox'
diff --git a/pytest_html/plugin.py b/pytest_html/plugin.py
index 49578cba..7e14df5d 100644
--- a/pytest_html/plugin.py
+++ b/pytest_html/plugin.py
@@ -2,8 +2,6 @@
# License, v. 2.0. If a copy of the MPL was not distributed with this
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
-from __future__ import absolute_import
-
from base64 import b64encode, b64decode
from collections import OrderedDict
from os.path import isfile
@@ -11,12 +9,13 @@
import json
import os
import pkg_resources
-import sys
import time
import bisect
import warnings
import re
+from html import escape
+
try:
from ansi2html import Ansi2HTMLConverter, style
@@ -30,16 +29,6 @@
from . import extras
from . import __version__, __pypi_url__
-PY3 = sys.version_info[0] == 3
-
-# Python 2.X and 3.X compatibility
-if PY3:
- basestring = str
- from html import escape
-else:
- from codecs import open
- from cgi import escape
-
def pytest_addhooks(pluginmanager):
from . import hooks
@@ -95,10 +84,10 @@ def pytest_unconfigure(config):
def data_uri(content, mime_type="text/plain", charset="utf-8"):
data = b64encode(content.encode(charset)).decode("ascii")
- return "data:{0};charset={1};base64,{2}".format(mime_type, charset, data)
+ return f"data:{mime_type};charset={charset};base64,{data}"
-class HTMLReport(object):
+class HTMLReport:
def __init__(self, logfile, config):
logfile = os.path.expanduser(os.path.expandvars(logfile))
self.logfile = os.path.abspath(logfile)
@@ -136,7 +125,7 @@ def __init__(self, outcome, report, logfile, config):
cells = [
html.td(self.outcome, class_="col-result"),
html.td(self.test_id, class_="col-name"),
- html.td("{0:.2f}".format(self.time), class_="col-duration"),
+ html.td(f"{self.time:.2f}", class_="col-duration"),
html.td(self.links_html, class_="col-links"),
]
@@ -181,7 +170,7 @@ def create_asset(
if not os.path.exists(os.path.dirname(asset_path)):
os.makedirs(os.path.dirname(asset_path))
- relative_path = "{0}/{1}".format("assets", asset_file_name)
+ relative_path = f"assets/{asset_file_name}"
kwargs = {"encoding": "utf-8"} if "b" not in mode else {}
with open(asset_path, mode, **kwargs) as f:
@@ -209,13 +198,10 @@ def append_extra_html(self, extra, extra_index, test_index):
)
html_div = html.a(html.img(src=content), href=content)
elif self.self_contained:
- src = "data:{0};base64,{1}".format(extra.get("mime_type"), content)
+ src = "data:{};base64,{}".format(extra.get("mime_type"), content)
html_div = html.img(src=src)
else:
- if PY3:
- content = content.encode("utf-8")
-
- content = b64decode(content)
+ content = b64decode(content.encode("utf-8"))
href = src = self.create_asset(
content, extra_index, test_index, extra.get("extension"), "wb"
)
@@ -276,7 +262,7 @@ def append_log_html(self, report, additional_html):
for section in report.sections:
header, content = map(escape, section)
- log.append(" {0} ".format(header).center(80, "-"))
+ log.append(f" {header:-^80} ")
log.append(html.br())
if ANSI:
converter = Ansi2HTMLConverter(inline=False, escaped=False)
@@ -296,7 +282,7 @@ def _appendrow(self, outcome, report):
self.results.insert(index, result)
tbody = html.tbody(
result.row_table,
- class_="{0} results-table-row".format(result.outcome.lower()),
+ class_="{} results-table-row".format(result.outcome.lower()),
)
if result.row_extra is not None:
tbody.append(result.row_extra)
@@ -345,9 +331,7 @@ def _generate_report(self, session):
self.style_css = pkg_resources.resource_string(
__name__, os.path.join("resources", "style.css")
- )
- if PY3:
- self.style_css = self.style_css.decode("utf-8")
+ ).decode("utf-8")
if ANSI:
ansi_css = [
@@ -362,12 +346,12 @@ def _generate_report(self, session):
for path in self.config.getoption("css"):
self.style_css += "\n/******************************"
self.style_css += "\n * CUSTOM CSS"
- self.style_css += "\n * {}".format(path)
+ self.style_css += f"\n * {path}"
self.style_css += "\n ******************************/\n\n"
with open(path, "r") as f:
self.style_css += f.read()
- css_href = "{0}/{1}".format("assets", "style.css")
+ css_href = "assets/style.css"
html_css = html.link(href=css_href, rel="stylesheet", type="text/css")
if self.self_contained:
html_css = html.style(raw(self.style_css))
@@ -401,12 +385,12 @@ def generate_checkbox(self):
name="filter_checkbox",
class_="filter",
hidden="true",
- **checkbox_kwargs
+ **checkbox_kwargs,
)
def generate_summary_item(self):
self.summary_item = html.span(
- "{0} {1}".format(self.total, self.label), class_=self.class_html
+ f"{self.total} {self.label}", class_=self.class_html
)
outcomes = [
@@ -422,9 +406,7 @@ def generate_summary_item(self):
outcomes.append(Outcome("rerun", self.rerun))
summary = [
- html.p(
- "{0} tests ran in {1:.2f} seconds. ".format(numtests, suite_time_delta)
- ),
+ html.p(f"{numtests} tests ran in {suite_time_delta:.2f} seconds. "),
html.p(
"(Un)check the boxes to filter the results.",
class_="filter",
@@ -472,19 +454,17 @@ def generate_summary_item(self):
main_js = pkg_resources.resource_string(
__name__, os.path.join("resources", "main.js")
- )
- if PY3:
- main_js = main_js.decode("utf-8")
+ ).decode("utf-8")
body = html.body(
html.script(raw(main_js)),
html.h1(os.path.basename(self.logfile)),
html.p(
- "Report generated on {0} at {1} by ".format(
+ "Report generated on {} at {} by ".format(
generated.strftime("%d-%b-%Y"), generated.strftime("%H:%M:%S")
),
html.a("pytest-html", href=__pypi_url__),
- " v{0}".format(__version__),
+ f" v{__version__}",
),
onLoad="init()",
)
@@ -501,12 +481,11 @@ def generate_summary_item(self):
doc = html.html(head, body)
- unicode_doc = u"\n{0}".format(doc.unicode(indent=2))
- if PY3:
- # Fix encoding issues, e.g. with surrogates
- unicode_doc = unicode_doc.encode("utf-8", errors="xmlcharrefreplace")
- unicode_doc = unicode_doc.decode("utf-8")
- return unicode_doc
+ unicode_doc = "\n{}".format(doc.unicode(indent=2))
+
+ # Fix encoding issues, e.g. with surrogates
+ unicode_doc = unicode_doc.encode("utf-8", errors="xmlcharrefreplace")
+ return unicode_doc.decode("utf-8")
def _generate_environment(self, config):
if not hasattr(config, "_metadata") or config._metadata is None:
@@ -522,10 +501,10 @@ def _generate_environment(self, config):
for key in keys:
value = metadata[key]
- if isinstance(value, basestring) and value.startswith("http"):
+ if isinstance(value, str) and value.startswith("http"):
value = html.a(value, href=value, target="_blank")
elif isinstance(value, (list, tuple, set)):
- value = ", ".join((str(i) for i in value))
+ value = ", ".join(str(i) for i in value)
rows.append(html.tr(html.td(key), html.td(value)))
environment.append(html.table(rows, id="environment"))
@@ -569,6 +548,4 @@ def pytest_sessionfinish(self, session):
self._save_report(report_content)
def pytest_terminal_summary(self, terminalreporter):
- terminalreporter.write_sep(
- "-", "generated html file: file://{0}".format(self.logfile)
- )
+ terminalreporter.write_sep("-", f"generated html file: file://{self.logfile}")
diff --git a/setup.py b/setup.py
index 1f4922c3..97f40083 100644
--- a/setup.py
+++ b/setup.py
@@ -12,9 +12,10 @@
package_data={"pytest_html": ["resources/*"]},
entry_points={"pytest11": ["html = pytest_html.plugin"]},
setup_requires=["setuptools_scm"],
- install_requires=["pytest>=3.0", "pytest-metadata"],
+ install_requires=["pytest>=5.0", "pytest-metadata"],
license="Mozilla Public License 2.0 (MPL 2.0)",
keywords="py.test pytest html report",
+ python_requires=">=3.6",
classifiers=[
"Development Status :: 5 - Production/Stable",
"Framework :: Pytest",
@@ -27,8 +28,9 @@
"Topic :: Software Development :: Testing",
"Topic :: Utilities",
"Programming Language :: Python",
- "Programming Language :: Python :: 2.7",
+ "Programming Language :: Python :: 3",
"Programming Language :: Python :: 3.6",
"Programming Language :: Python :: 3.7",
+ "Programming Language :: Python :: 3 :: Only",
],
)
diff --git a/testing/test_pytest_html.py b/testing/test_pytest_html.py
index c7309a40..1fe847e6 100644
--- a/testing/test_pytest_html.py
+++ b/testing/test_pytest_html.py
@@ -3,17 +3,14 @@
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
from base64 import b64encode
-from distutils.version import LooseVersion
import json
import os
-import sys
import pkg_resources
import random
import re
import pytest
-PY3 = sys.version_info[0] == 3
pytest_plugins = ("pytester",)
@@ -30,20 +27,19 @@ def read_html(path):
def assert_results_by_outcome(html, test_outcome, test_outcome_number, label=None):
# Asserts if the test number of this outcome in the summary is correct
- regex_summary = r"(\d)+ {0}".format(label or test_outcome)
+ regex_summary = r"(\d)+ {}".format(label or test_outcome)
assert int(re.search(regex_summary, html).group(1)) == test_outcome_number
# Asserts if the generated checkbox of this outcome is correct
regex_checkbox = (
- '{report_name}"
assert report_title in html
def test_report_title_addopts_env_var(self, testdir, monkeypatch):
@@ -232,17 +224,15 @@ def test_report_title_addopts_env_var(self, testdir, monkeypatch):
monkeypatch.setenv(report_location, report_name)
testdir.makefile(
".ini",
- pytest="""
+ pytest=f"""
[pytest]
- addopts = --html ${0}
- """.format(
- report_location
- ),
+ addopts = --html ${report_location}
+ """,
)
testdir.makepyfile("def test_pass(): pass")
result = testdir.runpytest()
assert result.ret == 0
- report_title = "
{0}
".format(report_name)
+ report_title = f"{report_name}
"
assert report_title in read_html(report_name)
def test_resources_inline_css(self, testdir):
@@ -253,8 +243,7 @@ def test_resources_inline_css(self, testdir):
content = pkg_resources.resource_string(
"pytest_html", os.path.join("resources", "style.css")
)
- if PY3:
- content = content.decode("utf-8")
+ content = content.decode("utf-8")
assert content
assert content in html
@@ -266,8 +255,7 @@ def test_resources(self, testdir):
content = pkg_resources.resource_string(
"pytest_html", os.path.join("resources", "main.js")
)
- if PY3:
- content = content.decode("utf-8")
+ content = content.decode("utf-8")
assert content
assert content in html
regex_css_link = '{0}')]
- """.format(
- content
- )
+ report.extra = [extras.html('{content}
')]
+ """
)
testdir.makepyfile("def test_pass(): pass")
result, html = run(testdir)
@@ -340,7 +322,7 @@ def pytest_runtest_makereport(item, call):
)
def test_extra_text(self, testdir, content, encoded):
testdir.makeconftest(
- """
+ f"""
import pytest
@pytest.hookimpl(hookwrapper=True)
def pytest_runtest_makereport(item, call):
@@ -348,22 +330,20 @@ def pytest_runtest_makereport(item, call):
report = outcome.get_result()
if report.when == 'call':
from pytest_html import extras
- report.extra = [extras.text({0})]
- """.format(
- content
- )
+ report.extra = [extras.text({content})]
+ """
)
testdir.makepyfile("def test_pass(): pass")
result, html = run(testdir, "report.html", "--self-contained-html")
assert result.ret == 0
- href = "data:text/plain;charset=utf-8;base64,{0}".format(encoded)
- link = 'Text'.format(href)
+ href = f"data:text/plain;charset=utf-8;base64,{encoded}"
+ link = f'Text'
assert link in html
def test_extra_json(self, testdir):
content = {str(random.random()): str(random.random())}
testdir.makeconftest(
- """
+ f"""
import pytest
@pytest.hookimpl(hookwrapper=True)
def pytest_runtest_makereport(item, call):
@@ -371,27 +351,22 @@ def pytest_runtest_makereport(item, call):
report = outcome.get_result()
if report.when == 'call':
from pytest_html import extras
- report.extra = [extras.json({0})]
- """.format(
- content
- )
+ report.extra = [extras.json({content})]
+ """
)
testdir.makepyfile("def test_pass(): pass")
result, html = run(testdir, "report.html", "--self-contained-html")
assert result.ret == 0
content_str = json.dumps(content)
- if PY3:
- data = b64encode(content_str.encode("utf-8")).decode("ascii")
- else:
- data = b64encode(content_str)
- href = "data:application/json;charset=utf-8;base64,{0}".format(data)
- link = 'JSON'.format(href)
+ data = b64encode(content_str.encode("utf-8")).decode("ascii")
+ href = f"data:application/json;charset=utf-8;base64,{data}"
+ link = f'JSON'
assert link in html
def test_extra_url(self, testdir):
content = str(random.random())
testdir.makeconftest(
- """
+ f"""
import pytest
@pytest.hookimpl(hookwrapper=True)
def pytest_runtest_makereport(item, call):
@@ -399,15 +374,13 @@ def pytest_runtest_makereport(item, call):
report = outcome.get_result()
if report.when == 'call':
from pytest_html import extras
- report.extra = [extras.url('{0}')]
- """.format(
- content
- )
+ report.extra = [extras.url('{content}')]
+ """
)
testdir.makepyfile("def test_pass(): pass")
result, html = run(testdir)
assert result.ret == 0
- link = 'URL'.format(content)
+ link = f'URL'
assert link in html
@pytest.mark.parametrize(
@@ -422,7 +395,7 @@ def pytest_runtest_makereport(item, call):
def test_extra_image(self, testdir, mime_type, extension):
content = str(random.random())
testdir.makeconftest(
- """
+ f"""
import pytest
@pytest.hookimpl(hookwrapper=True)
def pytest_runtest_makereport(item, call):
@@ -430,16 +403,14 @@ def pytest_runtest_makereport(item, call):
report = outcome.get_result()
if report.when == 'call':
from pytest_html import extras
- report.extra = [extras.{0}('{1}')]
- """.format(
- extension, content
- )
+ report.extra = [extras.{extension}('{content}')]
+ """
)
testdir.makepyfile("def test_pass(): pass")
result, html = run(testdir, "report.html", "--self-contained-html")
assert result.ret == 0
- src = "data:{0};base64,{1}".format(mime_type, content)
- assert '
'.format(src) in html
+ src = f"data:{mime_type};base64,{content}"
+ assert f'
' in html
def test_extra_image_windows(self, mocker, testdir):
mock_isfile = mocker.patch("pytest_html.plugin.isfile")
@@ -452,7 +423,7 @@ def test_extra_image_windows(self, mocker, testdir):
)
def test_extra_text_separated(self, testdir, content):
testdir.makeconftest(
- """
+ f"""
import pytest
@pytest.hookimpl(hookwrapper=True)
def pytest_runtest_makereport(item, call):
@@ -460,16 +431,14 @@ def pytest_runtest_makereport(item, call):
report = outcome.get_result()
if report.when == 'call':
from pytest_html import extras
- report.extra = [extras.text({0})]
- """.format(
- content
- )
+ report.extra = [extras.text({content})]
+ """
)
testdir.makepyfile("def test_pass(): pass")
result, html = run(testdir)
assert result.ret == 0
src = "assets/test_extra_text_separated.py__test_pass_0_0.txt"
- link = ''.format(src)
+ link = f''
assert link in html
assert os.path.exists(src)
@@ -478,9 +447,9 @@ def pytest_runtest_makereport(item, call):
[("png", "image"), ("png", "png"), ("svg", "svg"), ("jpg", "jpg")],
)
def test_extra_image_separated(self, testdir, file_extension, extra_type):
- content = b64encode("foo".encode("utf-8")).decode("ascii")
+ content = b64encode(b"foo").decode("ascii")
testdir.makeconftest(
- """
+ f"""
import pytest
@pytest.hookimpl(hookwrapper=True)
def pytest_runtest_makereport(item, call):
@@ -488,18 +457,14 @@ def pytest_runtest_makereport(item, call):
report = outcome.get_result()
if report.when == 'call':
from pytest_html import extras
- report.extra = [extras.{0}('{1}')]
- """.format(
- extra_type, content
- )
+ report.extra = [extras.{extra_type}('{content}')]
+ """
)
testdir.makepyfile("def test_pass(): pass")
result, html = run(testdir)
assert result.ret == 0
- src = "assets/test_extra_image_separated.py__test_pass_0_0.{}".format(
- file_extension
- )
- link = ''.format(src)
+ src = f"assets/test_extra_image_separated.py__test_pass_0_0.{file_extension}"
+ link = f''
assert link in html
assert os.path.exists(src)
@@ -508,9 +473,9 @@ def pytest_runtest_makereport(item, call):
[("png", "image"), ("png", "png"), ("svg", "svg"), ("jpg", "jpg")],
)
def test_extra_image_separated_rerun(self, testdir, file_extension, extra_type):
- content = b64encode("foo".encode("utf-8")).decode("ascii")
+ content = b64encode(b"foo").decode("ascii")
testdir.makeconftest(
- """
+ f"""
import pytest
@pytest.hookimpl(hookwrapper=True)
def pytest_runtest_makereport(item, call):
@@ -518,10 +483,8 @@ def pytest_runtest_makereport(item, call):
report = outcome.get_result()
if report.when == 'call':
from pytest_html import extras
- report.extra = [extras.{0}('{1}')]
- """.format(
- extra_type, content
- )
+ report.extra = [extras.{extra_type}('{content}')]
+ """
)
testdir.makepyfile(
"""
@@ -534,8 +497,8 @@ def test_fail():
for i in range(1, 4):
asset_name = "test_extra_image_separated_rerun.py__test_fail"
- src = "assets/{}_0_{}.{}".format(asset_name, i, file_extension)
- link = ''.format(src)
+ src = f"assets/{asset_name}_0_{i}.{file_extension}"
+ link = f''
assert result.ret
assert link in html
assert os.path.exists(src)
@@ -544,7 +507,7 @@ def test_fail():
def test_extra_image_non_b64(self, testdir, src_type):
content = src_type
testdir.makeconftest(
- """
+ f"""
import pytest
@pytest.hookimpl(hookwrapper=True)
def pytest_runtest_makereport(item, call):
@@ -552,10 +515,8 @@ def pytest_runtest_makereport(item, call):
report = outcome.get_result()
if report.when == 'call':
from pytest_html import extras
- report.extra = [extras.image('{0}')]
- """.format(
- content
- )
+ report.extra = [extras.image('{content}')]
+ """
)
testdir.makepyfile("def test_pass(): pass")
if src_type == "image.png":
@@ -580,17 +541,15 @@ def pytest_runtest_makereport(item, call):
# This will get truncated
test_name = "test_{}".format("a" * 300)
testdir.makepyfile(
- """
- def {0}():
+ f"""
+ def {test_name}():
assert False
- """.format(
- test_name
- )
+ """
)
result, html = run(testdir)
- file_name = "test_very_long_test_name.py__{}_0_0.png".format(test_name)[-255:]
+ file_name = f"test_very_long_test_name.py__{test_name}_0_0.png"[-255:]
src = "assets/" + file_name
- link = ''.format(src)
+ link = f''
assert result.ret
assert link in html
assert os.path.exists(src)
@@ -633,12 +592,10 @@ def pytest_configure(config):
def test_environment(self, testdir):
content = str(random.random())
testdir.makeconftest(
- """
+ f"""
def pytest_configure(config):
- config._metadata['content'] = '{0}'
- """.format(
- content
- )
+ config._metadata['content'] = '{content}'
+ """
)
testdir.makepyfile("def test_pass(): pass")
result, html = run(testdir)
@@ -649,13 +606,11 @@ def pytest_configure(config):
def test_environment_xdist(self, testdir):
content = str(random.random())
testdir.makeconftest(
- """
+ f"""
def pytest_configure(config):
for i in range(2):
- config._metadata['content'] = '{0}'
- """.format(
- content
- )
+ config._metadata['content'] = '{content}'
+ """
)
testdir.makepyfile("def test_pass(): pass")
result, html = run(testdir, "report.html", "-n", "1")
@@ -666,13 +621,11 @@ def pytest_configure(config):
def test_environment_xdist_reruns(self, testdir):
content = str(random.random())
testdir.makeconftest(
- """
+ f"""
def pytest_configure(config):
for i in range(2):
- config._metadata['content'] = '{0}'
- """.format(
- content
- )
+ config._metadata['content'] = '{content}'
+ """
)
testdir.makepyfile("def test_fail(): assert False")
result, html = run(testdir, "report.html", "-n", "1", "--reruns", "1")
@@ -683,16 +636,14 @@ def pytest_configure(config):
def test_environment_list_value(self, testdir):
content = tuple(str(random.random()) for i in range(10))
content += tuple(random.random() for i in range(10))
- expected_content = ", ".join((str(i) for i in content))
- expected_html_re = r"content | \n\s+{} | ".format(expected_content)
+ expected_content = ", ".join(str(i) for i in content)
+ expected_html_re = fr"content | \n\s+{expected_content} | "
testdir.makeconftest(
- """
+ f"""
def pytest_configure(config):
for i in range(2):
- config._metadata['content'] = {0}
- """.format(
- content
- )
+ config._metadata['content'] = {content}
+ """
)
testdir.makepyfile("def test_pass(): pass")
result, html = run(testdir)
@@ -714,12 +665,6 @@ def pytest_configure(config):
assert "Environment" in html
assert len(re.findall("ZZZ.+AAA", html, re.DOTALL)) == 1
- @pytest.mark.xfail(
- sys.version_info < (3, 2)
- and LooseVersion(pytest.__version__) >= LooseVersion("2.8.0"),
- reason="Fails on earlier versions of Python and pytest",
- run=False,
- )
def test_xdist_crashing_slave(self, testdir):
"""https://github.com/pytest-dev/pytest-html/issues/21"""
testdir.makepyfile(
@@ -779,17 +724,15 @@ def test_ansi():
@pytest.mark.parametrize("content", [("'foo'"), ("u'\u0081'")])
def test_utf8_longrepr(self, testdir, content):
testdir.makeconftest(
- """
+ f"""
import pytest
@pytest.hookimpl(hookwrapper=True)
def pytest_runtest_makereport(item, call):
outcome = yield
report = outcome.get_result()
if report.when == 'call':
- report.longrepr = 'utf8 longrepr: ' + {0}
- """.format(
- content
- )
+ report.longrepr = 'utf8 longrepr: ' + {content}
+ """
)
testdir.makepyfile(
"""
@@ -821,7 +764,7 @@ def test_css(self, testdir, colors):
css = {}
cssargs = []
for color in colors:
- style = "* {{color: {}}}".format(color)
+ style = f"* {{color: {color}}}"
path = testdir.makefile(".css", **{color: style})
css[color] = {"style": style, "path": path}
cssargs.extend(["--css", path])
diff --git a/tox.ini b/tox.ini
index 97e4c015..6a9cc242 100644
--- a/tox.ini
+++ b/tox.ini
@@ -4,7 +4,7 @@
# and then run "tox" from this directory.
[tox]
-envlist = py{27,36,37,py,py3}{,-ansi2html}, linting
+envlist = py{36,37,py3}{,-ansi2html}, linting
[testenv]
setenv = PYTHONDONTWRITEBYTECODE=1
@@ -12,7 +12,7 @@ deps =
pytest-xdist
pytest-rerunfailures
pytest-mock
- py{27,36,py,py3}-ansi2html: ansi2html
+ py{36,37,py3}-ansi2html: ansi2html
commands = pytest -v -r a {posargs}
[testenv:linting]