Ignore .nfs* files in distutils (#7719).
authorÉric Araujo <aeric@mtlpy.org>
Sat, 8 Dec 2012 19:21:51 +0000 (14:21 -0500)
committerÉric Araujo <aeric@mtlpy.org>
Sat, 8 Dec 2012 19:21:51 +0000 (14:21 -0500)
These files are created by some NFS clients a file is edited and removed
concurrently (see added link in doc for more info).  If such a file is
removed between distutils calls listdir and copy, it will get confused.
Other special files are ignored in sdist (namely VCS directories), but
this has to be filtered out earlier.

Doc/distutils/apiref.rst
Lib/distutils/dir_util.py
Lib/distutils/tests/test_dir_util.py
Lib/distutils/tests/test_sdist.py
Misc/NEWS

index e15dc76c83c0ad29462de12e8372102175830831..74fba4ada7fa44f5ae419ebba8416384aca8de91 100644 (file)
@@ -992,6 +992,12 @@ directories.
    destination of the symlink will be copied.  *update* and *verbose* are the same
    as for :func:`copy_file`.
 
+   Files in *src* that begin with :file:`.nfs` are skipped (more information on
+   these files is available in answer D2 of the `NFS FAQ page
+   <http://nfs.sourceforge.net/#section_d>`_.
+
+   .. versionchanged:: 3.2.4
+      NFS files are ignored.
 
 .. function:: remove_tree(directory[, verbose=0, dry_run=0])
 
index 30daf49a6ea89d67b0f84c3e4f3d81713d78e635..2826ff805d77a4e1113e00c3afa16a1083e5c219 100644 (file)
@@ -141,6 +141,10 @@ def copy_tree(src, dst, preserve_mode=1, preserve_times=1,
         src_name = os.path.join(src, n)
         dst_name = os.path.join(dst, n)
 
+        if n.startswith('.nfs'):
+            # skip NFS rename files
+            continue
+
         if preserve_symlinks and os.path.islink(src_name):
             link_dest = os.readlink(src_name)
             if verbose >= 1:
index ce74589dde515987e64c65acc54384f47c8d3012..1589f1297db24bf662003d327b1373a66027e0f8 100644 (file)
@@ -76,7 +76,6 @@ class DirUtilTestCase(support.TempdirManager, unittest.TestCase):
 
         remove_tree(self.root_target, verbose=0)
 
-
     def test_copy_tree_verbosity(self):
 
         mkpath(self.target, verbose=0)
@@ -88,11 +87,8 @@ class DirUtilTestCase(support.TempdirManager, unittest.TestCase):
 
         mkpath(self.target, verbose=0)
         a_file = os.path.join(self.target, 'ok.txt')
-        f = open(a_file, 'w')
-        try:
+        with open(a_file, 'w') as f:
             f.write('some content')
-        finally:
-            f.close()
 
         wanted = ['copying %s -> %s' % (a_file, self.target2)]
         copy_tree(self.target, self.target2, verbose=1)
@@ -101,6 +97,21 @@ class DirUtilTestCase(support.TempdirManager, unittest.TestCase):
         remove_tree(self.root_target, verbose=0)
         remove_tree(self.target2, verbose=0)
 
+    def test_copy_tree_skips_nfs_temp_files(self):
+        mkpath(self.target, verbose=0)
+
+        a_file = os.path.join(self.target, 'ok.txt')
+        nfs_file = os.path.join(self.target, '.nfs123abc')
+        for f in a_file, nfs_file:
+            with open(f, 'w') as fh:
+                fh.write('some content')
+
+        copy_tree(self.target, self.target2)
+        self.assertEqual(os.listdir(self.target2), ['ok.txt'])
+
+        remove_tree(self.root_target, verbose=0)
+        remove_tree(self.target2, verbose=0)
+
     def test_ensure_relative(self):
         if os.sep == '/':
             self.assertEqual(ensure_relative('/home/foo'), 'home/foo')
index 1ba2a1a6a9aebaf6b8dd528c53445705bef2462a..e6359d6a8afae2e81bcf218668faf61101e2e7e6 100644 (file)
@@ -83,9 +83,8 @@ class SDistTestCase(PyPIRCCommandTestCase):
 
     @unittest.skipUnless(ZLIB_SUPPORT, 'Need zlib support to run')
     def test_prune_file_list(self):
-        # this test creates a package with some vcs dirs in it
-        # and launch sdist to make sure they get pruned
-        # on all systems
+        # this test creates a project with some VCS dirs and an NFS rename
+        # file, then launches sdist to check they get pruned on all systems
 
         # creating VCS directories with some files in them
         os.mkdir(join(self.tmp_dir, 'somecode', '.svn'))
@@ -99,6 +98,8 @@ class SDistTestCase(PyPIRCCommandTestCase):
         self.write_file((self.tmp_dir, 'somecode', '.git',
                          'ok'), 'xxx')
 
+        self.write_file((self.tmp_dir, 'somecode', '.nfs0001'), 'xxx')
+
         # now building a sdist
         dist, cmd = self.get_cmd()
 
index 3c9f382fe3f797de4f2cf45e58e45aadc6428063..02e4d4882d545fbd7514e88b578fdae2897ba97b 100644 (file)
--- a/Misc/NEWS
+++ b/Misc/NEWS
@@ -177,6 +177,9 @@ Library
 
 - Issue #16628: Fix a memory leak in ctypes.resize().
 
+- Issue #7719: Make distutils ignore ``.nfs*`` files instead of choking later
+  on.  Initial patch by SilentGhost and Jeff Ramnani.
+
 - Issue #13120: Allow to call pdb.set_trace() from thread.
   Patch by Ilya Sandler.