Skip to content

Commit 1b1bbe9

Browse files
authored
Merge pull request #195 from facelessuser/chore/windows-seps
Improve documentation on Windows separators
2 parents a786269 + 5f081ed commit 1b1bbe9

File tree

3 files changed

+52
-33
lines changed

3 files changed

+52
-33
lines changed

docs/src/markdown/fnmatch.md

Lines changed: 14 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ Pattern | Meaning
2222
`[seq]` | Matches any character in seq.
2323
`[!seq]` | Matches any character not in seq. Will also accept character exclusions in the form of `[^seq]`.
2424
`[[:alnum:]]` | POSIX style character classes inside sequences. See [POSIX Character Classes](#posix-character-classes) for more info.
25-
`\` | Escapes characters. If applied to a meta character, it will be treated as a normal character.
25+
`\` | Escapes characters. If applied to a meta character or non-meta characters, the character will be treated as a literal character. If applied to another escape, the backslash will be a literal backslash.
2626
`!` | When used at the start of a pattern, the pattern will be an exclusion pattern. Requires the [`NEGATE`](#negate) flag. If also using the [`MINUSNEGATE`](#minusnegate) flag, `-` will be used instead of `!`.
2727
`?(pattern_list)` | The pattern matches if zero or one occurrences of any of the patterns in the `pattern_list` match the input string. Requires the [`EXTMATCH`](#extmatch) flag.
2828
`*(pattern_list)` | The pattern matches if zero or more occurrences of any of the patterns in the `pattern_list` match the input string. Requires the [`EXTMATCH`](#extmatch) flag.
@@ -63,15 +63,15 @@ a list of patterns. It will return a boolean indicating whether the file name wa
6363

6464
```pycon3
6565
>>> from wcmatch import fnmatch
66-
>>> fnmatch.fnmatch('test.txt', r'@(*.txt|*.py)', flags=fnmatch.EXTMATCH)
66+
>>> fnmatch.fnmatch('test.txt', '@(*.txt|*.py)', flags=fnmatch.EXTMATCH)
6767
True
6868
```
6969

7070
When applying multiple patterns, a file matches if it matches any of the patterns:
7171

7272
```pycon3
7373
>>> from wcmatch import fnmatch
74-
>>> fnmatch.fnmatch('test.txt', [r'*.txt', r'*.py'], flags=fnmatch.EXTMATCH)
74+
>>> fnmatch.fnmatch('test.txt', ['*.txt', '*.py'], flags=fnmatch.EXTMATCH)
7575
True
7676
```
7777

@@ -93,13 +93,13 @@ meant to filter other patterns, not match anything by themselves.
9393

9494
```pycon3
9595
>>> from wcmatch import fnmatch
96-
>>> fnmatch.fnmatch('test.py', r'*|!*.py', flags=fnmatch.NEGATE | fnmatch.SPLIT)
96+
>>> fnmatch.fnmatch('test.py', '*|!*.py', flags=fnmatch.NEGATE | fnmatch.SPLIT)
9797
False
98-
>>> fnmatch.fnmatch('test.txt', r'*|!*.py', flags=fnmatch.NEGATE | fnmatch.SPLIT)
98+
>>> fnmatch.fnmatch('test.txt', '*|!*.py', flags=fnmatch.NEGATE | fnmatch.SPLIT)
9999
True
100-
>>> fnmatch.fnmatch('test.txt', [r'*.txt', r'!avoid.txt'], flags=fnmatch.NEGATE)
100+
>>> fnmatch.fnmatch('test.txt', ['*.txt', '!avoid.txt'], flags=fnmatch.NEGATE)
101101
True
102-
>>> fnmatch.fnmatch('avoid.txt', [r'*.txt', r'!avoid.txt'], flags=fnmatch.NEGATE)
102+
>>> fnmatch.fnmatch('avoid.txt', ['*.txt', '!avoid.txt'], flags=fnmatch.NEGATE)
103103
False
104104
```
105105

@@ -110,9 +110,9 @@ pattern were given: `*` and `!*.md`.
110110

111111
```pycon3
112112
>>> from wcmatch import fnmatch
113-
>>> fnmatch.fnmatch('test.py', r'!*.py', flags=fnmatch.NEGATE | fnmatch.NEGATEALL)
113+
>>> fnmatch.fnmatch('test.py', '!*.py', flags=fnmatch.NEGATE | fnmatch.NEGATEALL)
114114
False
115-
>>> fnmatch.fnmatch('test.txt', r'!*.py', flags=fnmatch.NEGATE | fnmatch.NEGATEALL)
115+
>>> fnmatch.fnmatch('test.txt', '!*.py', flags=fnmatch.NEGATE | fnmatch.NEGATEALL)
116116
True
117117
```
118118

@@ -135,7 +135,7 @@ pattern or a list of patterns.It returns a list of all files that matched the pa
135135

136136
```pycon3
137137
>>> from wcmatch import fnmatch
138-
>>> fnmatch.filter(['a.txt', 'b.txt', 'c.py'], r'*.txt')
138+
>>> fnmatch.filter(['a.txt', 'b.txt', 'c.py'], '*.txt')
139139
['a.txt', 'b.txt']
140140
```
141141

@@ -159,9 +159,9 @@ matches at least one inclusion pattern and matches **none** of the exclusion pat
159159

160160
```pycon3
161161
>>> from wcmatch import fnmatch
162-
>>> fnmatch.translate(r'*.{a,{b,c}}', flags=fnmatch.BRACE)
162+
>>> fnmatch.translate('*.{a,{b,c}}', flags=fnmatch.BRACE)
163163
(['^(?s:(?=.)(?![.]).*?\\.a)$', '^(?s:(?=.)(?![.]).*?\\.b)$', '^(?s:(?=.)(?![.]).*?\\.c)$'], [])
164-
>>> fnmatch.translate(r'**|!*.{a,{b,c}}', flags=fnmatch.BRACE | fnmatch.NEGATE | fnmatch.SPLIT)
164+
>>> fnmatch.translate('**|!*.{a,{b,c}}', flags=fnmatch.BRACE | fnmatch.NEGATE | fnmatch.SPLIT)
165165
(['^(?s:(?=.)(?![.]).*?)$'], ['^(?s:(?=.).*?\\.a)$', '^(?s:(?=.).*?\\.b)$', '^(?s:(?=.).*?\\.c)$'])
166166
```
167167

@@ -346,9 +346,9 @@ it's warnings related to pairing it with `SPLIT`.
346346

347347
```pycon3
348348
>>> from wcmatch import fnmatch
349-
>>> fnmatch.fnmatch('test.txt', r'*.txt|*.py', flags=fnmatch.SPLIT)
349+
>>> fnmatch.fnmatch('test.txt', '*.txt|*.py', flags=fnmatch.SPLIT)
350350
True
351-
>>> fnmatch.fnmatch('test.py', r'*.txt|*.py', flags=fnmatch.SPLIT)
351+
>>> fnmatch.fnmatch('test.py', '*.txt|*.py', flags=fnmatch.SPLIT)
352352
True
353353
```
354354

docs/src/markdown/glob.md

Lines changed: 36 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ Pattern | Meaning
2323
`[seq]` | Matches any character in seq.
2424
`[!seq]` | Matches any character not in seq. Will also accept character exclusions in the form of `[^seq]`.
2525
`[[:alnum:]]` | POSIX style character classes inside sequences. See [POSIX Character Classes](#posix-character-classes) for more info.
26-
`\` | Escapes characters. If applied to a meta character, it will be treated as a normal character.
26+
`\` | Escapes characters. If applied to a meta character or non-meta characters, the character will be treated as a literal character. If applied to another escape, the backslash will be a literal backslash.
2727
`!` | When used at the start of a pattern, the pattern will be an exclusion pattern. Requires the [`NEGATE`](#negate) flag. If also using the [`MINUSNEGATE`](#minusnegate) flag, `-` will be used instead of `!`.
2828
`?(pattern_list)` | The pattern matches if zero or one occurrences of any of the patterns in the `pattern_list` match the input string. Requires the [`EXTGLOB`](#extglob) flag.
2929
`*(pattern_list)` | The pattern matches if zero or more occurrences of any of the patterns in the `pattern_list` match the input string. Requires the [`EXTGLOB`](#extglob) flag.
@@ -152,6 +152,24 @@ Pattern | Meaning
152152
153153
--8<-- "posix.md"
154154
155+
## Windows Separators
156+
157+
On Windows, it is not required to use backslashes for path separators as `/` will match path separators for all systems.
158+
The following will work on Windows and Linux/Unix systems.
159+
160+
```python
161+
glob.glob('docs/.*')
162+
```
163+
164+
With that said, you can match Windows separators with backslashes as well. Keep in mind that Wildcard Match allows
165+
escaped characters in patterns, so to match a literal backslash separator, you must escape the backslash. It is advised
166+
to use raw strings when using backslashes to make the patterns more readable, but either of the below will work.
167+
168+
```python
169+
glob.glob(r'docs\\.*')
170+
glob.glob('docs\\\\.*')
171+
```
172+
155173
## Multi-Pattern Limits
156174

157175
Many of the API functions allow passing in multiple patterns or using either [`BRACE`](#brace) or
@@ -180,23 +198,23 @@ file system returning matching files.
180198

181199
```pycon3
182200
>>> from wcmatch import glob
183-
>>> glob.glob(r'**/*.md')
201+
>>> glob.glob('**/*.md')
184202
['docs/src/markdown/_snippets/abbr.md', 'docs/src/markdown/_snippets/links.md', 'docs/src/markdown/_snippets/refs.md', 'docs/src/markdown/changelog.md', 'docs/src/markdown/fnmatch.md', 'docs/src/markdown/glob.md', 'docs/src/markdown/index.md', 'docs/src/markdown/installation.md', 'docs/src/markdown/license.md', 'README.md']
185203
```
186204

187205
Using a list, we can add exclusion patterns and also exclude directories and/or files:
188206

189207
```pycon3
190208
>>> from wcmatch import glob
191-
>>> glob.glob([r'**/*.md', r'!README.md', r'!**/_snippets'], flags=glob.NEGATE)
209+
>>> glob.glob(['**/*.md', '!README.md', '!**/_snippets'], flags=glob.NEGATE)
192210
['docs/src/markdown/changelog.md', 'docs/src/markdown/fnmatch.md', 'docs/src/markdown/glob.md', 'docs/src/markdown/index.md', 'docs/src/markdown/installation.md', 'docs/src/markdown/license.md']
193211
```
194212

195213
When a glob pattern ends with a slash, it will only return directories:
196214

197215
```pycon3
198216
>>> from wcmatch import glob
199-
>>> glob.glob(r'**/')
217+
>>> glob.glob('**/')
200218
['__pycache__/', 'docs/', 'docs/src/', 'docs/src/markdown/', 'docs/src/markdown/_snippets/', 'docs/theme/', 'requirements/', 'stuff/', 'tests/', 'tests/__pycache__/', 'wcmatch/', 'wcmatch/__pycache__/']
201219
```
202220

@@ -313,7 +331,7 @@ def iglob(patterns, *, flags=0, root_dir=None, dir_fd=None, limit=1000, exclude=
313331

314332
```pycon3
315333
>>> from wcmatch import glob
316-
>>> list(glob.iglob(r'**/*.md'))
334+
>>> list(glob.iglob('**/*.md'))
317335
['docs/src/markdown/_snippets/abbr.md', 'docs/src/markdown/_snippets/links.md', 'docs/src/markdown/_snippets/refs.md', 'docs/src/markdown/changelog.md', 'docs/src/markdown/fnmatch.md', 'docs/src/markdown/glob.md', 'docs/src/markdown/index.md', 'docs/src/markdown/installation.md', 'docs/src/markdown/license.md', 'README.md']
318336
```
319337

@@ -342,15 +360,15 @@ boolean indicating whether the file path was matched by the pattern(s).
342360

343361
```pycon3
344362
>>> from wcmatch import glob
345-
>>> glob.globmatch('some/path/test.txt', r'**/*/@(*.txt|*.py)', flags=glob.EXTGLOB)
363+
>>> glob.globmatch('some/path/test.txt', '**/*/@(*.txt|*.py)', flags=glob.EXTGLOB)
346364
True
347365
```
348366

349367
When applying multiple patterns, a file path matches if it matches any of the patterns:
350368

351369
```pycon3
352370
>>> from wcmatch import glob
353-
>>> glob.globmatch('some/path/test.txt', [r'**/*/*.txt', r'**/*/*.py'])
371+
>>> glob.globmatch('some/path/test.txt', ['**/*/*.txt', '**/*/*.py'])
354372
True
355373
```
356374

@@ -361,13 +379,13 @@ to filter other patterns, not match anything by themselves.
361379

362380
```pycon3
363381
>>> from wcmatch import glob
364-
>>> glob.globmatch('some/path/test.py', r'**|!**/*.txt', flags=glob.NEGATE | glob.GLOBSTAR | glob.SPLIT)
382+
>>> glob.globmatch('some/path/test.py', '**|!**/*.txt', flags=glob.NEGATE | glob.GLOBSTAR | glob.SPLIT)
365383
True
366-
>>> glob.globmatch('some/path/test.txt', r'**|!**/*.txt', flags=glob.NEGATE | glob.GLOBSTAR | glob.SPLIT)
384+
>>> glob.globmatch('some/path/test.txt', '**|!**/*.txt', flags=glob.NEGATE | glob.GLOBSTAR | glob.SPLIT)
367385
False
368-
>>> glob.globmatch('some/path/test.txt', [r'*/*/*.txt', r'!*/*/avoid.txt'], flags=glob.NEGATE)
386+
>>> glob.globmatch('some/path/test.txt', ['*/*/*.txt', '!*/*/avoid.txt'], flags=glob.NEGATE)
369387
True
370-
>>> glob.globmatch('some/path/avoid.txt', [r'*/*/*.txt', r'!*/*/avoid.txt'], flags=glob.NEGATE)
388+
>>> glob.globmatch('some/path/avoid.txt', ['*/*/*.txt', '!*/*/avoid.txt'], flags=glob.NEGATE)
371389
False
372390
```
373391

@@ -379,9 +397,9 @@ if [`GLOBSTAR`](#globstar) was enabled).
379397

380398
```pycon3
381399
>>> from wcmatch import glob
382-
>>> glob.globmatch('some/path/test.py', r'!**/*.txt', flags=glob.NEGATE | glob.GLOBSTAR | glob.NEGATEALL)
400+
>>> glob.globmatch('some/path/test.py', '!**/*.txt', flags=glob.NEGATE | glob.GLOBSTAR | glob.NEGATEALL)
383401
True
384-
>>> glob.globmatch('some/path/test.txt', r'!**/*.txt', flags=glob.NEGATE | glob.GLOBSTAR | glob.NEGATEALL)
402+
>>> glob.globmatch('some/path/test.txt', '!**/*.txt', flags=glob.NEGATE | glob.GLOBSTAR | glob.NEGATEALL)
385403
False
386404
```
387405

@@ -485,7 +503,7 @@ for [`globmatch`](#globmatch) is used for `globfilter`, albeit more efficient fo
485503

486504
```pycon3
487505
>>> from wcmatch import glob
488-
>>> glob.globfilter(['some/path/a.txt', 'b.txt', 'another/path/c.py'], r'**/*.txt')
506+
>>> glob.globfilter(['some/path/a.txt', 'b.txt', 'another/path/c.py'], '**/*.txt')
489507
['some/path/a.txt', 'b.txt']
490508
```
491509

@@ -521,9 +539,9 @@ matches at least one inclusion pattern and matches **none** of the exclusion pat
521539

522540
```pycon3
523541
>>> from wcmatch import glob
524-
>>> glob.translate(r'**/*.{py,txt}')
542+
>>> glob.translate('**/*.{py,txt}')
525543
(['^(?s:(?=[^/])(?!(?:\\.{1,2})(?:$|[/]))(?:(?!\\.)[^/]*?)?[/]+(?=[^/])(?!(?:\\.{1,2})(?:$|[/]))(?:(?!\\.)[^/]*?)?\\.\\{py,txt\\}[/]*?)$'], [])
526-
>>> glob.translate(r'**|!**/*.{py,txt}', flags=glob.NEGATE | glob.SPLIT)
544+
>>> glob.translate('**|!**/*.{py,txt}', flags=glob.NEGATE | glob.SPLIT)
527545
(['^(?s:(?=[^/])(?!(?:\\.{1,2})(?:$|[/]))(?:(?!\\.)[^/]*?)?[/]*?)$'], ['^(?s:(?=[^/])(?!(?:\\.{1,2})(?:$|[/]))[^/]*?[/]+(?=[^/])(?!(?:\\.{1,2})(?:$|[/]))[^/]*?\\.\\{py,txt\\}[/]*?)$'])
528546
```
529547

@@ -967,9 +985,9 @@ related to pairing it with `SPLIT`.
967985

968986
```pycon3
969987
>>> from wcmatch import glob
970-
>>> glob.globmatch('test.txt', r'*.txt|*.py', flags=fnmatch.SPLIT)
988+
>>> glob.globmatch('test.txt', '*.txt|*.py', flags=fnmatch.SPLIT)
971989
True
972-
>>> glob.globmatch('test.py', r'*.txt|*.py', flags=fnmatch.SPLIT)
990+
>>> glob.globmatch('test.py', '*.txt|*.py', flags=fnmatch.SPLIT)
973991
True
974992
```
975993

mkdocs.yml

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -109,7 +109,8 @@ extra:
109109

110110
plugins:
111111
- search
112-
- git-revision-date-localized
112+
- git-revision-date-localized:
113+
fallback_to_build_date: true
113114
- mkdocs_pymdownx_material_extras
114115
- minify:
115116
minify_html: true

0 commit comments

Comments
 (0)