Kaydet (Commit) 735b790f authored tarafından Serhiy Storchaka's avatar Serhiy Storchaka

Issue #25584: Fixed recursive glob() with patterns starting with '**'.

üst f9827ea6
...@@ -30,6 +30,13 @@ def iglob(pathname, *, recursive=False): ...@@ -30,6 +30,13 @@ def iglob(pathname, *, recursive=False):
If recursive is true, the pattern '**' will match any files and If recursive is true, the pattern '**' will match any files and
zero or more directories and subdirectories. zero or more directories and subdirectories.
""" """
it = _iglob(pathname, recursive)
if recursive and _isrecursive(pathname):
s = next(it) # skip empty string
assert not s
return it
def _iglob(pathname, recursive):
dirname, basename = os.path.split(pathname) dirname, basename = os.path.split(pathname)
if not has_magic(pathname): if not has_magic(pathname):
if basename: if basename:
...@@ -50,7 +57,7 @@ def iglob(pathname, *, recursive=False): ...@@ -50,7 +57,7 @@ def iglob(pathname, *, recursive=False):
# drive or UNC path. Prevent an infinite recursion if a drive or UNC path # drive or UNC path. Prevent an infinite recursion if a drive or UNC path
# contains magic characters (i.e. r'\\?\C:'). # contains magic characters (i.e. r'\\?\C:').
if dirname != pathname and has_magic(dirname): if dirname != pathname and has_magic(dirname):
dirs = iglob(dirname, recursive=recursive) dirs = _iglob(dirname, recursive)
else: else:
dirs = [dirname] dirs = [dirname]
if has_magic(basename): if has_magic(basename):
...@@ -98,12 +105,10 @@ def glob0(dirname, basename): ...@@ -98,12 +105,10 @@ def glob0(dirname, basename):
def glob2(dirname, pattern): def glob2(dirname, pattern):
assert _isrecursive(pattern) assert _isrecursive(pattern)
if dirname: yield pattern[:0]
yield pattern[:0]
yield from _rlistdir(dirname) yield from _rlistdir(dirname)
# Recursively yields relative pathnames inside a literal directory. # Recursively yields relative pathnames inside a literal directory.
def _rlistdir(dirname): def _rlistdir(dirname):
if not dirname: if not dirname:
if isinstance(dirname, bytes): if isinstance(dirname, bytes):
......
...@@ -31,6 +31,7 @@ class GlobTests(unittest.TestCase): ...@@ -31,6 +31,7 @@ class GlobTests(unittest.TestCase):
self.mktemp('.bb', 'H') self.mktemp('.bb', 'H')
self.mktemp('aaa', 'zzzF') self.mktemp('aaa', 'zzzF')
self.mktemp('ZZZ') self.mktemp('ZZZ')
self.mktemp('EF')
self.mktemp('a', 'bcd', 'EF') self.mktemp('a', 'bcd', 'EF')
self.mktemp('a', 'bcd', 'efg', 'ha') self.mktemp('a', 'bcd', 'efg', 'ha')
if can_symlink(): if can_symlink():
...@@ -200,7 +201,7 @@ class GlobTests(unittest.TestCase): ...@@ -200,7 +201,7 @@ class GlobTests(unittest.TestCase):
def test_recursive_glob(self): def test_recursive_glob(self):
eq = self.assertSequencesEqual_noorder eq = self.assertSequencesEqual_noorder
full = [('ZZZ',), full = [('EF',), ('ZZZ',),
('a',), ('a', 'D'), ('a',), ('a', 'D'),
('a', 'bcd'), ('a', 'bcd'),
('a', 'bcd', 'EF'), ('a', 'bcd', 'EF'),
...@@ -217,8 +218,8 @@ class GlobTests(unittest.TestCase): ...@@ -217,8 +218,8 @@ class GlobTests(unittest.TestCase):
('sym3', 'efg', 'ha'), ('sym3', 'efg', 'ha'),
] ]
eq(self.rglob('**'), self.joins(('',), *full)) eq(self.rglob('**'), self.joins(('',), *full))
eq(self.rglob('.', '**'), self.joins(('.',''), eq(self.rglob(os.curdir, '**'),
*(('.',) + i for i in full))) self.joins((os.curdir, ''), *((os.curdir,) + i for i in full)))
dirs = [('a', ''), ('a', 'bcd', ''), ('a', 'bcd', 'efg', ''), dirs = [('a', ''), ('a', 'bcd', ''), ('a', 'bcd', 'efg', ''),
('aaa', ''), ('aab', '')] ('aaa', ''), ('aab', '')]
if can_symlink(): if can_symlink():
...@@ -229,11 +230,11 @@ class GlobTests(unittest.TestCase): ...@@ -229,11 +230,11 @@ class GlobTests(unittest.TestCase):
('a', ''), ('a', 'D'), ('a', 'bcd'), ('a', 'bcd', 'EF'), ('a', ''), ('a', 'D'), ('a', 'bcd'), ('a', 'bcd', 'EF'),
('a', 'bcd', 'efg'), ('a', 'bcd', 'efg', 'ha'))) ('a', 'bcd', 'efg'), ('a', 'bcd', 'efg', 'ha')))
eq(self.rglob('a**'), self.joins(('a',), ('aaa',), ('aab',))) eq(self.rglob('a**'), self.joins(('a',), ('aaa',), ('aab',)))
expect = [('a', 'bcd', 'EF')] expect = [('a', 'bcd', 'EF'), ('EF',)]
if can_symlink(): if can_symlink():
expect += [('sym3', 'EF')] expect += [('sym3', 'EF')]
eq(self.rglob('**', 'EF'), self.joins(*expect)) eq(self.rglob('**', 'EF'), self.joins(*expect))
expect = [('a', 'bcd', 'EF'), ('aaa', 'zzzF'), ('aab', 'F')] expect = [('a', 'bcd', 'EF'), ('aaa', 'zzzF'), ('aab', 'F'), ('EF',)]
if can_symlink(): if can_symlink():
expect += [('sym3', 'EF')] expect += [('sym3', 'EF')]
eq(self.rglob('**', '*F'), self.joins(*expect)) eq(self.rglob('**', '*F'), self.joins(*expect))
...@@ -247,10 +248,18 @@ class GlobTests(unittest.TestCase): ...@@ -247,10 +248,18 @@ class GlobTests(unittest.TestCase):
eq(glob.glob('**', recursive=True), [join(*i) for i in full]) eq(glob.glob('**', recursive=True), [join(*i) for i in full])
eq(glob.glob(join('**', ''), recursive=True), eq(glob.glob(join('**', ''), recursive=True),
[join(*i) for i in dirs]) [join(*i) for i in dirs])
eq(glob.glob(join('**', '*'), recursive=True),
[join(*i) for i in full])
eq(glob.glob(join(os.curdir, '**'), recursive=True),
[join(os.curdir, '')] + [join(os.curdir, *i) for i in full])
eq(glob.glob(join(os.curdir, '**', ''), recursive=True),
[join(os.curdir, '')] + [join(os.curdir, *i) for i in dirs])
eq(glob.glob(join(os.curdir, '**', '*'), recursive=True),
[join(os.curdir, *i) for i in full])
eq(glob.glob(join('**','zz*F'), recursive=True), eq(glob.glob(join('**','zz*F'), recursive=True),
[join('aaa', 'zzzF')]) [join('aaa', 'zzzF')])
eq(glob.glob('**zz*F', recursive=True), []) eq(glob.glob('**zz*F', recursive=True), [])
expect = [join('a', 'bcd', 'EF')] expect = [join('a', 'bcd', 'EF'), 'EF']
if can_symlink(): if can_symlink():
expect += [join('sym3', 'EF')] expect += [join('sym3', 'EF')]
eq(glob.glob(join('**', 'EF'), recursive=True), expect) eq(glob.glob(join('**', 'EF'), recursive=True), expect)
......
...@@ -61,6 +61,8 @@ Core and Builtins ...@@ -61,6 +61,8 @@ Core and Builtins
Library Library
------- -------
- Issue #25584: Fixed recursive glob() with patterns starting with '\*\*'.
- Issue #25446: Fix regression in smtplib's AUTH LOGIN support. - Issue #25446: Fix regression in smtplib's AUTH LOGIN support.
- Issue #18010: Fix the pydoc web server's module search function to handle - Issue #18010: Fix the pydoc web server's module search function to handle
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment