]> granicus.if.org Git - python/commitdiff
Ignore .nfs* files in distutils (#7719).
authorÉric Araujo <merwok@netwok.org>
Tue, 3 Jul 2012 05:12:42 +0000 (01:12 -0400)
committerÉric Araujo <merwok@netwok.org>
Tue, 3 Jul 2012 05:12:42 +0000 (01:12 -0400)
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/ACKS
Misc/NEWS

index ba4fc9f5a5098c4479bab864425820d6dac30873..60c0dd8fe75ef9484895e7df79d3924bc83e2c26 100644 (file)
@@ -973,8 +973,8 @@ directories.
    Copy an entire directory tree *src* to a new location *dst*.  Both *src* and
    *dst* must be directory names.  If *src* is not a directory, raise
    :exc:`DistutilsFileError`.  If *dst* does  not exist, it is created with
-   :func:`mkpath`.  The end result of the  copy is that every file in *src* is
-   copied to *dst*, and  directories under *src* are recursively copied to *dst*.
+   :func:`mkpath`.  The end result of the copy is that every file in *src* is
+   copied to *dst*, and directories under *src* are recursively copied to *dst*.
    Return the list of files that were copied or might have been copied, using their
    output name. The return value is unaffected by *update* or *dry_run*: it is
    simply the list of all files under *src*, with the names changed to be under
@@ -987,6 +987,10 @@ 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>`_.
+
 
 .. function:: remove_tree(directory[, verbose=0, dry_run=0])
 
index 9c5cf337c6c9ab87fa693e3d754b584573424a8d..5026e246685eacf3575db56b944924b2d0e84042 100644 (file)
@@ -144,6 +144,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 693f77cf6461096f36c2685d64f906e351a7eca8..d82d9133d0411a516055843ed26400e893202dad 100644 (file)
@@ -101,6 +101,24 @@ 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:
+            fh = open(f, 'w')
+            try:
+                fh.write('some content')
+            finally:
+                fh.close()
+
+        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 3a89f73fa2b9a13676a46df72a6d5868240ce048..7e7d98d096c58dde9932f674c53b685686f5972b 100644 (file)
@@ -91,9 +91,8 @@ class SDistTestCase(PyPIRCCommandTestCase):
 
     @unittest.skipUnless(zlib, "requires zlib")
     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'))
@@ -107,6 +106,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 e1adbe7006f73e701d400640b99f2b9a8b990587..fed05535d90016725411289f940384cacc388efb 100644 (file)
--- a/Misc/ACKS
+++ b/Misc/ACKS
@@ -688,6 +688,7 @@ Eduardo Pérez
 Brian Quinlan
 Anders Qvist
 Burton Radons
+Jeff Ramnani
 Brodie Rao
 Antti Rasinen
 Sridhar Ratnakumar
index 94da2775349a222b3ac0a346b0a8d86b5aae75b6..063a6dbf3efb60c83fdc88c6dc2e17ee29999844 100644 (file)
--- a/Misc/NEWS
+++ b/Misc/NEWS
@@ -14,6 +14,9 @@ Core and Builtins
   longer raised due to a read system call returning EINTR from within these
   methods.
 
+- Issue #7719: Make distutils ignore ``.nfs*`` files instead of choking later
+  on.  Initial patch by SilentGhost and Jeff Ramnani.
+
 - Issue #10053: Don't close FDs when FileIO.__init__ fails. Loosely based on
   the work by Hirokazu Yamamoto.