Skip to content
Open
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
5 changes: 5 additions & 0 deletions babel/util.py
Original file line number Diff line number Diff line change
Expand Up @@ -149,6 +149,11 @@ def pathmatch(pattern: str, filename: str) -> bool:
* also supports a convenience pattern ("**") to match files at any
directory level.

``*`` matches one or more characters other than the path separator, not
an empty string. ``**/`` matches zero or more directory levels, whereas
``**`` without a trailing slash also consumes one or more filename
characters. Use ``**/`` before a pattern for a specific filename prefix.

Examples:

>>> pathmatch('**.py', 'bar.py')
Expand Down
24 changes: 18 additions & 6 deletions docs/messages.rst
Original file line number Diff line number Diff line change
Expand Up @@ -140,12 +140,24 @@ Genshi markup templates and text templates:
extract_messages = $._, jQuery._

The extended glob patterns used in this configuration are similar to the glob
patterns provided by most shells. A single asterisk (``*``) is a wildcard for
any number of characters (except for the pathname component separator "/"),
while a question mark (``?``) only matches a single character. In addition,
two subsequent asterisk characters (``**``) can be used to make the wildcard
match any directory level, so the pattern ``**.txt`` matches any file with the
extension ``.txt`` in any directory.
patterns provided by most shells, with the following differences:

* A single asterisk (``*``) matches one or more characters within a pathname
component, but never the separator ``/``. Unlike shell globs, it does not
match an empty string.
* A question mark (``?``) matches exactly one character other than ``/``.
* ``**/`` matches zero or more directory levels. Use it before a filename
pattern to match that pattern both in the base directory and in subdirectories.
* ``**`` without a trailing slash also matches one or more characters of the
filename. For example, ``**.txt`` matches ``notes.txt`` and
``docs/notes.txt``.

To ignore files whose names start with ``._``, have at least one character
after that prefix, and end with ``.py``, use ``[ignore: **/._*.py]`` before
the Python extraction rule. This matches
``._module.py`` and ``pkg/._module.py``. In contrast, ``**._*.py`` requires
at least one filename character before ``._``, so it does not match either
of those paths.

Babel supports two configuration file formats: INI and TOML.

Expand Down
22 changes: 22 additions & 0 deletions tests/test_util.py
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,28 @@ def test_pathmatch():
assert not util.pathmatch('./foo/**.py', 'blah/foo/bar/baz.py')


@pytest.mark.parametrize(('pattern', 'filename', 'expected'), [
('*.txt', 'notes.txt', True),
('*.txt', '.txt', False),
('*.txt', 'docs/notes.txt', False),
('?.txt', 'a.txt', True),
('?.txt', '.txt', False),
('?.txt', '/.txt', False),
('**.txt', 'notes.txt', True),
('**.txt', 'docs/notes.txt', True),
('**.txt', '.txt', False),
('**/._*.py', '._module.py', True),
('**/._*.py', 'pkg/._module.py', True),
('**/._*.py', 'pkg/sub/._module.py', True),
('**/._*.py', 'pkg/module.py', False),
('**._*.py', '._module.py', False),
('**._*.py', 'pkg/._module.py', False),
('**._*.py', 'pkg/prefix._module.py', True),
])
def test_pathmatch_documented_wildcards(pattern, filename, expected):
assert util.pathmatch(pattern, filename) is expected


def test_fixed_zone_negative_offset():
assert util.FixedOffsetTimezone(-60).zone == 'Etc/GMT-60'

Expand Down