All writes to a file foo will be written into foo.lock in the same
directory, and the lockfile will be renamed to overwrite the original file
- on close. The lockfile is automatically removed upon filesystem error.
+ on close.
:note: You *must* call close() or abort() on a _GitFile for the lock to be
released. Typically this will happen in a finally block.
self._file = os.fdopen(fd, mode, bufsize)
for method in self.PROXY_METHODS:
- setattr(self, method,
- self._safe_method(getattr(self._file, method)))
-
- def _safe_method(self, file_method):
- # note that built-in file methods have no kwargs
- def do_safe_method(*args):
- try:
- return file_method(*args)
- except (OSError, IOError):
- self.abort()
- raise
- return do_safe_method
+ setattr(self, method, getattr(self._file, method))
def abort(self):
"""Close and discard the lockfile without overwriting the target.
new_orig_f = open(foo, 'rb')
self.assertEquals(new_orig_f.read(), 'foo contents')
new_orig_f.close()
-
- def test_safe_method(self):
- foo = self.path('foo')
- foo_lock = '%s.lock' % foo
-
- f = GitFile(foo, 'wb')
- f.write('new contents')
-
- def error_method(x):
- f._test = x
- raise IOError('fake IO error')
-
- try:
- f._safe_method(error_method)('test value')
- fail()
- except IOError, e:
- # error is re-raised
- self.assertEquals('fake IO error', e.message)
-
- # method got correct args
- self.assertEquals('test value', f._test)
- self.assertFalse(os.path.exists(foo_lock))
-
- new_orig_f = open(foo, 'rb')
- self.assertEquals(new_orig_f.read(), 'foo contents')
- new_orig_f.close()