Comments
Patch
@@ -303,6 +303,53 @@
finally:
vfs._backgroundfilecloser = None
+class _appendfileproxy(object):
+ """Proxy type to prevent .tell() before .seek() or .write() append files.
+
+ Files opened for append aren't required to have a meaningful fpos
+ after open, so we require a write or explicit seek before allowing
+ .tell() on those files.
+ """
+ def __init__(self, fp):
+ object.__setattr__(self, r'_fp', fp)
+ object.__setattr__(self, r'_tellok', False)
+
+ def tell(self):
+ if not self._tellok:
+ raise error.ProgrammingError(
+ 'tell() on append-mode file requires write() or seek() first')
+ return self._fp.tell()
+
+ def seek(self, *args, **kwargs):
+ object.__setattr__(self, r'_tellok', True)
+ return self._fp.seek(*args, **kwargs)
+
+ def write(self, *args, **kwargs):
+ object.__setattr__(self, r'_tellok', True)
+ return self._fp.write(*args, **kwargs)
+
+ def __repr__(self):
+ return r'<_appendfileproxy of %r>' % self._fp
+
+ # __magic__ methods get looked up on the type, not the instance,
+ # so we have to proxy __enter__ and __exit__ by hand.
+ def __enter__(self):
+ self._fp.__enter__()
+ return self
+
+ def __exit__(self, *args, **kwargs):
+ self._fp.__exit__(*args, **kwargs)
+
+ # proxy all other methods
+ def __getattr__(self, attr):
+ return getattr(self._fp, attr)
+
+ def __setattr__(self, attr, value):
+ return setattr(self._fp, attr, value)
+
+ def __delattr__(self, attr):
+ return delattr(self._fp, attr)
+
class vfs(abstractvfs):
'''Operate files relative to a base directory
@@ -441,7 +488,8 @@
)
fp = delayclosedfile(fp, self._backgroundfilecloser)
-
+ if mode in ('a', 'ab'):
+ return _appendfileproxy(fp)
return fp
def symlink(self, src, dst):