* pygnulib/constants.py (movefile): New function.
* pygnulib/*.py: Use it instead of shutil.
2022-08-03 Bruno Haible <bruno@clisp.org>
+ gnulib-tool.py: Avoid errors when writing to a VFAT file system, part 2.
+ * pygnulib/constants.py (movefile): New function.
+ * pygnulib/*.py: Use it instead of shutil.
+
gnulib-tool.py: Avoid errors when writing to a VFAT file system.
* pygnulib/constants.py (copyfile, copyfile2): New functions.
* gnulib-tool.py: Use them instead of shutil.
DIRS = constants.DIRS
joinpath = constants.joinpath
copyfile = constants.copyfile
+movefile = constants.movefile
isdir = os.path.isdir
isfile = os.path.isfile
lookedup, joinpath(destdir, rewritten))
else: # if any of these conditions is not met
try: # Try to move file
- shutil.move(tmpfile, joinpath(destdir, rewritten))
+ movefile(tmpfile, joinpath(destdir, rewritten))
except Exception as error:
raise GLError(17, original)
else: # if self.config['dryrun']
if isfile(backuppath):
os.remove(backuppath)
try: # Try to replace the given file
- shutil.move(basepath, backuppath)
+ movefile(basepath, backuppath)
except Exception as error:
raise GLError(17, original)
if self.filesystem.shouldLink(original, lookedup) == CopyAction.Symlink \
if not self.config['dryrun']:
if isfile(backuppath):
os.remove(backuppath)
- shutil.move(basepath, backuppath)
- shutil.move(tmpfile, basepath)
+ movefile(basepath, backuppath)
+ movefile(tmpfile, basepath)
else: # if self.config['dryrun']
os.remove(tmpfile)
else: # if not isfile(basepath)
if not self.config['dryrun']:
if isfile(basepath):
os.remove(basepath)
- shutil.move(tmpfile, basepath)
+ movefile(tmpfile, basepath)
else: # if self.config['dryrun']
os.remove(tmpfile)
result = tuple([basename, backupname, result_flag])
joinpath = constants.joinpath
cleaner = constants.cleaner
copyfile2 = constants.copyfile2
+movefile = constants.movefile
isabs = os.path.isabs
isdir = os.path.isdir
isfile = os.path.isfile
try: # Try to move file
if os.path.exists(backup):
os.remove(backup)
- shutil.move(path, '%s~' % path)
+ movefile(path, '%s~' % path)
except Exception as error:
raise GLError(14, file)
else: # if self.config['dryrun']
tmpfile = self.assistant.tmpfilename(joinpath(pobase, file))
path = joinpath('build-aux', 'po', file)
lookedup, flag = filesystem.lookup(path)
- shutil.move(lookedup, tmpfile)
+ movefile(lookedup, tmpfile)
basename = joinpath(pobase, file)
filename, backup, flag = self.assistant.super_update(
basename, tmpfile)
compiler = constants.compiler
joinpath = constants.joinpath
copyfile = constants.copyfile
+movefile = constants.movefile
isdir = os.path.isdir
isfile = os.path.isfile
normpath = os.path.normpath
dest = src[:-1]
if isfile(dest):
os.remove(dest)
- shutil.move(src, dest)
+ movefile(src, dest)
# libtoolize
if libtool:
args = [UTILS['libtoolize'], '--copy']
dest = src[:-1]
if isfile(dest):
os.remove(dest)
- shutil.move(src, dest)
+ movefile(src, dest)
# aclocal
args = [UTILS['aclocal'], '-I', joinpath('..', m4base)]
constants.execute(args, verbose)
pass
+def movefile(src, dest):
+ '''Move/rename file src to file dest. Like shutil.move, but gracefully
+ handle common errors.'''
+ try:
+ shutil.move(src, dest)
+ except PermissionError:
+ # shutil.move invokes os.rename, catches the resulting OSError for
+ # errno=EXDEV, attempts a copy instead, and encounters a PermissionError
+ # while doing that.
+ copyfile2(src, dest)
+ os.remove(src)
+
+
def link_relative(src, dest):
'''Like ln -s, except that src is given relative to the current directory
(or absolute), not given relative to the directory of dest.'''