Serhiy Storchaka <storch...@gmail.com> added the comment:
> IMO adding follow_symlinks to the functions currently supporting
> symlinks/followlinks is a bugfix. Such a patch would be ok to go into 3.3.
Here is an other patch, that implements Larry's suggestion about
renaming followlinks in (f)walk to follow_symlinks (with keeping old
name as alias). I hope native speakers corrected me in docs. However, I
don't think that this is the best solution (but it better than nothing).
----------
Added file:
http://bugs.python.org/file26182/followlinks-to-follow_symlinks.patch
_______________________________________
Python tracker <rep...@bugs.python.org>
<http://bugs.python.org/issue15202>
_______________________________________
diff -r b66e82c9f852 Doc/library/os.rst
--- a/Doc/library/os.rst Tue Jun 26 23:05:27 2012 +0200
+++ b/Doc/library/os.rst Wed Jun 27 20:49:59 2012 +0300
@@ -2128,7 +2128,7 @@
and the *dir_fd*, *follow_symlinks*, and *ns* parameters.
-.. function:: walk(top, topdown=True, onerror=None, followlinks=False)
+.. function:: walk(top, topdown=True, onerror=None, follow_symlinks=False)
.. index::
single: directory; walking
@@ -2168,12 +2168,12 @@
is available as the ``filename`` attribute of the exception object.
By default, :func:`walk` will not walk down into symbolic links that
resolve to
- directories. Set *followlinks* to ``True`` to visit directories pointed to
by
+ directories. Set *follow_symlinks* to ``True`` to visit directories pointed
to by
symlinks, on systems that support them.
.. note::
- Be aware that setting *followlinks* to ``True`` can lead to infinite
+ Be aware that setting *follow_symlinks* to ``True`` can lead to infinite
recursion if a link points to a parent directory of itself. :func:`walk`
does not keep track of the directories it visited already.
@@ -2210,8 +2210,12 @@
for name in dirs:
os.rmdir(os.path.join(root, name))
-
-.. function:: fwalk(top='.', topdown=True, onerror=None, followlinks=False, *,
dir_fd=None)
+ .. versionchanged:: 3.3
+ *followlinks* renamed to *follow_symlinks*. For backward compatibility
+ the old name accepted as alias to new one.
+
+
+.. function:: fwalk(top='.', topdown=True, onerror=None,
follow_symlinks=False, *, dir_fd=None)
.. index::
single: directory; walking
diff -r b66e82c9f852 Lib/os.py
--- a/Lib/os.py Tue Jun 26 23:05:27 2012 +0200
+++ b/Lib/os.py Wed Jun 27 20:49:59 2012 +0300
@@ -331,7 +331,9 @@
__all__.extend(["makedirs", "removedirs", "renames"])
-def walk(top, topdown=True, onerror=None, followlinks=False):
+_sentry = object()
+
+def walk(top, topdown=True, onerror=None, follow_symlinks=_sentry, *,
followlinks=_sentry):
"""Directory tree generator.
For each directory in the directory tree rooted at top (including top
@@ -369,7 +371,7 @@
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.
+ optional argument 'follow_symlinks' to true.
Caution: if you pass a relative pathname for top, don't change the
current working directory between resumptions of walk. walk never
@@ -387,7 +389,18 @@
if 'CVS' in dirs:
dirs.remove('CVS') # don't visit CVS directories
"""
+ if follow_symlinks is _sentry:
+ if followlinks is _sentry:
+ follow_symlinks = False
+ else:
+ follow_symlinks = followlinks
+ elif followlinks is not _sentry:
+ raise ValueError(
+ "'follow_symlinks' and 'followlinks' arguments are
incompatible")
+ yield from _walk(top, topdown, onerror, follow_symlinks)
+
+def _walk(top, topdown, onerror, follow_symlinks):
islink, join, isdir = path.islink, path.join, path.isdir
# We may not have read permission for top, in which case we can't
@@ -415,8 +428,8 @@
yield top, dirs, nondirs
for name in dirs:
new_path = join(top, name)
- if followlinks or not islink(new_path):
- yield from walk(new_path, topdown, onerror, followlinks)
+ if follow_symlinks or not islink(new_path):
+ yield from walk(new_path, topdown, onerror, follow_symlinks)
if not topdown:
yield top, dirs, nondirs
@@ -424,7 +437,7 @@
if {open, stat} <= supports_dir_fd and {listdir, stat} <= supports_fd:
- def fwalk(top=".", topdown=True, onerror=None, followlinks=False, *,
dir_fd=None):
+ def fwalk(top=".", topdown=True, onerror=None, follow_symlinks=False, *,
dir_fd=None):
"""Directory tree generator.
This behaves exactly like walk(), except that it yields a 4-tuple
@@ -435,7 +448,7 @@
and `dirfd` is a file descriptor referring to the directory `dirpath`.
The advantage of fwalk() over walk() is that it's safe against symlink
- races (when followlinks is False).
+ races (when follow_symlinks is False).
If dir_fd is not None, it should be a file descriptor open to a
directory,
and top should be relative; top will then be relative to that
directory.
@@ -462,13 +475,13 @@
orig_st = stat(top, follow_symlinks=False, dir_fd=dir_fd)
topfd = open(top, O_RDONLY, dir_fd=dir_fd)
try:
- if (followlinks or (st.S_ISDIR(orig_st.st_mode) and
- path.samestat(orig_st, stat(topfd)))):
- yield from _fwalk(topfd, top, topdown, onerror, followlinks)
+ if (follow_symlinks or (st.S_ISDIR(orig_st.st_mode) and
+ path.samestat(orig_st, stat(topfd)))):
+ yield from _fwalk(topfd, top, topdown, onerror,
follow_symlinks)
finally:
close(topfd)
- def _fwalk(topfd, toppath, topdown, onerror, followlinks):
+ def _fwalk(topfd, toppath, topdown, onerror, follow_symlinks):
# Note: This uses O(depth of the directory tree) file descriptors: if
# necessary, it can be adapted to only require O(1) FDs, see issue
# #13734.
@@ -499,16 +512,16 @@
for name in dirs:
try:
- orig_st = stat(name, dir_fd=topfd, follow_symlinks=followlinks)
+ orig_st = stat(name, dir_fd=topfd,
follow_symlinks=follow_symlinks)
dirfd = open(name, O_RDONLY, dir_fd=topfd)
except error as err:
if onerror is not None:
onerror(err)
return
try:
- if followlinks or path.samestat(orig_st, stat(dirfd)):
+ if follow_symlinks or path.samestat(orig_st, stat(dirfd)):
dirpath = path.join(toppath, name)
- yield from _fwalk(dirfd, dirpath, topdown, onerror,
followlinks)
+ yield from _fwalk(dirfd, dirpath, topdown, onerror,
follow_symlinks)
finally:
close(dirfd)
diff -r b66e82c9f852 Lib/test/test_os.py
--- a/Lib/test/test_os.py Tue Jun 26 23:05:27 2012 +0200
+++ b/Lib/test/test_os.py Wed Jun 27 20:49:59 2012 +0300
@@ -712,6 +712,14 @@
if support.can_symlink():
# Walk, following symlinks.
+ for root, dirs, files in os.walk(walk_path, follow_symlinks=True):
+ if root == link_path:
+ self.assertEqual(dirs, [])
+ self.assertEqual(files, ["tmp4"])
+ break
+ else:
+ self.fail("Didn't follow symlink with follow_symlinks=True")
+ # Walk, using backward compatible argument name "followlinks".
for root, dirs, files in os.walk(walk_path, followlinks=True):
if root == link_path:
self.assertEqual(dirs, [])
@@ -720,6 +728,10 @@
else:
self.fail("Didn't follow symlink with followlinks=True")
+ # Incopatible using new and old argument names for
"follow_symlinks".
+ self.assertRaises(ValueError, os.walk, walk_path,
+ follow_links=True, followlinks=True)
+
def tearDown(self):
# Tear everything down. This is a decent use for bottom-up on
# Windows, which doesn't have a recursive delete command. The
@@ -745,8 +757,8 @@
"""
compare with walk() results.
"""
- for topdown, followlinks in itertools.product((True, False), repeat=2):
- d = {'topdown': topdown, 'followlinks': followlinks}
+ for topdown, follow_symlinks in itertools.product((True, False),
repeat=2):
+ d = {'topdown': topdown, 'follow_symlinks': follow_symlinks}
walk_kwargs.update(d)
fwalk_kwargs.update(d)
@@ -774,8 +786,8 @@
def test_yields_correct_dir_fd(self):
# check returned file descriptors
- for topdown, followlinks in itertools.product((True, False), repeat=2):
- args = support.TESTFN, topdown, None, followlinks
+ for topdown, follow_symlinks in itertools.product((True, False),
repeat=2):
+ args = support.TESTFN, topdown, None, follow_symlinks
for root, dirs, files, rootfd in os.fwalk(*args):
# check that the FD is valid
os.fstat(rootfd)
diff -r b66e82c9f852 Modules/_ctypes/libffi/generate-ios-source-and-headers.py
--- a/Modules/_ctypes/libffi/generate-ios-source-and-headers.py Tue Jun 26
23:05:27 2012 +0200
+++ b/Modules/_ctypes/libffi/generate-ios-source-and-headers.py Wed Jun 27
20:49:59 2012 +0300
@@ -83,7 +83,7 @@
headers_seen = collections.defaultdict(set)
def move_source_tree(src_dir, dest_dir, dest_include_dir, arch=None,
prefix=None, suffix=None):
- for root, dirs, files in os.walk(src_dir, followlinks=True):
+ for root, dirs, files in os.walk(src_dir, follow_symlinks=True):
relroot = os.path.relpath(root,src_dir)
def move_dir(arch, prefix='', suffix='', files=[]):
diff -r b66e82c9f852 Modules/_ctypes/libffi/generate-osx-source-and-headers.py
--- a/Modules/_ctypes/libffi/generate-osx-source-and-headers.py Tue Jun 26
23:05:27 2012 +0200
+++ b/Modules/_ctypes/libffi/generate-osx-source-and-headers.py Wed Jun 27
20:49:59 2012 +0300
@@ -77,7 +77,7 @@
headers_seen = collections.defaultdict(set)
def move_source_tree(src_dir, dest_dir, dest_include_dir, arch=None,
prefix=None, suffix=None):
- for root, dirs, files in os.walk(src_dir, followlinks=True):
+ for root, dirs, files in os.walk(src_dir, follow_symlinks=True):
relroot = os.path.relpath(root,src_dir)
def move_dir(arch, prefix='', suffix='', files=[]):
_______________________________________________
Python-bugs-list mailing list
Unsubscribe:
http://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com