]>
Commit | Line | Data |
---|---|---|
53e6db90 DC |
1 | """ |
2 | Provide the class Message and its subclasses. | |
3 | """ | |
4 | ||
5 | ||
6 | class Message: | |
7 | message = '' | |
8 | message_args = () | |
9 | ||
10 | def __init__(self, filename, loc): | |
11 | self.filename = filename | |
12 | self.lineno = loc.lineno | |
13 | self.col = loc.col_offset | |
14 | ||
15 | def __str__(self): | |
16 | return '{}:{}:{}: {}'.format(self.filename, self.lineno, self.col+1, | |
17 | self.message % self.message_args) | |
18 | ||
19 | ||
20 | class UnusedImport(Message): | |
21 | message = '%r imported but unused' | |
22 | ||
23 | def __init__(self, filename, loc, name): | |
24 | Message.__init__(self, filename, loc) | |
25 | self.message_args = (name,) | |
26 | ||
27 | ||
28 | class RedefinedWhileUnused(Message): | |
29 | message = 'redefinition of unused %r from line %r' | |
30 | ||
31 | def __init__(self, filename, loc, name, orig_loc): | |
32 | Message.__init__(self, filename, loc) | |
33 | self.message_args = (name, orig_loc.lineno) | |
34 | ||
35 | ||
36 | class ImportShadowedByLoopVar(Message): | |
37 | message = 'import %r from line %r shadowed by loop variable' | |
38 | ||
39 | def __init__(self, filename, loc, name, orig_loc): | |
40 | Message.__init__(self, filename, loc) | |
41 | self.message_args = (name, orig_loc.lineno) | |
42 | ||
43 | ||
44 | class ImportStarNotPermitted(Message): | |
45 | message = "'from %s import *' only allowed at module level" | |
46 | ||
47 | def __init__(self, filename, loc, modname): | |
48 | Message.__init__(self, filename, loc) | |
49 | self.message_args = (modname,) | |
50 | ||
51 | ||
52 | class ImportStarUsed(Message): | |
53 | message = "'from %s import *' used; unable to detect undefined names" | |
54 | ||
55 | def __init__(self, filename, loc, modname): | |
56 | Message.__init__(self, filename, loc) | |
57 | self.message_args = (modname,) | |
58 | ||
59 | ||
60 | class ImportStarUsage(Message): | |
61 | message = "%r may be undefined, or defined from star imports: %s" | |
62 | ||
63 | def __init__(self, filename, loc, name, from_list): | |
64 | Message.__init__(self, filename, loc) | |
65 | self.message_args = (name, from_list) | |
66 | ||
67 | ||
68 | class UndefinedName(Message): | |
69 | message = 'undefined name %r' | |
70 | ||
71 | def __init__(self, filename, loc, name): | |
72 | Message.__init__(self, filename, loc) | |
73 | self.message_args = (name,) | |
74 | ||
75 | ||
76 | class DoctestSyntaxError(Message): | |
77 | message = 'syntax error in doctest' | |
78 | ||
79 | def __init__(self, filename, loc, position=None): | |
80 | Message.__init__(self, filename, loc) | |
81 | if position: | |
82 | (self.lineno, self.col) = position | |
83 | self.message_args = () | |
84 | ||
85 | ||
86 | class UndefinedExport(Message): | |
87 | message = 'undefined name %r in __all__' | |
88 | ||
89 | def __init__(self, filename, loc, name): | |
90 | Message.__init__(self, filename, loc) | |
91 | self.message_args = (name,) | |
92 | ||
93 | ||
94 | class UndefinedLocal(Message): | |
95 | message = 'local variable %r {0} referenced before assignment' | |
96 | ||
97 | default = 'defined in enclosing scope on line %r' | |
98 | builtin = 'defined as a builtin' | |
99 | ||
100 | def __init__(self, filename, loc, name, orig_loc): | |
101 | Message.__init__(self, filename, loc) | |
102 | if orig_loc is None: | |
103 | self.message = self.message.format(self.builtin) | |
104 | self.message_args = name | |
105 | else: | |
106 | self.message = self.message.format(self.default) | |
107 | self.message_args = (name, orig_loc.lineno) | |
108 | ||
109 | ||
110 | class DuplicateArgument(Message): | |
111 | message = 'duplicate argument %r in function definition' | |
112 | ||
113 | def __init__(self, filename, loc, name): | |
114 | Message.__init__(self, filename, loc) | |
115 | self.message_args = (name,) | |
116 | ||
117 | ||
118 | class MultiValueRepeatedKeyLiteral(Message): | |
119 | message = 'dictionary key %r repeated with different values' | |
120 | ||
121 | def __init__(self, filename, loc, key): | |
122 | Message.__init__(self, filename, loc) | |
123 | self.message_args = (key,) | |
124 | ||
125 | ||
126 | class MultiValueRepeatedKeyVariable(Message): | |
127 | message = 'dictionary key variable %s repeated with different values' | |
128 | ||
129 | def __init__(self, filename, loc, key): | |
130 | Message.__init__(self, filename, loc) | |
131 | self.message_args = (key,) | |
132 | ||
133 | ||
134 | class LateFutureImport(Message): | |
135 | message = 'from __future__ imports must occur at the beginning of the file' | |
136 | ||
137 | ||
138 | class FutureFeatureNotDefined(Message): | |
139 | """An undefined __future__ feature name was imported.""" | |
140 | message = 'future feature %s is not defined' | |
141 | ||
142 | def __init__(self, filename, loc, name): | |
143 | Message.__init__(self, filename, loc) | |
144 | self.message_args = (name,) | |
145 | ||
146 | ||
147 | class UnusedVariable(Message): | |
148 | """ | |
149 | Indicates that a variable has been explicitly assigned to but not actually | |
150 | used. | |
151 | """ | |
152 | message = 'local variable %r is assigned to but never used' | |
153 | ||
154 | def __init__(self, filename, loc, names): | |
155 | Message.__init__(self, filename, loc) | |
156 | self.message_args = (names,) | |
157 | ||
158 | ||
159 | class UnusedAnnotation(Message): | |
160 | """ | |
161 | Indicates that a variable has been explicitly annotated to but not actually | |
162 | used. | |
163 | """ | |
164 | message = 'local variable %r is annotated but never used' | |
165 | ||
166 | def __init__(self, filename, loc, names): | |
167 | Message.__init__(self, filename, loc) | |
168 | self.message_args = (names,) | |
169 | ||
170 | ||
171 | class ReturnOutsideFunction(Message): | |
172 | """ | |
173 | Indicates a return statement outside of a function/method. | |
174 | """ | |
175 | message = '\'return\' outside function' | |
176 | ||
177 | ||
178 | class YieldOutsideFunction(Message): | |
179 | """ | |
180 | Indicates a yield or yield from statement outside of a function/method. | |
181 | """ | |
182 | message = '\'yield\' outside function' | |
183 | ||
184 | ||
185 | # For whatever reason, Python gives different error messages for these two. We | |
186 | # match the Python error message exactly. | |
187 | class ContinueOutsideLoop(Message): | |
188 | """ | |
189 | Indicates a continue statement outside of a while or for loop. | |
190 | """ | |
191 | message = '\'continue\' not properly in loop' | |
192 | ||
193 | ||
194 | class BreakOutsideLoop(Message): | |
195 | """ | |
196 | Indicates a break statement outside of a while or for loop. | |
197 | """ | |
198 | message = '\'break\' outside loop' | |
199 | ||
200 | ||
201 | class DefaultExceptNotLast(Message): | |
202 | """ | |
203 | Indicates an except: block as not the last exception handler. | |
204 | """ | |
205 | message = 'default \'except:\' must be last' | |
206 | ||
207 | ||
208 | class TwoStarredExpressions(Message): | |
209 | """ | |
210 | Two or more starred expressions in an assignment (a, *b, *c = d). | |
211 | """ | |
212 | message = 'two starred expressions in assignment' | |
213 | ||
214 | ||
215 | class TooManyExpressionsInStarredAssignment(Message): | |
216 | """ | |
217 | Too many expressions in an assignment with star-unpacking | |
218 | """ | |
219 | message = 'too many expressions in star-unpacking assignment' | |
220 | ||
221 | ||
222 | class IfTuple(Message): | |
223 | """ | |
224 | Conditional test is a non-empty tuple literal, which are always True. | |
225 | """ | |
226 | message = '\'if tuple literal\' is always true, perhaps remove accidental comma?' | |
227 | ||
228 | ||
229 | class AssertTuple(Message): | |
230 | """ | |
231 | Assertion test is a non-empty tuple literal, which are always True. | |
232 | """ | |
233 | message = 'assertion is always true, perhaps remove parentheses?' | |
234 | ||
235 | ||
236 | class ForwardAnnotationSyntaxError(Message): | |
237 | message = 'syntax error in forward annotation %r' | |
238 | ||
239 | def __init__(self, filename, loc, annotation): | |
240 | Message.__init__(self, filename, loc) | |
241 | self.message_args = (annotation,) | |
242 | ||
243 | ||
244 | class RaiseNotImplemented(Message): | |
245 | message = "'raise NotImplemented' should be 'raise NotImplementedError'" | |
246 | ||
247 | ||
248 | class InvalidPrintSyntax(Message): | |
249 | message = 'use of >> is invalid with print function' | |
250 | ||
251 | ||
252 | class IsLiteral(Message): | |
253 | message = 'use ==/!= to compare constant literals (str, bytes, int, float, tuple)' | |
254 | ||
255 | ||
256 | class FStringMissingPlaceholders(Message): | |
257 | message = 'f-string is missing placeholders' | |
258 | ||
259 | ||
260 | class StringDotFormatExtraPositionalArguments(Message): | |
261 | message = "'...'.format(...) has unused arguments at position(s): %s" | |
262 | ||
263 | def __init__(self, filename, loc, extra_positions): | |
264 | Message.__init__(self, filename, loc) | |
265 | self.message_args = (extra_positions,) | |
266 | ||
267 | ||
268 | class StringDotFormatExtraNamedArguments(Message): | |
269 | message = "'...'.format(...) has unused named argument(s): %s" | |
270 | ||
271 | def __init__(self, filename, loc, extra_keywords): | |
272 | Message.__init__(self, filename, loc) | |
273 | self.message_args = (extra_keywords,) | |
274 | ||
275 | ||
276 | class StringDotFormatMissingArgument(Message): | |
277 | message = "'...'.format(...) is missing argument(s) for placeholder(s): %s" | |
278 | ||
279 | def __init__(self, filename, loc, missing_arguments): | |
280 | Message.__init__(self, filename, loc) | |
281 | self.message_args = (missing_arguments,) | |
282 | ||
283 | ||
284 | class StringDotFormatMixingAutomatic(Message): | |
285 | message = "'...'.format(...) mixes automatic and manual numbering" | |
286 | ||
287 | ||
288 | class StringDotFormatInvalidFormat(Message): | |
289 | message = "'...'.format(...) has invalid format string: %s" | |
290 | ||
291 | def __init__(self, filename, loc, error): | |
292 | Message.__init__(self, filename, loc) | |
293 | self.message_args = (error,) | |
294 | ||
295 | ||
296 | class PercentFormatInvalidFormat(Message): | |
297 | message = "'...' %% ... has invalid format string: %s" | |
298 | ||
299 | def __init__(self, filename, loc, error): | |
300 | Message.__init__(self, filename, loc) | |
301 | self.message_args = (error,) | |
302 | ||
303 | ||
304 | class PercentFormatMixedPositionalAndNamed(Message): | |
305 | message = "'...' %% ... has mixed positional and named placeholders" | |
306 | ||
307 | ||
308 | class PercentFormatUnsupportedFormatCharacter(Message): | |
309 | message = "'...' %% ... has unsupported format character %r" | |
310 | ||
311 | def __init__(self, filename, loc, c): | |
312 | Message.__init__(self, filename, loc) | |
313 | self.message_args = (c,) | |
314 | ||
315 | ||
316 | class PercentFormatPositionalCountMismatch(Message): | |
317 | message = "'...' %% ... has %d placeholder(s) but %d substitution(s)" | |
318 | ||
319 | def __init__(self, filename, loc, n_placeholders, n_substitutions): | |
320 | Message.__init__(self, filename, loc) | |
321 | self.message_args = (n_placeholders, n_substitutions) | |
322 | ||
323 | ||
324 | class PercentFormatExtraNamedArguments(Message): | |
325 | message = "'...' %% ... has unused named argument(s): %s" | |
326 | ||
327 | def __init__(self, filename, loc, extra_keywords): | |
328 | Message.__init__(self, filename, loc) | |
329 | self.message_args = (extra_keywords,) | |
330 | ||
331 | ||
332 | class PercentFormatMissingArgument(Message): | |
333 | message = "'...' %% ... is missing argument(s) for placeholder(s): %s" | |
334 | ||
335 | def __init__(self, filename, loc, missing_arguments): | |
336 | Message.__init__(self, filename, loc) | |
337 | self.message_args = (missing_arguments,) | |
338 | ||
339 | ||
340 | class PercentFormatExpectedMapping(Message): | |
341 | message = "'...' %% ... expected mapping but got sequence" | |
342 | ||
343 | ||
344 | class PercentFormatExpectedSequence(Message): | |
345 | message = "'...' %% ... expected sequence but got mapping" | |
346 | ||
347 | ||
348 | class PercentFormatStarRequiresSequence(Message): | |
349 | message = "'...' %% ... `*` specifier requires sequence" |