Issue #8402: Added the escape() function to the glob module.
This commit is contained in:
parent
e3010fd740
commit
fd32fffa5a
|
@ -40,6 +40,17 @@ For example, ``'[?]'`` matches the character ``'?'``.
|
|||
without actually storing them all simultaneously.
|
||||
|
||||
|
||||
.. function:: escape(pathname)
|
||||
|
||||
Escape all special characters (``'?'``, ``'*'`` and ``'['``).
|
||||
This is useful if you want to match an arbitrary literal string that may
|
||||
have special characters in it. Special characters in drive/UNC
|
||||
sharepoints are not escaped, e.g. on Windows
|
||||
``escape('//?/c:/Quo vadis?.txt')`` returns ``'//?/c:/Quo vadis[?].txt'``.
|
||||
|
||||
.. versionadded:: 3.4
|
||||
|
||||
|
||||
For example, consider a directory containing only the following files:
|
||||
:file:`1.gif`, :file:`2.txt`, and :file:`card.gif`. :func:`glob` will produce
|
||||
the following results. Notice how any leading components of the path are
|
||||
|
|
16
Lib/glob.py
16
Lib/glob.py
|
@ -79,8 +79,8 @@ def glob0(dirname, basename):
|
|||
return []
|
||||
|
||||
|
||||
magic_check = re.compile('[*?[]')
|
||||
magic_check_bytes = re.compile(b'[*?[]')
|
||||
magic_check = re.compile('([*?[])')
|
||||
magic_check_bytes = re.compile(b'([*?[])')
|
||||
|
||||
def has_magic(s):
|
||||
if isinstance(s, bytes):
|
||||
|
@ -91,3 +91,15 @@ def has_magic(s):
|
|||
|
||||
def _ishidden(path):
|
||||
return path[0] in ('.', b'.'[0])
|
||||
|
||||
def escape(pathname):
|
||||
"""Escape all special characters.
|
||||
"""
|
||||
# Escaping is done by wrapping any of "*?[" between square brackets.
|
||||
# Metacharacters do not work in the drive part and shouldn't be escaped.
|
||||
drive, pathname = os.path.splitdrive(pathname)
|
||||
if isinstance(pathname, bytes):
|
||||
pathname = magic_check_bytes.sub(br'[\1]', pathname)
|
||||
else:
|
||||
pathname = magic_check.sub(r'[\1]', pathname)
|
||||
return drive + pathname
|
||||
|
|
|
@ -169,6 +169,28 @@ class GlobTests(unittest.TestCase):
|
|||
eq(glob.glob('\\\\*\\*\\'), [])
|
||||
eq(glob.glob(b'\\\\*\\*\\'), [])
|
||||
|
||||
def check_escape(self, arg, expected):
|
||||
self.assertEqual(glob.escape(arg), expected)
|
||||
self.assertEqual(glob.escape(os.fsencode(arg)), os.fsencode(expected))
|
||||
|
||||
def test_escape(self):
|
||||
check = self.check_escape
|
||||
check('abc', 'abc')
|
||||
check('[', '[[]')
|
||||
check('?', '[?]')
|
||||
check('*', '[*]')
|
||||
check('[[_/*?*/_]]', '[[][[]_/[*][?][*]/_]]')
|
||||
check('/[[_/*?*/_]]/', '/[[][[]_/[*][?][*]/_]]/')
|
||||
|
||||
@unittest.skipUnless(sys.platform == "win32", "Win32 specific test")
|
||||
def test_escape_windows(self):
|
||||
check = self.check_escape
|
||||
check('?:?', '?:[?]')
|
||||
check('*:*', '*:[*]')
|
||||
check(r'\\?\c:\?', r'\\?\c:\[?]')
|
||||
check(r'\\*\*\*', r'\\*\*\[*]')
|
||||
check('//?/c:/?', '//?/c:/[?]')
|
||||
check('//*/*/*', '//*/*/[*]')
|
||||
|
||||
def test_main():
|
||||
run_unittest(GlobTests)
|
||||
|
|
Loading…
Reference in New Issue