From 7e0c8ae5140e7cd4969c09c8262945b90c0e61a6 Mon Sep 17 00:00:00 2001 From: Ned Batchelder Date: Tue, 29 Aug 2023 19:14:47 -0400 Subject: [PATCH] test/doc: add more tests of star behavior, and document it. --- CHANGES.rst | 11 +++++++++-- doc/_static/coverage.css | 9 +++++++++ doc/source.rst | 40 +++++++++++++++++++++++++++++++++++++--- tests/test_files.py | 17 ++++++++++++++++- 4 files changed, 71 insertions(+), 6 deletions(-) diff --git a/CHANGES.rst b/CHANGES.rst index f056ddd6d..69eed03b2 100644 --- a/CHANGES.rst +++ b/CHANGES.rst @@ -20,8 +20,15 @@ development at the same time, such as 4.5.x and 5.0. Unreleased ---------- -Nothing yet. +- The semantics of stars in file patterns has been clarified in the docs. A + leading or trailing star matches any number of path components, like a double + star would. This is different than the behavior of a star in the middle of a + pattern. This discrepancy was `identified by Sviatoslav Sydorenko + `_, who `provided patient detailed diagnosis `_ and + graciously agreed to a pragmatic resolution. +.. _starbad: https://github.com/nedbat/coveragepy/issues/1407#issuecomment-1631085209 +.. _pull 1650: https://github.com/nedbat/coveragepy/pull/1650 .. scriv-start-here @@ -32,7 +39,7 @@ Version 7.3.0 — 2023-08-12 - Added a :meth:`.Coverage.collect` context manager to start and stop coverage data collection. - + - Dropped support for Python 3.7. - Fix: in unusual circumstances, SQLite cannot be set to asynchronous mode. diff --git a/doc/_static/coverage.css b/doc/_static/coverage.css index ee5349910..8915cc04c 100644 --- a/doc/_static/coverage.css +++ b/doc/_static/coverage.css @@ -66,6 +66,15 @@ img.tideliftlogo { background: #efc; } +/* I'm not sure why I had to make this so specific to get it to take effect... */ +div.rst-content div.document div.wy-table-responsive table.docutils.align-default tbody tr td { + vertical-align: top !important; +} + +div.rst-content div.document div.wy-table-responsive table.docutils.align-default tbody tr td .line-block { + margin-bottom: 0; +} + /* sphinx-code-tabs */ /* Some selectors here are extra-specific (.container) because this file comes diff --git a/doc/source.rst b/doc/source.rst index 44b84f001..dc7c6e526 100644 --- a/doc/source.rst +++ b/doc/source.rst @@ -181,12 +181,46 @@ File patterns File path patterns are used for include and omit, and for combining path remapping. They follow common shell syntax: -- ``*`` matches any number of file name characters, not including the directory - separator. - - ``?`` matches a single file name character. +- ``*`` matches any number of file name characters, not including the directory + separator. As a special case, if a pattern starts with ``*/``, it is treated + as ``**/``, and if a pattern ends with ``/*``, it is treated as ``/**``. + - ``**`` matches any number of nested directory names, including none. - Both ``/`` and ``\`` will match either a slash or a backslash, to make cross-platform matching easier. + +- A pattern with no directory separators matches the file name in any + directory. + +Some examples: + +.. list-table:: + :widths: 20 20 20 + :header-rows: 1 + + * - Pattern + - Matches + - Doesn't Match + * - ``a*.py`` + - | anything.py + | sub1/sub2/another.py + - | cat.py + * - ``sub/*/*.py`` + - | sub/a/main.py + | sub/b/another.py + - | sub/foo.py + | sub/m1/m2/foo.py + * - ``sub/**/*.py`` + - | sub/something.py + | sub/a/main.py + | sub/b/another.py + | sub/m1/m2/foo.py + - | sub1/anything.py + | sub1/more/code/main.py + * - ``*/sub/*`` + - | some/where/sub/more/something.py + | sub/hello.py + - | sub1/anything.py diff --git a/tests/test_files.py b/tests/test_files.py index ae3a5e2b2..09da65c20 100644 --- a/tests/test_files.py +++ b/tests/test_files.py @@ -235,9 +235,24 @@ def globs_to_regex_params( ), globs_to_regex_params( ["*/foo"], case_insensitive=False, partial=True, - matches=["abc/foo/hi.py", "foo/hi.py"], + matches=["abc/foo/hi.py", "foo/hi.py", "abc/def/foo/hi.py"], nomatches=["abc/xfoo/hi.py"], ), + globs_to_regex_params( + ["*c/foo"], case_insensitive=False, partial=True, + matches=["abc/foo/hi.py"], + nomatches=["abc/xfoo/hi.py", "foo/hi.py", "def/abc/foo/hi.py"], + ), + globs_to_regex_params( + ["foo/x*"], case_insensitive=False, partial=True, + matches=["foo/x", "foo/xhi.py", "foo/x/hi.py"], + nomatches=[], + ), + globs_to_regex_params( + ["foo/x*"], case_insensitive=False, partial=False, + matches=["foo/x", "foo/xhi.py"], + nomatches=["foo/x/hi.py"], + ), globs_to_regex_params( ["**/foo"], matches=["foo", "hello/foo", "hi/there/foo"],