mirror of
https://github.com/python/cpython.git
synced 2025-07-29 06:05:00 +00:00
New test for rev. 54407 which only uses directories under TESTFN.
This commit is contained in:
parent
5cb76c19ba
commit
cae9f3d916
4 changed files with 70 additions and 32 deletions
|
@ -1233,7 +1233,8 @@ Availability: Macintosh, \UNIX, Windows.
|
|||
\end{funcdesc}
|
||||
|
||||
\begin{funcdesc}{walk}{top\optional{, topdown\code{=True}
|
||||
\optional{, onerror\code{=None}}}}
|
||||
\optional{, onerror\code{=None}\optional{,
|
||||
followlinks\code{=False}}}}}
|
||||
\index{directory!walking}
|
||||
\index{directory!traversal}
|
||||
\function{walk()} generates the file names in a directory tree, by
|
||||
|
@ -1273,8 +1274,18 @@ report the error to continue with the walk, or raise the exception
|
|||
to abort the walk. Note that the filename is available as the
|
||||
\code{filename} attribute of the exception object.
|
||||
|
||||
By default, \function{walk()} will not walk down into symbolic links that
|
||||
resolve to directories. Set \var{followlinks} to True to visit directories
|
||||
pointed to by symlinks, on systems that support them.
|
||||
|
||||
\versionadded[The \var{followlinks} parameter]{2.6}
|
||||
|
||||
\begin{notice}
|
||||
Be aware that setting \var{followlinks} to true can lead to infinite recursion
|
||||
if a link points to a parent directory of itself. \function{walk()} does not
|
||||
keep track of the directories it visited already.
|
||||
\end{notice}
|
||||
|
||||
\begin{notice}
|
||||
If you pass a relative pathname, don't change the current working
|
||||
directory between resumptions of \function{walk()}. \function{walk()}
|
||||
|
@ -1282,15 +1293,6 @@ never changes the current directory, and assumes that its caller
|
|||
doesn't either.
|
||||
\end{notice}
|
||||
|
||||
\begin{notice}
|
||||
On systems that support symbolic links, links to subdirectories appear
|
||||
in \var{dirnames} lists, but \function{walk()} will not visit them
|
||||
(infinite loops are hard to avoid when following symbolic links).
|
||||
To visit linked directories, you can identify them with
|
||||
\code{os.path.islink(\var{path})}, and invoke \code{walk(\var{path})}
|
||||
on each directly.
|
||||
\end{notice}
|
||||
|
||||
This example displays the number of bytes taken by non-directory files
|
||||
in each directory under the starting directory, except that it doesn't
|
||||
look under any CVS subdirectory:
|
||||
|
|
10
Lib/os.py
10
Lib/os.py
|
@ -221,7 +221,7 @@ def renames(old, new):
|
|||
|
||||
__all__.extend(["makedirs", "removedirs", "renames"])
|
||||
|
||||
def walk(top, topdown=True, onerror=None):
|
||||
def walk(top, topdown=True, onerror=None, followlinks=False):
|
||||
"""Directory tree generator.
|
||||
|
||||
For each directory in the directory tree rooted at top (including top
|
||||
|
@ -257,6 +257,10 @@ def walk(top, topdown=True, onerror=None):
|
|||
to abort the walk. Note that the filename is available as the
|
||||
filename attribute of the exception object.
|
||||
|
||||
By default, os.walk does not follow symbolic links to subdirectories on
|
||||
systems that support them. In order to get this functionality, set the
|
||||
optional argument 'followlinks' to true.
|
||||
|
||||
Caution: if you pass a relative pathname for top, don't change the
|
||||
current working directory between resumptions of walk. walk never
|
||||
changes the current directory, and assumes that the client doesn't
|
||||
|
@ -300,8 +304,8 @@ def walk(top, topdown=True, onerror=None):
|
|||
yield top, dirs, nondirs
|
||||
for name in dirs:
|
||||
path = join(top, name)
|
||||
if not islink(path):
|
||||
for x in walk(path, topdown, onerror):
|
||||
if followlinks or not islink(path):
|
||||
for x in walk(path, topdown, onerror, followlinks):
|
||||
yield x
|
||||
if not topdown:
|
||||
yield top, dirs, nondirs
|
||||
|
|
|
@ -272,65 +272,89 @@ class WalkTests(unittest.TestCase):
|
|||
from os.path import join
|
||||
|
||||
# Build:
|
||||
# TESTFN/ a file kid and two directory kids
|
||||
# TESTFN/
|
||||
# TEST1/ a file kid and two directory kids
|
||||
# tmp1
|
||||
# SUB1/ a file kid and a directory kid
|
||||
# tmp2
|
||||
# SUB11/ no kids
|
||||
# SUB2/ just a file kid
|
||||
# tmp3
|
||||
sub1_path = join(test_support.TESTFN, "SUB1")
|
||||
# tmp2
|
||||
# SUB11/ no kids
|
||||
# SUB2/ a file kid and a dirsymlink kid
|
||||
# tmp3
|
||||
# link/ a symlink to TESTFN.2
|
||||
# TEST2/
|
||||
# tmp4 a lone file
|
||||
walk_path = join(test_support.TESTFN, "TEST1")
|
||||
sub1_path = join(walk_path, "SUB1")
|
||||
sub11_path = join(sub1_path, "SUB11")
|
||||
sub2_path = join(test_support.TESTFN, "SUB2")
|
||||
tmp1_path = join(test_support.TESTFN, "tmp1")
|
||||
sub2_path = join(walk_path, "SUB2")
|
||||
tmp1_path = join(walk_path, "tmp1")
|
||||
tmp2_path = join(sub1_path, "tmp2")
|
||||
tmp3_path = join(sub2_path, "tmp3")
|
||||
link_path = join(sub2_path, "link")
|
||||
t2_path = join(test_support.TESTFN, "TEST2")
|
||||
tmp4_path = join(test_support.TESTFN, "TEST2", "tmp4")
|
||||
|
||||
# Create stuff.
|
||||
os.makedirs(sub11_path)
|
||||
os.makedirs(sub2_path)
|
||||
for path in tmp1_path, tmp2_path, tmp3_path:
|
||||
os.makedirs(t2_path)
|
||||
for path in tmp1_path, tmp2_path, tmp3_path, tmp4_path:
|
||||
f = file(path, "w")
|
||||
f.write("I'm " + path + " and proud of it. Blame test_os.\n")
|
||||
f.close()
|
||||
if hasattr(os, "symlink"):
|
||||
os.symlink(os.path.abspath(t2_path), link_path)
|
||||
else:
|
||||
# it must be a directory because the test expects that
|
||||
os.mkdir(link_path)
|
||||
|
||||
# Walk top-down.
|
||||
all = list(os.walk(test_support.TESTFN))
|
||||
all = list(os.walk(walk_path))
|
||||
self.assertEqual(len(all), 4)
|
||||
# We can't know which order SUB1 and SUB2 will appear in.
|
||||
# Not flipped: TESTFN, SUB1, SUB11, SUB2
|
||||
# flipped: TESTFN, SUB2, SUB1, SUB11
|
||||
flipped = all[0][1][0] != "SUB1"
|
||||
all[0][1].sort()
|
||||
self.assertEqual(all[0], (test_support.TESTFN, ["SUB1", "SUB2"], ["tmp1"]))
|
||||
self.assertEqual(all[0], (walk_path, ["SUB1", "SUB2"], ["tmp1"]))
|
||||
self.assertEqual(all[1 + flipped], (sub1_path, ["SUB11"], ["tmp2"]))
|
||||
self.assertEqual(all[2 + flipped], (sub11_path, [], []))
|
||||
self.assertEqual(all[3 - 2 * flipped], (sub2_path, [], ["tmp3"]))
|
||||
self.assertEqual(all[3 - 2 * flipped], (sub2_path, ["link"], ["tmp3"]))
|
||||
|
||||
# Prune the search.
|
||||
all = []
|
||||
for root, dirs, files in os.walk(test_support.TESTFN):
|
||||
for root, dirs, files in os.walk(walk_path):
|
||||
all.append((root, dirs, files))
|
||||
# Don't descend into SUB1.
|
||||
if 'SUB1' in dirs:
|
||||
# Note that this also mutates the dirs we appended to all!
|
||||
dirs.remove('SUB1')
|
||||
self.assertEqual(len(all), 2)
|
||||
self.assertEqual(all[0], (test_support.TESTFN, ["SUB2"], ["tmp1"]))
|
||||
self.assertEqual(all[1], (sub2_path, [], ["tmp3"]))
|
||||
self.assertEqual(all[0], (walk_path, ["SUB2"], ["tmp1"]))
|
||||
self.assertEqual(all[1], (sub2_path, ["link"], ["tmp3"]))
|
||||
|
||||
# Walk bottom-up.
|
||||
all = list(os.walk(test_support.TESTFN, topdown=False))
|
||||
all = list(os.walk(walk_path, topdown=False))
|
||||
self.assertEqual(len(all), 4)
|
||||
# We can't know which order SUB1 and SUB2 will appear in.
|
||||
# Not flipped: SUB11, SUB1, SUB2, TESTFN
|
||||
# flipped: SUB2, SUB11, SUB1, TESTFN
|
||||
flipped = all[3][1][0] != "SUB1"
|
||||
all[3][1].sort()
|
||||
self.assertEqual(all[3], (test_support.TESTFN, ["SUB1", "SUB2"], ["tmp1"]))
|
||||
self.assertEqual(all[3], (walk_path, ["SUB1", "SUB2"], ["tmp1"]))
|
||||
self.assertEqual(all[flipped], (sub11_path, [], []))
|
||||
self.assertEqual(all[flipped + 1], (sub1_path, ["SUB11"], ["tmp2"]))
|
||||
self.assertEqual(all[2 - 2 * flipped], (sub2_path, [], ["tmp3"]))
|
||||
self.assertEqual(all[2 - 2 * flipped], (sub2_path, ["link"], ["tmp3"]))
|
||||
|
||||
# Walk, following symlinks.
|
||||
for root, dirs, files in os.walk(walk_path, followlinks=True):
|
||||
if root == link_path:
|
||||
self.assertEqual(dirs, [])
|
||||
self.assertEqual(files, ["tmp4"])
|
||||
break
|
||||
else:
|
||||
self.fail("Didn't follow symlink with followlinks=True")
|
||||
|
||||
|
||||
# Tear everything down. This is a decent use for bottom-up on
|
||||
# Windows, which doesn't have a recursive delete command. The
|
||||
|
@ -340,7 +364,11 @@ class WalkTests(unittest.TestCase):
|
|||
for name in files:
|
||||
os.remove(join(root, name))
|
||||
for name in dirs:
|
||||
os.rmdir(join(root, name))
|
||||
dirname = join(root, name)
|
||||
if not os.path.islink(dirname):
|
||||
os.rmdir(dirname)
|
||||
else:
|
||||
os.remove(dirname)
|
||||
os.rmdir(test_support.TESTFN)
|
||||
|
||||
class MakedirTests (unittest.TestCase):
|
||||
|
|
|
@ -194,6 +194,10 @@ Library
|
|||
|
||||
- Patch #1630118: add a SpooledTemporaryFile class to tempfile.py.
|
||||
|
||||
- Patch #1273829: os.walk() now has a "followlinks" parameter. If set to
|
||||
True (which is not the default), it visits symlinks pointing to
|
||||
directories.
|
||||
|
||||
- Bug #1681228: the webbrowser module now correctly uses the default
|
||||
GNOME or KDE browser, depending on whether there is a session of one
|
||||
of those present. Also, it tries the Windows default browser before
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue