From fce4db23e6b7581d1ae7b58e2e50dbaaf49b47e3 Mon Sep 17 00:00:00 2001 From: xuu33030 <268775543+xuu33030@users.noreply.github.com> Date: Wed, 16 Sep 2026 17:26:28 +0800 Subject: [PATCH] docs: clarify extraction glob directory and filename matching --- babel/util.py | 5 +++++ docs/messages.rst | 24 ++++++++++++++++++------ tests/test_util.py | 22 ++++++++++++++++++++++ 3 files changed, 45 insertions(+), 6 deletions(-) diff --git a/babel/util.py b/babel/util.py index a2bf728cc..ef075debd 100644 --- a/babel/util.py +++ b/babel/util.py @@ -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') diff --git a/docs/messages.rst b/docs/messages.rst index c835d60a7..62bc058a1 100644 --- a/docs/messages.rst +++ b/docs/messages.rst @@ -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. diff --git a/tests/test_util.py b/tests/test_util.py index f51626e25..c9b3d4e43 100644 --- a/tests/test_util.py +++ b/tests/test_util.py @@ -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'