New test for rev. 54407 which only uses directories under TESTFN.
diff --git a/Doc/lib/libos.tex b/Doc/lib/libos.tex
index 1a39693..638ed6b 100644
--- a/Doc/lib/libos.tex
+++ b/Doc/lib/libos.tex
@@ -1233,7 +1233,8 @@
 \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,24 +1274,25 @@
 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()}
 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:
diff --git a/Lib/os.py b/Lib/os.py
index c8cc274..991716e 100644
--- a/Lib/os.py
+++ b/Lib/os.py
@@ -221,7 +221,7 @@
 
 __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 @@
     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 @@
         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
diff --git a/Lib/test/test_os.py b/Lib/test/test_os.py
index 9dcdb18..6d7fe8e 100644
--- a/Lib/test/test_os.py
+++ b/Lib/test/test_os.py
@@ -272,65 +272,89 @@
         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 @@
             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):
diff --git a/Misc/NEWS b/Misc/NEWS
index a9d05e0..a2ec9a7 100644
--- a/Misc/NEWS
+++ b/Misc/NEWS
@@ -194,6 +194,10 @@
 
 - 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