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