Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 10 additions & 0 deletions CHANGES.rst
Original file line number Diff line number Diff line change
Expand Up @@ -202,6 +202,16 @@ Version 7.10.0 — 2025-07-24
.. _issue 2001: https://github.com/nedbat/coveragepy/issues/2001
.. _issue 2005: https://github.com/nedbat/coveragepy/issues/2005

- Feature: Added support for ``.coveragerc.toml`` configuration files. This
provides a more flexible approach to manage coverage settings as many
projects have switched to TOML configurations. Closes `issue 1643`_.

.. _issue 1643: https://github.com/nedbat/coveragepy/issues/1643
.. _pull 1952: https://github.com/nedbat/coveragepy/pull/1952


.. start-releases
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Invalid conflict resolution?


.. _changes_7-9-2:

Version 7.9.2 — 2025-07-03
Expand Down
1 change: 1 addition & 0 deletions CONTRIBUTORS.txt
Original file line number Diff line number Diff line change
Expand Up @@ -187,6 +187,7 @@ Nils Kattenbeck
Noel O'Boyle
Oleg Höfling
Oleh Krehel
Olena Yefymenko
Olivier Grisel
Ori Avtalion
Pablo Carballo
Expand Down
1 change: 1 addition & 0 deletions coverage/config.py
Original file line number Diff line number Diff line change
Expand Up @@ -644,6 +644,7 @@ def config_files_to_try(config_file: bool | str) -> list[tuple[str, bool, bool]]
assert isinstance(config_file, str)
files_to_try = [
(config_file, True, specified_file),
(".coveragerc.toml", True, False),
("setup.cfg", False, False),
Comment on lines +647 to 648
Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is the priority of the new config properly determined in the config_files_to_try function?

Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good.

("tox.ini", False, False),
("pyproject.toml", False, False),
Expand Down
8 changes: 7 additions & 1 deletion doc/cmd.rst
Original file line number Diff line number Diff line change
Expand Up @@ -322,6 +322,12 @@ file:
[run]
disable_warnings = no-data-collected

.. code-tab:: toml
:caption: .coveragerc.toml

[tool.coverage.run]
disable_warnings = ["no-data-collected"]

.. code-tab:: toml
:caption: pyproject.toml

Expand All @@ -334,7 +340,7 @@ file:
[coverage:run]
disable_warnings = no-data-collected

.. [[[end]]] (sum: SJKFvPoXO2)
.. [[[end]]] (sum: CZaDzmXkEi)


.. _cmd_datafile:
Expand Down
3 changes: 2 additions & 1 deletion doc/cog_helpers.py
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,7 @@ def show_configs(ini, toml):
The equivalence is checked for accuracy, and the process fails if there's
a mismatch.

A three-tabbed box will be produced.
A four-tabbed box will be produced.
"""
ini, ini_vals = _read_config(ini, "covrc")
toml, toml_vals = _read_config(toml, "covrc.toml")
Expand All @@ -89,6 +89,7 @@ def show_configs(ini, toml):
print(".. tabs::\n")
for name, syntax, text in [
(".coveragerc", "ini", ini),
(".coveragerc.toml", "toml", toml),
("pyproject.toml", "toml", toml),
("setup.cfg or tox.ini", "ini", ini2),
]:
Expand Down
54 changes: 49 additions & 5 deletions doc/config.rst
Original file line number Diff line number Diff line change
Expand Up @@ -39,12 +39,15 @@ environment variable.

If ``.coveragerc`` doesn't exist and another file hasn't been specified, then
coverage.py will look for settings in other common configuration files, in this
order: setup.cfg, tox.ini, or pyproject.toml. The first file found with
order: .coveragerc.toml, setup.cfg, tox.ini, or pyproject.toml. The first file
found with
coverage.py settings will be used and other files won't be consulted.

Coverage.py will read from "pyproject.toml" if TOML support is available,
Coverage.py will read from ".coveragerc.toml" and "pyproject.toml" if TOML
support is available,
either because you are running on Python 3.11 or later, or because you
installed with the ``toml`` extra (``pip install coverage[toml]``).
installed with the ``toml`` extra (``pip install coverage[toml]``). Both files
use the same ``[tool.coverage]`` section structure.


Syntax
Expand Down Expand Up @@ -136,6 +139,7 @@ Here's a sample configuration file, in each syntax:
[html]
directory = coverage_html_report
""",

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Stray edit?

toml=r"""
[tool.coverage.run]
branch = true
Expand Down Expand Up @@ -198,6 +202,36 @@ Here's a sample configuration file, in each syntax:
[html]
directory = coverage_html_report

.. code-tab:: toml
:caption: .coveragerc.toml

[tool.coverage.run]
branch = true

[tool.coverage.report]
# Regexes for lines to exclude from consideration
exclude_also = [
# Don't complain about missing debug-only code:
"def __repr__",
"if self\\.debug",

# Don't complain if tests don't hit defensive assertion code:
"raise AssertionError",
"raise NotImplementedError",

# Don't complain if non-runnable code isn't run:
"if 0:",
"if __name__ == .__main__.:",

# Don't complain about abstract methods, they aren't run:
"@(abc\\.)?abstractmethod",
]

ignore_errors = true

[tool.coverage.html]
directory = "coverage_html_report"

.. code-tab:: toml
:caption: pyproject.toml

Expand Down Expand Up @@ -257,7 +291,7 @@ Here's a sample configuration file, in each syntax:
[coverage:html]
directory = coverage_html_report

.. [[[end]]] (sum: HU1Z62mvRK)
.. [[[end]]] (sum: EQ1Fn4BHJk)


The specific configuration settings are described below. Many sections and
Expand Down Expand Up @@ -597,6 +631,16 @@ equivalent when combining data from different machines:
/jenkins/build/*/src
c:\myproj\src

.. code-tab:: toml
:caption: .coveragerc.toml

[tool.coverage.paths]
source = [
"src/",
"/jenkins/build/*/src",
"c:\\myproj\\src",
]

.. code-tab:: toml
:caption: pyproject.toml

Expand All @@ -616,7 +660,7 @@ equivalent when combining data from different machines:
/jenkins/build/*/src
c:\myproj\src

.. [[[end]]] (sum: oHSl8SGiMT)
.. [[[end]]] (sum: QLgJoxGH3G)


The names of the entries ("source" in this example) are ignored, you may choose
Expand Down
8 changes: 7 additions & 1 deletion doc/contexts.rst
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,12 @@ The ``[run] dynamic_context`` setting has only one option now. Set it to
[run]
dynamic_context = test_function

.. code-tab:: toml
:caption: .coveragerc.toml

[tool.coverage.run]
dynamic_context = "test_function"

.. code-tab:: toml
:caption: pyproject.toml

Expand All @@ -108,7 +114,7 @@ The ``[run] dynamic_context`` setting has only one option now. Set it to
[coverage:run]
dynamic_context = test_function

.. [[[end]]] (sum: dZTDYjHw71)
.. [[[end]]] (sum: oHx7GVdhqU)

Each test function you run will be considered a separate dynamic context, and
coverage data will be segregated for each. A test function is any function
Expand Down
44 changes: 41 additions & 3 deletions doc/excluding.rst
Original file line number Diff line number Diff line change
Expand Up @@ -144,6 +144,14 @@ all of them by adding a regex to the exclusion list:
exclude_also =
def __repr__

.. code-tab:: toml
:caption: .coveragerc.toml

[tool.coverage.report]
exclude_also = [
"def __repr__",
]

.. code-tab:: toml
:caption: pyproject.toml

Expand All @@ -159,7 +167,7 @@ all of them by adding a regex to the exclusion list:
exclude_also =
def __repr__

.. [[[end]]] (sum: 8+cOvxKPvv)
.. [[[end]]] (sum: 4lYsdpcbf/)

For example, here's a list of exclusions I've used:

Expand Down Expand Up @@ -215,6 +223,23 @@ For example, here's a list of exclusions I've used:
class .*\bProtocol\):
@(abc\.)?abstractmethod

.. code-tab:: toml
:caption: .coveragerc.toml

[tool.coverage.report]
exclude_also = [
'def __repr__',
'if self.debug:',
'if settings.DEBUG',
'raise AssertionError',
'raise NotImplementedError',
'if 0:',
'if __name__ == .__main__.:',
'if TYPE_CHECKING:',
'class .*\bProtocol\):',
'@(abc\.)?abstractmethod',
]

.. code-tab:: toml
:caption: pyproject.toml

Expand Down Expand Up @@ -248,7 +273,7 @@ For example, here's a list of exclusions I've used:
class .*\bProtocol\):
@(abc\.)?abstractmethod

.. [[[end]]] (sum: ZQsgnt0nES)
.. [[[end]]] (sum: +D/FLd6oVC)

The :ref:`config_report_exclude_also` option adds regexes to the built-in
default list so that you can add your own exclusions. The older
Expand Down Expand Up @@ -318,6 +343,19 @@ Here are some examples:
; 3. A pragma comment that excludes an entire file:
\A(?s:.*# pragma: exclude file.*)\Z

.. code-tab:: toml
:caption: .coveragerc.toml

[tool.coverage.report]
exclude_also = [
# 1. Exclude an except clause of a specific form:
'except ValueError:\n\s*assume\(False\)',
# 2. Comments to turn coverage on and off:
'no cover: start(?s:.)*?no cover: stop',
# 3. A pragma comment that excludes an entire file:
'\A(?s:.*# pragma: exclude file.*)\Z',
]

.. code-tab:: toml
:caption: pyproject.toml

Expand All @@ -343,7 +381,7 @@ Here are some examples:
; 3. A pragma comment that excludes an entire file:
\A(?s:.*# pragma: exclude file.*)\Z

.. [[[end]]] (sum: xG6Bmtmh06)
.. [[[end]]] (sum: eg9c8WbMqW)

The first regex matches a specific except line followed by a specific function
call. Both lines must be present for the exclusion to take effect. Note that
Expand Down
17 changes: 15 additions & 2 deletions doc/plugins.rst
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,12 @@ a coverage.py plug-in called ``something.plugin``.
plugins =
something.plugin

.. code-tab:: toml
:caption: .coveragerc.toml

[tool.coverage.run]
plugins = [ "something.plugin" ]

.. code-tab:: toml
:caption: pyproject.toml

Expand All @@ -84,7 +90,7 @@ a coverage.py plug-in called ``something.plugin``.
plugins =
something.plugin

.. [[[end]]] (sum: boZjI9S8MZ)
.. [[[end]]] (sum: +V9pwwXF47)

#. If the plug-in needs its own configuration, you can add those settings in
the .coveragerc file in a section named for the plug-in:
Expand Down Expand Up @@ -113,6 +119,13 @@ a coverage.py plug-in called ``something.plugin``.
option1 = True
option2 = abc.foo

.. code-tab:: toml
:caption: .coveragerc.toml

[tool.coverage.something.plugin]
option1 = true
option2 = "abc.foo"

.. code-tab:: toml
:caption: pyproject.toml

Expand All @@ -127,7 +140,7 @@ a coverage.py plug-in called ``something.plugin``.
option1 = True
option2 = abc.foo

.. [[[end]]] (sum: tpARXb5/bH)
.. [[[end]]] (sum: woHFW9mOUC)

Check the documentation for the plug-in for details on the options it takes.

Expand Down
15 changes: 14 additions & 1 deletion doc/source.rst
Original file line number Diff line number Diff line change
Expand Up @@ -114,6 +114,19 @@ current directory:
# omit this single file
utils/tirefire.py

.. code-tab:: toml
:caption: .coveragerc.toml

[tool.coverage.run]
omit = [
# omit anything in a .local directory anywhere
"*/.local/*",
# omit everything in /usr
"/usr/*",
# omit this single file
"utils/tirefire.py",
]

.. code-tab:: toml
:caption: pyproject.toml

Expand All @@ -139,7 +152,7 @@ current directory:
# omit this single file
utils/tirefire.py

.. [[[end]]] (sum: hK0nQ8wMeg)
.. [[[end]]] (sum: lKoRbHzA05)

The ``source``, ``include``, and ``omit`` values all work together to determine
the source that will be measured.
Expand Down
Loading
Loading