##// END OF EJS Templates
windows: insert file positioning call between reads and writes...
Gregory Szorc -
r26375:3686fa2b default
parent child Browse files
Show More
@@ -27,6 +27,74 b' unlink = win32.unlink'
27
27
28 umask = 0o022
28 umask = 0o022
29
29
30 class mixedfilemodewrapper(object):
31 """Wraps a file handle when it is opened in read/write mode.
32
33 fopen() and fdopen() on Windows have a specific-to-Windows requirement
34 that files opened with mode r+, w+, or a+ make a call to a file positioning
35 function when switching between reads and writes. Without this extra call,
36 Python will raise a not very intuitive "IOError: [Errno 0] Error."
37
38 This class wraps posixfile instances when the file is opened in read/write
39 mode and automatically adds checks or inserts appropriate file positioning
40 calls when necessary.
41 """
42 OPNONE = 0
43 OPREAD = 1
44 OPWRITE = 2
45
46 def __init__(self, fp):
47 object.__setattr__(self, '_fp', fp)
48 object.__setattr__(self, '_lastop', 0)
49
50 def __getattr__(self, name):
51 return getattr(self._fp, name)
52
53 def __setattr__(self, name, value):
54 return self._fp.__setattr__(name, value)
55
56 def _noopseek(self):
57 self._fp.seek(0, os.SEEK_CUR)
58
59 def seek(self, *args, **kwargs):
60 object.__setattr__(self, '_lastop', self.OPNONE)
61 return self._fp.seek(*args, **kwargs)
62
63 def write(self, d):
64 if self._lastop == self.OPREAD:
65 self._noopseek()
66
67 object.__setattr__(self, '_lastop', self.OPWRITE)
68 return self._fp.write(d)
69
70 def writelines(self, *args, **kwargs):
71 if self._lastop == self.OPREAD:
72 self._noopeseek()
73
74 object.__setattr__(self, '_lastop', self.OPWRITE)
75 return self._fp.writelines(*args, **kwargs)
76
77 def read(self, *args, **kwargs):
78 if self._lastop == self.OPWRITE:
79 self._noopseek()
80
81 object.__setattr__(self, '_lastop', self.OPREAD)
82 return self._fp.read(*args, **kwargs)
83
84 def readline(self, *args, **kwargs):
85 if self._lastop == self.OPWRITE:
86 self._noopseek()
87
88 object.__setattr__(self, '_lastop', self.OPREAD)
89 return self._fp.readline(*args, **kwargs)
90
91 def readlines(self, *args, **kwargs):
92 if self._lastop == self.OPWRITE:
93 self._noopseek()
94
95 object.__setattr__(self, '_lastop', self.OPREAD)
96 return self._fp.readlines(*args, **kwargs)
97
30 def posixfile(name, mode='r', buffering=-1):
98 def posixfile(name, mode='r', buffering=-1):
31 '''Open a file with even more POSIX-like semantics'''
99 '''Open a file with even more POSIX-like semantics'''
32 try:
100 try:
@@ -37,6 +105,9 b" def posixfile(name, mode='r', buffering="
37 if 'a' in mode:
105 if 'a' in mode:
38 fp.seek(0, os.SEEK_END)
106 fp.seek(0, os.SEEK_END)
39
107
108 if '+' in mode:
109 return mixedfilemodewrapper(fp)
110
40 return fp
111 return fp
41 except WindowsError as err:
112 except WindowsError as err:
42 # convert to a friendlier exception
113 # convert to a friendlier exception
General Comments 0
You need to be logged in to leave comments. Login now