Skip to content

Commit

Permalink
The [paths] setting is ordered. #649
Browse files Browse the repository at this point in the history
  • Loading branch information
nedbat committed Dec 1, 2019
1 parent 12e019d commit 7f68a21
Show file tree
Hide file tree
Showing 4 changed files with 56 additions and 2 deletions.
5 changes: 5 additions & 0 deletions CHANGES.rst
Expand Up @@ -33,12 +33,17 @@ Unreleased
fixes `issue 745`_ (about not being able to run unittest tests that spawn
subprocesses), and `issue 838`_, which described the problem directly.

- The ``[paths]`` configuration section is now ordered. If you specify more
than one list of patterns, the first one that matches will be used. Fixes
`issue 649`_.

- The :func:`.coverage.numbits.register_sqlite_functions` function now also
registers `numbits_to_nums` for use in SQLite queries. Thanks, Simon
Willison.

- Python 3.9a1 is supported.

.. _issue 649: https://github.com/nedbat/coveragepy/issues/649
.. _issue 745: https://github.com/nedbat/coveragepy/issues/745
.. _issue 838: https://github.com/nedbat/coveragepy/issues/838

Expand Down
7 changes: 5 additions & 2 deletions coverage/config.py
Expand Up @@ -226,7 +226,7 @@ def __init__(self):
self.json_show_contexts = False

# Defaults for [paths]
self.paths = {}
self.paths = collections.OrderedDict()

# Options for plugins
self.plugin_options = {}
Expand Down Expand Up @@ -536,6 +536,9 @@ def read_coverage_config(config_file, **kwargs):
config.data_file = os.path.expanduser(config.data_file)
config.html_dir = os.path.expanduser(config.html_dir)
config.xml_output = os.path.expanduser(config.xml_output)
config.paths = {k: [os.path.expanduser(f) for f in v] for k, v in config.paths.items()}
config.paths = collections.OrderedDict(
(k, [os.path.expanduser(f) for f in v])
for k, v in config.paths.items()
)

return config
3 changes: 3 additions & 0 deletions doc/config.rst
Expand Up @@ -238,6 +238,9 @@ In this example, data collected for "/jenkins/build/1234/src/module.py" will be
combined with data for "c:\myproj\src\module.py", and will be reported against
the source file found at "src/module.py".

If you specify more than one list of paths, they will be considered in order.
The first list that has a match will be used.

See :ref:`cmd_combining` for more information.


Expand Down
43 changes: 43 additions & 0 deletions tests/test_api.py
Expand Up @@ -425,6 +425,49 @@ def test_combining_with_a_used_coverage(self):
cov.combine()
self.check_code1_code2(cov)

def test_ordered_combine(self):
# https://github.com/nedbat/coveragepy/issues/649
# The order of the [paths] setting matters
def make_data_file():
data = coverage.CoverageData(".coverage.1")
data.add_lines({os.path.abspath('ci/girder/g1.py'): dict.fromkeys(range(10))})
data.add_lines({os.path.abspath('ci/girder/plugins/p1.py'): dict.fromkeys(range(10))})
data.write()

def get_combined_filenames():
cov = coverage.Coverage()
cov.combine()
cov.save()
data = cov.get_data()
filenames = {os.path.relpath(f).replace("\\", "/") for f in data.measured_files()}
return filenames

# Case 1: get the order right.
make_data_file()
self.make_file(".coveragerc", """\
[paths]
plugins =
plugins/
ci/girder/plugins/
girder =
girder/
ci/girder/
""")
assert get_combined_filenames() == {'girder/g1.py', 'plugins/p1.py'}

# Case 2: get the order wrong.
make_data_file()
self.make_file(".coveragerc", """\
[paths]
girder =
girder/
ci/girder/
plugins =
plugins/
ci/girder/plugins/
""")
assert get_combined_filenames() == {'girder/g1.py', 'girder/plugins/p1.py'}

def test_warnings(self):
self.make_file("hello.py", """\
import sys, os
Expand Down

0 comments on commit 7f68a21

Please sign in to comment.