Skip to content
Permalink

Comparing changes

Choose two branches to see what’s changed or to start a new pull request. If you need to, you can also or learn more about diff comparisons.

Open a pull request

Create a new pull request by comparing changes across two branches. If you need to, you can also . Learn more about diff comparisons here.
base repository: nedbat/coveragepy
Failed to load repositories. Confirm that selected base ref is valid, then try again.
Loading
base: 7.4.4
Choose a base ref
...
head repository: nedbat/coveragepy
Failed to load repositories. Confirm that selected head ref is valid, then try again.
Loading
compare: 7.5.0
Choose a head ref

Commits on Mar 14, 2024

  1. build: bump version

    nedbat committed Mar 14, 2024
    Copy the full SHA
    3f75d80 View commit details
  2. build: keep twine output quiet

    nedbat committed Mar 14, 2024
    Copy the full SHA
    fb36364 View commit details

Commits on Mar 15, 2024

  1. Copy the full SHA
    6a269a6 View commit details
  2. build: 3.13.0a5 is available

    nedbat committed Mar 15, 2024
    Copy the full SHA
    fb23aa6 View commit details

Commits on Mar 17, 2024

  1. Copy the full SHA
    45cbdd2 View commit details
  2. Copy the full SHA
    49b3288 View commit details
  3. Copy the full SHA
    73cba7e View commit details
  4. Copy the full SHA
    7877fcc View commit details
  5. perf: more functools.lru_cache for reducing work

    Got rid of some custom one-element caching, including one that didn't help
    because the duplicated requests were not sequential.  Used functools.lru_cache
    instead of my own code.  Caching file_reporters now means a method might be
    called more than once, which @Expensive was trying to prevent.  But the results
    are cached in the parser, so no worries.
    nedbat committed Mar 17, 2024
    Copy the full SHA
    121703b View commit details
  6. Copy the full SHA
    c02c967 View commit details

Commits on Mar 22, 2024

  1. Copy the full SHA
    52db90e View commit details

Commits on Mar 29, 2024

  1. Copy the full SHA
    9c7857d View commit details

Commits on Apr 6, 2024

  1. refactor: html report files start with z_

    When I download an HTML report and unzip it, I need to open the
    directory and find the index.html file.  With a d_ prefix, index.html is
    almost the last file in the directory.  Change the prefix to z_ so that
    now index.html is nearly the first. More convenient for me.
    nedbat committed Apr 6, 2024
    Copy the full SHA
    a1e6eed View commit details

Commits on Apr 7, 2024

  1. Copy the full SHA
    d915667 View commit details

Commits on Apr 18, 2024

  1. docs: measurement, not testing

    nedbat committed Apr 18, 2024
    Copy the full SHA
    12809de View commit details
  2. Copy the full SHA
    366c05b View commit details

Commits on Apr 21, 2024

  1. chore: make upgrade

    nedbat committed Apr 21, 2024
    Copy the full SHA
    ebe08b9 View commit details
  2. Copy the full SHA
    df04b17 View commit details
  3. Copy the full SHA
    15f9c1c View commit details

Commits on Apr 22, 2024

  1. Copy the full SHA
    4e50273 View commit details
  2. Copy the full SHA
    68c5f93 View commit details
  3. refactor: remove unused data item

    `statement` has been unused since
    cfdcace
    nedbat committed Apr 22, 2024
    Copy the full SHA
    19fda8b View commit details
  4. Copy the full SHA
    3376bd3 View commit details
  5. Copy the full SHA
    00103e2 View commit details
  6. Copy the full SHA
    7235b80 View commit details
  7. Copy the full SHA
    3ff14b1 View commit details
  8. fix: improve the layout of the HTML report

    Names are proportionally spaced, but with a minimum width.  Column
    headers are proportionally spaced with no minimum width.
    nedbat committed Apr 22, 2024
    Copy the full SHA
    ca9f622 View commit details
  9. feat: function and class pages separate file name from region name.

    Filtering in the index page is now smartcase.
    nedbat committed Apr 22, 2024
    Copy the full SHA
    6483980 View commit details

Commits on Apr 23, 2024

  1. build: bump version to 7.5.0a1

    nedbat committed Apr 23, 2024
    Copy the full SHA
    478a120 View commit details
  2. Copy the full SHA
    7057c7d View commit details
  3. refactor: sorting is more modularized

    Also, sort order is stored when changed, instead of onunload.
    nedbat committed Apr 23, 2024
    Copy the full SHA
    b1c2a58 View commit details
  4. Copy the full SHA
    de8e905 View commit details
  5. Copy the full SHA
    7771c53 View commit details
  6. Copy the full SHA
    3d47c9f View commit details
  7. Copy the full SHA
    e016967 View commit details
  8. Copy the full SHA
    74c87a8 View commit details
  9. Copy the full SHA
    a6ba1c8 View commit details
  10. Copy the full SHA
    2ff9933 View commit details
  11. Copy the full SHA
    40a052e View commit details
  12. Copy the full SHA
    b115ed3 View commit details
  13. Copy the full SHA
    583f0c0 View commit details
  14. Copy the full SHA
    41e01d3 View commit details
  15. docs: prep for 7.5.0

    nedbat committed Apr 23, 2024
    Copy the full SHA
    ed97cfb View commit details
  16. docs: sample HTML for 7.5.0

    nedbat committed Apr 23, 2024
    Copy the full SHA
    5f4e034 View commit details
Showing with 9,478 additions and 1,851 deletions.
  1. +9 −7 .github/workflows/coverage.yml
  2. +15 −13 .github/workflows/kit.yml
  3. +4 −3 .github/workflows/python-nightly.yml
  4. +3 −3 .github/workflows/quality.yml
  5. +10 −7 .github/workflows/testsuite.yml
  6. +32 −0 CHANGES.rst
  7. +1 −0 CONTRIBUTORS.txt
  8. +2 −2 Makefile
  9. +3 −2 README.rst
  10. +1 −4 coverage/__init__.py
  11. +2 −2 coverage/cmdline.py
  12. +2 −2 coverage/config.py
  13. +16 −20 coverage/control.py
  14. +2 −2 coverage/files.py
  15. +288 −156 coverage/html.py
  16. +95 −48 coverage/htmlfiles/coverage_html.js
  17. +48 −26 coverage/htmlfiles/index.html
  18. +15 −15 coverage/htmlfiles/pyfile.html
  19. +44 −16 coverage/htmlfiles/style.css
  20. +68 −23 coverage/htmlfiles/style.scss
  21. +1 −1 coverage/jsonreport.py
  22. +1 −1 coverage/lcovreport.py
  23. +1 −25 coverage/misc.py
  24. +4 −0 coverage/parser.py
  25. +9 −23 coverage/phystokens.py
  26. +55 −0 coverage/plugin.py
  27. +12 −5 coverage/python.py
  28. +114 −0 coverage/regions.py
  29. +6 −6 coverage/report_core.py
  30. +144 −122 coverage/results.py
  31. +1 −0 coverage/types.py
  32. +1 −1 coverage/version.py
  33. +7 −0 doc/api_plugin.rst
  34. +3 −3 doc/conf.py
  35. +8 −5 doc/config.rst
  36. +82 −73 doc/contributing.rst
  37. +1 −1 doc/index.rst
  38. +553 −0 doc/sample_html/class_index.html
  39. +95 −48 doc/sample_html/coverage_html.js
  40. +2,393 −0 doc/sample_html/function_index.html
  41. +48 −39 doc/sample_html/index.html
  42. +1 −1 doc/sample_html/status.json
  43. +44 −16 doc/sample_html/style.css
  44. +19 −19 doc/sample_html/{d_7b071bdc2a35fa80___init___py.html → z_7b071bdc2a35fa80___init___py.html}
  45. +20 −20 doc/sample_html/{d_7b071bdc2a35fa80___main___py.html → z_7b071bdc2a35fa80___main___py.html}
  46. +20 −20 doc/sample_html/{d_7b071bdc2a35fa80_cogapp_py.html → z_7b071bdc2a35fa80_cogapp_py.html}
  47. +20 −20 doc/sample_html/{d_7b071bdc2a35fa80_makefiles_py.html → z_7b071bdc2a35fa80_makefiles_py.html}
  48. +20 −20 doc/sample_html/{d_7b071bdc2a35fa80_test_cogapp_py.html → z_7b071bdc2a35fa80_test_cogapp_py.html}
  49. +20 −20 ...mple_html/{d_7b071bdc2a35fa80_test_makefiles_py.html → z_7b071bdc2a35fa80_test_makefiles_py.html}
  50. +20 −20 ...le_html/{d_7b071bdc2a35fa80_test_whiteutils_py.html → z_7b071bdc2a35fa80_test_whiteutils_py.html}
  51. +20 −20 doc/sample_html/{d_7b071bdc2a35fa80_utils_py.html → z_7b071bdc2a35fa80_utils_py.html}
  52. +19 −19 doc/sample_html/{d_7b071bdc2a35fa80_whiteutils_py.html → z_7b071bdc2a35fa80_whiteutils_py.html}
  53. +3 −1 pyproject.toml
  54. +28 −20 requirements/dev.pip
  55. +6 −6 requirements/kit.pip
  56. +4 −4 requirements/light-threads.pip
  57. +5 −5 requirements/mypy.pip
  58. +4 −4 requirements/pip-tools.pip
  59. +3 −3 requirements/pip.pip
  60. +4 −4 requirements/pytest.pip
  61. +4 −4 requirements/tox.pip
  62. +5 −4 tests/coveragetest.py
  63. 0 ...d/annotate/anno_dir/{d_80084bf2fba02475___init__.py,cover → z_80084bf2fba02475___init__.py,cover}
  64. 0 tests/gold/annotate/anno_dir/{d_80084bf2fba02475_a.py,cover → z_80084bf2fba02475_a.py,cover}
  65. 0 ...d/annotate/anno_dir/{d_b039179a8a4ce2c2___init__.py,cover → z_b039179a8a4ce2c2___init__.py,cover}
  66. 0 tests/gold/annotate/anno_dir/{d_b039179a8a4ce2c2_b.py,cover → z_b039179a8a4ce2c2_b.py,cover}
  67. +18 −18 tests/gold/html/a/a_py.html
  68. +115 −0 tests/gold/html/a/class_index.html
  69. +115 −0 tests/gold/html/a/function_index.html
  70. +29 −20 tests/gold/html/a/index.html
  71. +18 −18 tests/gold/html/b_branch/b_py.html
  72. +123 −0 tests/gold/html/b_branch/class_index.html
  73. +153 −0 tests/gold/html/b_branch/function_index.html
  74. +31 −22 tests/gold/html/b_branch/index.html
  75. +18 −18 tests/gold/html/bom/bom_py.html
  76. +115 −0 tests/gold/html/bom/class_index.html
  77. +115 −0 tests/gold/html/bom/function_index.html
  78. +29 −20 tests/gold/html/bom/index.html
  79. +115 −0 tests/gold/html/contexts/class_index.html
  80. +139 −0 tests/gold/html/contexts/function_index.html
  81. +29 −20 tests/gold/html/contexts/index.html
  82. +27 −27 tests/gold/html/contexts/two_tests_py.html
  83. +115 −0 tests/gold/html/isolatin1/class_index.html
  84. +115 −0 tests/gold/html/isolatin1/function_index.html
  85. +29 −20 tests/gold/html/isolatin1/index.html
  86. +18 −18 tests/gold/html/isolatin1/isolatin1_py.html
  87. +139 −0 tests/gold/html/omit_1/class_index.html
  88. +139 −0 tests/gold/html/omit_1/function_index.html
  89. +32 −23 tests/gold/html/omit_1/index.html
  90. +18 −18 tests/gold/html/omit_1/m1_py.html
  91. +18 −18 tests/gold/html/omit_1/m2_py.html
  92. +18 −18 tests/gold/html/omit_1/m3_py.html
  93. +18 −18 tests/gold/html/omit_1/main_py.html
  94. +131 −0 tests/gold/html/omit_2/class_index.html
  95. +131 −0 tests/gold/html/omit_2/function_index.html
  96. +31 −22 tests/gold/html/omit_2/index.html
  97. +18 −18 tests/gold/html/omit_2/m2_py.html
  98. +18 −18 tests/gold/html/omit_2/m3_py.html
  99. +18 −18 tests/gold/html/omit_2/main_py.html
  100. +123 −0 tests/gold/html/omit_3/class_index.html
  101. +123 −0 tests/gold/html/omit_3/function_index.html
  102. +30 −21 tests/gold/html/omit_3/index.html
  103. +18 −18 tests/gold/html/omit_3/m3_py.html
  104. +18 −18 tests/gold/html/omit_3/main_py.html
  105. +131 −0 tests/gold/html/omit_4/class_index.html
  106. +131 −0 tests/gold/html/omit_4/function_index.html
  107. +31 −22 tests/gold/html/omit_4/index.html
  108. +18 −18 tests/gold/html/omit_4/m1_py.html
  109. +18 −18 tests/gold/html/omit_4/m3_py.html
  110. +18 −18 tests/gold/html/omit_4/main_py.html
  111. +123 −0 tests/gold/html/omit_5/class_index.html
  112. +123 −0 tests/gold/html/omit_5/function_index.html
  113. +30 −21 tests/gold/html/omit_5/index.html
  114. +18 −18 tests/gold/html/omit_5/m1_py.html
  115. +18 −18 tests/gold/html/omit_5/main_py.html
  116. +20 −20 tests/gold/html/other/blah_blah_other_py.html
  117. +123 −0 tests/gold/html/other/class_index.html
  118. +123 −0 tests/gold/html/other/function_index.html
  119. +19 −19 tests/gold/html/other/here_py.html
  120. +31 −22 tests/gold/html/other/index.html
  121. +123 −0 tests/gold/html/partial/class_index.html
  122. +123 −0 tests/gold/html/partial/function_index.html
  123. +31 −22 tests/gold/html/partial/index.html
  124. +18 −18 tests/gold/html/partial/partial_py.html
  125. +123 −0 tests/gold/html/partial_626/class_index.html
  126. +123 −0 tests/gold/html/partial_626/function_index.html
  127. +31 −22 tests/gold/html/partial_626/index.html
  128. +18 −18 tests/gold/html/partial_626/partial_py.html
  129. +18 −18 tests/gold/html/styled/a_py.html
  130. +116 −0 tests/gold/html/styled/class_index.html
  131. +116 −0 tests/gold/html/styled/function_index.html
  132. +29 −20 tests/gold/html/styled/index.html
  133. +44 −16 tests/gold/html/styled/style.css
  134. +105 −58 tests/gold/html/support/coverage_html.js
  135. +45 −17 tests/gold/html/support/style.css
  136. +115 −0 tests/gold/html/unicode/class_index.html
  137. +115 −0 tests/gold/html/unicode/function_index.html
  138. +29 −20 tests/gold/html/unicode/index.html
  139. +18 −18 tests/gold/html/unicode/unicode_py.html
  140. +1 −1 tests/test_debug.py
  141. +8 −8 tests/test_files.py
  142. +32 −5 tests/test_html.py
  143. +2 −2 tests/test_plugins.py
  144. +122 −0 tests/test_regions.py
  145. +1 −1 tests/test_report_common.py
  146. +2 −10 tests/test_results.py
16 changes: 9 additions & 7 deletions .github/workflows/coverage.yml
Original file line number Diff line number Diff line change
@@ -30,7 +30,7 @@ concurrency:
jobs:
coverage:
name: "${{ matrix.python-version }} on ${{ matrix.os }}"
runs-on: "${{ matrix.os }}-latest"
runs-on: "${{ matrix.os }}-${{ matrix.os-version || 'latest' }}"
env:
MATRIX_ID: "${{ matrix.python-version }}.${{ matrix.os }}"

@@ -69,13 +69,15 @@ jobs:
python-version: "pypy-3.9"
- os: windows
python-version: "pypy-3.10"
# Skip 3.13.0a4 and pin to 3.13.0a3 for Windows due to build error.
# Undo when 3.13.0a5 is released.
- os: windows
python-version: "3.13"
# GitHub is rolling out macos 14, but it doesn't have Python 3.8 or 3.9.
# https://mastodon.social/@hugovk/112320493602782374
include:
- os: windows
python-version: "3.13.0-alpha.3"
- python-version: "3.8"
os: "macos"
os-version: "13"
- python-version: "3.9"
os: "macos"
os-version: "13"
# If one job fails, stop the whole thing.
fail-fast: true

28 changes: 15 additions & 13 deletions .github/workflows/kit.yml
Original file line number Diff line number Diff line change
@@ -48,7 +48,7 @@ concurrency:
jobs:
wheels:
name: "${{ matrix.py }} ${{ matrix.os }} ${{ matrix.arch }} wheels"
runs-on: ${{ matrix.os }}-latest
runs-on: "${{ matrix.os }}-${{ matrix.os-version || 'latest' }}"
env:
MATRIX_ID: "${{ matrix.py }}-${{ matrix.os }}-${{ matrix.arch }}"
strategy:
@@ -84,7 +84,7 @@ jobs:
#
# # Some OS/arch combinations need overrides for the Python versions:
# os_arch_pys = {
# ("macos", "arm64"): ["cp38", "cp39", "cp310", "cp311", "cp312"],
# # ("macos", "arm64"): ["cp38", "cp39", "cp310", "cp311", "cp312"],
# }
#
# #----- ^^^ ---------------------- ^^^ -----
@@ -98,6 +98,8 @@ jobs:
# "py": the_py,
# "arch": the_arch,
# }
# if the_os == "macos":
# them["os-version"] = "13"
# print(f"- {json.dumps(them)}")
# ]]]
- {"os": "ubuntu", "py": "cp38", "arch": "x86_64"}
@@ -115,16 +117,16 @@ jobs:
- {"os": "ubuntu", "py": "cp310", "arch": "aarch64"}
- {"os": "ubuntu", "py": "cp311", "arch": "aarch64"}
- {"os": "ubuntu", "py": "cp312", "arch": "aarch64"}
- {"os": "macos", "py": "cp38", "arch": "arm64"}
- {"os": "macos", "py": "cp39", "arch": "arm64"}
- {"os": "macos", "py": "cp310", "arch": "arm64"}
- {"os": "macos", "py": "cp311", "arch": "arm64"}
- {"os": "macos", "py": "cp312", "arch": "arm64"}
- {"os": "macos", "py": "cp38", "arch": "x86_64"}
- {"os": "macos", "py": "cp39", "arch": "x86_64"}
- {"os": "macos", "py": "cp310", "arch": "x86_64"}
- {"os": "macos", "py": "cp311", "arch": "x86_64"}
- {"os": "macos", "py": "cp312", "arch": "x86_64"}
- {"os": "macos", "py": "cp38", "arch": "arm64", "os-version": "13"}
- {"os": "macos", "py": "cp39", "arch": "arm64", "os-version": "13"}
- {"os": "macos", "py": "cp310", "arch": "arm64", "os-version": "13"}
- {"os": "macos", "py": "cp311", "arch": "arm64", "os-version": "13"}
- {"os": "macos", "py": "cp312", "arch": "arm64", "os-version": "13"}
- {"os": "macos", "py": "cp38", "arch": "x86_64", "os-version": "13"}
- {"os": "macos", "py": "cp39", "arch": "x86_64", "os-version": "13"}
- {"os": "macos", "py": "cp310", "arch": "x86_64", "os-version": "13"}
- {"os": "macos", "py": "cp311", "arch": "x86_64", "os-version": "13"}
- {"os": "macos", "py": "cp312", "arch": "x86_64", "os-version": "13"}
- {"os": "windows", "py": "cp38", "arch": "x86"}
- {"os": "windows", "py": "cp39", "arch": "x86"}
- {"os": "windows", "py": "cp310", "arch": "x86"}
@@ -135,7 +137,7 @@ jobs:
- {"os": "windows", "py": "cp310", "arch": "AMD64"}
- {"os": "windows", "py": "cp311", "arch": "AMD64"}
- {"os": "windows", "py": "cp312", "arch": "AMD64"}
# [[[end]]] (checksum: a6ca53e9c620c9e5ca85e7322122056c)
# [[[end]]] (checksum: 16ed28c185d540b2d9972a0217864472)
fail-fast: false

steps:
7 changes: 4 additions & 3 deletions .github/workflows/python-nightly.yml
Original file line number Diff line number Diff line change
@@ -37,8 +37,10 @@ jobs:
# because jammy ships 3.10, and deadsnakes doesn't want to clobber it.
# https://launchpad.net/~deadsnakes/+archive/ubuntu/nightly/+packages
# https://github.com/deadsnakes/issues/issues/234
# bionic: 18, focal: 20, jammy: 22
runs-on: ubuntu-20.04
# See https://github.com/deadsnakes/nightly for the source of the nightly
# builds.
# bionic: 18, focal: 20, jammy: 22, noble: 24
runs-on: ubuntu-22.04
# If it doesn't finish in an hour, it's not going to. Don't spin for six
# hours needlessly.
timeout-minutes: 60
@@ -50,7 +52,6 @@ jobs:
# tox.ini so that tox will run properly. PYVERSIONS
# Available versions:
# https://launchpad.net/~deadsnakes/+archive/ubuntu/nightly/+packages
- "3.11-dev"
- "3.12-dev"
- "3.13-dev"
# https://github.com/actions/setup-python#available-versions-of-pypy
6 changes: 3 additions & 3 deletions .github/workflows/quality.yml
Original file line number Diff line number Diff line change
@@ -31,7 +31,9 @@ jobs:
# Because pylint can report different things on different OS's (!)
# (https://github.com/PyCQA/pylint/issues/3489), run this on Mac where local
# pylint gets run.
runs-on: macos-latest
# GitHub is rolling out macos 14, but it doesn't have Python 3.8 or 3.9.
# https://mastodon.social/@hugovk/112320493602782374
runs-on: macos-13

steps:
- name: "Check out the repo"
@@ -69,8 +71,6 @@ jobs:

- name: "Install dependencies"
run: |
# We run on 3.8, but the pins were made on 3.7, so don't insist on
# hashes, which won't match.
python -m pip install -r requirements/tox.pip
- name: "Tox mypy"
17 changes: 10 additions & 7 deletions .github/workflows/testsuite.yml
Original file line number Diff line number Diff line change
@@ -30,7 +30,7 @@ concurrency:
jobs:
tests:
name: "${{ matrix.python-version }} on ${{ matrix.os }}"
runs-on: "${{ matrix.os }}-latest"
runs-on: "${{ matrix.os }}-${{ matrix.os-version || 'latest' }}"
# Don't run tests if the branch name includes "-notests"
if: "!contains(github.ref, '-notests')"
strategy:
@@ -62,13 +62,16 @@ jobs:
python-version: "pypy-3.9"
- os: windows
python-version: "pypy-3.10"
# Skip 3.13.0a4 and pin to 3.13.0a3 for Windows due to build error.
# Undo when 3.13.0a5 is released.
- os: windows
python-version: "3.13"
# GitHub is rolling out macos 14, but it doesn't have Python 3.8 or 3.9.
# https://mastodon.social/@hugovk/112320493602782374
include:
- os: windows
python-version: "3.13.0-alpha.3"
- python-version: "3.8"
os: "macos"
os-version: "13"
- python-version: "3.9"
os: "macos"
os-version: "13"

fail-fast: false

steps:
32 changes: 32 additions & 0 deletions CHANGES.rst
Original file line number Diff line number Diff line change
@@ -22,6 +22,38 @@ upgrading your version of coverage.py.
.. scriv-start-here
.. _changes_7-5-0:

Version 7.5.0 — 2024-04-23
--------------------------

- Added initial support for function and class reporting in the HTML report.
There are now three index pages which link to each other: files, functions,
and classes. Other reports don't yet have this information, but it will be
added in the future where it makes sense. Feedback gladly accepted!

- Other HTML report improvements:

- There is now a "hide covered" checkbox to filter out 100% files, finishing
`issue 1384`_.

- The index page is always sorted by one of its columns, with clearer
indications of the sorting.

- The "previous file" shortcut key didn't work on the index page, but now it
does, fixing `issue 1765`_.

- The debug output showing which configuration files were tried now shows
absolute paths to help diagnose problems where settings aren't taking effect,
and is renamed from "attempted_config_files" to the more logical
"config_files_attempted."

- Python 3.13.0a6 is supported.

.. _issue 1384: https://github.com/nedbat/coveragepy/issues/1384
.. _issue 1765: https://github.com/nedbat/coveragepy/issues/1765


.. _changes_7-4-4:

Version 7.4.4 — 2024-03-14
1 change: 1 addition & 0 deletions CONTRIBUTORS.txt
Original file line number Diff line number Diff line change
@@ -102,6 +102,7 @@ J. M. F. Tsang
JT Olds
Jacqueline Lee
Jakub Wilk
James Valleroy
Jan Rusak
Janakarajan Natarajan
Jerin Peter George
4 changes: 2 additions & 2 deletions Makefile
Original file line number Diff line number Diff line change
@@ -198,10 +198,10 @@ kit: ## Make the source distribution.
python -m build

kit_upload: ## Upload the built distributions to PyPI.
twine upload --verbose dist/*
twine upload dist/*

test_upload: ## Upload the distributions to PyPI's testing server.
twine upload --verbose --repository testpypi --password $$TWINE_TEST_PASSWORD dist/*
twine upload --repository testpypi --password $$TWINE_TEST_PASSWORD dist/*

kit_local:
# pip.conf looks like this:
5 changes: 3 additions & 2 deletions README.rst
Original file line number Diff line number Diff line change
@@ -5,7 +5,7 @@
Coverage.py
===========

Code coverage testing for Python.
Code coverage measurement for Python.

.. image:: https://raw.githubusercontent.com/vshymanskyy/StandWithUkraine/main/banner2-direct.svg
:target: https://vshymanskyy.github.io/StandWithUkraine
@@ -25,7 +25,7 @@ Coverage.py runs on these versions of Python:

.. PYVERSIONS
* Python 3.8 through 3.12, and 3.13.0a3 and up.
* Python 3.8 through 3.12, and 3.13.0a6 and up.
* PyPy3 versions 3.8 through 3.10.

Documentation is on `Read the Docs`_. Code repository and issue tracker are on
@@ -35,6 +35,7 @@ Documentation is on `Read the Docs`_. Code repository and issue tracker are on
.. _GitHub: https://github.com/nedbat/coveragepy

**New in 7.x:**
initial function/class reporting;
experimental support for sys.monitoring;
dropped support for Python 3.7;
added ``Coverage.collect()`` context manager;
5 changes: 1 addition & 4 deletions coverage/__init__.py
Original file line number Diff line number Diff line change
@@ -28,14 +28,11 @@
from coverage.data import CoverageData as CoverageData
from coverage.exceptions import CoverageException as CoverageException
from coverage.plugin import (
CodeRegion as CodeRegion,
CoveragePlugin as CoveragePlugin,
FileReporter as FileReporter,
FileTracer as FileTracer,
)

# Backward compatibility.
coverage = Coverage

# On Windows, we encode and decode deep enough that something goes wrong and
# the encodings.utf_8 module is loaded and then unloaded, I don't know why.
# Adding a reference here prevents it from being unloaded. Yuk.
4 changes: 2 additions & 2 deletions coverage/cmdline.py
Original file line number Diff line number Diff line change
@@ -26,7 +26,7 @@
from coverage.debug import info_header, short_stack, write_formatted_info
from coverage.exceptions import _BaseCoverageException, _ExceptionDuringRun, NoSource
from coverage.execfile import PyRunner
from coverage.results import Numbers, should_fail_under
from coverage.results import display_covered, should_fail_under
from coverage.version import __url__

# When adding to this file, alphabetization is important. Look for
@@ -760,7 +760,7 @@ def command_line(self, argv: list[str]) -> int:
precision = cast(int, self.coverage.get_option("report:precision"))
if should_fail_under(total, fail_under, precision):
msg = "total of {total} is less than fail-under={fail_under:.{p}f}".format(
total=Numbers(precision=precision).display_covered(total),
total=display_covered(total, precision),
fail_under=fail_under,
p=precision,
)
4 changes: 2 additions & 2 deletions coverage/config.py
Original file line number Diff line number Diff line change
@@ -180,7 +180,7 @@ def __init__(self) -> None:
"""Initialize the configuration attributes to their defaults."""
# Metadata about the config.
# We tried to read these config files.
self.attempted_config_files: list[str] = []
self.config_files_attempted: list[str] = []
# We did read these config files, but maybe didn't find any content for us.
self.config_files_read: list[str] = []
# The file that gave us our configuration.
@@ -291,7 +291,7 @@ def from_file(self, filename: str, warn: Callable[[str], None], our_file: bool)
else:
cp = HandyConfigParser(our_file)

self.attempted_config_files.append(filename)
self.config_files_attempted.append(os.path.abspath(filename))

try:
files_read = cp.read(filename)
36 changes: 16 additions & 20 deletions coverage/control.py
Original file line number Diff line number Diff line change
@@ -8,6 +8,7 @@
import atexit
import collections
import contextlib
import functools
import os
import os.path
import platform
@@ -47,7 +48,7 @@
from coverage.python import PythonFileReporter
from coverage.report import SummaryReporter
from coverage.report_core import render_report
from coverage.results import Analysis
from coverage.results import Analysis, analysis_from_file_reporter
from coverage.types import (
FilePath, TConfigurable, TConfigSectionIn, TConfigValueIn, TConfigValueOut,
TFileDisposition, TLineNo, TMorf,
@@ -930,24 +931,17 @@ def analysis2(
analysis.missing_formatted(),
)

def _analyze(self, it: FileReporter | TMorf) -> Analysis:
"""Analyze a single morf or code unit.
Returns an `Analysis` object.
"""
# All reporting comes through here, so do reporting initialization.
def _analyze(self, morf: TMorf) -> Analysis:
"""Analyze a module or file. Private for now."""
self._init()
self._post_init()

data = self.get_data()
if isinstance(it, FileReporter):
fr = it
else:
fr = self._get_file_reporter(it)

return Analysis(data, self.config.precision, fr, self._file_mapper)
file_reporter = self._get_file_reporter(morf)
filename = self._file_mapper(file_reporter.filename)
return analysis_from_file_reporter(data, self.config.precision, file_reporter, filename)

@functools.lru_cache(maxsize=1)
def _get_file_reporter(self, morf: TMorf) -> FileReporter:
"""Get a FileReporter for a module or file name."""
assert self._data is not None
@@ -975,11 +969,14 @@ def _get_file_reporter(self, morf: TMorf) -> FileReporter:
assert isinstance(file_reporter, FileReporter)
return file_reporter

def _get_file_reporters(self, morfs: Iterable[TMorf] | None = None) -> list[FileReporter]:
"""Get a list of FileReporters for a list of modules or file names.
def _get_file_reporters(
self,
morfs: Iterable[TMorf] | None = None,
) -> list[tuple[FileReporter, TMorf]]:
"""Get FileReporters for a list of modules or file names.
For each module or file name in `morfs`, find a FileReporter. Return
the list of FileReporters.
a list pairing FileReporters with the morfs.
If `morfs` is a single module or file name, this returns a list of one
FileReporter. If `morfs` is empty or None, then the list of all files
@@ -994,8 +991,7 @@ def _get_file_reporters(self, morfs: Iterable[TMorf] | None = None) -> list[File
if not isinstance(morfs, (list, tuple, set)):
morfs = [morfs] # type: ignore[list-item]

file_reporters = [self._get_file_reporter(morf) for morf in morfs]
return file_reporters
return [(self._get_file_reporter(morf), morf) for morf in morfs]

def _prepare_data_for_reporting(self) -> None:
"""Re-map data before reporting, to get implicit "combine" behavior."""
@@ -1302,7 +1298,7 @@ def plugin_info(plugins: list[Any]) -> list[str]:
("plugins.file_tracers", plugin_info(self._plugins.file_tracers)),
("plugins.configurers", plugin_info(self._plugins.configurers)),
("plugins.context_switchers", plugin_info(self._plugins.context_switchers)),
("configs_attempted", self.config.attempted_config_files),
("configs_attempted", self.config.config_files_attempted),
("configs_read", self.config.config_files_read),
("config_file", self.config.config_file),
("config_contents",
Loading