diff options
50 files changed, 811 insertions, 344 deletions
diff --git a/CHANGES.rst b/CHANGES.rst index b63ad42b..4c5bdcab 100644 --- a/CHANGES.rst +++ b/CHANGES.rst @@ -24,7 +24,17 @@ want to know what's different in 5.0 since 4.5.x, see :ref:`whatsnew5x`. Unreleased ---------- -Nothing yet. +- The HTML report has been redesigned by Victor Salvino. There is now a dark + mode, the code text is larger, and system san serif fonts are used. + +- The ``coverage report`` and ``coverage html`` commands now accept a + ``--precision`` option to control the number of decimal points displayed. + Thanks, Teake Nutma. + +- TOML configuration files with non-ASCII characters would cause errors on + Windows (`issue 990`_). This is now fixed. + +.. _issue 990: https://github.com/nedbat/coveragepy/issues/990 .. _changes_51: diff --git a/CONTRIBUTORS.txt b/CONTRIBUTORS.txt index a3cc9be7..c418a049 100644 --- a/CONTRIBUTORS.txt +++ b/CONTRIBUTORS.txt @@ -127,9 +127,11 @@ Stephen Finucane Steve Leonard Steve Peak S. Y. Lee +Teake Nutma Ted Wexler Thijs Triemstra Titus Brown +Victor Salvino Ville Skyttä Yury Selivanov Zac Hatfield-Dodds @@ -133,17 +133,17 @@ WEBHOME = ~/web/stellated/ WEBSAMPLE = $(WEBHOME)/files/sample_coverage_html WEBSAMPLEBETA = $(WEBHOME)/files/sample_coverage_html_beta -docreqs: +$(DOCPYTHON): tox -q -e doc --notest -dochtml: docreqs ## Build the docs HTML output. +dochtml: $(DOCBIN) ## Build the docs HTML output. $(DOCBIN)/python doc/check_copied_from.py doc/*.rst $(SPHINXBUILD) -b html doc doc/_build/html docdev: dochtml ## Build docs, and auto-watch for changes. PATH=$(DOCBIN):$(PATH) $(SPHINXAUTOBUILD) -b html doc doc/_build/html -docspell: docreqs +docspell: $(DOCBIN) $(SPHINXBUILD) -b spelling doc doc/_spell publish: @@ -156,7 +156,19 @@ publishbeta: mkdir -p $(WEBSAMPLEBETA) cp doc/sample_html_beta/*.* $(WEBSAMPLEBETA) -upload_relnotes: docreqs ## Upload parsed release notes to Tidelift. +CHANGES_MD = /tmp/rst_rst/changes.md +RELNOTES_JSON = /tmp/relnotes.json + +$(CHANGES_MD): CHANGES.rst $(DOCBIN) $(SPHINXBUILD) -b rst doc /tmp/rst_rst - pandoc -frst -tmarkdown_strict --atx-headers /tmp/rst_rst/changes.rst > /tmp/rst_rst/changes.md - python ci/upload_relnotes.py /tmp/rst_rst/changes.md pypi/coverage + pandoc -frst -tmarkdown_strict --atx-headers --wrap=none /tmp/rst_rst/changes.rst > $(CHANGES_MD) + +relnotes_json: $(RELNOTES_JSON) +$(RELNOTES_JSON): $(CHANGES_MD) + $(DOCBIN)/python ci/parse_relnotes.py /tmp/rst_rst/changes.md $(RELNOTES_JSON) + +tidelift_relnotes: $(RELNOTES_JSON) ## Upload parsed release notes to Tidelift. + $(DOCBIN)/python ci/tidelift_relnotes.py $(RELNOTES_JSON) pypi/coverage + +github_releases: $(RELNOTES_JSON) ## Update GitHub releases. + $(DOCBIN)/python ci/github_releases.py $(RELNOTES_JSON) nedbat/coveragepy @@ -9,7 +9,7 @@ Code coverage testing for Python. | |license| |versions| |status| | |ci-status| |win-ci-status| |docs| |codecov| -| |kit| |format| |repos| +| |kit| |format| |repos| |downloads| | |stars| |forks| |contributors| | |tidelift| |twitter-coveragepy| |twitter-nedbat| @@ -38,7 +38,6 @@ For Enterprise -------------- .. |tideliftlogo| image:: https://nedbatchelder.com/pix/Tidelift_Logo_small.png - :width: 75 :alt: Tidelift :target: https://tidelift.com/subscription/pkg/pypi-coverage?utm_source=pypi-coverage&utm_medium=referral&utm_campaign=readme diff --git a/appveyor.yml b/appveyor.yml index 76e21dad..35c670a1 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -131,11 +131,9 @@ install: # Check that we have the expected version and architecture for Python - "python -c \"import struct, sys; print('{}\\n{}-bit'.format(sys.version, struct.calcsize('P') * 8))\"" - # Upgrade to the latest version of pip to avoid it displaying warnings + # Upgrade to the right version of pip to avoid it displaying warnings # about it being out of date. - - "python -m pip install --disable-pip-version-check --upgrade pip" - # And upgrade virtualenv to get the latest pip inside .tox virtualenvs. - - "python -m pip install --disable-pip-version-check --upgrade virtualenv" + - "python -m pip install --disable-pip-version-check -r requirements/pip.pip" # Install requirements. - "%CMD_IN_ENV% pip install -r requirements/ci.pip" diff --git a/ci/github_releases.py b/ci/github_releases.py new file mode 100644 index 00000000..1c7ee604 --- /dev/null +++ b/ci/github_releases.py @@ -0,0 +1,138 @@ +#!/usr/bin/env python3 +""" +Upload release notes into GitHub releases. +""" + +import json +import shlex +import subprocess +import sys + +import pkg_resources +import requests + + +RELEASES_URL = "https://api.github.com/repos/{repo}/releases" + +def run_command(cmd): + """ + Run a command line (with no shell). + + Returns a tuple: + bool: true if the command succeeded. + str: the output of the command. + + """ + proc = subprocess.run( + shlex.split(cmd), + shell=False, + check=False, + stdout=subprocess.PIPE, + stderr=subprocess.STDOUT, + ) + output = proc.stdout.decode("utf-8") + succeeded = proc.returncode == 0 + return succeeded, output + +def does_tag_exist(tag_name): + """ + Does `tag_name` exist as a tag in git? + """ + return run_command(f"git rev-parse --verify {tag_name}")[0] + +def check_ok(resp): + """ + Check that the Requests response object was successful. + + Raise an exception if not. + """ + if not resp: + print(f"text: {resp.text!r}") + resp.raise_for_status() + +def github_paginated(session, url): + """ + Get all the results from a paginated GitHub url. + """ + while True: + resp = session.get(url) + check_ok(resp) + yield from resp.json() + next_link = resp.links.get("next", None) + if not next_link: + break + url = next_link["url"] + +def get_releases(session, repo): + """ + Get all the releases from a name/project repo. + + Returns: + A dict mapping tag names to release dictionaries. + """ + url = RELEASES_URL.format(repo=repo) + releases = { r['tag_name']: r for r in github_paginated(session, url) } + return releases + +def release_for_relnote(relnote): + """ + Turn a release note dict into the data needed by GitHub for a release. + """ + tag = f"coverage-{relnote['version']}" + return { + "tag_name": tag, + "name": tag, + "body": relnote["text"], + "draft": False, + "prerelease": relnote["prerelease"], + } + +def create_release(session, repo, relnote): + """ + Create a new GitHub release. + """ + print(f"Creating {relnote['version']}") + data = release_for_relnote(relnote) + resp = session.post(RELEASES_URL.format(repo=repo), json=data) + check_ok(resp) + +def update_release(session, url, relnote): + """ + Update an existing GitHub release. + """ + print(f"Updating {relnote['version']}") + data = release_for_relnote(relnote) + resp = session.patch(url, json=data) + check_ok(resp) + +def update_github_releases(json_filename, repo): + """ + Read the json file, and create or update releases in GitHub. + """ + gh_session = requests.Session() + releases = get_releases(gh_session, repo) + if 0: # if you need to delete all the releases! + for release in releases.values(): + print(release["tag_name"]) + resp = gh_session.delete(release["url"]) + check_ok(resp) + return + + with open(json_filename) as jf: + relnotes = json.load(jf) + relnotes.sort(key=lambda rel: pkg_resources.parse_version(rel["version"])) + for relnote in relnotes: + tag = "coverage-" + relnote["version"] + if not does_tag_exist(tag): + continue + exists = tag in releases + if not exists: + create_release(gh_session, repo, relnote) + else: + release = releases[tag] + if release["body"] != relnote["text"]: + url = release["url"] + update_release(gh_session, url, relnote) + +if __name__ == "__main__": + update_github_releases(*sys.argv[1:]) # pylint: disable=no-value-for-parameter diff --git a/ci/upload_relnotes.py b/ci/parse_relnotes.py index 630f4d0a..d19e6d60 100644 --- a/ci/upload_relnotes.py +++ b/ci/parse_relnotes.py @@ -1,26 +1,20 @@ #!/usr/bin/env python3 """ -Upload CHANGES.md to Tidelift as Markdown chunks +Parse CHANGES.md into a JSON structure. -Put your Tidelift API token in a file called tidelift.token alongside this -program, for example: +Run with two arguments: the .md file to parse, and the JSON file to write: - user/n3IwOpxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxc2ZwE4 - -Run with two arguments: the .md file to parse, and the Tidelift package name: - - python upload_relnotes.py CHANGES.md pypi/coverage + python parse_relnotes.py CHANGES.md relnotes.json Every section that has something that looks like a version number in it will -be uploaded as the release notes for that version. +be recorded as the release notes for that version. """ -import os.path +import json import re import sys -import requests class TextChunkBuffer: """Hold onto text chunks until needed.""" @@ -82,6 +76,14 @@ def sections(parsed_data): yield (*header, "\n".join(text)) +def refind(regex, text): + """Find a regex in some text, and return the matched text, or None.""" + m = re.search(regex, text) + if m: + return m.group() + else: + return None + def relnotes(mdlines): r"""Yield (version, text) pairs from markdown lines. @@ -91,32 +93,23 @@ def relnotes(mdlines): """ for _, htext, text in sections(parse_md(mdlines)): - m_version = re.search(r"\d+\.\d[^ ]*", htext) - if m_version: - version = m_version.group() - yield version, text - -def update_release_note(package, version, text): - """Update the release notes for one version of a package.""" - url = f"https://api.tidelift.com/external-api/lifting/{package}/release-notes/{version}" - token_file = os.path.join(os.path.dirname(__file__), "tidelift.token") - with open(token_file) as ftoken: - token = ftoken.read().strip() - headers = { - "Authorization": f"Bearer: {token}", - } - req_args = dict(url=url, data=text.encode('utf8'), headers=headers) - result = requests.post(**req_args) - if result.status_code == 409: - result = requests.put(**req_args) - print(f"{version}: {result.status_code}") - -def parse_and_upload(md_filename, package): - """Main function: parse markdown and upload to Tidelift.""" - with open(md_filename) as f: - markdown = f.read() - for version, text in relnotes(markdown.splitlines(True)): - update_release_note(package, version, text) + version = refind(r"\d+\.\d[^ ]*", htext) + if version: + prerelease = any(c in version for c in "abc") + when = refind(r"\d+-\d+-\d+", htext) + yield { + "version": version, + "text": text, + "prerelease": prerelease, + "when": when, + } + +def parse(md_filename, json_filename): + """Main function: parse markdown and write JSON.""" + with open(md_filename) as mf: + markdown = mf.read() + with open(json_filename, "w") as jf: + json.dump(list(relnotes(markdown.splitlines(True))), jf, indent=4) if __name__ == "__main__": - parse_and_upload(*sys.argv[1:]) # pylint: disable=no-value-for-parameter + parse(*sys.argv[1:]) # pylint: disable=no-value-for-parameter diff --git a/ci/tidelift_relnotes.py b/ci/tidelift_relnotes.py new file mode 100644 index 00000000..bc3a37d4 --- /dev/null +++ b/ci/tidelift_relnotes.py @@ -0,0 +1,50 @@ +#!/usr/bin/env python3 +""" +Upload release notes from a JSON file to Tidelift as Markdown chunks + +Put your Tidelift API token in a file called tidelift.token alongside this +program, for example: + + user/n3IwOpxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxc2ZwE4 + +Run with two arguments: the JSON file of release notes, and the Tidelift +package name: + + python tidelift_relnotes.py relnotes.json pypi/coverage + +Every section that has something that looks like a version number in it will +be uploaded as the release notes for that version. + +""" + +import json +import os.path +import sys + +import requests + + +def update_release_note(package, version, text): + """Update the release notes for one version of a package.""" + url = f"https://api.tidelift.com/external-api/lifting/{package}/release-notes/{version}" + token_file = os.path.join(os.path.dirname(__file__), "tidelift.token") + with open(token_file) as ftoken: + token = ftoken.read().strip() + headers = { + "Authorization": f"Bearer: {token}", + } + req_args = dict(url=url, data=text.encode('utf8'), headers=headers) + result = requests.post(**req_args) + if result.status_code == 409: + result = requests.put(**req_args) + print(f"{version}: {result.status_code}") + +def upload(json_filename, package): + """Main function: parse markdown and upload to Tidelift.""" + with open(json_filename) as jf: + relnotes = json.load(jf) + for relnote in relnotes: + update_release_note(package, relnote["version"], relnote["text"]) + +if __name__ == "__main__": + upload(*sys.argv[1:]) # pylint: disable=no-value-for-parameter diff --git a/coverage/backunittest.py b/coverage/backunittest.py index 078f48cc..123bb2a1 100644 --- a/coverage/backunittest.py +++ b/coverage/backunittest.py @@ -18,7 +18,7 @@ class TestCase(unittest.TestCase): `unittest` doesn't have them. """ - # pylint: disable=arguments-differ, deprecated-method + # pylint: disable=signature-differs, deprecated-method if not unittest_has('assertCountEqual'): def assertCountEqual(self, *args, **kwargs): diff --git a/coverage/cmdline.py b/coverage/cmdline.py index 23ebd8f5..d557ddf1 100644 --- a/coverage/cmdline.py +++ b/coverage/cmdline.py @@ -146,6 +146,13 @@ class Opts(object): "to be run as 'python -m' would run it." ), ) + precision = optparse.make_option( + '', '--precision', action='store', metavar='N', type=int, + help=( + "Number of digits after the decimal point to display for " + "reported coverage percentages." + ), + ) rcfile = optparse.make_option( '', '--rcfile', action='store', help=( @@ -203,6 +210,7 @@ class CoverageOptionParser(optparse.OptionParser, object): omit=None, contexts=None, parallel_mode=None, + precision=None, pylib=None, rcfile=True, show_missing=None, @@ -358,6 +366,7 @@ CMDS = { Opts.ignore_errors, Opts.include, Opts.omit, + Opts.precision, Opts.show_contexts, Opts.skip_covered, Opts.skip_empty, @@ -395,6 +404,7 @@ CMDS = { Opts.ignore_errors, Opts.include, Opts.omit, + Opts.precision, Opts.show_missing, Opts.skip_covered, Opts.skip_empty, @@ -583,6 +593,7 @@ class CoverageScript(object): show_missing=options.show_missing, skip_covered=options.skip_covered, skip_empty=options.skip_empty, + precision=options.precision, **report_args ) elif options.action == "annotate": @@ -594,6 +605,7 @@ class CoverageScript(object): skip_covered=options.skip_covered, skip_empty=options.skip_empty, show_contexts=options.show_contexts, + precision=options.precision, **report_args ) elif options.action == "xml": @@ -807,7 +819,7 @@ HELP_TOPICS = { """, 'minimum_help': """\ - Code coverage for Python. Use '{program_name} help' for help. + Code coverage for Python, version {__version__} {extension_modifier}. Use '{program_name} help' for help. """, 'version': """\ @@ -858,8 +870,8 @@ if _profile: # pragma: debugging def main(argv=None): # pylint: disable=function-redefined """A wrapper around main that profiles.""" + profiler = SimpleLauncher.launch() try: - profiler = SimpleLauncher.launch() return original_main(argv) finally: data, _ = profiler.query(re_filter='coverage', max_records=100) diff --git a/coverage/config.py b/coverage/config.py index 7876052b..6d336d1f 100644 --- a/coverage/config.py +++ b/coverage/config.py @@ -72,7 +72,7 @@ class HandyConfigParser(configparser.RawConfigParser): d[opt] = self.get(section, opt) return d - def get(self, section, option, *args, **kwargs): # pylint: disable=arguments-differ + def get(self, section, option, *args, **kwargs): """Get a value, replacing environment variables also. The arguments are the same as `RawConfigParser.get`, but in the found @@ -325,7 +325,7 @@ class CoverageConfig(object): if used: self.config_file = os.path.abspath(filename) - with open(filename) as f: + with open(filename, "rb") as f: self._config_contents = f.read() return used diff --git a/coverage/control.py b/coverage/control.py index 2b8c3d26..c2f40e70 100644 --- a/coverage/control.py +++ b/coverage/control.py @@ -829,7 +829,7 @@ class Coverage(object): def report( self, morfs=None, show_missing=None, ignore_errors=None, file=None, omit=None, include=None, skip_covered=None, - contexts=None, skip_empty=None, + contexts=None, skip_empty=None, precision=None, ): """Write a textual summary report to `file`. @@ -857,6 +857,9 @@ class Coverage(object): expressions (using :func:`re.search <python:re.search>`) will be included in the report. + `precision` is the number of digits to display after the decimal + point for percentages. + All of the arguments default to the settings read from the :ref:`configuration file <config>`. @@ -868,12 +871,15 @@ class Coverage(object): .. versionadded:: 5.0 The `contexts` and `skip_empty` parameters. + .. versionadded:: 5.2 + The `precision` parameter. + """ with override_config( self, ignore_errors=ignore_errors, report_omit=omit, report_include=include, show_missing=show_missing, skip_covered=skip_covered, - report_contexts=contexts, skip_empty=skip_empty, + report_contexts=contexts, skip_empty=skip_empty, precision=precision, ): reporter = SummaryReporter(self) return reporter.report(morfs, outfile=file) @@ -899,10 +905,12 @@ class Coverage(object): reporter = AnnotateReporter(self) reporter.report(morfs, directory=directory) - def html_report(self, morfs=None, directory=None, ignore_errors=None, - omit=None, include=None, extra_css=None, title=None, - skip_covered=None, show_contexts=None, contexts=None, - skip_empty=None): + def html_report( + self, morfs=None, directory=None, ignore_errors=None, + omit=None, include=None, extra_css=None, title=None, + skip_covered=None, show_contexts=None, contexts=None, + skip_empty=None, precision=None, + ): """Generate an HTML report. The HTML is written to `directory`. The file "index.html" is the @@ -930,7 +938,7 @@ class Coverage(object): ignore_errors=ignore_errors, report_omit=omit, report_include=include, html_dir=directory, extra_css=extra_css, html_title=title, skip_covered=skip_covered, show_contexts=show_contexts, report_contexts=contexts, - skip_empty=skip_empty, + skip_empty=skip_empty, precision=precision, ): reporter = HtmlReporter(self) return reporter.report(morfs) diff --git a/coverage/htmlfiles/pyfile.html b/coverage/htmlfiles/pyfile.html index eb0f99c8..ec0f416f 100644 --- a/coverage/htmlfiles/pyfile.html +++ b/coverage/htmlfiles/pyfile.html @@ -33,12 +33,12 @@ <h2 class="stats"> {{nums.n_statements}} statements - <span class="{{category.run}} shortkey_r button_toggle_run">{{nums.n_executed}} run</span> - <span class="{{category.mis}} shortkey_m button_toggle_mis">{{nums.n_missing}} missing</span> - <span class="{{category.exc}} shortkey_x button_toggle_exc">{{nums.n_excluded}} excluded</span> + <button type="button" class="{{category.run}} shortkey_r button_toggle_run" title="Toggle lines run">{{nums.n_executed}} run</button> + <button type="button" class="{{category.mis}} shortkey_m button_toggle_mis" title="Toggle lines missing">{{nums.n_missing}} missing</button> + <button type="button" class="{{category.exc}} shortkey_x button_toggle_exc" title="Toggle lines excluded">{{nums.n_excluded}} excluded</button> {% if has_arcs %} - <span class="{{category.par}} shortkey_p button_toggle_par">{{nums.n_partial_branches}} partial</span> + <button type="button" class="{{category.par}} shortkey_p button_toggle_par" title="Toggle lines partially run">{{nums.n_partial_branches}} partial</button> {% endif %} </h2> </div> diff --git a/coverage/htmlfiles/style.css b/coverage/htmlfiles/style.css index e8ff5765..5a79a2e7 100644 --- a/coverage/htmlfiles/style.css +++ b/coverage/htmlfiles/style.css @@ -4,11 +4,15 @@ /* Don't edit this .css file. Edit the .scss file instead! */ html, body, h1, h2, h3, p, table, td, th { margin: 0; padding: 0; border: 0; font-weight: inherit; font-style: inherit; font-size: 100%; font-family: inherit; vertical-align: baseline; } -body { font-family: georgia, serif; font-size: 1em; } +body { font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Ubuntu, Cantarell, "Helvetica Neue", sans-serif; font-size: 1em; background: #fff; color: #000; } +@media (prefers-color-scheme: dark) { body { background: #1e1e1e; } } +@media (prefers-color-scheme: dark) { body { color: #eee; } } html > body { font-size: 16px; } -p { font-size: .75em; line-height: 1.33333333em; } +a:active, a:focus { outline: 2px dashed #007acc; } + +p { font-size: .875em; line-height: 1.4em; } table { border-collapse: collapse; } @@ -22,35 +26,53 @@ a.nav { text-decoration: none; color: inherit; } a.nav:hover { text-decoration: underline; color: inherit; } #header { background: #f8f8f8; width: 100%; border-bottom: 1px solid #eee; } +@media (prefers-color-scheme: dark) { #header { background: black; } } +@media (prefers-color-scheme: dark) { #header { border-color: #333; } } -.indexfile #footer { margin: 1em 3em; } +.indexfile #footer { margin: 1rem 3rem; } -.pyfile #footer { margin: 1em 1em; } +.pyfile #footer { margin: 1rem 1rem; } -#footer .content { padding: 0; font-size: 85%; font-family: verdana, sans-serif; color: #666666; font-style: italic; } +#footer .content { padding: 0; color: #666; font-style: italic; } +@media (prefers-color-scheme: dark) { #footer .content { color: #aaa; } } -#index { margin: 1em 0 0 3em; } +#index { margin: 1rem 0 0 3rem; } -#header .content { padding: 1em 3rem; } +#header .content { padding: 1rem 3rem; } h1 { font-size: 1.25em; display: inline-block; } -#filter_container { display: inline-block; float: right; margin: 0 2em 0 0; } -#filter_container input { width: 10em; } +#filter_container { float: right; margin: 0 2em 0 0; } +#filter_container input { width: 10em; padding: 0.2em 0.5em; border: 2px solid #ccc; background: #fff; color: #000; } +@media (prefers-color-scheme: dark) { #filter_container input { border-color: #444; } } +@media (prefers-color-scheme: dark) { #filter_container input { background: #1e1e1e; } } +@media (prefers-color-scheme: dark) { #filter_container input { color: #eee; } } +#filter_container input:focus { border-color: #007acc; } h2.stats { margin-top: .5em; font-size: 1em; } -.stats span { border: 1px solid; border-radius: .1em; padding: .1em .5em; margin: 0 .1em; cursor: pointer; border-color: #ccc #999 #999 #ccc; } -.stats span.run { background: #eeffee; } -.stats span.run.show_run { border-color: #999 #ccc #ccc #999; background: #ddffdd; } -.stats span.mis { background: #ffeeee; } -.stats span.mis.show_mis { border-color: #999 #ccc #ccc #999; background: #ffdddd; } -.stats span.exc { background: #f7f7f7; } -.stats span.exc.show_exc { border-color: #999 #ccc #ccc #999; background: #eeeeee; } -.stats span.par { background: #ffffd5; } -.stats span.par.show_par { border-color: #999 #ccc #ccc #999; background: #ffffaa; } - -#source p .annotate.long, .help_panel { display: none; position: absolute; z-index: 999; background: #ffffcc; border: 1px solid #888; border-radius: .2em; box-shadow: #cccccc .2em .2em .2em; color: #333; padding: .25em .5em; } +.stats button { font-family: inherit; font-size: inherit; border: 1px solid; border-radius: .2em; color: inherit; padding: .1em .5em; margin: 1px calc(.1em + 1px); cursor: pointer; border-color: #ccc; } +@media (prefers-color-scheme: dark) { .stats button { border-color: #444; } } +.stats button:active, .stats button:focus { outline: 2px dashed #007acc; } +.stats button:active, .stats button:focus { outline: 2px dashed #007acc; } +.stats button.run { background: #eeffee; } +@media (prefers-color-scheme: dark) { .stats button.run { background: #373d29; } } +.stats button.run.show_run { background: #dfd; border: 2px solid #00dd00; margin: 0 .1em; } +@media (prefers-color-scheme: dark) { .stats button.run.show_run { background: #373d29; } } +.stats button.mis { background: #ffeeee; } +@media (prefers-color-scheme: dark) { .stats button.mis { background: #4b1818; } } +.stats button.mis.show_mis { background: #fdd; border: 2px solid #ff0000; margin: 0 .1em; } +@media (prefers-color-scheme: dark) { .stats button.mis.show_mis { background: #4b1818; } } +.stats button.exc { background: #f7f7f7; } +@media (prefers-color-scheme: dark) { .stats button.exc { background: #333; } } +.stats button.exc.show_exc { background: #eee; border: 2px solid #808080; margin: 0 .1em; } +@media (prefers-color-scheme: dark) { .stats button.exc.show_exc { background: #333; } } +.stats button.par { background: #ffffd5; } +@media (prefers-color-scheme: dark) { .stats button.par { background: #650; } } +.stats button.par.show_par { background: #ffa; border: 2px solid #dddd00; margin: 0 .1em; } +@media (prefers-color-scheme: dark) { .stats button.par.show_par { background: #650; } } + +#source p .annotate.long, .help_panel { display: none; position: absolute; z-index: 999; background: #ffffcc; border: 1px solid #888; border-radius: .2em; color: #333; padding: .25em .5em; } #source p .annotate.long { white-space: normal; float: right; top: 1.75em; right: 1em; height: auto; } @@ -58,41 +80,57 @@ h2.stats { margin-top: .5em; font-size: 1em; } .help_panel { padding: .5em; border: 1px solid #883; } .help_panel .legend { font-style: italic; margin-bottom: 1em; } -.indexfile .help_panel { width: 20em; height: 4em; } -.pyfile .help_panel { width: 16em; height: 8em; } +.indexfile .help_panel { width: 20em; min-height: 4em; } +.pyfile .help_panel { width: 16em; min-height: 8em; } #panel_icon { float: right; cursor: pointer; } .keyhelp { margin: .75em; } -.keyhelp .key { border: 1px solid black; border-color: #888 #333 #333 #888; padding: .1em .35em; font-family: monospace; font-weight: bold; background: #eee; } +.keyhelp .key { border: 1px solid black; border-color: #888 #333 #333 #888; padding: .1em .35em; font-family: SFMono-Regular, Menlo, Monaco, Consolas, monospace; font-weight: bold; background: #eee; } -#source { padding: 1em 0 1em 3rem; font-family: Consolas, "Liberation Mono", Menlo, Courier, monospace; } +#source { padding: 1em 0 1em 3rem; font-family: SFMono-Regular, Menlo, Monaco, Consolas, monospace; } #source p { position: relative; white-space: pre; } #source p * { box-sizing: border-box; } -#source p .n { float: left; text-align: right; width: 3rem; box-sizing: border-box; margin-left: -3rem; padding-right: 1em; color: #999999; font-family: verdana, sans-serif; } -#source p .n a { text-decoration: none; color: #999999; font-size: .8333em; line-height: 1em; } -#source p .n a:hover { text-decoration: underline; color: #999999; } +#source p .n { float: left; text-align: right; width: 3rem; box-sizing: border-box; margin-left: -3rem; padding-right: 1em; color: #999; } +@media (prefers-color-scheme: dark) { #source p .n { color: #777; } } +#source p .n a { text-decoration: none; color: #999; } +@media (prefers-color-scheme: dark) { #source p .n a { color: #777; } } +#source p .n a:hover { text-decoration: underline; color: #999; } +@media (prefers-color-scheme: dark) { #source p .n a:hover { color: #777; } } #source p.highlight .n { background: #ffdd00; } -#source p .t { display: inline-block; width: 100%; box-sizing: border-box; margin-left: -.5em; padding-left: 0.3em; border-left: 0.2em solid white; } +#source p .t { display: inline-block; width: 100%; box-sizing: border-box; margin-left: -.5em; padding-left: 0.3em; border-left: 0.2em solid #fff; } +@media (prefers-color-scheme: dark) { #source p .t { border-color: #1e1e1e; } } #source p .t:hover { background: #f2f2f2; } +@media (prefers-color-scheme: dark) { #source p .t:hover { background: #282828; } } #source p .t:hover ~ .r .annotate.long { display: block; } -#source p .t .com { color: green; font-style: italic; line-height: 1px; } +#source p .t .com { color: #008000; font-style: italic; line-height: 1px; } +@media (prefers-color-scheme: dark) { #source p .t .com { color: #6A9955; } } #source p .t .key { font-weight: bold; line-height: 1px; } -#source p .t .str { color: #000080; } +#source p .t .str { color: #0451A5; } +@media (prefers-color-scheme: dark) { #source p .t .str { color: #9CDCFE; } } #source p.mis .t { border-left: 0.2em solid #ff0000; } -#source p.mis.show_mis .t { background: #ffdddd; } +#source p.mis.show_mis .t { background: #fdd; } +@media (prefers-color-scheme: dark) { #source p.mis.show_mis .t { background: #4b1818; } } #source p.mis.show_mis .t:hover { background: #f2d2d2; } -#source p.run .t { border-left: 0.2em solid #00ff00; } -#source p.run.show_run .t { background: #ddffdd; } +@media (prefers-color-scheme: dark) { #source p.mis.show_mis .t:hover { background: #532323; } } +#source p.run .t { border-left: 0.2em solid #00dd00; } +#source p.run.show_run .t { background: #dfd; } +@media (prefers-color-scheme: dark) { #source p.run.show_run .t { background: #373d29; } } #source p.run.show_run .t:hover { background: #d2f2d2; } +@media (prefers-color-scheme: dark) { #source p.run.show_run .t:hover { background: #404633; } } #source p.exc .t { border-left: 0.2em solid #808080; } -#source p.exc.show_exc .t { background: #eeeeee; } +#source p.exc.show_exc .t { background: #eee; } +@media (prefers-color-scheme: dark) { #source p.exc.show_exc .t { background: #333; } } #source p.exc.show_exc .t:hover { background: #e2e2e2; } -#source p.par .t { border-left: 0.2em solid #eeee99; } -#source p.par.show_par .t { background: #ffffaa; } +@media (prefers-color-scheme: dark) { #source p.exc.show_exc .t:hover { background: #3c3c3c; } } +#source p.par .t { border-left: 0.2em solid #dddd00; } +#source p.par.show_par .t { background: #ffa; } +@media (prefers-color-scheme: dark) { #source p.par.show_par .t { background: #650; } } #source p.par.show_par .t:hover { background: #f2f2a2; } -#source p .r { position: absolute; top: 0; right: 2.5em; font-family: verdana, sans-serif; } -#source p .annotate { font-family: georgia; color: #666; padding-right: .5em; } +@media (prefers-color-scheme: dark) { #source p.par.show_par .t:hover { background: #6d5d0c; } } +#source p .r { position: absolute; top: 0; right: 2.5em; font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Ubuntu, Cantarell, "Helvetica Neue", sans-serif; } +#source p .annotate { font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Ubuntu, Cantarell, "Helvetica Neue", sans-serif; color: #666; padding-right: .5em; } +@media (prefers-color-scheme: dark) { #source p .annotate { color: #ddd; } } #source p .annotate.short:hover ~ .long { display: block; } #source p .annotate.long { width: 30em; right: 2.5em; } #source p input { display: none; } @@ -103,22 +141,32 @@ h2.stats { margin-top: .5em; font-size: 1em; } #source p input:checked ~ .r label.ctx::before { content: "▼ "; } #source p input:checked ~ .ctxs { padding: .25em .5em; overflow-y: scroll; max-height: 10.5em; } #source p label.ctx { color: #999; display: inline-block; padding: 0 .5em; font-size: .8333em; } -#source p .ctxs { display: block; max-height: 0; overflow-y: hidden; transition: all .2s; padding: 0 .5em; font-family: verdana, sans-serif; white-space: nowrap; background: #aaeeff; border-radius: .25em; margin-right: 1.75em; } +@media (prefers-color-scheme: dark) { #source p label.ctx { color: #777; } } +#source p .ctxs { display: block; max-height: 0; overflow-y: hidden; transition: all .2s; padding: 0 .5em; font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Ubuntu, Cantarell, "Helvetica Neue", sans-serif; white-space: nowrap; background: #aaeeff; border-radius: .25em; margin-right: 1.75em; } #source p .ctxs span { display: block; text-align: right; } +#index { font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Ubuntu, Cantarell, "Helvetica Neue", sans-serif; font-size: 0.875em; } #index td, #index th { text-align: right; width: 5em; padding: .25em .5em; border-bottom: 1px solid #eee; } +@media (prefers-color-scheme: dark) { #index td, #index th { border-color: #333; } } #index td.left, #index th.left { padding-left: 0; } #index td.right, #index th.right { padding-right: 0; } #index td.name, #index th.name { text-align: left; width: auto; } -#index th { font-style: italic; color: #333; border-bottom: 1px solid #ccc; cursor: pointer; } -#index th:hover { background: #eee; border-bottom: 1px solid #999; } -#index th.headerSortDown, #index th.headerSortUp { border-bottom: 1px solid #000; white-space: nowrap; background: #eee; } +#index th { font-style: italic; color: #333; cursor: pointer; } +@media (prefers-color-scheme: dark) { #index th { color: #ddd; } } +#index th:hover { background: #eee; } +@media (prefers-color-scheme: dark) { #index th:hover { background: #333; } } +#index th.headerSortDown, #index th.headerSortUp { white-space: nowrap; background: #eee; } +@media (prefers-color-scheme: dark) { #index th.headerSortDown, #index th.headerSortUp { background: #333; } } #index th.headerSortDown:after { content: " ↓"; } #index th.headerSortUp:after { content: " ↑"; } -#index td.name a { text-decoration: none; color: #000; } +#index td.name a { text-decoration: none; color: inherit; } #index tr.total td, #index tr.total_dynamic td { font-weight: bold; border-top: 1px solid #ccc; border-bottom: none; } -#index tr.file:hover { background: #eeeeee; } -#index tr.file:hover td.name { text-decoration: underline; color: #000; } - -#scroll_marker { position: fixed; right: 0; top: 0; width: 16px; height: 100%; background: white; border-left: 1px solid #eee; will-change: transform; } -#scroll_marker .marker { background: #ddd; position: absolute; min-height: 3px; width: 100%; } +#index tr.file:hover { background: #eee; } +@media (prefers-color-scheme: dark) { #index tr.file:hover { background: #333; } } +#index tr.file:hover td.name { text-decoration: underline; color: inherit; } + +#scroll_marker { position: fixed; right: 0; top: 0; width: 16px; height: 100%; background: #fff; border-left: 1px solid #eee; will-change: transform; } +@media (prefers-color-scheme: dark) { #scroll_marker { background: #1e1e1e; } } +@media (prefers-color-scheme: dark) { #scroll_marker { border-color: #333; } } +#scroll_marker .marker { background: #ccc; position: absolute; min-height: 3px; width: 100%; } +@media (prefers-color-scheme: dark) { #scroll_marker .marker { background: #444; } } diff --git a/coverage/htmlfiles/style.scss b/coverage/htmlfiles/style.scss index 901cccc4..b3c63e75 100644 --- a/coverage/htmlfiles/style.scss +++ b/coverage/htmlfiles/style.scss @@ -8,6 +8,9 @@ // When working on the file, this command is useful: // sass --watch --style=compact --sourcemap=none --no-cache coverage/htmlfiles/style.scss:htmlcov/style.css +// +// OR you can process sass purely in python with `pip install pysass`, then: +// pysassc --style=compact coverage/htmlfiles/style.scss coverage/htmlfiles/style.css // Ignore this comment, it's for the CSS output file: /* Don't edit this .css file. Edit the .scss file instead! */ @@ -15,6 +18,82 @@ // Dimensions $left-gutter: 3rem; + +// +// Declare colors and variables +// + +$font-normal: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Ubuntu, Cantarell, "Helvetica Neue", sans-serif; +$font-code: SFMono-Regular, Menlo, Monaco, Consolas, monospace; + +$off-button-lighten: 50%; +$hover-dark-amt: 95%; + +$focus-color: #007acc; + +$mis-color: #ff0000; +$run-color: #00dd00; +$exc-color: #808080; +$par-color: #dddd00; + +$light-bg: #fff; +$light-fg: #000; +$light-gray1: #f8f8f8; +$light-gray2: #eee; +$light-gray3: #ccc; +$light-gray4: #999; +$light-gray5: #666; +$light-gray6: #333; +$light-pln-bg: $light-bg; +$light-mis-bg: #fdd; +$light-run-bg: #dfd; +$light-exc-bg: $light-gray2; +$light-par-bg: #ffa; +$light-token-com: #008000; +$light-token-str: #0451A5; + +$dark-bg: #1e1e1e; +$dark-fg: #eee; +$dark-gray1: #222; +$dark-gray2: #333; +$dark-gray3: #444; +$dark-gray4: #777; +$dark-gray5: #aaa; +$dark-gray6: #ddd; +$dark-pln-bg: $dark-bg; +$dark-mis-bg: #4b1818; +$dark-run-bg: #373d29; +$dark-exc-bg: $dark-gray2; +$dark-par-bg: #650; +$dark-token-com: #6A9955; +$dark-token-str: #9CDCFE; + +// +// Mixins and utilities +// +@mixin background-dark($color) { + @media (prefers-color-scheme: dark) { + background: $color; + } +} +@mixin color-dark($color) { + @media (prefers-color-scheme: dark) { + color: $color; + } +} +@mixin border-color-dark($color) { + @media (prefers-color-scheme: dark) { + border-color: $color; + } +} + +// Add visual outline to navigable elements on focus improve accessibility. +@mixin focus-border { + &:active, &:focus { + outline: 2px dashed $focus-color; + } +} + // Page-wide styles html, body, h1, h2, h3, p, table, td, th { margin: 0; @@ -29,18 +108,25 @@ html, body, h1, h2, h3, p, table, td, th { // Set baseline grid to 16 pt. body { - font-family: georgia, serif; + font-family: $font-normal; font-size: 1em; + background: $light-bg; + color: $light-fg; + @include background-dark($dark-bg); + @include color-dark($dark-fg); } html>body { font-size: 16px; } -// Set base font size to 12/16 +a { + @include focus-border; +} + p { - font-size: .75em; // 12/16 - line-height: 1.33333333em; // 16/12 + font-size: .875em; + line-height: 1.4em; } table { @@ -70,34 +156,35 @@ a.nav { // Page structure #header { - background: #f8f8f8; + background: $light-gray1; + @include background-dark(black); width: 100%; - border-bottom: 1px solid #eee; + border-bottom: 1px solid $light-gray2; + @include border-color-dark($dark-gray2); } .indexfile #footer { - margin: 1em 3em; + margin: 1rem 3rem; } .pyfile #footer { - margin: 1em 1em; + margin: 1rem 1rem; } #footer .content { padding: 0; - font-size: 85%; - font-family: verdana, sans-serif; - color: #666666; + color: $light-gray5; + @include color-dark($dark-gray5); font-style: italic; } #index { - margin: 1em 0 0 3em; + margin: 1rem 0 0 3rem; } // Header styles #header .content { - padding: 1em $left-gutter; + padding: 1rem $left-gutter; } h1 { @@ -106,61 +193,81 @@ h1 { } #filter_container { - display: inline-block; float: right; margin: 0 2em 0 0; input { width: 10em; + padding: 0.2em 0.5em; + border: 2px solid $light-gray3; + background: $light-bg; + color: $light-fg; + @include border-color-dark($dark-gray3); + @include background-dark($dark-bg); + @include color-dark($dark-fg); + &:focus { + border-color: $focus-color; + } } } -$pln-color: #ffffff; -$mis-color: #ffdddd; -$run-color: #ddffdd; -$exc-color: #eeeeee; -$par-color: #ffffaa; - -$off-button-lighten: 50%; - h2.stats { margin-top: .5em; font-size: 1em; } -.stats span { +.stats button { + font-family: inherit; + font-size: inherit; border: 1px solid; - border-radius: .1em; + border-radius: .2em; + color: inherit; padding: .1em .5em; - margin: 0 .1em; + margin: 1px calc(.1em + 1px); cursor: pointer; - border-color: #ccc #999 #999 #ccc; + border-color: $light-gray3; + @include border-color-dark($dark-gray3); + @include focus-border; + + @include focus-border; &.run { - background: mix($run-color, #fff, $off-button-lighten); + background: mix($light-run-bg, $light-bg, $off-button-lighten); + @include background-dark($dark-run-bg); &.show_run { - border-color: #999 #ccc #ccc #999; - background: $run-color; + background: $light-run-bg; + @include background-dark($dark-run-bg); + border: 2px solid $run-color; + margin: 0 .1em; } } &.mis { - background: mix($mis-color, #fff, $off-button-lighten); + background: mix($light-mis-bg, $light-bg, $off-button-lighten); + @include background-dark($dark-mis-bg); &.show_mis { - border-color: #999 #ccc #ccc #999; - background: $mis-color; + background: $light-mis-bg; + @include background-dark($dark-mis-bg); + border: 2px solid $mis-color; + margin: 0 .1em; } } &.exc { - background: mix($exc-color, #fff, $off-button-lighten); + background: mix($light-exc-bg, $light-bg, $off-button-lighten); + @include background-dark($dark-exc-bg); &.show_exc { - border-color: #999 #ccc #ccc #999; - background: $exc-color; + background: $light-exc-bg; + @include background-dark($dark-exc-bg); + border: 2px solid $exc-color; + margin: 0 .1em; } } &.par { - background: mix($par-color, #fff, $off-button-lighten); + background: mix($light-par-bg, $light-bg, $off-button-lighten); + @include background-dark($dark-par-bg); &.show_par { - border-color: #999 #ccc #ccc #999; - background: $par-color; + background: $light-par-bg; + @include background-dark($dark-par-bg); + border: 2px solid $par-color; + margin: 0 .1em; } } } @@ -173,7 +280,6 @@ h2.stats { background: #ffffcc; border: 1px solid #888; border-radius: .2em; - box-shadow: #cccccc .2em .2em .2em; color: #333; padding: .25em .5em; } @@ -207,12 +313,12 @@ h2.stats { .indexfile & { width: 20em; - height: 4em; + min-height: 4em; } .pyfile & { width: 16em; - height: 8em; + min-height: 8em; } } @@ -228,7 +334,7 @@ h2.stats { border: 1px solid black; border-color: #888 #333 #333 #888; padding: .1em .35em; - font-family: monospace; + font-family: $font-code; font-weight: bold; background: #eee; } @@ -236,13 +342,6 @@ h2.stats { // Source file styles -$hover-dark-amt: 95%; -$pln-hover-color: mix($pln-color, #000, $hover-dark-amt); -$mis-hover-color: mix($mis-color, #000, $hover-dark-amt); -$run-hover-color: mix($run-color, #000, $hover-dark-amt); -$exc-hover-color: mix($exc-color, #000, $hover-dark-amt); -$par-hover-color: mix($par-color, #000, $hover-dark-amt); - // The slim bar at the left edge of the source lines, colored by coverage. $border-indicator-width: .2em; @@ -250,7 +349,7 @@ $context-panel-color: #aaeeff; #source { padding: 1em 0 1em $left-gutter; - font-family: Consolas, "Liberation Mono", Menlo, Courier, monospace; + font-family: $font-code; p { // position relative makes position:absolute pop-ups appear in the right place. @@ -268,17 +367,17 @@ $context-panel-color: #aaeeff; box-sizing: border-box; margin-left: -$left-gutter; padding-right: 1em; - color: #999999; - font-family: verdana, sans-serif; + color: $light-gray4; + @include color-dark($dark-gray4); a { text-decoration: none; - color: #999999; - font-size: .8333em; // 10/12 - line-height: 1em; + color: $light-gray4; + @include color-dark($dark-gray4); &:hover { text-decoration: underline; - color: #999999; + color: $light-gray4; + @include color-dark($dark-gray4); } } } @@ -293,10 +392,12 @@ $context-panel-color: #aaeeff; box-sizing: border-box; margin-left: -.5em; padding-left: .5em - $border-indicator-width; - border-left: $border-indicator-width solid white; + border-left: $border-indicator-width solid $light-bg; + @include border-color-dark($dark-bg); &:hover { - background: $pln-hover-color; + background: mix($light-pln-bg, $light-fg, $hover-dark-amt); + @include background-dark(mix($dark-pln-bg, $dark-fg, $hover-dark-amt)); & ~ .r .annotate.long { display: block; @@ -305,7 +406,8 @@ $context-panel-color: #aaeeff; // Syntax coloring .com { - color: green; + color: $light-token-com; + @include color-dark($dark-token-com); font-style: italic; line-height: 1px; } @@ -314,62 +416,71 @@ $context-panel-color: #aaeeff; line-height: 1px; } .str { - color: #000080; + color: $light-token-str; + @include color-dark($dark-token-str); } } &.mis { .t { - border-left: $border-indicator-width solid #ff0000; + border-left: $border-indicator-width solid $mis-color; } &.show_mis .t { - background: $mis-color; + background: $light-mis-bg; + @include background-dark($dark-mis-bg); &:hover { - background: $mis-hover-color; + background: mix($light-mis-bg, $light-fg, $hover-dark-amt); + @include background-dark(mix($dark-mis-bg, $dark-fg, $hover-dark-amt)); } } } &.run { .t { - border-left: $border-indicator-width solid #00ff00; + border-left: $border-indicator-width solid $run-color; } &.show_run .t { - background: $run-color; + background: $light-run-bg; + @include background-dark($dark-run-bg); &:hover { - background: $run-hover-color; + background: mix($light-run-bg, $light-fg, $hover-dark-amt); + @include background-dark(mix($dark-run-bg, $dark-fg, $hover-dark-amt)); } } } &.exc { .t { - border-left: $border-indicator-width solid #808080; + border-left: $border-indicator-width solid $exc-color; } &.show_exc .t { - background: $exc-color; + background: $light-exc-bg; + @include background-dark($dark-exc-bg); &:hover { - background: $exc-hover-color; + background: mix($light-exc-bg, $light-fg, $hover-dark-amt); + @include background-dark(mix($dark-exc-bg, $dark-fg, $hover-dark-amt)); } } } &.par { .t { - border-left: $border-indicator-width solid #eeee99; + border-left: $border-indicator-width solid $par-color; } &.show_par .t { - background: $par-color; + background: $light-par-bg; + @include background-dark($dark-par-bg); &:hover { - background: $par-hover-color; + background: mix($light-par-bg, $light-fg, $hover-dark-amt); + @include background-dark(mix($dark-par-bg, $dark-fg, $hover-dark-amt)); } } @@ -379,12 +490,13 @@ $context-panel-color: #aaeeff; position: absolute; top: 0; right: 2.5em; - font-family: verdana, sans-serif; + font-family: $font-normal; } .annotate { - font-family: georgia; - color: #666; + font-family: $font-normal; + color: $light-gray5; + @include color-dark($dark-gray6); padding-right: .5em; &.short:hover ~ .long { @@ -432,7 +544,8 @@ $context-panel-color: #aaeeff; } label.ctx { - color: #999; + color: $light-gray4; + @include color-dark($dark-gray4); display: inline-block; padding: 0 .5em; font-size: .8333em; // 10/12 @@ -444,7 +557,7 @@ $context-panel-color: #aaeeff; overflow-y: hidden; transition: all .2s; padding: 0 .5em; - font-family: verdana, sans-serif; + font-family: $font-normal; white-space: nowrap; background: $context-panel-color; border-radius: .25em; @@ -460,11 +573,15 @@ $context-panel-color: #aaeeff; // index styles #index { + font-family: $font-normal; + font-size: 0.875em; + td, th { text-align: right; width: 5em; padding: .25em .5em; - border-bottom: 1px solid #eee; + border-bottom: 1px solid $light-gray2; + @include border-color-dark($dark-gray2); &.left { padding-left: 0; } @@ -478,17 +595,17 @@ $context-panel-color: #aaeeff; } th { font-style: italic; - color: #333; - border-bottom: 1px solid #ccc; + color: $light-gray6; + @include color-dark($dark-gray6); cursor: pointer; &:hover { - background: #eee; - border-bottom: 1px solid #999; + background: $light-gray2; + @include background-dark($dark-gray2); } &.headerSortDown, &.headerSortUp { - border-bottom: 1px solid #000; white-space: nowrap; - background: #eee; + background: $light-gray2; + @include background-dark($dark-gray2); } &.headerSortDown:after { content: " ↓"; @@ -499,7 +616,7 @@ $context-panel-color: #aaeeff; } td.name a { text-decoration: none; - color: #000; + color: inherit; } tr.total td, @@ -509,10 +626,11 @@ $context-panel-color: #aaeeff; border-bottom: none; } tr.file:hover { - background: #eeeeee; + background: $light-gray2; + @include background-dark($dark-gray2); td.name { text-decoration: underline; - color: #000; + color: inherit; } } } @@ -524,12 +642,15 @@ $context-panel-color: #aaeeff; top: 0; width: 16px; height: 100%; - background: white; - border-left: 1px solid #eee; + background: $light-bg; + border-left: 1px solid $light-gray2; + @include background-dark($dark-bg); + @include border-color-dark($dark-gray2); will-change: transform; // for faster scrolling of fixed element in Chrome .marker { - background: #ddd; + background: $light-gray3; + @include background-dark($dark-gray3); position: absolute; min-height: 3px; width: 100%; diff --git a/coverage/multiproc.py b/coverage/multiproc.py index 2931b3be..0afcb0c9 100644 --- a/coverage/multiproc.py +++ b/coverage/multiproc.py @@ -28,7 +28,7 @@ original_bootstrap = OriginalProcess._bootstrap class ProcessWithCoverage(OriginalProcess): # pylint: disable=abstract-method """A replacement for multiprocess.Process that starts coverage.""" - def _bootstrap(self, *args, **kwargs): # pylint: disable=arguments-differ + def _bootstrap(self, *args, **kwargs): # pylint: disable=signature-differs """Wrapper around _bootstrap to start coverage.""" try: from coverage import Coverage # avoid circular import diff --git a/doc/cmd.rst b/doc/cmd.rst index cbbb26bb..31ae6e01 100644 --- a/doc/cmd.rst +++ b/doc/cmd.rst @@ -371,6 +371,9 @@ If you have :ref:`recorded contexts <contexts>`, the ``--contexts`` option lets you choose which contexts to report on. See :ref:`context_reporting` for details. +The ``--precision`` option controls the number of digits displayed after the +decimal point in coverage percentages, defaulting to none. + Other common reporting options are described above in :ref:`cmd_reporting`. @@ -418,6 +421,9 @@ The ``--skip-covered`` switch will skip any file with 100% coverage, letting you focus on the files that still need attention. The ``--skip-empty`` switch will skip any file with no executable statements. +The ``--precision`` option controls the number of digits displayed after the +decimal point in coverage percentages, defaulting to none. + If you have :ref:`recorded contexts <contexts>`, the ``--contexts`` option lets you choose which contexts to report on, and the ``--show-contexts`` option will annotate lines with the contexts that ran them. See :ref:`context_reporting` @@ -74,7 +74,9 @@ - add an "Unreleased" section to the top. - git push - Update Tidelift: - - make upload_relnotes + - make tidelift_relnotes +- Update GitHub releases: + - make github_releases - Update readthedocs - IF NOT PRE-RELEASE: - update git "stable" branch to point to latest release diff --git a/requirements/dev.pip b/requirements/dev.pip index a11729cd..96591414 100644 --- a/requirements/dev.pip +++ b/requirements/dev.pip @@ -4,8 +4,7 @@ # Requirements for doing local development work on coverage.py. # https://requires.io/github/nedbat/coveragepy/requirements/ -pip==20.0.2 -virtualenv==16.7.9 +-r pip.pip pluggy==0.13.1 @@ -15,9 +14,9 @@ pluggy==0.13.1 # for linting. greenlet==0.4.15 -pylint==2.4.4 +pylint==2.5.2 check-manifest==0.40 -readme_renderer==24.0 +readme_renderer==26.0 # for kitting. requests==2.22.0 diff --git a/requirements/pip.pip b/requirements/pip.pip new file mode 100644 index 00000000..71c7f213 --- /dev/null +++ b/requirements/pip.pip @@ -0,0 +1,5 @@ +# Licensed under the Apache License: http://www.apache.org/licenses/LICENSE-2.0 +# For details: https://github.com/nedbat/coveragepy/blob/master/NOTICE.txt + +pip==20.0.2 +virtualenv==16.7.9 diff --git a/tests/gold/html/Makefile b/tests/gold/html/Makefile index fa98714e..604ece7a 100644 --- a/tests/gold/html/Makefile +++ b/tests/gold/html/Makefile @@ -7,7 +7,7 @@ help: complete: ## Copy support files into directories so the HTML can be viewed properly. @for sub in *; do \ - if [[ -f $$sub/index.html ]]; then \ + if [ -f "$$sub/index.html" ]; then \ echo Copying into $$sub ; \ cp -n support/* $$sub ; \ fi ; \ diff --git a/tests/gold/html/a/a_py.html b/tests/gold/html/a/a_py.html index 2ce52414..d534c6a3 100644 --- a/tests/gold/html/a/a_py.html +++ b/tests/gold/html/a/a_py.html @@ -22,9 +22,9 @@ <img id="keyboard_icon" src="keybd_closed.png" alt="Show keyboard shortcuts" /> <h2 class="stats"> 3 statements - <span class="run shortkey_r button_toggle_run">2 run</span> - <span class="mis show_mis shortkey_m button_toggle_mis">1 missing</span> - <span class="exc show_exc shortkey_x button_toggle_exc">0 excluded</span> + <button type="button" class="run shortkey_r button_toggle_run" title="Toggle lines run">2 run</button> + <button type="button" class="mis show_mis shortkey_m button_toggle_mis" title="Toggle lines missing">1 missing</button> + <button type="button" class="exc show_exc shortkey_x button_toggle_exc" title="Toggle lines excluded">0 excluded</button> </h2> </div> </div> diff --git a/tests/gold/html/b_branch/b_py.html b/tests/gold/html/b_branch/b_py.html index ce8bb875..67a1b83b 100644 --- a/tests/gold/html/b_branch/b_py.html +++ b/tests/gold/html/b_branch/b_py.html @@ -22,10 +22,10 @@ <img id="keyboard_icon" src="keybd_closed.png" alt="Show keyboard shortcuts" /> <h2 class="stats"> 17 statements - <span class="run shortkey_r button_toggle_run">14 run</span> - <span class="mis show_mis shortkey_m button_toggle_mis">3 missing</span> - <span class="exc show_exc shortkey_x button_toggle_exc">0 excluded</span> - <span class="par run show_par shortkey_p button_toggle_par">4 partial</span> + <button type="button" class="run shortkey_r button_toggle_run" title="Toggle lines run">14 run</button> + <button type="button" class="mis show_mis shortkey_m button_toggle_mis" title="Toggle lines missing">3 missing</button> + <button type="button" class="exc show_exc shortkey_x button_toggle_exc" title="Toggle lines excluded">0 excluded</button> + <button type="button" class="par run show_par shortkey_p button_toggle_par" title="Toggle lines partially run">4 partial</button> </h2> </div> </div> diff --git a/tests/gold/html/bom/2/bom_py.html b/tests/gold/html/bom/2/bom_py.html index 3d1c98fb..74f4f2fe 100644 --- a/tests/gold/html/bom/2/bom_py.html +++ b/tests/gold/html/bom/2/bom_py.html @@ -22,9 +22,9 @@ <img id="keyboard_icon" src="keybd_closed.png" alt="Show keyboard shortcuts" /> <h2 class="stats"> 7 statements - <span class="run shortkey_r button_toggle_run">5 run</span> - <span class="mis show_mis shortkey_m button_toggle_mis">2 missing</span> - <span class="exc show_exc shortkey_x button_toggle_exc">0 excluded</span> + <button type="button" class="run shortkey_r button_toggle_run" title="Toggle lines run">5 run</button> + <button type="button" class="mis show_mis shortkey_m button_toggle_mis" title="Toggle lines missing">2 missing</button> + <button type="button" class="exc show_exc shortkey_x button_toggle_exc" title="Toggle lines excluded">0 excluded</button> </h2> </div> </div> diff --git a/tests/gold/html/bom/bom_py.html b/tests/gold/html/bom/bom_py.html index 635f8b51..10b84ede 100644 --- a/tests/gold/html/bom/bom_py.html +++ b/tests/gold/html/bom/bom_py.html @@ -22,9 +22,9 @@ <img id="keyboard_icon" src="keybd_closed.png" alt="Show keyboard shortcuts" /> <h2 class="stats"> 7 statements - <span class="run shortkey_r button_toggle_run">5 run</span> - <span class="mis show_mis shortkey_m button_toggle_mis">2 missing</span> - <span class="exc show_exc shortkey_x button_toggle_exc">0 excluded</span> + <button type="button" class="run shortkey_r button_toggle_run" title="Toggle lines run">5 run</button> + <button type="button" class="mis show_mis shortkey_m button_toggle_mis" title="Toggle lines missing">2 missing</button> + <button type="button" class="exc show_exc shortkey_x button_toggle_exc" title="Toggle lines excluded">0 excluded</button> </h2> </div> </div> diff --git a/tests/gold/html/isolatin1/isolatin1_py.html b/tests/gold/html/isolatin1/isolatin1_py.html index 9c12c445..b344bad6 100644 --- a/tests/gold/html/isolatin1/isolatin1_py.html +++ b/tests/gold/html/isolatin1/isolatin1_py.html @@ -22,9 +22,9 @@ <img id="keyboard_icon" src="keybd_closed.png" alt="Show keyboard shortcuts" /> <h2 class="stats"> 2 statements - <span class="run shortkey_r button_toggle_run">2 run</span> - <span class="mis show_mis shortkey_m button_toggle_mis">0 missing</span> - <span class="exc show_exc shortkey_x button_toggle_exc">0 excluded</span> + <button type="button" class="run shortkey_r button_toggle_run" title="Toggle lines run">2 run</button> + <button type="button" class="mis show_mis shortkey_m button_toggle_mis" title="Toggle lines missing">0 missing</button> + <button type="button" class="exc show_exc shortkey_x button_toggle_exc" title="Toggle lines excluded">0 excluded</button> </h2> </div> </div> diff --git a/tests/gold/html/omit_1/m1_py.html b/tests/gold/html/omit_1/m1_py.html index 60923930..57584495 100644 --- a/tests/gold/html/omit_1/m1_py.html +++ b/tests/gold/html/omit_1/m1_py.html @@ -22,9 +22,9 @@ <img id="keyboard_icon" src="keybd_closed.png" alt="Show keyboard shortcuts" /> <h2 class="stats"> 2 statements - <span class="run shortkey_r button_toggle_run">2 run</span> - <span class="mis show_mis shortkey_m button_toggle_mis">0 missing</span> - <span class="exc show_exc shortkey_x button_toggle_exc">0 excluded</span> + <button type="button" class="run shortkey_r button_toggle_run" title="Toggle lines run">2 run</button> + <button type="button" class="mis show_mis shortkey_m button_toggle_mis" title="Toggle lines missing">0 missing</button> + <button type="button" class="exc show_exc shortkey_x button_toggle_exc" title="Toggle lines excluded">0 excluded</button> </h2> </div> </div> diff --git a/tests/gold/html/omit_1/m2_py.html b/tests/gold/html/omit_1/m2_py.html index de060f32..e8c1791d 100644 --- a/tests/gold/html/omit_1/m2_py.html +++ b/tests/gold/html/omit_1/m2_py.html @@ -22,9 +22,9 @@ <img id="keyboard_icon" src="keybd_closed.png" alt="Show keyboard shortcuts" /> <h2 class="stats"> 2 statements - <span class="run shortkey_r button_toggle_run">2 run</span> - <span class="mis show_mis shortkey_m button_toggle_mis">0 missing</span> - <span class="exc show_exc shortkey_x button_toggle_exc">0 excluded</span> + <button type="button" class="run shortkey_r button_toggle_run" title="Toggle lines run">2 run</button> + <button type="button" class="mis show_mis shortkey_m button_toggle_mis" title="Toggle lines missing">0 missing</button> + <button type="button" class="exc show_exc shortkey_x button_toggle_exc" title="Toggle lines excluded">0 excluded</button> </h2> </div> </div> diff --git a/tests/gold/html/omit_1/m3_py.html b/tests/gold/html/omit_1/m3_py.html index 76a91a4a..e714d47f 100644 --- a/tests/gold/html/omit_1/m3_py.html +++ b/tests/gold/html/omit_1/m3_py.html @@ -22,9 +22,9 @@ <img id="keyboard_icon" src="keybd_closed.png" alt="Show keyboard shortcuts" /> <h2 class="stats"> 2 statements - <span class="run shortkey_r button_toggle_run">2 run</span> - <span class="mis show_mis shortkey_m button_toggle_mis">0 missing</span> - <span class="exc show_exc shortkey_x button_toggle_exc">0 excluded</span> + <button type="button" class="run shortkey_r button_toggle_run" title="Toggle lines run">2 run</button> + <button type="button" class="mis show_mis shortkey_m button_toggle_mis" title="Toggle lines missing">0 missing</button> + <button type="button" class="exc show_exc shortkey_x button_toggle_exc" title="Toggle lines excluded">0 excluded</button> </h2> </div> </div> diff --git a/tests/gold/html/omit_1/main_py.html b/tests/gold/html/omit_1/main_py.html index 9f242537..28173d12 100644 --- a/tests/gold/html/omit_1/main_py.html +++ b/tests/gold/html/omit_1/main_py.html @@ -22,9 +22,9 @@ <img id="keyboard_icon" src="keybd_closed.png" alt="Show keyboard shortcuts" /> <h2 class="stats"> 8 statements - <span class="run shortkey_r button_toggle_run">8 run</span> - <span class="mis show_mis shortkey_m button_toggle_mis">0 missing</span> - <span class="exc show_exc shortkey_x button_toggle_exc">0 excluded</span> + <button type="button" class="run shortkey_r button_toggle_run" title="Toggle lines run">8 run</button> + <button type="button" class="mis show_mis shortkey_m button_toggle_mis" title="Toggle lines missing">0 missing</button> + <button type="button" class="exc show_exc shortkey_x button_toggle_exc" title="Toggle lines excluded">0 excluded</button> </h2> </div> </div> diff --git a/tests/gold/html/omit_2/m2_py.html b/tests/gold/html/omit_2/m2_py.html index de060f32..e8c1791d 100644 --- a/tests/gold/html/omit_2/m2_py.html +++ b/tests/gold/html/omit_2/m2_py.html @@ -22,9 +22,9 @@ <img id="keyboard_icon" src="keybd_closed.png" alt="Show keyboard shortcuts" /> <h2 class="stats"> 2 statements - <span class="run shortkey_r button_toggle_run">2 run</span> - <span class="mis show_mis shortkey_m button_toggle_mis">0 missing</span> - <span class="exc show_exc shortkey_x button_toggle_exc">0 excluded</span> + <button type="button" class="run shortkey_r button_toggle_run" title="Toggle lines run">2 run</button> + <button type="button" class="mis show_mis shortkey_m button_toggle_mis" title="Toggle lines missing">0 missing</button> + <button type="button" class="exc show_exc shortkey_x button_toggle_exc" title="Toggle lines excluded">0 excluded</button> </h2> </div> </div> diff --git a/tests/gold/html/omit_2/m3_py.html b/tests/gold/html/omit_2/m3_py.html index 76a91a4a..e714d47f 100644 --- a/tests/gold/html/omit_2/m3_py.html +++ b/tests/gold/html/omit_2/m3_py.html @@ -22,9 +22,9 @@ <img id="keyboard_icon" src="keybd_closed.png" alt="Show keyboard shortcuts" /> <h2 class="stats"> 2 statements - <span class="run shortkey_r button_toggle_run">2 run</span> - <span class="mis show_mis shortkey_m button_toggle_mis">0 missing</span> - <span class="exc show_exc shortkey_x button_toggle_exc">0 excluded</span> + <button type="button" class="run shortkey_r button_toggle_run" title="Toggle lines run">2 run</button> + <button type="button" class="mis show_mis shortkey_m button_toggle_mis" title="Toggle lines missing">0 missing</button> + <button type="button" class="exc show_exc shortkey_x button_toggle_exc" title="Toggle lines excluded">0 excluded</button> </h2> </div> </div> diff --git a/tests/gold/html/omit_2/main_py.html b/tests/gold/html/omit_2/main_py.html index 9f242537..28173d12 100644 --- a/tests/gold/html/omit_2/main_py.html +++ b/tests/gold/html/omit_2/main_py.html @@ -22,9 +22,9 @@ <img id="keyboard_icon" src="keybd_closed.png" alt="Show keyboard shortcuts" /> <h2 class="stats"> 8 statements - <span class="run shortkey_r button_toggle_run">8 run</span> - <span class="mis show_mis shortkey_m button_toggle_mis">0 missing</span> - <span class="exc show_exc shortkey_x button_toggle_exc">0 excluded</span> + <button type="button" class="run shortkey_r button_toggle_run" title="Toggle lines run">8 run</button> + <button type="button" class="mis show_mis shortkey_m button_toggle_mis" title="Toggle lines missing">0 missing</button> + <button type="button" class="exc show_exc shortkey_x button_toggle_exc" title="Toggle lines excluded">0 excluded</button> </h2> </div> </div> diff --git a/tests/gold/html/omit_3/m3_py.html b/tests/gold/html/omit_3/m3_py.html index 76a91a4a..e714d47f 100644 --- a/tests/gold/html/omit_3/m3_py.html +++ b/tests/gold/html/omit_3/m3_py.html @@ -22,9 +22,9 @@ <img id="keyboard_icon" src="keybd_closed.png" alt="Show keyboard shortcuts" /> <h2 class="stats"> 2 statements - <span class="run shortkey_r button_toggle_run">2 run</span> - <span class="mis show_mis shortkey_m button_toggle_mis">0 missing</span> - <span class="exc show_exc shortkey_x button_toggle_exc">0 excluded</span> + <button type="button" class="run shortkey_r button_toggle_run" title="Toggle lines run">2 run</button> + <button type="button" class="mis show_mis shortkey_m button_toggle_mis" title="Toggle lines missing">0 missing</button> + <button type="button" class="exc show_exc shortkey_x button_toggle_exc" title="Toggle lines excluded">0 excluded</button> </h2> </div> </div> diff --git a/tests/gold/html/omit_3/main_py.html b/tests/gold/html/omit_3/main_py.html index 9f242537..28173d12 100644 --- a/tests/gold/html/omit_3/main_py.html +++ b/tests/gold/html/omit_3/main_py.html @@ -22,9 +22,9 @@ <img id="keyboard_icon" src="keybd_closed.png" alt="Show keyboard shortcuts" /> <h2 class="stats"> 8 statements - <span class="run shortkey_r button_toggle_run">8 run</span> - <span class="mis show_mis shortkey_m button_toggle_mis">0 missing</span> - <span class="exc show_exc shortkey_x button_toggle_exc">0 excluded</span> + <button type="button" class="run shortkey_r button_toggle_run" title="Toggle lines run">8 run</button> + <button type="button" class="mis show_mis shortkey_m button_toggle_mis" title="Toggle lines missing">0 missing</button> + <button type="button" class="exc show_exc shortkey_x button_toggle_exc" title="Toggle lines excluded">0 excluded</button> </h2> </div> </div> diff --git a/tests/gold/html/omit_4/m1_py.html b/tests/gold/html/omit_4/m1_py.html index 60923930..57584495 100644 --- a/tests/gold/html/omit_4/m1_py.html +++ b/tests/gold/html/omit_4/m1_py.html @@ -22,9 +22,9 @@ <img id="keyboard_icon" src="keybd_closed.png" alt="Show keyboard shortcuts" /> <h2 class="stats"> 2 statements - <span class="run shortkey_r button_toggle_run">2 run</span> - <span class="mis show_mis shortkey_m button_toggle_mis">0 missing</span> - <span class="exc show_exc shortkey_x button_toggle_exc">0 excluded</span> + <button type="button" class="run shortkey_r button_toggle_run" title="Toggle lines run">2 run</button> + <button type="button" class="mis show_mis shortkey_m button_toggle_mis" title="Toggle lines missing">0 missing</button> + <button type="button" class="exc show_exc shortkey_x button_toggle_exc" title="Toggle lines excluded">0 excluded</button> </h2> </div> </div> diff --git a/tests/gold/html/omit_4/m3_py.html b/tests/gold/html/omit_4/m3_py.html index 76a91a4a..e714d47f 100644 --- a/tests/gold/html/omit_4/m3_py.html +++ b/tests/gold/html/omit_4/m3_py.html @@ -22,9 +22,9 @@ <img id="keyboard_icon" src="keybd_closed.png" alt="Show keyboard shortcuts" /> <h2 class="stats"> 2 statements - <span class="run shortkey_r button_toggle_run">2 run</span> - <span class="mis show_mis shortkey_m button_toggle_mis">0 missing</span> - <span class="exc show_exc shortkey_x button_toggle_exc">0 excluded</span> + <button type="button" class="run shortkey_r button_toggle_run" title="Toggle lines run">2 run</button> + <button type="button" class="mis show_mis shortkey_m button_toggle_mis" title="Toggle lines missing">0 missing</button> + <button type="button" class="exc show_exc shortkey_x button_toggle_exc" title="Toggle lines excluded">0 excluded</button> </h2> </div> </div> diff --git a/tests/gold/html/omit_4/main_py.html b/tests/gold/html/omit_4/main_py.html index 9f242537..28173d12 100644 --- a/tests/gold/html/omit_4/main_py.html +++ b/tests/gold/html/omit_4/main_py.html @@ -22,9 +22,9 @@ <img id="keyboard_icon" src="keybd_closed.png" alt="Show keyboard shortcuts" /> <h2 class="stats"> 8 statements - <span class="run shortkey_r button_toggle_run">8 run</span> - <span class="mis show_mis shortkey_m button_toggle_mis">0 missing</span> - <span class="exc show_exc shortkey_x button_toggle_exc">0 excluded</span> + <button type="button" class="run shortkey_r button_toggle_run" title="Toggle lines run">8 run</button> + <button type="button" class="mis show_mis shortkey_m button_toggle_mis" title="Toggle lines missing">0 missing</button> + <button type="button" class="exc show_exc shortkey_x button_toggle_exc" title="Toggle lines excluded">0 excluded</button> </h2> </div> </div> diff --git a/tests/gold/html/omit_5/m1_py.html b/tests/gold/html/omit_5/m1_py.html index 60923930..57584495 100644 --- a/tests/gold/html/omit_5/m1_py.html +++ b/tests/gold/html/omit_5/m1_py.html @@ -22,9 +22,9 @@ <img id="keyboard_icon" src="keybd_closed.png" alt="Show keyboard shortcuts" /> <h2 class="stats"> 2 statements - <span class="run shortkey_r button_toggle_run">2 run</span> - <span class="mis show_mis shortkey_m button_toggle_mis">0 missing</span> - <span class="exc show_exc shortkey_x button_toggle_exc">0 excluded</span> + <button type="button" class="run shortkey_r button_toggle_run" title="Toggle lines run">2 run</button> + <button type="button" class="mis show_mis shortkey_m button_toggle_mis" title="Toggle lines missing">0 missing</button> + <button type="button" class="exc show_exc shortkey_x button_toggle_exc" title="Toggle lines excluded">0 excluded</button> </h2> </div> </div> diff --git a/tests/gold/html/omit_5/main_py.html b/tests/gold/html/omit_5/main_py.html index 9f242537..28173d12 100644 --- a/tests/gold/html/omit_5/main_py.html +++ b/tests/gold/html/omit_5/main_py.html @@ -22,9 +22,9 @@ <img id="keyboard_icon" src="keybd_closed.png" alt="Show keyboard shortcuts" /> <h2 class="stats"> 8 statements - <span class="run shortkey_r button_toggle_run">8 run</span> - <span class="mis show_mis shortkey_m button_toggle_mis">0 missing</span> - <span class="exc show_exc shortkey_x button_toggle_exc">0 excluded</span> + <button type="button" class="run shortkey_r button_toggle_run" title="Toggle lines run">8 run</button> + <button type="button" class="mis show_mis shortkey_m button_toggle_mis" title="Toggle lines missing">0 missing</button> + <button type="button" class="exc show_exc shortkey_x button_toggle_exc" title="Toggle lines excluded">0 excluded</button> </h2> </div> </div> diff --git a/tests/gold/html/other/blah_blah_other_py.html b/tests/gold/html/other/blah_blah_other_py.html index d3a4ebfc..8f0309d4 100644 --- a/tests/gold/html/other/blah_blah_other_py.html +++ b/tests/gold/html/other/blah_blah_other_py.html @@ -22,9 +22,9 @@ <img id="keyboard_icon" src="keybd_closed.png" alt="Show keyboard shortcuts" /> <h2 class="stats"> 1 statements - <span class="run shortkey_r button_toggle_run">1 run</span> - <span class="mis show_mis shortkey_m button_toggle_mis">0 missing</span> - <span class="exc show_exc shortkey_x button_toggle_exc">0 excluded</span> + <button type="button" class="run shortkey_r button_toggle_run" title="Toggle lines run">1 run</button> + <button type="button" class="mis show_mis shortkey_m button_toggle_mis" title="Toggle lines missing">0 missing</button> + <button type="button" class="exc show_exc shortkey_x button_toggle_exc" title="Toggle lines excluded">0 excluded</button> </h2> </div> </div> diff --git a/tests/gold/html/other/here_py.html b/tests/gold/html/other/here_py.html index df2715d6..c2f6b5f1 100644 --- a/tests/gold/html/other/here_py.html +++ b/tests/gold/html/other/here_py.html @@ -22,9 +22,9 @@ <img id="keyboard_icon" src="keybd_closed.png" alt="Show keyboard shortcuts" /> <h2 class="stats"> 4 statements - <span class="run shortkey_r button_toggle_run">3 run</span> - <span class="mis show_mis shortkey_m button_toggle_mis">1 missing</span> - <span class="exc show_exc shortkey_x button_toggle_exc">0 excluded</span> + <button type="button" class="run shortkey_r button_toggle_run" title="Toggle lines run">3 run</button> + <button type="button" class="mis show_mis shortkey_m button_toggle_mis" title="Toggle lines missing">1 missing</button> + <button type="button" class="exc show_exc shortkey_x button_toggle_exc" title="Toggle lines excluded">0 excluded</button> </h2> </div> </div> diff --git a/tests/gold/html/partial/partial_py.html b/tests/gold/html/partial/partial_py.html index f004808a..abd755d0 100644 --- a/tests/gold/html/partial/partial_py.html +++ b/tests/gold/html/partial/partial_py.html @@ -22,10 +22,10 @@ <img id="keyboard_icon" src="keybd_closed.png" alt="Show keyboard shortcuts" /> <h2 class="stats"> 7 statements - <span class="run shortkey_r button_toggle_run">7 run</span> - <span class="mis show_mis shortkey_m button_toggle_mis">0 missing</span> - <span class="exc show_exc shortkey_x button_toggle_exc">1 excluded</span> - <span class="par run show_par shortkey_p button_toggle_par">1 partial</span> + <button type="button" class="run shortkey_r button_toggle_run" title="Toggle lines run">7 run</button> + <button type="button" class="mis show_mis shortkey_m button_toggle_mis" title="Toggle lines missing">0 missing</button> + <button type="button" class="exc show_exc shortkey_x button_toggle_exc" title="Toggle lines excluded">1 excluded</button> + <button type="button" class="par run show_par shortkey_p button_toggle_par" title="Toggle lines partially run">1 partial</button> </h2> </div> </div> diff --git a/tests/gold/html/styled/a_py.html b/tests/gold/html/styled/a_py.html index 4687e464..7b6f9dcd 100644 --- a/tests/gold/html/styled/a_py.html +++ b/tests/gold/html/styled/a_py.html @@ -23,9 +23,9 @@ <img id="keyboard_icon" src="keybd_closed.png" alt="Show keyboard shortcuts" /> <h2 class="stats"> 3 statements - <span class="run shortkey_r button_toggle_run">2 run</span> - <span class="mis show_mis shortkey_m button_toggle_mis">1 missing</span> - <span class="exc show_exc shortkey_x button_toggle_exc">0 excluded</span> + <button type="button" class="run shortkey_r button_toggle_run" title="Toggle lines run">2 run</button> + <button type="button" class="mis show_mis shortkey_m button_toggle_mis" title="Toggle lines missing">1 missing</button> + <button type="button" class="exc show_exc shortkey_x button_toggle_exc" title="Toggle lines excluded">0 excluded</button> </h2> </div> </div> diff --git a/tests/gold/html/styled/style.css b/tests/gold/html/styled/style.css index e8ff5765..5a79a2e7 100644 --- a/tests/gold/html/styled/style.css +++ b/tests/gold/html/styled/style.css @@ -4,11 +4,15 @@ /* Don't edit this .css file. Edit the .scss file instead! */ html, body, h1, h2, h3, p, table, td, th { margin: 0; padding: 0; border: 0; font-weight: inherit; font-style: inherit; font-size: 100%; font-family: inherit; vertical-align: baseline; } -body { font-family: georgia, serif; font-size: 1em; } +body { font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Ubuntu, Cantarell, "Helvetica Neue", sans-serif; font-size: 1em; background: #fff; color: #000; } +@media (prefers-color-scheme: dark) { body { background: #1e1e1e; } } +@media (prefers-color-scheme: dark) { body { color: #eee; } } html > body { font-size: 16px; } -p { font-size: .75em; line-height: 1.33333333em; } +a:active, a:focus { outline: 2px dashed #007acc; } + +p { font-size: .875em; line-height: 1.4em; } table { border-collapse: collapse; } @@ -22,35 +26,53 @@ a.nav { text-decoration: none; color: inherit; } a.nav:hover { text-decoration: underline; color: inherit; } #header { background: #f8f8f8; width: 100%; border-bottom: 1px solid #eee; } +@media (prefers-color-scheme: dark) { #header { background: black; } } +@media (prefers-color-scheme: dark) { #header { border-color: #333; } } -.indexfile #footer { margin: 1em 3em; } +.indexfile #footer { margin: 1rem 3rem; } -.pyfile #footer { margin: 1em 1em; } +.pyfile #footer { margin: 1rem 1rem; } -#footer .content { padding: 0; font-size: 85%; font-family: verdana, sans-serif; color: #666666; font-style: italic; } +#footer .content { padding: 0; color: #666; font-style: italic; } +@media (prefers-color-scheme: dark) { #footer .content { color: #aaa; } } -#index { margin: 1em 0 0 3em; } +#index { margin: 1rem 0 0 3rem; } -#header .content { padding: 1em 3rem; } +#header .content { padding: 1rem 3rem; } h1 { font-size: 1.25em; display: inline-block; } -#filter_container { display: inline-block; float: right; margin: 0 2em 0 0; } -#filter_container input { width: 10em; } +#filter_container { float: right; margin: 0 2em 0 0; } +#filter_container input { width: 10em; padding: 0.2em 0.5em; border: 2px solid #ccc; background: #fff; color: #000; } +@media (prefers-color-scheme: dark) { #filter_container input { border-color: #444; } } +@media (prefers-color-scheme: dark) { #filter_container input { background: #1e1e1e; } } +@media (prefers-color-scheme: dark) { #filter_container input { color: #eee; } } +#filter_container input:focus { border-color: #007acc; } h2.stats { margin-top: .5em; font-size: 1em; } -.stats span { border: 1px solid; border-radius: .1em; padding: .1em .5em; margin: 0 .1em; cursor: pointer; border-color: #ccc #999 #999 #ccc; } -.stats span.run { background: #eeffee; } -.stats span.run.show_run { border-color: #999 #ccc #ccc #999; background: #ddffdd; } -.stats span.mis { background: #ffeeee; } -.stats span.mis.show_mis { border-color: #999 #ccc #ccc #999; background: #ffdddd; } -.stats span.exc { background: #f7f7f7; } -.stats span.exc.show_exc { border-color: #999 #ccc #ccc #999; background: #eeeeee; } -.stats span.par { background: #ffffd5; } -.stats span.par.show_par { border-color: #999 #ccc #ccc #999; background: #ffffaa; } - -#source p .annotate.long, .help_panel { display: none; position: absolute; z-index: 999; background: #ffffcc; border: 1px solid #888; border-radius: .2em; box-shadow: #cccccc .2em .2em .2em; color: #333; padding: .25em .5em; } +.stats button { font-family: inherit; font-size: inherit; border: 1px solid; border-radius: .2em; color: inherit; padding: .1em .5em; margin: 1px calc(.1em + 1px); cursor: pointer; border-color: #ccc; } +@media (prefers-color-scheme: dark) { .stats button { border-color: #444; } } +.stats button:active, .stats button:focus { outline: 2px dashed #007acc; } +.stats button:active, .stats button:focus { outline: 2px dashed #007acc; } +.stats button.run { background: #eeffee; } +@media (prefers-color-scheme: dark) { .stats button.run { background: #373d29; } } +.stats button.run.show_run { background: #dfd; border: 2px solid #00dd00; margin: 0 .1em; } +@media (prefers-color-scheme: dark) { .stats button.run.show_run { background: #373d29; } } +.stats button.mis { background: #ffeeee; } +@media (prefers-color-scheme: dark) { .stats button.mis { background: #4b1818; } } +.stats button.mis.show_mis { background: #fdd; border: 2px solid #ff0000; margin: 0 .1em; } +@media (prefers-color-scheme: dark) { .stats button.mis.show_mis { background: #4b1818; } } +.stats button.exc { background: #f7f7f7; } +@media (prefers-color-scheme: dark) { .stats button.exc { background: #333; } } +.stats button.exc.show_exc { background: #eee; border: 2px solid #808080; margin: 0 .1em; } +@media (prefers-color-scheme: dark) { .stats button.exc.show_exc { background: #333; } } +.stats button.par { background: #ffffd5; } +@media (prefers-color-scheme: dark) { .stats button.par { background: #650; } } +.stats button.par.show_par { background: #ffa; border: 2px solid #dddd00; margin: 0 .1em; } +@media (prefers-color-scheme: dark) { .stats button.par.show_par { background: #650; } } + +#source p .annotate.long, .help_panel { display: none; position: absolute; z-index: 999; background: #ffffcc; border: 1px solid #888; border-radius: .2em; color: #333; padding: .25em .5em; } #source p .annotate.long { white-space: normal; float: right; top: 1.75em; right: 1em; height: auto; } @@ -58,41 +80,57 @@ h2.stats { margin-top: .5em; font-size: 1em; } .help_panel { padding: .5em; border: 1px solid #883; } .help_panel .legend { font-style: italic; margin-bottom: 1em; } -.indexfile .help_panel { width: 20em; height: 4em; } -.pyfile .help_panel { width: 16em; height: 8em; } +.indexfile .help_panel { width: 20em; min-height: 4em; } +.pyfile .help_panel { width: 16em; min-height: 8em; } #panel_icon { float: right; cursor: pointer; } .keyhelp { margin: .75em; } -.keyhelp .key { border: 1px solid black; border-color: #888 #333 #333 #888; padding: .1em .35em; font-family: monospace; font-weight: bold; background: #eee; } +.keyhelp .key { border: 1px solid black; border-color: #888 #333 #333 #888; padding: .1em .35em; font-family: SFMono-Regular, Menlo, Monaco, Consolas, monospace; font-weight: bold; background: #eee; } -#source { padding: 1em 0 1em 3rem; font-family: Consolas, "Liberation Mono", Menlo, Courier, monospace; } +#source { padding: 1em 0 1em 3rem; font-family: SFMono-Regular, Menlo, Monaco, Consolas, monospace; } #source p { position: relative; white-space: pre; } #source p * { box-sizing: border-box; } -#source p .n { float: left; text-align: right; width: 3rem; box-sizing: border-box; margin-left: -3rem; padding-right: 1em; color: #999999; font-family: verdana, sans-serif; } -#source p .n a { text-decoration: none; color: #999999; font-size: .8333em; line-height: 1em; } -#source p .n a:hover { text-decoration: underline; color: #999999; } +#source p .n { float: left; text-align: right; width: 3rem; box-sizing: border-box; margin-left: -3rem; padding-right: 1em; color: #999; } +@media (prefers-color-scheme: dark) { #source p .n { color: #777; } } +#source p .n a { text-decoration: none; color: #999; } +@media (prefers-color-scheme: dark) { #source p .n a { color: #777; } } +#source p .n a:hover { text-decoration: underline; color: #999; } +@media (prefers-color-scheme: dark) { #source p .n a:hover { color: #777; } } #source p.highlight .n { background: #ffdd00; } -#source p .t { display: inline-block; width: 100%; box-sizing: border-box; margin-left: -.5em; padding-left: 0.3em; border-left: 0.2em solid white; } +#source p .t { display: inline-block; width: 100%; box-sizing: border-box; margin-left: -.5em; padding-left: 0.3em; border-left: 0.2em solid #fff; } +@media (prefers-color-scheme: dark) { #source p .t { border-color: #1e1e1e; } } #source p .t:hover { background: #f2f2f2; } +@media (prefers-color-scheme: dark) { #source p .t:hover { background: #282828; } } #source p .t:hover ~ .r .annotate.long { display: block; } -#source p .t .com { color: green; font-style: italic; line-height: 1px; } +#source p .t .com { color: #008000; font-style: italic; line-height: 1px; } +@media (prefers-color-scheme: dark) { #source p .t .com { color: #6A9955; } } #source p .t .key { font-weight: bold; line-height: 1px; } -#source p .t .str { color: #000080; } +#source p .t .str { color: #0451A5; } +@media (prefers-color-scheme: dark) { #source p .t .str { color: #9CDCFE; } } #source p.mis .t { border-left: 0.2em solid #ff0000; } -#source p.mis.show_mis .t { background: #ffdddd; } +#source p.mis.show_mis .t { background: #fdd; } +@media (prefers-color-scheme: dark) { #source p.mis.show_mis .t { background: #4b1818; } } #source p.mis.show_mis .t:hover { background: #f2d2d2; } -#source p.run .t { border-left: 0.2em solid #00ff00; } -#source p.run.show_run .t { background: #ddffdd; } +@media (prefers-color-scheme: dark) { #source p.mis.show_mis .t:hover { background: #532323; } } +#source p.run .t { border-left: 0.2em solid #00dd00; } +#source p.run.show_run .t { background: #dfd; } +@media (prefers-color-scheme: dark) { #source p.run.show_run .t { background: #373d29; } } #source p.run.show_run .t:hover { background: #d2f2d2; } +@media (prefers-color-scheme: dark) { #source p.run.show_run .t:hover { background: #404633; } } #source p.exc .t { border-left: 0.2em solid #808080; } -#source p.exc.show_exc .t { background: #eeeeee; } +#source p.exc.show_exc .t { background: #eee; } +@media (prefers-color-scheme: dark) { #source p.exc.show_exc .t { background: #333; } } #source p.exc.show_exc .t:hover { background: #e2e2e2; } -#source p.par .t { border-left: 0.2em solid #eeee99; } -#source p.par.show_par .t { background: #ffffaa; } +@media (prefers-color-scheme: dark) { #source p.exc.show_exc .t:hover { background: #3c3c3c; } } +#source p.par .t { border-left: 0.2em solid #dddd00; } +#source p.par.show_par .t { background: #ffa; } +@media (prefers-color-scheme: dark) { #source p.par.show_par .t { background: #650; } } #source p.par.show_par .t:hover { background: #f2f2a2; } -#source p .r { position: absolute; top: 0; right: 2.5em; font-family: verdana, sans-serif; } -#source p .annotate { font-family: georgia; color: #666; padding-right: .5em; } +@media (prefers-color-scheme: dark) { #source p.par.show_par .t:hover { background: #6d5d0c; } } +#source p .r { position: absolute; top: 0; right: 2.5em; font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Ubuntu, Cantarell, "Helvetica Neue", sans-serif; } +#source p .annotate { font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Ubuntu, Cantarell, "Helvetica Neue", sans-serif; color: #666; padding-right: .5em; } +@media (prefers-color-scheme: dark) { #source p .annotate { color: #ddd; } } #source p .annotate.short:hover ~ .long { display: block; } #source p .annotate.long { width: 30em; right: 2.5em; } #source p input { display: none; } @@ -103,22 +141,32 @@ h2.stats { margin-top: .5em; font-size: 1em; } #source p input:checked ~ .r label.ctx::before { content: "▼ "; } #source p input:checked ~ .ctxs { padding: .25em .5em; overflow-y: scroll; max-height: 10.5em; } #source p label.ctx { color: #999; display: inline-block; padding: 0 .5em; font-size: .8333em; } -#source p .ctxs { display: block; max-height: 0; overflow-y: hidden; transition: all .2s; padding: 0 .5em; font-family: verdana, sans-serif; white-space: nowrap; background: #aaeeff; border-radius: .25em; margin-right: 1.75em; } +@media (prefers-color-scheme: dark) { #source p label.ctx { color: #777; } } +#source p .ctxs { display: block; max-height: 0; overflow-y: hidden; transition: all .2s; padding: 0 .5em; font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Ubuntu, Cantarell, "Helvetica Neue", sans-serif; white-space: nowrap; background: #aaeeff; border-radius: .25em; margin-right: 1.75em; } #source p .ctxs span { display: block; text-align: right; } +#index { font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Ubuntu, Cantarell, "Helvetica Neue", sans-serif; font-size: 0.875em; } #index td, #index th { text-align: right; width: 5em; padding: .25em .5em; border-bottom: 1px solid #eee; } +@media (prefers-color-scheme: dark) { #index td, #index th { border-color: #333; } } #index td.left, #index th.left { padding-left: 0; } #index td.right, #index th.right { padding-right: 0; } #index td.name, #index th.name { text-align: left; width: auto; } -#index th { font-style: italic; color: #333; border-bottom: 1px solid #ccc; cursor: pointer; } -#index th:hover { background: #eee; border-bottom: 1px solid #999; } -#index th.headerSortDown, #index th.headerSortUp { border-bottom: 1px solid #000; white-space: nowrap; background: #eee; } +#index th { font-style: italic; color: #333; cursor: pointer; } +@media (prefers-color-scheme: dark) { #index th { color: #ddd; } } +#index th:hover { background: #eee; } +@media (prefers-color-scheme: dark) { #index th:hover { background: #333; } } +#index th.headerSortDown, #index th.headerSortUp { white-space: nowrap; background: #eee; } +@media (prefers-color-scheme: dark) { #index th.headerSortDown, #index th.headerSortUp { background: #333; } } #index th.headerSortDown:after { content: " ↓"; } #index th.headerSortUp:after { content: " ↑"; } -#index td.name a { text-decoration: none; color: #000; } +#index td.name a { text-decoration: none; color: inherit; } #index tr.total td, #index tr.total_dynamic td { font-weight: bold; border-top: 1px solid #ccc; border-bottom: none; } -#index tr.file:hover { background: #eeeeee; } -#index tr.file:hover td.name { text-decoration: underline; color: #000; } - -#scroll_marker { position: fixed; right: 0; top: 0; width: 16px; height: 100%; background: white; border-left: 1px solid #eee; will-change: transform; } -#scroll_marker .marker { background: #ddd; position: absolute; min-height: 3px; width: 100%; } +#index tr.file:hover { background: #eee; } +@media (prefers-color-scheme: dark) { #index tr.file:hover { background: #333; } } +#index tr.file:hover td.name { text-decoration: underline; color: inherit; } + +#scroll_marker { position: fixed; right: 0; top: 0; width: 16px; height: 100%; background: #fff; border-left: 1px solid #eee; will-change: transform; } +@media (prefers-color-scheme: dark) { #scroll_marker { background: #1e1e1e; } } +@media (prefers-color-scheme: dark) { #scroll_marker { border-color: #333; } } +#scroll_marker .marker { background: #ccc; position: absolute; min-height: 3px; width: 100%; } +@media (prefers-color-scheme: dark) { #scroll_marker .marker { background: #444; } } diff --git a/tests/gold/html/unicode/unicode_py.html b/tests/gold/html/unicode/unicode_py.html index 46722961..a4218bcc 100644 --- a/tests/gold/html/unicode/unicode_py.html +++ b/tests/gold/html/unicode/unicode_py.html @@ -22,9 +22,9 @@ <img id="keyboard_icon" src="keybd_closed.png" alt="Show keyboard shortcuts" /> <h2 class="stats"> 2 statements - <span class="run shortkey_r button_toggle_run">2 run</span> - <span class="mis show_mis shortkey_m button_toggle_mis">0 missing</span> - <span class="exc show_exc shortkey_x button_toggle_exc">0 excluded</span> + <button type="button" class="run shortkey_r button_toggle_run" title="Toggle lines run">2 run</button> + <button type="button" class="mis show_mis shortkey_m button_toggle_mis" title="Toggle lines missing">0 missing</button> + <button type="button" class="exc show_exc shortkey_x button_toggle_exc" title="Toggle lines excluded">0 excluded</button> </h2> </div> </div> diff --git a/tests/test_cmdline.py b/tests/test_cmdline.py index f5e8e96a..2406d93d 100644 --- a/tests/test_cmdline.py +++ b/tests/test_cmdline.py @@ -37,11 +37,11 @@ class BaseCmdLineTest(CoverageTest): _defaults.Coverage().html_report( directory=None, ignore_errors=None, include=None, omit=None, morfs=[], skip_covered=None, show_contexts=None, title=None, contexts=None, - skip_empty=None, + skip_empty=None, precision=None, ) _defaults.Coverage().report( ignore_errors=None, include=None, omit=None, morfs=[], - show_missing=None, skip_covered=None, contexts=None, skip_empty=None, + show_missing=None, skip_covered=None, contexts=None, skip_empty=None, precision=None, ) _defaults.Coverage().xml_report( ignore_errors=None, include=None, omit=None, morfs=[], outfile=None, @@ -49,7 +49,7 @@ class BaseCmdLineTest(CoverageTest): ) _defaults.Coverage().json_report( ignore_errors=None, include=None, omit=None, morfs=[], outfile=None, - contexts=None, pretty_print=None, show_contexts=None + contexts=None, pretty_print=None, show_contexts=None, ) _defaults.Coverage( cover_pylib=None, data_suffix=None, timid=None, branch=None, @@ -324,6 +324,11 @@ class CmdLineTest(BaseCmdLineTest): cov.load() cov.html_report(morfs=["mod1", "mod2", "mod3"]) """) + self.cmd_executes("html --precision=3", """\ + cov = Coverage() + cov.load() + cov.html_report(precision=3) + """) self.cmd_executes("html --title=Hello_there", """\ cov = Coverage() cov.load() @@ -367,6 +372,11 @@ class CmdLineTest(BaseCmdLineTest): cov.load() cov.report(morfs=["mod1", "mod2", "mod3"]) """) + self.cmd_executes("report --precision=7", """\ + cov = Coverage() + cov.load() + cov.report(precision=7) + """) self.cmd_executes("report --skip-covered", """\ cov = Coverage() cov.load() @@ -781,7 +791,7 @@ class CmdLineStdoutTest(BaseCmdLineTest): def test_minimum_help(self): self.command_line("") out = self.stdout() - self.assertIn("Code coverage for Python.", out) + self.assertIn("Code coverage for Python", out) self.assertLess(out.count("\n"), 4) def test_version(self): diff --git a/tests/test_config.py b/tests/test_config.py index 51d9b9ef..89ecb17c 100644 --- a/tests/test_config.py +++ b/tests/test_config.py @@ -3,6 +3,7 @@ # For details: https://github.com/nedbat/coveragepy/blob/master/NOTICE.txt """Test the config file handling for coverage.py""" + from collections import OrderedDict import mock @@ -62,6 +63,8 @@ class ConfigTest(CoverageTest): # A .coveragerc file will be read into the configuration. self.make_file("pyproject.toml", """\ # This is just a bogus toml file for testing. + [tool.somethingelse] + authors = ["Joe D'Ávila <joe@gmail.com>"] [tool.coverage.run] concurrency = ["a", "b"] timid = true @@ -70,20 +73,23 @@ class ConfigTest(CoverageTest): [tool.coverage.report] precision = 3 fail_under = 90.5 + [tool.coverage.html] + title = "tabblo & «ταБЬℓσ»" [tool.coverage.plugins.a_plugin] hello = "world" """) cov = coverage.Coverage(config_file="pyproject.toml") self.assertTrue(cov.config.timid) self.assertFalse(cov.config.branch) - self.assertEqual(cov.config.concurrency, ["a", "b"]) - self.assertEqual(cov.config.data_file, ".hello_kitty.data") - self.assertEqual(cov.config.plugins, ["plugins.a_plugin"]) + self.assertEqual(cov.config.concurrency, [u"a", u"b"]) + self.assertEqual(cov.config.data_file, u".hello_kitty.data") + self.assertEqual(cov.config.plugins, [u"plugins.a_plugin"]) self.assertEqual(cov.config.precision, 3) + self.assertEqual(cov.config.html_title, u"tabblo & «ταБЬℓσ»") self.assertAlmostEqual(cov.config.fail_under, 90.5) self.assertEqual( cov.config.get_plugin_options("plugins.a_plugin"), - {'hello': 'world'} + {u"hello": u"world"} ) # Test that our class doesn't reject integers when loading floats diff --git a/tests/test_phystokens.py b/tests/test_phystokens.py index 6f38fc94..1256694a 100644 --- a/tests/test_phystokens.py +++ b/tests/test_phystokens.py @@ -285,5 +285,5 @@ class CompileUnicodeTest(CoverageTest): def test_double_coding_declaration(self): # Build this string in a weird way so that actual vim's won't try to # interpret it... - uni = u"# -*- coding:utf-8 -*-\n# v" "im: fileencoding=utf-8\n" + uni = u"# -*- coding:utf-8 -*-\n# v" + "im: fileencoding=utf-8\n" self.assert_compile_unicode(uni) @@ -14,8 +14,8 @@ extras = deps = # Check here for what might be out of date: # https://requires.io/github/nedbat/coveragepy/requirements/ + -r requirements/pip.pip -r requirements/pytest.pip - pip==20.0.2 setuptools==41.4.0 # gevent 1.3 causes a failure: https://github.com/nedbat/coveragepy/issues/663 py{27,35,36}: gevent==1.2.2 |