Commit | Line | Data |
---|---|---|
920dae64 AT |
1 | import sys |
2 | import os | |
3 | from array import array | |
4 | from weakref import proxy | |
5 | ||
6 | from test.test_support import verify, TESTFN, TestFailed | |
7 | from UserList import UserList | |
8 | ||
9 | # verify weak references | |
10 | f = file(TESTFN, 'w') | |
11 | p = proxy(f) | |
12 | p.write('teststring') | |
13 | verify(f.tell(), p.tell()) | |
14 | f.close() | |
15 | f = None | |
16 | try: | |
17 | p.tell() | |
18 | except ReferenceError: | |
19 | pass | |
20 | else: | |
21 | raise TestFailed('file proxy still exists when the file is gone') | |
22 | ||
23 | # verify expected attributes exist | |
24 | f = file(TESTFN, 'w') | |
25 | softspace = f.softspace | |
26 | f.name # merely shouldn't blow up | |
27 | f.mode # ditto | |
28 | f.closed # ditto | |
29 | ||
30 | # verify softspace is writable | |
31 | f.softspace = softspace # merely shouldn't blow up | |
32 | ||
33 | # verify the others aren't | |
34 | for attr in 'name', 'mode', 'closed': | |
35 | try: | |
36 | setattr(f, attr, 'oops') | |
37 | except TypeError: | |
38 | pass | |
39 | else: | |
40 | raise TestFailed('expected TypeError setting file attr %r' % attr) | |
41 | f.close() | |
42 | ||
43 | # verify writelines with instance sequence | |
44 | l = UserList(['1', '2']) | |
45 | f = open(TESTFN, 'wb') | |
46 | f.writelines(l) | |
47 | f.close() | |
48 | f = open(TESTFN, 'rb') | |
49 | buf = f.read() | |
50 | f.close() | |
51 | verify(buf == '12') | |
52 | ||
53 | # verify readinto | |
54 | a = array('c', 'x'*10) | |
55 | f = open(TESTFN, 'rb') | |
56 | n = f.readinto(a) | |
57 | f.close() | |
58 | verify(buf == a.tostring()[:n]) | |
59 | ||
60 | # verify writelines with integers | |
61 | f = open(TESTFN, 'wb') | |
62 | try: | |
63 | f.writelines([1, 2, 3]) | |
64 | except TypeError: | |
65 | pass | |
66 | else: | |
67 | print "writelines accepted sequence of integers" | |
68 | f.close() | |
69 | ||
70 | # verify writelines with integers in UserList | |
71 | f = open(TESTFN, 'wb') | |
72 | l = UserList([1,2,3]) | |
73 | try: | |
74 | f.writelines(l) | |
75 | except TypeError: | |
76 | pass | |
77 | else: | |
78 | print "writelines accepted sequence of integers" | |
79 | f.close() | |
80 | ||
81 | # verify writelines with non-string object | |
82 | class NonString: pass | |
83 | ||
84 | f = open(TESTFN, 'wb') | |
85 | try: | |
86 | f.writelines([NonString(), NonString()]) | |
87 | except TypeError: | |
88 | pass | |
89 | else: | |
90 | print "writelines accepted sequence of non-string objects" | |
91 | f.close() | |
92 | ||
93 | # verify that we get a sensible error message for bad mode argument | |
94 | bad_mode = "qwerty" | |
95 | try: | |
96 | open(TESTFN, bad_mode) | |
97 | except IOError, msg: | |
98 | if msg[0] != 0: | |
99 | s = str(msg) | |
100 | if s.find(TESTFN) != -1 or s.find(bad_mode) == -1: | |
101 | print "bad error message for invalid mode: %s" % s | |
102 | # if msg[0] == 0, we're probably on Windows where there may be | |
103 | # no obvious way to discover why open() failed. | |
104 | else: | |
105 | print "no error for invalid mode: %s" % bad_mode | |
106 | ||
107 | f = open(TESTFN) | |
108 | if f.name != TESTFN: | |
109 | raise TestFailed, 'file.name should be "%s"' % TESTFN | |
110 | if f.isatty(): | |
111 | raise TestFailed, 'file.isatty() should be false' | |
112 | ||
113 | if f.closed: | |
114 | raise TestFailed, 'file.closed should be false' | |
115 | ||
116 | try: | |
117 | f.readinto("") | |
118 | except TypeError: | |
119 | pass | |
120 | else: | |
121 | raise TestFailed, 'file.readinto("") should raise a TypeError' | |
122 | ||
123 | f.close() | |
124 | if not f.closed: | |
125 | raise TestFailed, 'file.closed should be true' | |
126 | ||
127 | # make sure that explicitly setting the buffer size doesn't cause | |
128 | # misbehaviour especially with repeated close() calls | |
129 | for s in (-1, 0, 1, 512): | |
130 | try: | |
131 | f = open(TESTFN, 'w', s) | |
132 | f.write(str(s)) | |
133 | f.close() | |
134 | f.close() | |
135 | f = open(TESTFN, 'r', s) | |
136 | d = int(f.read()) | |
137 | f.close() | |
138 | f.close() | |
139 | except IOError, msg: | |
140 | raise TestFailed, 'error setting buffer size %d: %s' % (s, str(msg)) | |
141 | if d != s: | |
142 | raise TestFailed, 'readback failure using buffer size %d' | |
143 | ||
144 | methods = ['fileno', 'flush', 'isatty', 'next', 'read', 'readinto', | |
145 | 'readline', 'readlines', 'seek', 'tell', 'truncate', 'write', | |
146 | 'xreadlines', '__iter__'] | |
147 | if sys.platform.startswith('atheos'): | |
148 | methods.remove('truncate') | |
149 | ||
150 | for methodname in methods: | |
151 | method = getattr(f, methodname) | |
152 | try: | |
153 | method() | |
154 | except ValueError: | |
155 | pass | |
156 | else: | |
157 | raise TestFailed, 'file.%s() on a closed file should raise a ValueError' % methodname | |
158 | ||
159 | try: | |
160 | f.writelines([]) | |
161 | except ValueError: | |
162 | pass | |
163 | else: | |
164 | raise TestFailed, 'file.writelines([]) on a closed file should raise a ValueError' | |
165 | ||
166 | os.unlink(TESTFN) | |
167 | ||
168 | def bug801631(): | |
169 | # SF bug <http://www.python.org/sf/801631> | |
170 | # "file.truncate fault on windows" | |
171 | f = file(TESTFN, 'wb') | |
172 | f.write('12345678901') # 11 bytes | |
173 | f.close() | |
174 | ||
175 | f = file(TESTFN,'rb+') | |
176 | data = f.read(5) | |
177 | if data != '12345': | |
178 | raise TestFailed("Read on file opened for update failed %r" % data) | |
179 | if f.tell() != 5: | |
180 | raise TestFailed("File pos after read wrong %d" % f.tell()) | |
181 | ||
182 | f.truncate() | |
183 | if f.tell() != 5: | |
184 | raise TestFailed("File pos after ftruncate wrong %d" % f.tell()) | |
185 | ||
186 | f.close() | |
187 | size = os.path.getsize(TESTFN) | |
188 | if size != 5: | |
189 | raise TestFailed("File size after ftruncate wrong %d" % size) | |
190 | ||
191 | try: | |
192 | bug801631() | |
193 | finally: | |
194 | os.unlink(TESTFN) |