[Checkins] SVN: zope.file/trunk/src/zope/file/ Add support for '+'.
Change some semantics to match experiential evidence...at
least on one OS (Ubuntu).
Gary Poster
gary at zope.com
Sun Nov 19 11:19:32 EST 2006
Log message for revision 71185:
Add support for '+'. Change some semantics to match experiential evidence...at least on one OS (Ubuntu).
Changed:
U zope.file/trunk/src/zope/file/README.txt
U zope.file/trunk/src/zope/file/file.py
U zope.file/trunk/src/zope/file/interfaces.py
-=-
Modified: zope.file/trunk/src/zope/file/README.txt
===================================================================
--- zope.file/trunk/src/zope/file/README.txt 2006-11-19 16:04:44 UTC (rev 71184)
+++ zope.file/trunk/src/zope/file/README.txt 2006-11-19 16:19:31 UTC (rev 71185)
@@ -196,3 +196,38 @@
>>> r.tell()
Traceback (most recent call last):
ValueError: I/O operation on closed file
+
+The file object also supports the '+' mode--both reading and writing
+simultaneously. This can be convenient for allowing it to be used with
+tools (such as the TIFF PIL plugin as of this writing) with features
+that expect files in this mode.
+
+ >>> rw = f.open('r+')
+ >>> rw.tell()
+ 0L
+ >>> rw.read()
+ 'some text more text still more woohoo!'
+ >>> rw.tell()
+ 38
+ >>> rw.write(' yippee!')
+ >>> rw.seek(31)
+ >>> rw.read()
+ 'woohoo! yippee!'
+ >>> rw.seek(31)
+ >>> rw.write('THE END')
+ >>> rw.seek(0)
+ >>> rw.read()
+ 'some text more text still more THE END yippee!'
+ >>> rw.close()
+ >>> rw = f.open('w+')
+ >>> rw.tell()
+ 0L
+ >>> rw.read()
+ ''
+ >>> rw.write('hi.')
+ >>> rw.tell()
+ 3
+ >>> rw.seek(0)
+ >>> rw.read()
+ 'hi.'
+ >>> rw.close()
Modified: zope.file/trunk/src/zope/file/file.py
===================================================================
--- zope.file/trunk/src/zope/file/file.py 2006-11-19 16:04:44 UTC (rev 71184)
+++ zope.file/trunk/src/zope/file/file.py 2006-11-19 16:19:31 UTC (rev 71185)
@@ -50,6 +50,10 @@
return Reader(self, mode)
if mode in ("w", "wb"):
return Writer(self, mode)
+ if mode in ("r+", "r+b", "rb+"):
+ return ReaderPlus(self, mode)
+ if mode in ("w+", "w+b", "wb+"):
+ return WriterPlus(self, mode)
raise ValueError("unsupported `mode` value")
@@ -84,6 +88,30 @@
raise TypeError("%s.%s instance is not picklable"
% (cls.__module__, cls.__name__))
+ _write = False
+
+ def _get_stream(self):
+ # get the right string io
+ if self._sio is None:
+ self._data = self.__parent__._data
+ # create if we don't have one yet
+ self._sio = cStringIO.StringIO() # cStringIO creates immutable
+ # instance if you pass a string, unlike StringIO :-/
+ if not self._write:
+ self._sio.write(self._data)
+ self._sio.seek(0)
+ elif self._data is not self.__parent__._data:
+ # if the data for the underlying object has changed,
+ # update our view of the data:
+ pos = self._sio.tell()
+ self._data = self.__parent__._data
+ self._sio = cStringIO.StringIO()
+ self._sio.write(self._data)
+ self._sio.seek(pos) # this may seek beyond EOF, but that appears to
+ # be how it is supposed to work, based on experiments. Writing
+ # will insert NULLs in the previous positions.
+ return self._sio
+
def _close(self):
pass
@@ -115,46 +143,33 @@
else:
return self._sio.tell()
- def _get_stream(self):
- # get the right string io
- if self._sio is None:
- # create if we don't have one yet
- self._data = self.__parent__._data
- self._sio = cStringIO.StringIO(self._data)
- elif self._data is not self.__parent__._data:
- # if the data for the underlying object has changed,
- # update our view of the data:
- pos = self._sio.tell()
- self._data = self.__parent__._data
- if pos > len(self._data):
- # need to check if this is really right
- pos = len(self._data)
- self._sio = cStringIO.StringIO(self._data)
- self._sio.seek(pos)
- return self._sio
-
class Writer(Accessor):
zope.interface.implements(
zope.file.interfaces.IFileWriter)
+ _write = True
+
def flush(self):
if self._closed:
raise ValueError("I/O operation on closed file")
if self._sio is not None:
self.__parent__._data = self._sio.getvalue()
self.__parent__.size = len(self.__parent__._data)
+ self._data = self.__parent__._data
def write(self, data):
if self._closed:
raise ValueError("I/O operation on closed file")
self._get_stream().write(data)
- def _get_stream(self):
- if self._sio is None:
- self._sio = cStringIO.StringIO()
- return self._sio
-
def _close(self):
self.flush()
+
+class WriterPlus(Writer, Reader):
+ pass
+
+class ReaderPlus(Writer, Reader):
+
+ _write = False
Modified: zope.file/trunk/src/zope/file/interfaces.py
===================================================================
--- zope.file/trunk/src/zope/file/interfaces.py 2006-11-19 16:04:44 UTC (rev 71184)
+++ zope.file/trunk/src/zope/file/interfaces.py 2006-11-19 16:19:31 UTC (rev 71185)
@@ -30,11 +30,13 @@
def open(mode="r"):
"""Return an object providing access to the file data.
- Allowed values for `mode` are 'r' and 'rb' (read) and 'w' and
- 'wb' (write). Other values cause `ValueError` to be raised.
+ Allowed values for `mode` are 'r' and 'rb' (read); 'w' and
+ 'wb' (write); and 'w+', 'w+b', 'wb+', 'r+', 'r+b', and 'rb+' (both).
+ Other values cause `ValueError` to be raised.
If the file is opened in read mode, an `IFileReader` is
returned; if opened in write mode, an `IFileWriter` is
+ returned; if in read/write, an object that implements both is
returned.
All readers and writers operate in 'binary' mode.
More information about the Checkins
mailing list