Show More
@@ -27,6 +27,74 b' unlink = win32.unlink' | |||
|
27 | 27 | |
|
28 | 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 | 98 | def posixfile(name, mode='r', buffering=-1): |
|
31 | 99 | '''Open a file with even more POSIX-like semantics''' |
|
32 | 100 | try: |
@@ -37,6 +105,9 b" def posixfile(name, mode='r', buffering=" | |||
|
37 | 105 | if 'a' in mode: |
|
38 | 106 | fp.seek(0, os.SEEK_END) |
|
39 | 107 | |
|
108 | if '+' in mode: | |
|
109 | return mixedfilemodewrapper(fp) | |
|
110 | ||
|
40 | 111 | return fp |
|
41 | 112 | except WindowsError as err: |
|
42 | 113 | # convert to a friendlier exception |
General Comments 0
You need to be logged in to leave comments.
Login now