Rietveld Code Review Tool
Help | Bug tracker | Discussion group | Source code | Sign in
(5)

Side by Side Diff: Lib/test/test_extcall.py

Issue 4806: Function calls taking a generator as star argument can mask TypeErrors in the generator
Patch Set: Created 5 years, 3 months ago
Left:
Right:
Use n/p to move between diff chunks; N/P to move between comments. Please Sign in to add in-line comments.
Jump to:
View unified diff | Download patch
« no previous file with comments | « no previous file | Python/ceval.c » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 1
2 """Doctest for method/function calls. 2 """Doctest for method/function calls.
3 3
4 We're going the use these types for extra testing 4 We're going the use these types for extra testing
5 5
6 >>> from collections import UserList 6 >>> from collections import UserList
7 >>> from collections import UserDict 7 >>> from collections import UserDict
8 8
9 We're defining four helper functions 9 We're defining four helper functions
10 10
(...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after
85 >>> g(1, 2, 3) 85 >>> g(1, 2, 3)
86 1 (2, 3) {} 86 1 (2, 3) {}
87 >>> g(1, 2, 3, *(4, 5)) 87 >>> g(1, 2, 3, *(4, 5))
88 1 (2, 3, 4, 5) {} 88 1 (2, 3, 4, 5) {}
89 89
90 >>> class Nothing: pass 90 >>> class Nothing: pass
91 ... 91 ...
92 >>> g(*Nothing()) 92 >>> g(*Nothing())
93 Traceback (most recent call last): 93 Traceback (most recent call last):
94 ... 94 ...
95 TypeError: g() argument after * must be a sequence, not Nothing 95 TypeError: g() argument after * must be an iterable, not Nothing
96 96
97 >>> class Nothing: 97 >>> class Nothing:
98 ... def __len__(self): return 5 98 ... def __len__(self): return 5
99 ... 99 ...
100 100
101 >>> g(*Nothing()) 101 >>> g(*Nothing())
102 Traceback (most recent call last): 102 Traceback (most recent call last):
103 ... 103 ...
104 TypeError: g() argument after * must be a sequence, not Nothing 104 TypeError: g() argument after * must be an iterable, not Nothing
105 105
106 >>> class Nothing(): 106 >>> class Nothing():
107 ... def __len__(self): return 5 107 ... def __len__(self): return 5
108 ... def __getitem__(self, i): 108 ... def __getitem__(self, i):
109 ... if i<3: return i 109 ... if i<3: return i
110 ... else: raise IndexError(i) 110 ... else: raise IndexError(i)
111 ... 111 ...
112 112
113 >>> g(*Nothing()) 113 >>> g(*Nothing())
114 0 (1, 2) {} 114 0 (1, 2) {}
115 115
116 >>> class Nothing: 116 >>> class Nothing:
117 ... def __init__(self): self.c = 0 117 ... def __init__(self): self.c = 0
118 ... def __iter__(self): return self 118 ... def __iter__(self): return self
119 ... def __next__(self): 119 ... def __next__(self):
120 ... if self.c == 4: 120 ... if self.c == 4:
121 ... raise StopIteration 121 ... raise StopIteration
122 ... c = self.c 122 ... c = self.c
123 ... self.c += 1 123 ... self.c += 1
124 ... return c 124 ... return c
125 ... 125 ...
126 126
127 >>> g(*Nothing()) 127 >>> g(*Nothing())
128 0 (1, 2, 3) {} 128 0 (1, 2, 3) {}
129
130 Check for issue #4806: Does a TypeError in a generator get propagated with the
131 right error message? (Also check with other iterables.)
132
133 >>> def broken(): raise TypeError("myerror")
134 ...
135
136 >>> g(*(broken() for i in range(1)))
137 Traceback (most recent call last):
138 ...
139 TypeError: myerror
140
141 >>> class BrokenIterable1:
142 ... def __iter__(self):
143 ... raise TypeError('myerror')
144 ...
145 >>> g(*BrokenIterable1())
146 Traceback (most recent call last):
147 ...
148 TypeError: myerror
149
150 >>> class BrokenIterable2:
151 ... def __iter__(self):
152 ... yield 0
153 ... raise TypeError('myerror')
154 ...
155 >>> g(*BrokenIterable2())
156 Traceback (most recent call last):
157 ...
158 TypeError: myerror
159
160 >>> class BrokenSequence:
161 ... def __getitem__(self, idx):
162 ... raise TypeError('myerror')
163 ...
164 >>> f(*BrokenSequence())
165 Traceback (most recent call last):
166 ...
167 TypeError: myerror
129 168
130 Make sure that the function doesn't stomp the dictionary 169 Make sure that the function doesn't stomp the dictionary
131 170
132 >>> d = {'a': 1, 'b': 2, 'c': 3} 171 >>> d = {'a': 1, 'b': 2, 'c': 3}
133 >>> d2 = d.copy() 172 >>> d2 = d.copy()
134 >>> g(1, d=4, **d) 173 >>> g(1, d=4, **d)
135 1 () {'a': 1, 'b': 2, 'c': 3, 'd': 4} 174 1 () {'a': 1, 'b': 2, 'c': 3, 'd': 4}
136 >>> d == d2 175 >>> d == d2
137 True 176 True
138 177
(...skipping 20 matching lines...) Expand all
159 TypeError: f() keywords must be strings 198 TypeError: f() keywords must be strings
160 199
161 >>> h(**{'e': 2}) 200 >>> h(**{'e': 2})
162 Traceback (most recent call last): 201 Traceback (most recent call last):
163 ... 202 ...
164 TypeError: h() got an unexpected keyword argument 'e' 203 TypeError: h() got an unexpected keyword argument 'e'
165 204
166 >>> h(*h) 205 >>> h(*h)
167 Traceback (most recent call last): 206 Traceback (most recent call last):
168 ... 207 ...
169 TypeError: h() argument after * must be a sequence, not function 208 TypeError: h() argument after * must be an iterable, not function
170 209
171 >>> dir(*h) 210 >>> dir(*h)
172 Traceback (most recent call last): 211 Traceback (most recent call last):
173 ... 212 ...
174 TypeError: dir() argument after * must be a sequence, not function 213 TypeError: dir() argument after * must be an iterable, not function
175 214
176 >>> None(*h) 215 >>> None(*h)
177 Traceback (most recent call last): 216 Traceback (most recent call last):
178 ... 217 ...
179 TypeError: NoneType object argument after * must be a sequence, \ 218 TypeError: NoneType object argument after * must be an iterable, \
180 not function 219 not function
181 220
182 >>> h(**h) 221 >>> h(**h)
183 Traceback (most recent call last): 222 Traceback (most recent call last):
184 ... 223 ...
185 TypeError: h() argument after ** must be a mapping, not function 224 TypeError: h() argument after ** must be a mapping, not function
186 225
187 >>> dir(**h) 226 >>> dir(**h)
188 Traceback (most recent call last): 227 Traceback (most recent call last):
189 ... 228 ...
(...skipping 150 matching lines...) Expand 10 before | Expand all | Expand 10 after
340 """ 379 """
341 380
342 import sys 381 import sys
343 from test import support 382 from test import support
344 383
345 def test_main(): 384 def test_main():
346 support.run_doctest(sys.modules[__name__], True) 385 support.run_doctest(sys.modules[__name__], True)
347 386
348 if __name__ == '__main__': 387 if __name__ == '__main__':
349 test_main() 388 test_main()
OLDNEW
« no previous file with comments | « no previous file | Python/ceval.c » ('j') | no next file with comments »

RSS Feeds Recent Issues | This issue
This is Rietveld 894c83f36cb7+