(original) (raw)
changeset: 102997:ade53661607a branch: 3.5 parent: 102987:546b1f70cbed parent: 102996:13619a3e0737 user: Jason R. Coombs jaraco@jaraco.com date: Thu Sep 01 21:15:04 2016 -0400 files: Misc/NEWS description: Issue #12285: Merge with 3.4 diff -r 546b1f70cbed -r ade53661607a Lib/distutils/filelist.py --- a/Lib/distutils/filelist.py Thu Sep 01 22🔞03 2016 +0300 +++ b/Lib/distutils/filelist.py Thu Sep 01 21:15:04 2016 -0400 @@ -6,6 +6,7 @@ import os, re import fnmatch +import functools from distutils.util import convert_path from distutils.errors import DistutilsTemplateError, DistutilsInternalError from distutils import log @@ -242,35 +243,28 @@ # ---------------------------------------------------------------------- # Utility functions -def findall(dir=os.curdir): - """Find all files under 'dir' and return the list of full filenames - (relative to 'dir'). +def _find_all_simple(path): + """ + Find all files under 'path' """ - from stat import ST_MODE, S_ISREG, S_ISDIR, S_ISLNK - - list = [] - stack = [dir] - pop = stack.pop - push = stack.append - - while stack: - dir = pop() - names = os.listdir(dir) + results = ( + os.path.join(base, file) + for base, dirs, files in os.walk(path, followlinks=True) + for file in files + ) + return filter(os.path.isfile, results) - for name in names: - if dir != os.curdir: # avoid the dreaded "./" syndrome - fullname = os.path.join(dir, name) - else: - fullname = name - # Avoid excess stat calls -- just one will do, thank you! - stat = os.stat(fullname) - mode = stat[ST_MODE] - if S_ISREG(mode): - list.append(fullname) - elif S_ISDIR(mode) and not S_ISLNK(mode): - push(fullname) - return list +def findall(dir=os.curdir): + """ + Find all files under 'dir' and return the list of full filenames. + Unless dir is '.', return full filenames with dir prepended. + """ + files = _find_all_simple(dir) + if dir == os.curdir: + make_rel = functools.partial(os.path.relpath, start=dir) + files = map(make_rel, files) + return list(files) def glob_to_re(pattern): diff -r 546b1f70cbed -r ade53661607a Lib/distutils/tests/test_filelist.py --- a/Lib/distutils/tests/test_filelist.py Thu Sep 01 22🔞03 2016 +0300 +++ b/Lib/distutils/tests/test_filelist.py Thu Sep 01 21:15:04 2016 -0400 @@ -6,8 +6,10 @@ from distutils.log import WARN from distutils.errors import DistutilsTemplateError from distutils.filelist import glob_to_re, translate_pattern, FileList +from distutils import filelist -from test.support import captured_stdout, run_unittest +import test.support +from test.support import captured_stdout from distutils.tests import support MANIFEST_IN = """\ @@ -292,8 +294,40 @@ self.assertWarnings() -def test_suite(): - return unittest.makeSuite(FileListTestCase) +class FindAllTestCase(unittest.TestCase): + @test.support.skip_unless_symlink + def test_missing_symlink(self): + with test.support.temp_cwd(): + os.symlink('foo', 'bar') + self.assertEqual(filelist.findall(), []) + + def test_basic_discovery(self): + """ + When findall is called with no parameters or with + '.' as the parameter, the dot should be omitted from + the results. + """ + with test.support.temp_cwd(): + os.mkdir('foo') + file1 = os.path.join('foo', 'file1.txt') + test.support.create_empty_file(file1) + os.mkdir('bar') + file2 = os.path.join('bar', 'file2.txt') + test.support.create_empty_file(file2) + expected = [file2, file1] + self.assertEqual(sorted(filelist.findall()), expected) + + def test_non_local_discovery(self): + """ + When findall is called with another path, the full + path name should be returned. + """ + with test.support.temp_dir() as temp_dir: + file1 = os.path.join(temp_dir, 'file1.txt') + test.support.create_empty_file(file1) + expected = [file1] + self.assertEqual(filelist.findall(temp_dir), expected) + if __name__ == "__main__": - run_unittest(test_suite()) + unittest.main() diff -r 546b1f70cbed -r ade53661607a Misc/NEWS --- a/Misc/NEWS Thu Sep 01 22🔞03 2016 +0300 +++ b/Misc/NEWS Thu Sep 01 21:15:04 2016 -0400 @@ -50,6 +50,8 @@ Library ------- +- Issue #12285: Fix error when distutils encounters symlink. + - Issue #27881: Fixed possible bugs when setting sqlite3.Connection.isolation_level. Based on patch by Xiang Zhang. /jaraco@jaraco.com