Commit 6e797216 authored by Michael Hanselmann's avatar Michael Hanselmann
Browse files

Add rename function automatically creating directories if needed

Unfortunately, os.makedirs in Python 2.4 is not safe against multiple
processes creating the same directory tree at the same time. This is
only fixed in Python 2.5 and up. Adding more checks in our code doesn't
make it any better.

Reviewed-by: iustinp
parent aea0ed67
......@@ -285,6 +285,32 @@ def RemoveFile(filename):
raise
def RenameFile(old, new, mkdir=False, mkdir_mode=0750):
"""Renames a file.
@type old: string
@param old: Original path
@type new: string
@param new: New path
@type mkdir: bool
@param mkdir: Whether to create target directory if it doesn't exist
@type mkdir_mode: int
@param mkdir_mode: Mode for newly created directories
"""
try:
return os.rename(old, new)
except OSError, err:
# In at least one use case of this function, the job queue, directory
# creation is very rare. Checking for the directory before renaming is not
# as efficient.
if mkdir and err.errno == errno.ENOENT:
# Create directory and try again
os.makedirs(os.path.dirname(new), mkdir_mode)
return os.rename(old, new)
raise
def _FingerprintFile(filename):
"""Compute the fingerprint of a file.
......
......@@ -277,6 +277,36 @@ class TestRemoveFile(unittest.TestCase):
self.fail("File '%s' not removed" % symlink)
class TestRename(unittest.TestCase):
"""Test case for RenameFile"""
def setUp(self):
"""Create a temporary directory"""
self.tmpdir = tempfile.mkdtemp()
self.tmpfile = os.path.join(self.tmpdir, "test1")
# Touch the file
open(self.tmpfile, "w").close()
def tearDown(self):
"""Remove temporary directory"""
shutil.rmtree(self.tmpdir)
def testSimpleRename1(self):
"""Simple rename 1"""
utils.RenameFile(self.tmpfile, os.path.join(self.tmpdir, "xyz"))
def testSimpleRename2(self):
"""Simple rename 2"""
utils.RenameFile(self.tmpfile, os.path.join(self.tmpdir, "xyz"),
mkdir=True)
def testRenameMkdir(self):
"""Rename with mkdir"""
utils.RenameFile(self.tmpfile, os.path.join(self.tmpdir, "test/xyz"),
mkdir=True)
class TestCheckdict(unittest.TestCase):
"""Test case for the CheckDict function"""
......
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