Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit fd32fff

Browse files
Issue #8402: Added the escape() function to the glob module.
1 parent e3010fd commit fd32fff

4 files changed

Lines changed: 49 additions & 2 deletions

File tree

Doc/library/glob.rst

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,17 @@ For example, ``'[?]'`` matches the character ``'?'``.
4040
without actually storing them all simultaneously.
4141

4242

43+
.. function:: escape(pathname)
44+
45+
Escape all special characters (``'?'``, ``'*'`` and ``'['``).
46+
This is useful if you want to match an arbitrary literal string that may
47+
have special characters in it. Special characters in drive/UNC
48+
sharepoints are not escaped, e.g. on Windows
49+
``escape('//?/c:/Quo vadis?.txt')`` returns ``'//?/c:/Quo vadis[?].txt'``.
50+
51+
.. versionadded:: 3.4
52+
53+
4354
For example, consider a directory containing only the following files:
4455
:file:`1.gif`, :file:`2.txt`, and :file:`card.gif`. :func:`glob` will produce
4556
the following results. Notice how any leading components of the path are

Lib/glob.py

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -79,8 +79,8 @@ def glob0(dirname, basename):
7979
return []
8080

8181

82-
magic_check = re.compile('[*?[]')
83-
magic_check_bytes = re.compile(b'[*?[]')
82+
magic_check = re.compile('([*?[])')
83+
magic_check_bytes = re.compile(b'([*?[])')
8484

8585
def has_magic(s):
8686
if isinstance(s, bytes):
@@ -91,3 +91,15 @@ def has_magic(s):
9191

9292
def _ishidden(path):
9393
return path[0] in ('.', b'.'[0])
94+
95+
def escape(pathname):
96+
"""Escape all special characters.
97+
"""
98+
# Escaping is done by wrapping any of "*?[" between square brackets.
99+
# Metacharacters do not work in the drive part and shouldn't be escaped.
100+
drive, pathname = os.path.splitdrive(pathname)
101+
if isinstance(pathname, bytes):
102+
pathname = magic_check_bytes.sub(br'[\1]', pathname)
103+
else:
104+
pathname = magic_check.sub(r'[\1]', pathname)
105+
return drive + pathname

Lib/test/test_glob.py

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -169,6 +169,28 @@ def test_glob_magic_in_drive(self):
169169
eq(glob.glob('\\\\*\\*\\'), [])
170170
eq(glob.glob(b'\\\\*\\*\\'), [])
171171

172+
def check_escape(self, arg, expected):
173+
self.assertEqual(glob.escape(arg), expected)
174+
self.assertEqual(glob.escape(os.fsencode(arg)), os.fsencode(expected))
175+
176+
def test_escape(self):
177+
check = self.check_escape
178+
check('abc', 'abc')
179+
check('[', '[[]')
180+
check('?', '[?]')
181+
check('*', '[*]')
182+
check('[[_/*?*/_]]', '[[][[]_/[*][?][*]/_]]')
183+
check('/[[_/*?*/_]]/', '/[[][[]_/[*][?][*]/_]]/')
184+
185+
@unittest.skipUnless(sys.platform == "win32", "Win32 specific test")
186+
def test_escape_windows(self):
187+
check = self.check_escape
188+
check('?:?', '?:[?]')
189+
check('*:*', '*:[*]')
190+
check(r'\\?\c:\?', r'\\?\c:\[?]')
191+
check(r'\\*\*\*', r'\\*\*\[*]')
192+
check('//?/c:/?', '//?/c:/[?]')
193+
check('//*/*/*', '//*/*/[*]')
172194

173195
def test_main():
174196
run_unittest(GlobTests)

Misc/NEWS

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,8 @@ Core and Builtins
5050
Library
5151
-------
5252

53+
- Issue #8402: Added the escape() function to the glob module.
54+
5355
- Issue #17618: Add Base85 and Ascii85 encoding/decoding to the base64 module.
5456

5557
- Issue #19634: time.strftime("%y") now raises a ValueError on AIX when given a

0 commit comments

Comments
 (0)