Commit 3cf202e9 authored by Éric Araujo's avatar Éric Araujo

Ignore .nfs* files in distutils (#7719).

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.
parent 96534689
...@@ -973,8 +973,8 @@ directories. ...@@ -973,8 +973,8 @@ directories.
Copy an entire directory tree *src* to a new location *dst*. Both *src* and 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 *dst* must be directory names. If *src* is not a directory, raise
:exc:`DistutilsFileError`. If *dst* does not exist, it is created with :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 :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*. 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 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 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 simply the list of all files under *src*, with the names changed to be under
...@@ -987,6 +987,10 @@ directories. ...@@ -987,6 +987,10 @@ directories.
destination of the symlink will be copied. *update* and *verbose* are the same destination of the symlink will be copied. *update* and *verbose* are the same
as for :func:`copy_file`. 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]) .. function:: remove_tree(directory[, verbose=0, dry_run=0])
......
...@@ -144,6 +144,10 @@ def copy_tree(src, dst, preserve_mode=1, preserve_times=1, ...@@ -144,6 +144,10 @@ def copy_tree(src, dst, preserve_mode=1, preserve_times=1,
src_name = os.path.join(src, n) src_name = os.path.join(src, n)
dst_name = os.path.join(dst, 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): if preserve_symlinks and os.path.islink(src_name):
link_dest = os.readlink(src_name) link_dest = os.readlink(src_name)
if verbose >= 1: if verbose >= 1:
......
...@@ -101,6 +101,24 @@ class DirUtilTestCase(support.TempdirManager, unittest.TestCase): ...@@ -101,6 +101,24 @@ class DirUtilTestCase(support.TempdirManager, unittest.TestCase):
remove_tree(self.root_target, verbose=0) remove_tree(self.root_target, verbose=0)
remove_tree(self.target2, 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): def test_ensure_relative(self):
if os.sep == '/': if os.sep == '/':
self.assertEqual(ensure_relative('/home/foo'), 'home/foo') self.assertEqual(ensure_relative('/home/foo'), 'home/foo')
......
...@@ -91,9 +91,8 @@ class SDistTestCase(PyPIRCCommandTestCase): ...@@ -91,9 +91,8 @@ class SDistTestCase(PyPIRCCommandTestCase):
@unittest.skipUnless(zlib, "requires zlib") @unittest.skipUnless(zlib, "requires zlib")
def test_prune_file_list(self): def test_prune_file_list(self):
# this test creates a package with some vcs dirs in it # this test creates a project with some VCS dirs and an NFS rename
# and launch sdist to make sure they get pruned # file, then launches sdist to check they get pruned on all systems
# on all systems
# creating VCS directories with some files in them # creating VCS directories with some files in them
os.mkdir(join(self.tmp_dir, 'somecode', '.svn')) os.mkdir(join(self.tmp_dir, 'somecode', '.svn'))
...@@ -107,6 +106,8 @@ class SDistTestCase(PyPIRCCommandTestCase): ...@@ -107,6 +106,8 @@ class SDistTestCase(PyPIRCCommandTestCase):
self.write_file((self.tmp_dir, 'somecode', '.git', self.write_file((self.tmp_dir, 'somecode', '.git',
'ok'), 'xxx') 'ok'), 'xxx')
self.write_file((self.tmp_dir, 'somecode', '.nfs0001'), 'xxx')
# now building a sdist # now building a sdist
dist, cmd = self.get_cmd() dist, cmd = self.get_cmd()
......
...@@ -688,6 +688,7 @@ Eduardo Pérez ...@@ -688,6 +688,7 @@ Eduardo Pérez
Brian Quinlan Brian Quinlan
Anders Qvist Anders Qvist
Burton Radons Burton Radons
Jeff Ramnani
Brodie Rao Brodie Rao
Antti Rasinen Antti Rasinen
Sridhar Ratnakumar Sridhar Ratnakumar
......
...@@ -14,6 +14,9 @@ Core and Builtins ...@@ -14,6 +14,9 @@ Core and Builtins
longer raised due to a read system call returning EINTR from within these longer raised due to a read system call returning EINTR from within these
methods. 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 - Issue #10053: Don't close FDs when FileIO.__init__ fails. Loosely based on
the work by Hirokazu Yamamoto. the work by Hirokazu Yamamoto.
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment