Merge lp:~divmod-dev/divmod.org/1095248-remove-pyflakes into lp:divmod.org
- 1095248-remove-pyflakes
- Merge into trunk
Proposed by
Florent
Status: | Merged | ||||
---|---|---|---|---|---|
Approved by: | Glyph Lefkowitz | ||||
Approved revision: | 2701 | ||||
Merged at revision: | 2701 | ||||
Proposed branch: | lp:~divmod-dev/divmod.org/1095248-remove-pyflakes | ||||
Merge into: | lp:divmod.org | ||||
Diff against target: |
3304 lines (+1/-3209) 16 files modified
Divmod.pth (+1/-2) Pyflakes/LICENSE (+0/-20) Pyflakes/MANIFEST.in (+0/-2) Pyflakes/NEWS.txt (+0/-35) Pyflakes/bin/pyflakes (+0/-3) Pyflakes/pyflakes/__init__.py (+0/-2) Pyflakes/pyflakes/checker.py (+0/-634) Pyflakes/pyflakes/messages.py (+0/-94) Pyflakes/pyflakes/reporter.py (+0/-79) Pyflakes/pyflakes/scripts/pyflakes.py (+0/-122) Pyflakes/pyflakes/test/harness.py (+0/-27) Pyflakes/pyflakes/test/test_imports.py (+0/-670) Pyflakes/pyflakes/test/test_other.py (+0/-654) Pyflakes/pyflakes/test/test_script.py (+0/-563) Pyflakes/pyflakes/test/test_undefined_names.py (+0/-273) Pyflakes/setup.py (+0/-29) |
||||
To merge this branch: | bzr merge lp:~divmod-dev/divmod.org/1095248-remove-pyflakes | ||||
Related bugs: |
|
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
Glyph Lefkowitz | Approve | ||
Review via email: mp+141590@code.launchpad.net |
Commit message
Description of the change
Move Pyflakes out of the divmod.org's repository
To post a comment you must log in.
Preview Diff
[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1 | === modified file 'Divmod.pth' |
2 | --- Divmod.pth 2008-10-01 18:28:58 +0000 |
3 | +++ Divmod.pth 2013-01-02 10:12:49 +0000 |
4 | @@ -1,10 +1,9 @@ |
5 | -# -*- test-case-name: axiom,combinator,epsilon,xmantissa,nevow,formless,pyflakes,xquotient,reverend,sine,vertex,hyperbola,imaginary,examplegame -*- |
6 | +# -*- test-case-name: axiom,combinator,epsilon,xmantissa,nevow,formless,xquotient,reverend,sine,vertex,hyperbola,imaginary,examplegame -*- |
7 | Axiom |
8 | Combinator |
9 | Epsilon |
10 | Mantissa |
11 | Nevow |
12 | -Pyflakes |
13 | Quotient |
14 | Reverend |
15 | Sine |
16 | |
17 | === removed directory 'Pyflakes' |
18 | === removed file 'Pyflakes/LICENSE' |
19 | --- Pyflakes/LICENSE 2011-09-03 16:03:07 +0000 |
20 | +++ Pyflakes/LICENSE 1970-01-01 00:00:00 +0000 |
21 | @@ -1,20 +0,0 @@ |
22 | -Copyright 2005-2011 Divmod, Inc. |
23 | - |
24 | -Permission is hereby granted, free of charge, to any person obtaining |
25 | -a copy of this software and associated documentation files (the |
26 | -"Software"), to deal in the Software without restriction, including |
27 | -without limitation the rights to use, copy, modify, merge, publish, |
28 | -distribute, sublicense, and/or sell copies of the Software, and to |
29 | -permit persons to whom the Software is furnished to do so, subject to |
30 | -the following conditions: |
31 | - |
32 | -The above copyright notice and this permission notice shall be |
33 | -included in all copies or substantial portions of the Software. |
34 | - |
35 | -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, |
36 | -EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF |
37 | -MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND |
38 | -NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE |
39 | -LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION |
40 | -OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION |
41 | -WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. |
42 | |
43 | === removed file 'Pyflakes/MANIFEST.in' |
44 | --- Pyflakes/MANIFEST.in 2011-09-03 16:06:14 +0000 |
45 | +++ Pyflakes/MANIFEST.in 1970-01-01 00:00:00 +0000 |
46 | @@ -1,2 +0,0 @@ |
47 | -include NEWS.txt |
48 | -include LICENSE |
49 | |
50 | === removed file 'Pyflakes/NEWS.txt' |
51 | --- Pyflakes/NEWS.txt 2011-09-03 16:03:28 +0000 |
52 | +++ Pyflakes/NEWS.txt 1970-01-01 00:00:00 +0000 |
53 | @@ -1,35 +0,0 @@ |
54 | -0.5.0 (2011-09-02): |
55 | - - Convert pyflakes to use newer _ast infrastructure rather than compiler. |
56 | - - Support for new syntax in 2.7 (including set literals, set comprehensions, |
57 | - and dictionary comprehensions). |
58 | - - Make sure class names don't get bound until after class definition. |
59 | - |
60 | -0.4.0 (2009-11-25): |
61 | - - Fix reporting for certain SyntaxErrors which lack line number |
62 | - information. |
63 | - - Check for syntax errors more rigorously. |
64 | - - Support checking names used with the class decorator syntax in versions |
65 | - of Python which have it. |
66 | - - Detect local variables which are bound but never used. |
67 | - - Handle permission errors when trying to read source files. |
68 | - - Handle problems with the encoding of source files. |
69 | - - Support importing dotted names so as not to incorrectly report them as |
70 | - redefined unused names. |
71 | - - Support all forms of the with statement. |
72 | - - Consider static `__all__` definitions and avoid reporting unused names |
73 | - if the names are listed there. |
74 | - - Fix incorrect checking of class names with respect to the names of their |
75 | - bases in the class statement. |
76 | - - Support the `__path__` global in `__init__.py`. |
77 | - |
78 | -0.3.0 (2009-01-30): |
79 | - - Display more informative SyntaxError messages. |
80 | - - Don't hang flymake with unmatched triple quotes (only report a single |
81 | - line of source for a multiline syntax error). |
82 | - - Recognize __builtins__ as a defined name. |
83 | - - Improve pyflakes support for python versions 2.3-2.5 |
84 | - - Support for if-else expressions and with statements. |
85 | - - Warn instead of error on non-existant file paths. |
86 | - - Check for __future__ imports after other statements. |
87 | - - Add reporting for some types of import shadowing. |
88 | - - Improve reporting of unbound locals |
89 | |
90 | === removed directory 'Pyflakes/bin' |
91 | === removed file 'Pyflakes/bin/pyflakes' |
92 | --- Pyflakes/bin/pyflakes 2012-07-08 13:48:46 +0000 |
93 | +++ Pyflakes/bin/pyflakes 1970-01-01 00:00:00 +0000 |
94 | @@ -1,3 +0,0 @@ |
95 | -#!/usr/bin/python |
96 | -from pyflakes.scripts.pyflakes import main |
97 | -main() |
98 | |
99 | === removed directory 'Pyflakes/pyflakes' |
100 | === removed file 'Pyflakes/pyflakes/__init__.py' |
101 | --- Pyflakes/pyflakes/__init__.py 2011-09-03 16:06:14 +0000 |
102 | +++ Pyflakes/pyflakes/__init__.py 1970-01-01 00:00:00 +0000 |
103 | @@ -1,2 +0,0 @@ |
104 | - |
105 | -__version__ = '0.5.0' |
106 | |
107 | === removed file 'Pyflakes/pyflakes/checker.py' |
108 | --- Pyflakes/pyflakes/checker.py 2012-01-10 19:09:22 +0000 |
109 | +++ Pyflakes/pyflakes/checker.py 1970-01-01 00:00:00 +0000 |
110 | @@ -1,634 +0,0 @@ |
111 | -# -*- test-case-name: pyflakes -*- |
112 | -# (c) 2005-2010 Divmod, Inc. |
113 | -# See LICENSE file for details |
114 | - |
115 | -import __builtin__ |
116 | -import os.path |
117 | -import _ast |
118 | - |
119 | -from pyflakes import messages |
120 | - |
121 | - |
122 | -# utility function to iterate over an AST node's children, adapted |
123 | -# from Python 2.6's standard ast module |
124 | -try: |
125 | - import ast |
126 | - iter_child_nodes = ast.iter_child_nodes |
127 | -except (ImportError, AttributeError): |
128 | - def iter_child_nodes(node, astcls=_ast.AST): |
129 | - """ |
130 | - Yield all direct child nodes of *node*, that is, all fields that are nodes |
131 | - and all items of fields that are lists of nodes. |
132 | - """ |
133 | - for name in node._fields: |
134 | - field = getattr(node, name, None) |
135 | - if isinstance(field, astcls): |
136 | - yield field |
137 | - elif isinstance(field, list): |
138 | - for item in field: |
139 | - yield item |
140 | - |
141 | - |
142 | -class Binding(object): |
143 | - """ |
144 | - Represents the binding of a value to a name. |
145 | - |
146 | - The checker uses this to keep track of which names have been bound and |
147 | - which names have not. See L{Assignment} for a special type of binding that |
148 | - is checked with stricter rules. |
149 | - |
150 | - @ivar used: pair of (L{Scope}, line-number) indicating the scope and |
151 | - line number that this binding was last used |
152 | - """ |
153 | - |
154 | - def __init__(self, name, source): |
155 | - self.name = name |
156 | - self.source = source |
157 | - self.used = False |
158 | - |
159 | - |
160 | - def __str__(self): |
161 | - return self.name |
162 | - |
163 | - |
164 | - def __repr__(self): |
165 | - return '<%s object %r from line %r at 0x%x>' % (self.__class__.__name__, |
166 | - self.name, |
167 | - self.source.lineno, |
168 | - id(self)) |
169 | - |
170 | - |
171 | - |
172 | -class UnBinding(Binding): |
173 | - '''Created by the 'del' operator.''' |
174 | - |
175 | - |
176 | - |
177 | -class Importation(Binding): |
178 | - """ |
179 | - A binding created by an import statement. |
180 | - |
181 | - @ivar fullName: The complete name given to the import statement, |
182 | - possibly including multiple dotted components. |
183 | - @type fullName: C{str} |
184 | - """ |
185 | - def __init__(self, name, source): |
186 | - self.fullName = name |
187 | - name = name.split('.')[0] |
188 | - super(Importation, self).__init__(name, source) |
189 | - |
190 | - |
191 | - |
192 | -class Argument(Binding): |
193 | - """ |
194 | - Represents binding a name as an argument. |
195 | - """ |
196 | - |
197 | - |
198 | -class Definition(Binding): |
199 | - """ |
200 | - A binding that defines a function or class. |
201 | - """ |
202 | - |
203 | - |
204 | -class Assignment(Binding): |
205 | - """ |
206 | - Represents binding a name with an explicit assignment. |
207 | - |
208 | - The checker will raise warnings for any Assignment that isn't used. Also, |
209 | - the checker does not consider assignments in tuple/list unpacking to be |
210 | - Assignments, rather it treats them as simple Bindings. |
211 | - """ |
212 | - |
213 | - |
214 | - |
215 | -class FunctionDefinition(Definition): |
216 | - pass |
217 | - |
218 | - |
219 | - |
220 | -class ClassDefinition(Definition): |
221 | - pass |
222 | - |
223 | - |
224 | - |
225 | -class ExportBinding(Binding): |
226 | - """ |
227 | - A binding created by an C{__all__} assignment. If the names in the list |
228 | - can be determined statically, they will be treated as names for export and |
229 | - additional checking applied to them. |
230 | - |
231 | - The only C{__all__} assignment that can be recognized is one which takes |
232 | - the value of a literal list containing literal strings. For example:: |
233 | - |
234 | - __all__ = ["foo", "bar"] |
235 | - |
236 | - Names which are imported and not otherwise used but appear in the value of |
237 | - C{__all__} will not have an unused import warning reported for them. |
238 | - """ |
239 | - def names(self): |
240 | - """ |
241 | - Return a list of the names referenced by this binding. |
242 | - """ |
243 | - names = [] |
244 | - if isinstance(self.source, _ast.List): |
245 | - for node in self.source.elts: |
246 | - if isinstance(node, _ast.Str): |
247 | - names.append(node.s) |
248 | - return names |
249 | - |
250 | - |
251 | - |
252 | -class Scope(dict): |
253 | - importStarred = False # set to True when import * is found |
254 | - |
255 | - |
256 | - def __repr__(self): |
257 | - return '<%s at 0x%x %s>' % (self.__class__.__name__, id(self), dict.__repr__(self)) |
258 | - |
259 | - |
260 | - def __init__(self): |
261 | - super(Scope, self).__init__() |
262 | - |
263 | - |
264 | - |
265 | -class ClassScope(Scope): |
266 | - pass |
267 | - |
268 | - |
269 | - |
270 | -class FunctionScope(Scope): |
271 | - """ |
272 | - I represent a name scope for a function. |
273 | - |
274 | - @ivar globals: Names declared 'global' in this function. |
275 | - """ |
276 | - def __init__(self): |
277 | - super(FunctionScope, self).__init__() |
278 | - self.globals = {} |
279 | - |
280 | - |
281 | - |
282 | -class ModuleScope(Scope): |
283 | - pass |
284 | - |
285 | - |
286 | -# Globally defined names which are not attributes of the __builtin__ module, or |
287 | -# are only present on some platforms. |
288 | -_MAGIC_GLOBALS = ['__file__', '__builtins__', 'WindowsError'] |
289 | - |
290 | - |
291 | - |
292 | -class Checker(object): |
293 | - """ |
294 | - I check the cleanliness and sanity of Python code. |
295 | - |
296 | - @ivar _deferredFunctions: Tracking list used by L{deferFunction}. Elements |
297 | - of the list are two-tuples. The first element is the callable passed |
298 | - to L{deferFunction}. The second element is a copy of the scope stack |
299 | - at the time L{deferFunction} was called. |
300 | - |
301 | - @ivar _deferredAssignments: Similar to C{_deferredFunctions}, but for |
302 | - callables which are deferred assignment checks. |
303 | - """ |
304 | - |
305 | - nodeDepth = 0 |
306 | - traceTree = False |
307 | - |
308 | - def __init__(self, tree, filename='(none)'): |
309 | - self._deferredFunctions = [] |
310 | - self._deferredAssignments = [] |
311 | - self.dead_scopes = [] |
312 | - self.messages = [] |
313 | - self.filename = filename |
314 | - self.scopeStack = [ModuleScope()] |
315 | - self.futuresAllowed = True |
316 | - self.handleChildren(tree) |
317 | - self._runDeferred(self._deferredFunctions) |
318 | - # Set _deferredFunctions to None so that deferFunction will fail |
319 | - # noisily if called after we've run through the deferred functions. |
320 | - self._deferredFunctions = None |
321 | - self._runDeferred(self._deferredAssignments) |
322 | - # Set _deferredAssignments to None so that deferAssignment will fail |
323 | - # noisly if called after we've run through the deferred assignments. |
324 | - self._deferredAssignments = None |
325 | - del self.scopeStack[1:] |
326 | - self.popScope() |
327 | - self.check_dead_scopes() |
328 | - |
329 | - |
330 | - def deferFunction(self, callable): |
331 | - ''' |
332 | - Schedule a function handler to be called just before completion. |
333 | - |
334 | - This is used for handling function bodies, which must be deferred |
335 | - because code later in the file might modify the global scope. When |
336 | - `callable` is called, the scope at the time this is called will be |
337 | - restored, however it will contain any new bindings added to it. |
338 | - ''' |
339 | - self._deferredFunctions.append((callable, self.scopeStack[:])) |
340 | - |
341 | - |
342 | - def deferAssignment(self, callable): |
343 | - """ |
344 | - Schedule an assignment handler to be called just after deferred |
345 | - function handlers. |
346 | - """ |
347 | - self._deferredAssignments.append((callable, self.scopeStack[:])) |
348 | - |
349 | - |
350 | - def _runDeferred(self, deferred): |
351 | - """ |
352 | - Run the callables in C{deferred} using their associated scope stack. |
353 | - """ |
354 | - for handler, scope in deferred: |
355 | - self.scopeStack = scope |
356 | - handler() |
357 | - |
358 | - |
359 | - def scope(self): |
360 | - return self.scopeStack[-1] |
361 | - scope = property(scope) |
362 | - |
363 | - def popScope(self): |
364 | - self.dead_scopes.append(self.scopeStack.pop()) |
365 | - |
366 | - |
367 | - def check_dead_scopes(self): |
368 | - """ |
369 | - Look at scopes which have been fully examined and report names in them |
370 | - which were imported but unused. |
371 | - """ |
372 | - for scope in self.dead_scopes: |
373 | - export = isinstance(scope.get('__all__'), ExportBinding) |
374 | - if export: |
375 | - all = scope['__all__'].names() |
376 | - if os.path.split(self.filename)[1] != '__init__.py': |
377 | - # Look for possible mistakes in the export list |
378 | - undefined = set(all) - set(scope) |
379 | - for name in undefined: |
380 | - self.report( |
381 | - messages.UndefinedExport, |
382 | - scope['__all__'].source.lineno, |
383 | - name) |
384 | - else: |
385 | - all = [] |
386 | - |
387 | - # Look for imported names that aren't used. |
388 | - for importation in scope.itervalues(): |
389 | - if isinstance(importation, Importation): |
390 | - if not importation.used and importation.name not in all: |
391 | - self.report( |
392 | - messages.UnusedImport, |
393 | - importation.source.lineno, |
394 | - importation.name) |
395 | - |
396 | - |
397 | - def pushFunctionScope(self): |
398 | - self.scopeStack.append(FunctionScope()) |
399 | - |
400 | - def pushClassScope(self): |
401 | - self.scopeStack.append(ClassScope()) |
402 | - |
403 | - def report(self, messageClass, *args, **kwargs): |
404 | - self.messages.append(messageClass(self.filename, *args, **kwargs)) |
405 | - |
406 | - def handleChildren(self, tree): |
407 | - for node in iter_child_nodes(tree): |
408 | - self.handleNode(node, tree) |
409 | - |
410 | - def isDocstring(self, node): |
411 | - """ |
412 | - Determine if the given node is a docstring, as long as it is at the |
413 | - correct place in the node tree. |
414 | - """ |
415 | - return isinstance(node, _ast.Str) or \ |
416 | - (isinstance(node, _ast.Expr) and |
417 | - isinstance(node.value, _ast.Str)) |
418 | - |
419 | - def handleNode(self, node, parent): |
420 | - node.parent = parent |
421 | - if self.traceTree: |
422 | - print ' ' * self.nodeDepth + node.__class__.__name__ |
423 | - self.nodeDepth += 1 |
424 | - if self.futuresAllowed and not \ |
425 | - (isinstance(node, _ast.ImportFrom) or self.isDocstring(node)): |
426 | - self.futuresAllowed = False |
427 | - nodeType = node.__class__.__name__.upper() |
428 | - try: |
429 | - handler = getattr(self, nodeType) |
430 | - handler(node) |
431 | - finally: |
432 | - self.nodeDepth -= 1 |
433 | - if self.traceTree: |
434 | - print ' ' * self.nodeDepth + 'end ' + node.__class__.__name__ |
435 | - |
436 | - def ignore(self, node): |
437 | - pass |
438 | - |
439 | - # "stmt" type nodes |
440 | - RETURN = DELETE = PRINT = WHILE = IF = WITH = RAISE = TRYEXCEPT = \ |
441 | - TRYFINALLY = ASSERT = EXEC = EXPR = handleChildren |
442 | - |
443 | - CONTINUE = BREAK = PASS = ignore |
444 | - |
445 | - # "expr" type nodes |
446 | - BOOLOP = BINOP = UNARYOP = IFEXP = DICT = SET = YIELD = COMPARE = \ |
447 | - CALL = REPR = ATTRIBUTE = SUBSCRIPT = LIST = TUPLE = handleChildren |
448 | - |
449 | - NUM = STR = ELLIPSIS = ignore |
450 | - |
451 | - # "slice" type nodes |
452 | - SLICE = EXTSLICE = INDEX = handleChildren |
453 | - |
454 | - # expression contexts are node instances too, though being constants |
455 | - LOAD = STORE = DEL = AUGLOAD = AUGSTORE = PARAM = ignore |
456 | - |
457 | - # same for operators |
458 | - AND = OR = ADD = SUB = MULT = DIV = MOD = POW = LSHIFT = RSHIFT = \ |
459 | - BITOR = BITXOR = BITAND = FLOORDIV = INVERT = NOT = UADD = USUB = \ |
460 | - EQ = NOTEQ = LT = LTE = GT = GTE = IS = ISNOT = IN = NOTIN = ignore |
461 | - |
462 | - # additional node types |
463 | - COMPREHENSION = EXCEPTHANDLER = KEYWORD = handleChildren |
464 | - |
465 | - def addBinding(self, lineno, value, reportRedef=True): |
466 | - '''Called when a binding is altered. |
467 | - |
468 | - - `lineno` is the line of the statement responsible for the change |
469 | - - `value` is the optional new value, a Binding instance, associated |
470 | - with the binding; if None, the binding is deleted if it exists. |
471 | - - if `reportRedef` is True (default), rebinding while unused will be |
472 | - reported. |
473 | - ''' |
474 | - if not isinstance(self.scope, ClassScope): |
475 | - for scope in self.scopeStack[::-1]: |
476 | - existing = scope.get(value.name) |
477 | - if (isinstance(existing, Importation) |
478 | - and not existing.used |
479 | - and (not isinstance(value, Importation) or value.fullName == existing.fullName) |
480 | - and reportRedef): |
481 | - |
482 | - self.report(messages.RedefinedWhileUnused, |
483 | - lineno, value.name, scope[value.name].source.lineno) |
484 | - |
485 | - existing = self.scope.get(value.name) |
486 | - if isinstance(value, UnBinding): |
487 | - try: |
488 | - del self.scope[value.name] |
489 | - except KeyError: |
490 | - self.report(messages.UndefinedName, lineno, value.name) |
491 | - elif isinstance(existing, Definition) and not existing.used: |
492 | - self.report(messages.RedefinedWhileUnused, |
493 | - lineno, value.name, existing.source.lineno) |
494 | - else: |
495 | - self.scope[value.name] = value |
496 | - |
497 | - def GLOBAL(self, node): |
498 | - """ |
499 | - Keep track of globals declarations. |
500 | - """ |
501 | - if isinstance(self.scope, FunctionScope): |
502 | - self.scope.globals.update(dict.fromkeys(node.names)) |
503 | - |
504 | - def LISTCOMP(self, node): |
505 | - # handle generators before element |
506 | - for gen in node.generators: |
507 | - self.handleNode(gen, node) |
508 | - self.handleNode(node.elt, node) |
509 | - |
510 | - GENERATOREXP = SETCOMP = LISTCOMP |
511 | - |
512 | - # dictionary comprehensions; introduced in Python 2.7 |
513 | - def DICTCOMP(self, node): |
514 | - for gen in node.generators: |
515 | - self.handleNode(gen, node) |
516 | - self.handleNode(node.key, node) |
517 | - self.handleNode(node.value, node) |
518 | - |
519 | - def FOR(self, node): |
520 | - """ |
521 | - Process bindings for loop variables. |
522 | - """ |
523 | - vars = [] |
524 | - def collectLoopVars(n): |
525 | - if isinstance(n, _ast.Name): |
526 | - vars.append(n.id) |
527 | - elif isinstance(n, _ast.expr_context): |
528 | - return |
529 | - else: |
530 | - for c in iter_child_nodes(n): |
531 | - collectLoopVars(c) |
532 | - |
533 | - collectLoopVars(node.target) |
534 | - for varn in vars: |
535 | - if (isinstance(self.scope.get(varn), Importation) |
536 | - # unused ones will get an unused import warning |
537 | - and self.scope[varn].used): |
538 | - self.report(messages.ImportShadowedByLoopVar, |
539 | - node.lineno, varn, self.scope[varn].source.lineno) |
540 | - |
541 | - self.handleChildren(node) |
542 | - |
543 | - def NAME(self, node): |
544 | - """ |
545 | - Handle occurrence of Name (which can be a load/store/delete access.) |
546 | - """ |
547 | - # Locate the name in locals / function / globals scopes. |
548 | - if isinstance(node.ctx, (_ast.Load, _ast.AugLoad)): |
549 | - # try local scope |
550 | - importStarred = self.scope.importStarred |
551 | - try: |
552 | - self.scope[node.id].used = (self.scope, node.lineno) |
553 | - except KeyError: |
554 | - pass |
555 | - else: |
556 | - return |
557 | - |
558 | - # try enclosing function scopes |
559 | - |
560 | - for scope in self.scopeStack[-2:0:-1]: |
561 | - importStarred = importStarred or scope.importStarred |
562 | - if not isinstance(scope, FunctionScope): |
563 | - continue |
564 | - try: |
565 | - scope[node.id].used = (self.scope, node.lineno) |
566 | - except KeyError: |
567 | - pass |
568 | - else: |
569 | - return |
570 | - |
571 | - # try global scope |
572 | - |
573 | - importStarred = importStarred or self.scopeStack[0].importStarred |
574 | - try: |
575 | - self.scopeStack[0][node.id].used = (self.scope, node.lineno) |
576 | - except KeyError: |
577 | - if ((not hasattr(__builtin__, node.id)) |
578 | - and node.id not in _MAGIC_GLOBALS |
579 | - and not importStarred): |
580 | - if (os.path.basename(self.filename) == '__init__.py' and |
581 | - node.id == '__path__'): |
582 | - # the special name __path__ is valid only in packages |
583 | - pass |
584 | - else: |
585 | - self.report(messages.UndefinedName, node.lineno, node.id) |
586 | - elif isinstance(node.ctx, (_ast.Store, _ast.AugStore)): |
587 | - # if the name hasn't already been defined in the current scope |
588 | - if isinstance(self.scope, FunctionScope) and node.id not in self.scope: |
589 | - # for each function or module scope above us |
590 | - for scope in self.scopeStack[:-1]: |
591 | - if not isinstance(scope, (FunctionScope, ModuleScope)): |
592 | - continue |
593 | - # if the name was defined in that scope, and the name has |
594 | - # been accessed already in the current scope, and hasn't |
595 | - # been declared global |
596 | - if (node.id in scope |
597 | - and scope[node.id].used |
598 | - and scope[node.id].used[0] is self.scope |
599 | - and node.id not in self.scope.globals): |
600 | - # then it's probably a mistake |
601 | - self.report(messages.UndefinedLocal, |
602 | - scope[node.id].used[1], |
603 | - node.id, |
604 | - scope[node.id].source.lineno) |
605 | - break |
606 | - |
607 | - if isinstance(node.parent, |
608 | - (_ast.For, _ast.comprehension, _ast.Tuple, _ast.List)): |
609 | - binding = Binding(node.id, node) |
610 | - elif (node.id == '__all__' and |
611 | - isinstance(self.scope, ModuleScope)): |
612 | - binding = ExportBinding(node.id, node.parent.value) |
613 | - else: |
614 | - binding = Assignment(node.id, node) |
615 | - if node.id in self.scope: |
616 | - binding.used = self.scope[node.id].used |
617 | - self.addBinding(node.lineno, binding) |
618 | - elif isinstance(node.ctx, _ast.Del): |
619 | - if isinstance(self.scope, FunctionScope) and \ |
620 | - node.id in self.scope.globals: |
621 | - del self.scope.globals[node.id] |
622 | - else: |
623 | - self.addBinding(node.lineno, UnBinding(node.id, node)) |
624 | - else: |
625 | - # must be a Param context -- this only happens for names in function |
626 | - # arguments, but these aren't dispatched through here |
627 | - raise RuntimeError( |
628 | - "Got impossible expression context: %r" % (node.ctx,)) |
629 | - |
630 | - |
631 | - def FUNCTIONDEF(self, node): |
632 | - # the decorators attribute is called decorator_list as of Python 2.6 |
633 | - if hasattr(node, 'decorators'): |
634 | - for deco in node.decorators: |
635 | - self.handleNode(deco, node) |
636 | - else: |
637 | - for deco in node.decorator_list: |
638 | - self.handleNode(deco, node) |
639 | - self.addBinding(node.lineno, FunctionDefinition(node.name, node)) |
640 | - self.LAMBDA(node) |
641 | - |
642 | - def LAMBDA(self, node): |
643 | - for default in node.args.defaults: |
644 | - self.handleNode(default, node) |
645 | - |
646 | - def runFunction(): |
647 | - args = [] |
648 | - |
649 | - def addArgs(arglist): |
650 | - for arg in arglist: |
651 | - if isinstance(arg, _ast.Tuple): |
652 | - addArgs(arg.elts) |
653 | - else: |
654 | - if arg.id in args: |
655 | - self.report(messages.DuplicateArgument, |
656 | - node.lineno, arg.id) |
657 | - args.append(arg.id) |
658 | - |
659 | - self.pushFunctionScope() |
660 | - addArgs(node.args.args) |
661 | - # vararg/kwarg identifiers are not Name nodes |
662 | - if node.args.vararg: |
663 | - args.append(node.args.vararg) |
664 | - if node.args.kwarg: |
665 | - args.append(node.args.kwarg) |
666 | - for name in args: |
667 | - self.addBinding(node.lineno, Argument(name, node), reportRedef=False) |
668 | - if isinstance(node.body, list): |
669 | - # case for FunctionDefs |
670 | - for stmt in node.body: |
671 | - self.handleNode(stmt, node) |
672 | - else: |
673 | - # case for Lambdas |
674 | - self.handleNode(node.body, node) |
675 | - def checkUnusedAssignments(): |
676 | - """ |
677 | - Check to see if any assignments have not been used. |
678 | - """ |
679 | - for name, binding in self.scope.iteritems(): |
680 | - if (not binding.used and not name in self.scope.globals |
681 | - and isinstance(binding, Assignment)): |
682 | - self.report(messages.UnusedVariable, |
683 | - binding.source.lineno, name) |
684 | - self.deferAssignment(checkUnusedAssignments) |
685 | - self.popScope() |
686 | - |
687 | - self.deferFunction(runFunction) |
688 | - |
689 | - |
690 | - def CLASSDEF(self, node): |
691 | - """ |
692 | - Check names used in a class definition, including its decorators, base |
693 | - classes, and the body of its definition. Additionally, add its name to |
694 | - the current scope. |
695 | - """ |
696 | - # decorator_list is present as of Python 2.6 |
697 | - for deco in getattr(node, 'decorator_list', []): |
698 | - self.handleNode(deco, node) |
699 | - for baseNode in node.bases: |
700 | - self.handleNode(baseNode, node) |
701 | - self.pushClassScope() |
702 | - for stmt in node.body: |
703 | - self.handleNode(stmt, node) |
704 | - self.popScope() |
705 | - self.addBinding(node.lineno, ClassDefinition(node.name, node)) |
706 | - |
707 | - def ASSIGN(self, node): |
708 | - self.handleNode(node.value, node) |
709 | - for target in node.targets: |
710 | - self.handleNode(target, node) |
711 | - |
712 | - def AUGASSIGN(self, node): |
713 | - # AugAssign is awkward: must set the context explicitly and visit twice, |
714 | - # once with AugLoad context, once with AugStore context |
715 | - node.target.ctx = _ast.AugLoad() |
716 | - self.handleNode(node.target, node) |
717 | - self.handleNode(node.value, node) |
718 | - node.target.ctx = _ast.AugStore() |
719 | - self.handleNode(node.target, node) |
720 | - |
721 | - def IMPORT(self, node): |
722 | - for alias in node.names: |
723 | - name = alias.asname or alias.name |
724 | - importation = Importation(name, node) |
725 | - self.addBinding(node.lineno, importation) |
726 | - |
727 | - def IMPORTFROM(self, node): |
728 | - if node.module == '__future__': |
729 | - if not self.futuresAllowed: |
730 | - self.report(messages.LateFutureImport, node.lineno, |
731 | - [n.name for n in node.names]) |
732 | - else: |
733 | - self.futuresAllowed = False |
734 | - |
735 | - for alias in node.names: |
736 | - if alias.name == '*': |
737 | - self.scope.importStarred = True |
738 | - self.report(messages.ImportStarUsed, node.lineno, node.module) |
739 | - continue |
740 | - name = alias.asname or alias.name |
741 | - importation = Importation(name, node) |
742 | - if node.module == '__future__': |
743 | - importation.used = (self.scope, node.lineno) |
744 | - self.addBinding(node.lineno, importation) |
745 | |
746 | === removed file 'Pyflakes/pyflakes/messages.py' |
747 | --- Pyflakes/pyflakes/messages.py 2011-10-31 15:19:35 +0000 |
748 | +++ Pyflakes/pyflakes/messages.py 1970-01-01 00:00:00 +0000 |
749 | @@ -1,94 +0,0 @@ |
750 | -# (c) 2005 Divmod, Inc. See LICENSE file for details |
751 | - |
752 | -class Message(object): |
753 | - message = '' |
754 | - message_args = () |
755 | - def __init__(self, filename, lineno): |
756 | - self.filename = filename |
757 | - self.lineno = lineno |
758 | - def __str__(self): |
759 | - return '%s:%s: %s' % (self.filename, self.lineno, self.message % self.message_args) |
760 | - |
761 | - |
762 | -class UnusedImport(Message): |
763 | - message = '%r imported but unused' |
764 | - def __init__(self, filename, lineno, name): |
765 | - Message.__init__(self, filename, lineno) |
766 | - self.message_args = (name,) |
767 | - |
768 | - |
769 | -class RedefinedWhileUnused(Message): |
770 | - message = 'redefinition of unused %r from line %r' |
771 | - def __init__(self, filename, lineno, name, orig_lineno): |
772 | - Message.__init__(self, filename, lineno) |
773 | - self.message_args = (name, orig_lineno) |
774 | - |
775 | - |
776 | -class ImportShadowedByLoopVar(Message): |
777 | - message = 'import %r from line %r shadowed by loop variable' |
778 | - def __init__(self, filename, lineno, name, orig_lineno): |
779 | - Message.__init__(self, filename, lineno) |
780 | - self.message_args = (name, orig_lineno) |
781 | - |
782 | - |
783 | -class ImportStarUsed(Message): |
784 | - message = "'from %s import *' used; unable to detect undefined names" |
785 | - def __init__(self, filename, lineno, modname): |
786 | - Message.__init__(self, filename, lineno) |
787 | - self.message_args = (modname,) |
788 | - |
789 | - |
790 | -class UndefinedName(Message): |
791 | - message = 'undefined name %r' |
792 | - def __init__(self, filename, lineno, name): |
793 | - Message.__init__(self, filename, lineno) |
794 | - self.message_args = (name,) |
795 | - |
796 | - |
797 | - |
798 | -class UndefinedExport(Message): |
799 | - message = 'undefined name %r in __all__' |
800 | - def __init__(self, filename, lineno, name): |
801 | - Message.__init__(self, filename, lineno) |
802 | - self.message_args = (name,) |
803 | - |
804 | - |
805 | - |
806 | -class UndefinedLocal(Message): |
807 | - message = "local variable %r (defined in enclosing scope on line %r) referenced before assignment" |
808 | - def __init__(self, filename, lineno, name, orig_lineno): |
809 | - Message.__init__(self, filename, lineno) |
810 | - self.message_args = (name, orig_lineno) |
811 | - |
812 | - |
813 | -class DuplicateArgument(Message): |
814 | - message = 'duplicate argument %r in function definition' |
815 | - def __init__(self, filename, lineno, name): |
816 | - Message.__init__(self, filename, lineno) |
817 | - self.message_args = (name,) |
818 | - |
819 | - |
820 | -class Redefined(Message): |
821 | - message = 'redefinition of %r from line %r' |
822 | - def __init__(self, filename, lineno, name, orig_lineno): |
823 | - Message.__init__(self, filename, lineno) |
824 | - self.message_args = (name, orig_lineno) |
825 | - |
826 | - |
827 | -class LateFutureImport(Message): |
828 | - message = 'future import(s) %r after other statements' |
829 | - def __init__(self, filename, lineno, names): |
830 | - Message.__init__(self, filename, lineno) |
831 | - self.message_args = (names,) |
832 | - |
833 | - |
834 | -class UnusedVariable(Message): |
835 | - """ |
836 | - Indicates that a variable has been explicity assigned to but not actually |
837 | - used. |
838 | - """ |
839 | - |
840 | - message = 'local variable %r is assigned to but never used' |
841 | - def __init__(self, filename, lineno, names): |
842 | - Message.__init__(self, filename, lineno) |
843 | - self.message_args = (names,) |
844 | |
845 | === removed file 'Pyflakes/pyflakes/reporter.py' |
846 | --- Pyflakes/pyflakes/reporter.py 2012-10-23 13:07:35 +0000 |
847 | +++ Pyflakes/pyflakes/reporter.py 1970-01-01 00:00:00 +0000 |
848 | @@ -1,79 +0,0 @@ |
849 | -# (c) 2005-2012 Divmod, Inc. |
850 | -# See LICENSE file for details |
851 | - |
852 | -import sys |
853 | - |
854 | - |
855 | -class Reporter(object): |
856 | - """ |
857 | - Formats the results of pyflakes checks to users. |
858 | - """ |
859 | - |
860 | - def __init__(self, warningStream, errorStream): |
861 | - """ |
862 | - Construct a L{Reporter}. |
863 | - |
864 | - @param warningStream: A file-like object where warnings will be |
865 | - written to. The stream's C{write} method must accept unicode. |
866 | - C{sys.stdout} is a good value. |
867 | - @param errorStream: A file-like object where error output will be |
868 | - written to. The stream's C{write} method must accept unicode. |
869 | - C{sys.stderr} is a good value. |
870 | - """ |
871 | - self._stdout = warningStream |
872 | - self._stderr = errorStream |
873 | - |
874 | - |
875 | - def unexpectedError(self, filename, msg): |
876 | - """ |
877 | - An unexpected error occurred trying to process C{filename}. |
878 | - |
879 | - @param filename: The path to a file that we could not process. |
880 | - @ptype filename: C{unicode} |
881 | - @param msg: A message explaining the problem. |
882 | - @ptype msg: C{unicode} |
883 | - """ |
884 | - self._stderr.write(u"%s: %s\n" % (filename, msg)) |
885 | - |
886 | - |
887 | - def syntaxError(self, filename, msg, lineno, offset, text): |
888 | - """ |
889 | - There was a syntax errror in C{filename}. |
890 | - |
891 | - @param filename: The path to the file with the syntax error. |
892 | - @ptype filename: C{unicode} |
893 | - @param msg: An explanation of the syntax error. |
894 | - @ptype msg: C{unicode} |
895 | - @param lineno: The line number where the syntax error occurred. |
896 | - @ptype lineno: C{int} |
897 | - @param offset: The column on which the syntax error occurred. |
898 | - @ptype offset: C{int} |
899 | - @param text: The source code containing the syntax error. |
900 | - @ptype text: C{unicode} |
901 | - """ |
902 | - line = text.splitlines()[-1] |
903 | - if offset is not None: |
904 | - offset = offset - (len(text) - len(line)) |
905 | - self._stderr.write(u'%s:%d: %s\n' % (filename, lineno, msg)) |
906 | - self._stderr.write(line) |
907 | - self._stderr.write(u'\n') |
908 | - if offset is not None: |
909 | - self._stderr.write(u" " * (offset + 1) + u"^\n") |
910 | - |
911 | - |
912 | - def flake(self, message): |
913 | - """ |
914 | - pyflakes found something wrong with the code. |
915 | - |
916 | - @param: A L{pyflakes.messages.Message}. |
917 | - """ |
918 | - self._stdout.write(unicode(message)) |
919 | - self._stdout.write(u'\n') |
920 | - |
921 | - |
922 | - |
923 | -def _makeDefaultReporter(): |
924 | - """ |
925 | - Make a reporter that can be used when no reporter is specified. |
926 | - """ |
927 | - return Reporter(sys.stdout, sys.stderr) |
928 | |
929 | === removed directory 'Pyflakes/pyflakes/scripts' |
930 | === removed file 'Pyflakes/pyflakes/scripts/__init__.py' |
931 | === removed file 'Pyflakes/pyflakes/scripts/pyflakes.py' |
932 | --- Pyflakes/pyflakes/scripts/pyflakes.py 2012-10-23 11:48:54 +0000 |
933 | +++ Pyflakes/pyflakes/scripts/pyflakes.py 1970-01-01 00:00:00 +0000 |
934 | @@ -1,122 +0,0 @@ |
935 | -""" |
936 | -Implementation of the command-line I{pyflakes} tool. |
937 | -""" |
938 | - |
939 | -from __future__ import absolute_import |
940 | - |
941 | -import sys |
942 | -import os |
943 | -import _ast |
944 | - |
945 | -from pyflakes import checker |
946 | -from pyflakes import reporter as modReporter |
947 | - |
948 | - |
949 | -def check(codeString, filename, reporter=None): |
950 | - """ |
951 | - Check the Python source given by C{codeString} for flakes. |
952 | - |
953 | - @param codeString: The Python source to check. |
954 | - @type codeString: C{str} |
955 | - |
956 | - @param filename: The name of the file the source came from, used to report |
957 | - errors. |
958 | - @type filename: C{str} |
959 | - |
960 | - @param reporter: A L{Reporter} instance, where errors and warnings will be |
961 | - reported. |
962 | - |
963 | - @return: The number of warnings emitted. |
964 | - @rtype: C{int} |
965 | - """ |
966 | - if reporter is None: |
967 | - reporter = modReporter._makeDefaultReporter() |
968 | - # First, compile into an AST and handle syntax errors. |
969 | - try: |
970 | - tree = compile(codeString, filename, "exec", _ast.PyCF_ONLY_AST) |
971 | - except SyntaxError, value: |
972 | - msg = value.args[0] |
973 | - |
974 | - (lineno, offset, text) = value.lineno, value.offset, value.text |
975 | - |
976 | - # If there's an encoding problem with the file, the text is None. |
977 | - if text is None: |
978 | - # Avoid using msg, since for the only known case, it contains a |
979 | - # bogus message that claims the encoding the file declared was |
980 | - # unknown. |
981 | - reporter.unexpectedError(filename, u'problem decoding source') |
982 | - else: |
983 | - reporter.syntaxError(filename, msg, lineno, offset, text) |
984 | - return 1 |
985 | - else: |
986 | - # Okay, it's syntactically valid. Now check it. |
987 | - w = checker.Checker(tree, filename) |
988 | - w.messages.sort(lambda a, b: cmp(a.lineno, b.lineno)) |
989 | - for warning in w.messages: |
990 | - reporter.flake(warning) |
991 | - return len(w.messages) |
992 | - |
993 | - |
994 | -def checkPath(filename, reporter=None): |
995 | - """ |
996 | - Check the given path, printing out any warnings detected. |
997 | - |
998 | - @param reporter: A L{Reporter} instance, where errors and warnings will be |
999 | - reported. |
1000 | - |
1001 | - @return: the number of warnings printed |
1002 | - """ |
1003 | - if reporter is None: |
1004 | - reporter = modReporter._makeDefaultReporter() |
1005 | - try: |
1006 | - return check(file(filename, 'U').read() + '\n', filename, reporter) |
1007 | - except IOError, msg: |
1008 | - reporter.unexpectedError(filename, msg.args[1]) |
1009 | - return 1 |
1010 | - |
1011 | - |
1012 | - |
1013 | -def iterSourceCode(paths): |
1014 | - """ |
1015 | - Iterate over all Python source files in C{paths}. |
1016 | - |
1017 | - @param paths: A list of paths. Directories will be recursed into and |
1018 | - any .py files found will be yielded. Any non-directories will be |
1019 | - yielded as-is. |
1020 | - """ |
1021 | - for path in paths: |
1022 | - if os.path.isdir(path): |
1023 | - for dirpath, dirnames, filenames in os.walk(path): |
1024 | - for filename in filenames: |
1025 | - if filename.endswith('.py'): |
1026 | - yield os.path.join(dirpath, filename) |
1027 | - else: |
1028 | - yield path |
1029 | - |
1030 | - |
1031 | - |
1032 | -def checkRecursive(paths, reporter): |
1033 | - """ |
1034 | - Recursively check all source files in C{paths}. |
1035 | - |
1036 | - @param paths: A list of paths to Python source files and directories |
1037 | - containing Python source files. |
1038 | - @param reporter: A L{Reporter} where all of the warnings and errors |
1039 | - will be reported to. |
1040 | - @return: The number of warnings found. |
1041 | - """ |
1042 | - warnings = 0 |
1043 | - for sourcePath in iterSourceCode(paths): |
1044 | - warnings += checkPath(sourcePath, reporter) |
1045 | - return warnings |
1046 | - |
1047 | - |
1048 | - |
1049 | -def main(): |
1050 | - args = sys.argv[1:] |
1051 | - reporter = modReporter._makeDefaultReporter() |
1052 | - if args: |
1053 | - warnings = checkRecursive(args, reporter) |
1054 | - else: |
1055 | - warnings = check(sys.stdin.read(), '<stdin>', reporter) |
1056 | - raise SystemExit(warnings > 0) |
1057 | |
1058 | === removed directory 'Pyflakes/pyflakes/test' |
1059 | === removed file 'Pyflakes/pyflakes/test/__init__.py' |
1060 | === removed file 'Pyflakes/pyflakes/test/harness.py' |
1061 | --- Pyflakes/pyflakes/test/harness.py 2010-04-13 14:53:04 +0000 |
1062 | +++ Pyflakes/pyflakes/test/harness.py 1970-01-01 00:00:00 +0000 |
1063 | @@ -1,27 +0,0 @@ |
1064 | - |
1065 | -import textwrap |
1066 | -import _ast |
1067 | - |
1068 | -from twisted.trial import unittest |
1069 | - |
1070 | -from pyflakes import checker |
1071 | - |
1072 | - |
1073 | -class Test(unittest.TestCase): |
1074 | - |
1075 | - def flakes(self, input, *expectedOutputs, **kw): |
1076 | - ast = compile(textwrap.dedent(input), "<test>", "exec", |
1077 | - _ast.PyCF_ONLY_AST) |
1078 | - w = checker.Checker(ast, **kw) |
1079 | - outputs = [type(o) for o in w.messages] |
1080 | - expectedOutputs = list(expectedOutputs) |
1081 | - outputs.sort() |
1082 | - expectedOutputs.sort() |
1083 | - self.assert_(outputs == expectedOutputs, '''\ |
1084 | -for input: |
1085 | -%s |
1086 | -expected outputs: |
1087 | -%s |
1088 | -but got: |
1089 | -%s''' % (input, repr(expectedOutputs), '\n'.join([str(o) for o in w.messages]))) |
1090 | - return w |
1091 | |
1092 | === removed file 'Pyflakes/pyflakes/test/test_imports.py' |
1093 | --- Pyflakes/pyflakes/test/test_imports.py 2011-10-31 15:19:35 +0000 |
1094 | +++ Pyflakes/pyflakes/test/test_imports.py 1970-01-01 00:00:00 +0000 |
1095 | @@ -1,670 +0,0 @@ |
1096 | - |
1097 | -from sys import version_info |
1098 | - |
1099 | -from pyflakes import messages as m |
1100 | -from pyflakes.test import harness |
1101 | - |
1102 | -class Test(harness.Test): |
1103 | - |
1104 | - def test_unusedImport(self): |
1105 | - self.flakes('import fu, bar', m.UnusedImport, m.UnusedImport) |
1106 | - self.flakes('from baz import fu, bar', m.UnusedImport, m.UnusedImport) |
1107 | - |
1108 | - def test_aliasedImport(self): |
1109 | - self.flakes('import fu as FU, bar as FU', m.RedefinedWhileUnused, m.UnusedImport) |
1110 | - self.flakes('from moo import fu as FU, bar as FU', m.RedefinedWhileUnused, m.UnusedImport) |
1111 | - |
1112 | - def test_usedImport(self): |
1113 | - self.flakes('import fu; print fu') |
1114 | - self.flakes('from baz import fu; print fu') |
1115 | - |
1116 | - def test_redefinedWhileUnused(self): |
1117 | - self.flakes('import fu; fu = 3', m.RedefinedWhileUnused) |
1118 | - self.flakes('import fu; del fu', m.RedefinedWhileUnused) |
1119 | - self.flakes('import fu; fu, bar = 3', m.RedefinedWhileUnused) |
1120 | - self.flakes('import fu; [fu, bar] = 3', m.RedefinedWhileUnused) |
1121 | - |
1122 | - def test_redefinedByFunction(self): |
1123 | - self.flakes(''' |
1124 | - import fu |
1125 | - def fu(): |
1126 | - pass |
1127 | - ''', m.RedefinedWhileUnused) |
1128 | - |
1129 | - def test_redefinedInNestedFunction(self): |
1130 | - """ |
1131 | - Test that shadowing a global name with a nested function definition |
1132 | - generates a warning. |
1133 | - """ |
1134 | - self.flakes(''' |
1135 | - import fu |
1136 | - def bar(): |
1137 | - def baz(): |
1138 | - def fu(): |
1139 | - pass |
1140 | - ''', m.RedefinedWhileUnused, m.UnusedImport) |
1141 | - |
1142 | - def test_redefinedByClass(self): |
1143 | - self.flakes(''' |
1144 | - import fu |
1145 | - class fu: |
1146 | - pass |
1147 | - ''', m.RedefinedWhileUnused) |
1148 | - |
1149 | - |
1150 | - def test_redefinedBySubclass(self): |
1151 | - """ |
1152 | - If an imported name is redefined by a class statement which also uses |
1153 | - that name in the bases list, no warning is emitted. |
1154 | - """ |
1155 | - self.flakes(''' |
1156 | - from fu import bar |
1157 | - class bar(bar): |
1158 | - pass |
1159 | - ''') |
1160 | - |
1161 | - |
1162 | - def test_redefinedInClass(self): |
1163 | - """ |
1164 | - Test that shadowing a global with a class attribute does not produce a |
1165 | - warning. |
1166 | - """ |
1167 | - self.flakes(''' |
1168 | - import fu |
1169 | - class bar: |
1170 | - fu = 1 |
1171 | - print fu |
1172 | - ''') |
1173 | - |
1174 | - def test_usedInFunction(self): |
1175 | - self.flakes(''' |
1176 | - import fu |
1177 | - def fun(): |
1178 | - print fu |
1179 | - ''') |
1180 | - |
1181 | - def test_shadowedByParameter(self): |
1182 | - self.flakes(''' |
1183 | - import fu |
1184 | - def fun(fu): |
1185 | - print fu |
1186 | - ''', m.UnusedImport) |
1187 | - |
1188 | - self.flakes(''' |
1189 | - import fu |
1190 | - def fun(fu): |
1191 | - print fu |
1192 | - print fu |
1193 | - ''') |
1194 | - |
1195 | - def test_newAssignment(self): |
1196 | - self.flakes('fu = None') |
1197 | - |
1198 | - def test_usedInGetattr(self): |
1199 | - self.flakes('import fu; fu.bar.baz') |
1200 | - self.flakes('import fu; "bar".fu.baz', m.UnusedImport) |
1201 | - |
1202 | - def test_usedInSlice(self): |
1203 | - self.flakes('import fu; print fu.bar[1:]') |
1204 | - |
1205 | - def test_usedInIfBody(self): |
1206 | - self.flakes(''' |
1207 | - import fu |
1208 | - if True: print fu |
1209 | - ''') |
1210 | - |
1211 | - def test_usedInIfConditional(self): |
1212 | - self.flakes(''' |
1213 | - import fu |
1214 | - if fu: pass |
1215 | - ''') |
1216 | - |
1217 | - def test_usedInElifConditional(self): |
1218 | - self.flakes(''' |
1219 | - import fu |
1220 | - if False: pass |
1221 | - elif fu: pass |
1222 | - ''') |
1223 | - |
1224 | - def test_usedInElse(self): |
1225 | - self.flakes(''' |
1226 | - import fu |
1227 | - if False: pass |
1228 | - else: print fu |
1229 | - ''') |
1230 | - |
1231 | - def test_usedInCall(self): |
1232 | - self.flakes('import fu; fu.bar()') |
1233 | - |
1234 | - def test_usedInClass(self): |
1235 | - self.flakes(''' |
1236 | - import fu |
1237 | - class bar: |
1238 | - bar = fu |
1239 | - ''') |
1240 | - |
1241 | - def test_usedInClassBase(self): |
1242 | - self.flakes(''' |
1243 | - import fu |
1244 | - class bar(object, fu.baz): |
1245 | - pass |
1246 | - ''') |
1247 | - |
1248 | - def test_notUsedInNestedScope(self): |
1249 | - self.flakes(''' |
1250 | - import fu |
1251 | - def bleh(): |
1252 | - pass |
1253 | - print fu |
1254 | - ''') |
1255 | - |
1256 | - def test_usedInFor(self): |
1257 | - self.flakes(''' |
1258 | - import fu |
1259 | - for bar in range(9): |
1260 | - print fu |
1261 | - ''') |
1262 | - |
1263 | - def test_usedInForElse(self): |
1264 | - self.flakes(''' |
1265 | - import fu |
1266 | - for bar in range(10): |
1267 | - pass |
1268 | - else: |
1269 | - print fu |
1270 | - ''') |
1271 | - |
1272 | - def test_redefinedByFor(self): |
1273 | - self.flakes(''' |
1274 | - import fu |
1275 | - for fu in range(2): |
1276 | - pass |
1277 | - ''', m.RedefinedWhileUnused) |
1278 | - |
1279 | - def test_shadowedByFor(self): |
1280 | - """ |
1281 | - Test that shadowing a global name with a for loop variable generates a |
1282 | - warning. |
1283 | - """ |
1284 | - self.flakes(''' |
1285 | - import fu |
1286 | - fu.bar() |
1287 | - for fu in (): |
1288 | - pass |
1289 | - ''', m.ImportShadowedByLoopVar) |
1290 | - |
1291 | - def test_shadowedByForDeep(self): |
1292 | - """ |
1293 | - Test that shadowing a global name with a for loop variable nested in a |
1294 | - tuple unpack generates a warning. |
1295 | - """ |
1296 | - self.flakes(''' |
1297 | - import fu |
1298 | - fu.bar() |
1299 | - for (x, y, z, (a, b, c, (fu,))) in (): |
1300 | - pass |
1301 | - ''', m.ImportShadowedByLoopVar) |
1302 | - |
1303 | - def test_usedInReturn(self): |
1304 | - self.flakes(''' |
1305 | - import fu |
1306 | - def fun(): |
1307 | - return fu |
1308 | - ''') |
1309 | - |
1310 | - def test_usedInOperators(self): |
1311 | - self.flakes('import fu; 3 + fu.bar') |
1312 | - self.flakes('import fu; 3 % fu.bar') |
1313 | - self.flakes('import fu; 3 - fu.bar') |
1314 | - self.flakes('import fu; 3 * fu.bar') |
1315 | - self.flakes('import fu; 3 ** fu.bar') |
1316 | - self.flakes('import fu; 3 / fu.bar') |
1317 | - self.flakes('import fu; 3 // fu.bar') |
1318 | - self.flakes('import fu; -fu.bar') |
1319 | - self.flakes('import fu; ~fu.bar') |
1320 | - self.flakes('import fu; 1 == fu.bar') |
1321 | - self.flakes('import fu; 1 | fu.bar') |
1322 | - self.flakes('import fu; 1 & fu.bar') |
1323 | - self.flakes('import fu; 1 ^ fu.bar') |
1324 | - self.flakes('import fu; 1 >> fu.bar') |
1325 | - self.flakes('import fu; 1 << fu.bar') |
1326 | - |
1327 | - def test_usedInAssert(self): |
1328 | - self.flakes('import fu; assert fu.bar') |
1329 | - |
1330 | - def test_usedInSubscript(self): |
1331 | - self.flakes('import fu; fu.bar[1]') |
1332 | - |
1333 | - def test_usedInLogic(self): |
1334 | - self.flakes('import fu; fu and False') |
1335 | - self.flakes('import fu; fu or False') |
1336 | - self.flakes('import fu; not fu.bar') |
1337 | - |
1338 | - def test_usedInList(self): |
1339 | - self.flakes('import fu; [fu]') |
1340 | - |
1341 | - def test_usedInTuple(self): |
1342 | - self.flakes('import fu; (fu,)') |
1343 | - |
1344 | - def test_usedInTry(self): |
1345 | - self.flakes(''' |
1346 | - import fu |
1347 | - try: fu |
1348 | - except: pass |
1349 | - ''') |
1350 | - |
1351 | - def test_usedInExcept(self): |
1352 | - self.flakes(''' |
1353 | - import fu |
1354 | - try: fu |
1355 | - except: pass |
1356 | - ''') |
1357 | - |
1358 | - def test_redefinedByExcept(self): |
1359 | - self.flakes(''' |
1360 | - import fu |
1361 | - try: pass |
1362 | - except Exception, fu: pass |
1363 | - ''', m.RedefinedWhileUnused) |
1364 | - |
1365 | - def test_usedInRaise(self): |
1366 | - self.flakes(''' |
1367 | - import fu |
1368 | - raise fu.bar |
1369 | - ''') |
1370 | - |
1371 | - def test_usedInYield(self): |
1372 | - self.flakes(''' |
1373 | - import fu |
1374 | - def gen(): |
1375 | - yield fu |
1376 | - ''') |
1377 | - |
1378 | - def test_usedInDict(self): |
1379 | - self.flakes('import fu; {fu:None}') |
1380 | - self.flakes('import fu; {1:fu}') |
1381 | - |
1382 | - def test_usedInParameterDefault(self): |
1383 | - self.flakes(''' |
1384 | - import fu |
1385 | - def f(bar=fu): |
1386 | - pass |
1387 | - ''') |
1388 | - |
1389 | - def test_usedInAttributeAssign(self): |
1390 | - self.flakes('import fu; fu.bar = 1') |
1391 | - |
1392 | - def test_usedInKeywordArg(self): |
1393 | - self.flakes('import fu; fu.bar(stuff=fu)') |
1394 | - |
1395 | - def test_usedInAssignment(self): |
1396 | - self.flakes('import fu; bar=fu') |
1397 | - self.flakes('import fu; n=0; n+=fu') |
1398 | - |
1399 | - def test_usedInListComp(self): |
1400 | - self.flakes('import fu; [fu for _ in range(1)]') |
1401 | - self.flakes('import fu; [1 for _ in range(1) if fu]') |
1402 | - |
1403 | - def test_redefinedByListComp(self): |
1404 | - self.flakes('import fu; [1 for fu in range(1)]', m.RedefinedWhileUnused) |
1405 | - |
1406 | - |
1407 | - def test_usedInTryFinally(self): |
1408 | - self.flakes(''' |
1409 | - import fu |
1410 | - try: pass |
1411 | - finally: fu |
1412 | - ''') |
1413 | - |
1414 | - self.flakes(''' |
1415 | - import fu |
1416 | - try: fu |
1417 | - finally: pass |
1418 | - ''') |
1419 | - |
1420 | - def test_usedInWhile(self): |
1421 | - self.flakes(''' |
1422 | - import fu |
1423 | - while 0: |
1424 | - fu |
1425 | - ''') |
1426 | - |
1427 | - self.flakes(''' |
1428 | - import fu |
1429 | - while fu: pass |
1430 | - ''') |
1431 | - |
1432 | - def test_usedInGlobal(self): |
1433 | - self.flakes(''' |
1434 | - import fu |
1435 | - def f(): global fu |
1436 | - ''', m.UnusedImport) |
1437 | - |
1438 | - def test_usedInBackquote(self): |
1439 | - self.flakes('import fu; `fu`') |
1440 | - |
1441 | - def test_usedInExec(self): |
1442 | - self.flakes('import fu; exec "print 1" in fu.bar') |
1443 | - |
1444 | - def test_usedInLambda(self): |
1445 | - self.flakes('import fu; lambda: fu') |
1446 | - |
1447 | - def test_shadowedByLambda(self): |
1448 | - self.flakes('import fu; lambda fu: fu', m.UnusedImport) |
1449 | - |
1450 | - def test_usedInSliceObj(self): |
1451 | - self.flakes('import fu; "meow"[::fu]') |
1452 | - |
1453 | - def test_unusedInNestedScope(self): |
1454 | - self.flakes(''' |
1455 | - def bar(): |
1456 | - import fu |
1457 | - fu |
1458 | - ''', m.UnusedImport, m.UndefinedName) |
1459 | - |
1460 | - def test_methodsDontUseClassScope(self): |
1461 | - self.flakes(''' |
1462 | - class bar: |
1463 | - import fu |
1464 | - def fun(self): |
1465 | - fu |
1466 | - ''', m.UnusedImport, m.UndefinedName) |
1467 | - |
1468 | - def test_nestedFunctionsNestScope(self): |
1469 | - self.flakes(''' |
1470 | - def a(): |
1471 | - def b(): |
1472 | - fu |
1473 | - import fu |
1474 | - ''') |
1475 | - |
1476 | - def test_nestedClassAndFunctionScope(self): |
1477 | - self.flakes(''' |
1478 | - def a(): |
1479 | - import fu |
1480 | - class b: |
1481 | - def c(self): |
1482 | - print fu |
1483 | - ''') |
1484 | - |
1485 | - def test_importStar(self): |
1486 | - self.flakes('from fu import *', m.ImportStarUsed) |
1487 | - |
1488 | - |
1489 | - def test_packageImport(self): |
1490 | - """ |
1491 | - If a dotted name is imported and used, no warning is reported. |
1492 | - """ |
1493 | - self.flakes(''' |
1494 | - import fu.bar |
1495 | - fu.bar |
1496 | - ''') |
1497 | - |
1498 | - |
1499 | - def test_unusedPackageImport(self): |
1500 | - """ |
1501 | - If a dotted name is imported and not used, an unused import warning is |
1502 | - reported. |
1503 | - """ |
1504 | - self.flakes('import fu.bar', m.UnusedImport) |
1505 | - |
1506 | - |
1507 | - def test_duplicateSubmoduleImport(self): |
1508 | - """ |
1509 | - If a submodule of a package is imported twice, an unused import warning |
1510 | - and a redefined while unused warning are reported. |
1511 | - """ |
1512 | - self.flakes(''' |
1513 | - import fu.bar, fu.bar |
1514 | - fu.bar |
1515 | - ''', m.RedefinedWhileUnused) |
1516 | - self.flakes(''' |
1517 | - import fu.bar |
1518 | - import fu.bar |
1519 | - fu.bar |
1520 | - ''', m.RedefinedWhileUnused) |
1521 | - |
1522 | - |
1523 | - def test_differentSubmoduleImport(self): |
1524 | - """ |
1525 | - If two different submodules of a package are imported, no duplicate |
1526 | - import warning is reported for the package. |
1527 | - """ |
1528 | - self.flakes(''' |
1529 | - import fu.bar, fu.baz |
1530 | - fu.bar, fu.baz |
1531 | - ''') |
1532 | - self.flakes(''' |
1533 | - import fu.bar |
1534 | - import fu.baz |
1535 | - fu.bar, fu.baz |
1536 | - ''') |
1537 | - |
1538 | - def test_assignRHSFirst(self): |
1539 | - self.flakes('import fu; fu = fu') |
1540 | - self.flakes('import fu; fu, bar = fu') |
1541 | - self.flakes('import fu; [fu, bar] = fu') |
1542 | - self.flakes('import fu; fu += fu') |
1543 | - |
1544 | - def test_tryingMultipleImports(self): |
1545 | - self.flakes(''' |
1546 | - try: |
1547 | - import fu |
1548 | - except ImportError: |
1549 | - import bar as fu |
1550 | - ''') |
1551 | - test_tryingMultipleImports.todo = '' |
1552 | - |
1553 | - def test_nonGlobalDoesNotRedefine(self): |
1554 | - self.flakes(''' |
1555 | - import fu |
1556 | - def a(): |
1557 | - fu = 3 |
1558 | - return fu |
1559 | - fu |
1560 | - ''') |
1561 | - |
1562 | - def test_functionsRunLater(self): |
1563 | - self.flakes(''' |
1564 | - def a(): |
1565 | - fu |
1566 | - import fu |
1567 | - ''') |
1568 | - |
1569 | - def test_functionNamesAreBoundNow(self): |
1570 | - self.flakes(''' |
1571 | - import fu |
1572 | - def fu(): |
1573 | - fu |
1574 | - fu |
1575 | - ''', m.RedefinedWhileUnused) |
1576 | - |
1577 | - def test_importingForImportError(self): |
1578 | - self.flakes(''' |
1579 | - try: |
1580 | - import fu |
1581 | - except ImportError: |
1582 | - pass |
1583 | - ''') |
1584 | - test_importingForImportError.todo = '' |
1585 | - |
1586 | - def test_importedInClass(self): |
1587 | - '''Imports in class scope can be used through self''' |
1588 | - self.flakes(''' |
1589 | - class c: |
1590 | - import i |
1591 | - def __init__(self): |
1592 | - self.i |
1593 | - ''') |
1594 | - test_importedInClass.todo = 'requires evaluating attribute access' |
1595 | - |
1596 | - def test_futureImport(self): |
1597 | - '''__future__ is special''' |
1598 | - self.flakes('from __future__ import division') |
1599 | - self.flakes(''' |
1600 | - "docstring is allowed before future import" |
1601 | - from __future__ import division |
1602 | - ''') |
1603 | - |
1604 | - def test_futureImportFirst(self): |
1605 | - """ |
1606 | - __future__ imports must come before anything else. |
1607 | - """ |
1608 | - self.flakes(''' |
1609 | - x = 5 |
1610 | - from __future__ import division |
1611 | - ''', m.LateFutureImport) |
1612 | - self.flakes(''' |
1613 | - from foo import bar |
1614 | - from __future__ import division |
1615 | - bar |
1616 | - ''', m.LateFutureImport) |
1617 | - |
1618 | - |
1619 | - |
1620 | -class TestSpecialAll(harness.Test): |
1621 | - """ |
1622 | - Tests for suppression of unused import warnings by C{__all__}. |
1623 | - """ |
1624 | - def test_ignoredInFunction(self): |
1625 | - """ |
1626 | - An C{__all__} definition does not suppress unused import warnings in a |
1627 | - function scope. |
1628 | - """ |
1629 | - self.flakes(''' |
1630 | - def foo(): |
1631 | - import bar |
1632 | - __all__ = ["bar"] |
1633 | - ''', m.UnusedImport, m.UnusedVariable) |
1634 | - |
1635 | - |
1636 | - def test_ignoredInClass(self): |
1637 | - """ |
1638 | - An C{__all__} definition does not suppress unused import warnings in a |
1639 | - class scope. |
1640 | - """ |
1641 | - self.flakes(''' |
1642 | - class foo: |
1643 | - import bar |
1644 | - __all__ = ["bar"] |
1645 | - ''', m.UnusedImport) |
1646 | - |
1647 | - |
1648 | - def test_warningSuppressed(self): |
1649 | - """ |
1650 | - If a name is imported and unused but is named in C{__all__}, no warning |
1651 | - is reported. |
1652 | - """ |
1653 | - self.flakes(''' |
1654 | - import foo |
1655 | - __all__ = ["foo"] |
1656 | - ''') |
1657 | - |
1658 | - |
1659 | - def test_unrecognizable(self): |
1660 | - """ |
1661 | - If C{__all__} is defined in a way that can't be recognized statically, |
1662 | - it is ignored. |
1663 | - """ |
1664 | - self.flakes(''' |
1665 | - import foo |
1666 | - __all__ = ["f" + "oo"] |
1667 | - ''', m.UnusedImport) |
1668 | - self.flakes(''' |
1669 | - import foo |
1670 | - __all__ = [] + ["foo"] |
1671 | - ''', m.UnusedImport) |
1672 | - |
1673 | - |
1674 | - def test_unboundExported(self): |
1675 | - """ |
1676 | - If C{__all__} includes a name which is not bound, a warning is emitted. |
1677 | - """ |
1678 | - self.flakes(''' |
1679 | - __all__ = ["foo"] |
1680 | - ''', m.UndefinedExport) |
1681 | - |
1682 | - # Skip this in __init__.py though, since the rules there are a little |
1683 | - # different. |
1684 | - for filename in ["foo/__init__.py", "__init__.py"]: |
1685 | - self.flakes(''' |
1686 | - __all__ = ["foo"] |
1687 | - ''', filename=filename) |
1688 | - |
1689 | - |
1690 | - def test_usedInGenExp(self): |
1691 | - """ |
1692 | - Using a global in a generator expression results in no warnings. |
1693 | - """ |
1694 | - self.flakes('import fu; (fu for _ in range(1))') |
1695 | - self.flakes('import fu; (1 for _ in range(1) if fu)') |
1696 | - |
1697 | - |
1698 | - def test_redefinedByGenExp(self): |
1699 | - """ |
1700 | - Re-using a global name as the loop variable for a generator |
1701 | - expression results in a redefinition warning. |
1702 | - """ |
1703 | - self.flakes('import fu; (1 for fu in range(1))', m.RedefinedWhileUnused) |
1704 | - |
1705 | - |
1706 | - def test_usedAsDecorator(self): |
1707 | - """ |
1708 | - Using a global name in a decorator statement results in no warnings, |
1709 | - but using an undefined name in a decorator statement results in an |
1710 | - undefined name warning. |
1711 | - """ |
1712 | - self.flakes(''' |
1713 | - from interior import decorate |
1714 | - @decorate |
1715 | - def f(): |
1716 | - return "hello" |
1717 | - ''') |
1718 | - |
1719 | - self.flakes(''' |
1720 | - from interior import decorate |
1721 | - @decorate('value') |
1722 | - def f(): |
1723 | - return "hello" |
1724 | - ''') |
1725 | - |
1726 | - self.flakes(''' |
1727 | - @decorate |
1728 | - def f(): |
1729 | - return "hello" |
1730 | - ''', m.UndefinedName) |
1731 | - |
1732 | - |
1733 | -class Python26Tests(harness.Test): |
1734 | - """ |
1735 | - Tests for checking of syntax which is valid in PYthon 2.6 and newer. |
1736 | - """ |
1737 | - if version_info < (2, 6): |
1738 | - skip = "Python 2.6 required for class decorator tests." |
1739 | - |
1740 | - |
1741 | - def test_usedAsClassDecorator(self): |
1742 | - """ |
1743 | - Using an imported name as a class decorator results in no warnings, |
1744 | - but using an undefined name as a class decorator results in an |
1745 | - undefined name warning. |
1746 | - """ |
1747 | - self.flakes(''' |
1748 | - from interior import decorate |
1749 | - @decorate |
1750 | - class foo: |
1751 | - pass |
1752 | - ''') |
1753 | - |
1754 | - self.flakes(''' |
1755 | - from interior import decorate |
1756 | - @decorate("foo") |
1757 | - class bar: |
1758 | - pass |
1759 | - ''') |
1760 | - |
1761 | - self.flakes(''' |
1762 | - @decorate |
1763 | - class foo: |
1764 | - pass |
1765 | - ''', m.UndefinedName) |
1766 | |
1767 | === removed file 'Pyflakes/pyflakes/test/test_other.py' |
1768 | --- Pyflakes/pyflakes/test/test_other.py 2011-11-17 16:21:58 +0000 |
1769 | +++ Pyflakes/pyflakes/test/test_other.py 1970-01-01 00:00:00 +0000 |
1770 | @@ -1,654 +0,0 @@ |
1771 | -# (c) 2005-2010 Divmod, Inc. |
1772 | -# See LICENSE file for details |
1773 | - |
1774 | -""" |
1775 | -Tests for various Pyflakes behavior. |
1776 | -""" |
1777 | - |
1778 | -from sys import version_info |
1779 | - |
1780 | -from pyflakes import messages as m |
1781 | -from pyflakes.test import harness |
1782 | - |
1783 | - |
1784 | -class Test(harness.Test): |
1785 | - |
1786 | - def test_duplicateArgs(self): |
1787 | - self.flakes('def fu(bar, bar): pass', m.DuplicateArgument) |
1788 | - |
1789 | - def test_localReferencedBeforeAssignment(self): |
1790 | - self.flakes(''' |
1791 | - a = 1 |
1792 | - def f(): |
1793 | - a; a=1 |
1794 | - f() |
1795 | - ''', m.UndefinedName) |
1796 | - test_localReferencedBeforeAssignment.todo = 'this requires finding all assignments in the function body first' |
1797 | - |
1798 | - def test_redefinedFunction(self): |
1799 | - """ |
1800 | - Test that shadowing a function definition with another one raises a |
1801 | - warning. |
1802 | - """ |
1803 | - self.flakes(''' |
1804 | - def a(): pass |
1805 | - def a(): pass |
1806 | - ''', m.RedefinedWhileUnused) |
1807 | - |
1808 | - def test_redefinedClassFunction(self): |
1809 | - """ |
1810 | - Test that shadowing a function definition in a class suite with another |
1811 | - one raises a warning. |
1812 | - """ |
1813 | - self.flakes(''' |
1814 | - class A: |
1815 | - def a(): pass |
1816 | - def a(): pass |
1817 | - ''', m.RedefinedWhileUnused) |
1818 | - |
1819 | - def test_functionDecorator(self): |
1820 | - """ |
1821 | - Test that shadowing a function definition with a decorated version of |
1822 | - that function does not raise a warning. |
1823 | - """ |
1824 | - self.flakes(''' |
1825 | - from somewhere import somedecorator |
1826 | - |
1827 | - def a(): pass |
1828 | - a = somedecorator(a) |
1829 | - ''') |
1830 | - |
1831 | - def test_classFunctionDecorator(self): |
1832 | - """ |
1833 | - Test that shadowing a function definition in a class suite with a |
1834 | - decorated version of that function does not raise a warning. |
1835 | - """ |
1836 | - self.flakes(''' |
1837 | - class A: |
1838 | - def a(): pass |
1839 | - a = classmethod(a) |
1840 | - ''') |
1841 | - |
1842 | - def test_unaryPlus(self): |
1843 | - '''Don't die on unary +''' |
1844 | - self.flakes('+1') |
1845 | - |
1846 | - |
1847 | - def test_undefinedBaseClass(self): |
1848 | - """ |
1849 | - If a name in the base list of a class definition is undefined, a |
1850 | - warning is emitted. |
1851 | - """ |
1852 | - self.flakes(''' |
1853 | - class foo(foo): |
1854 | - pass |
1855 | - ''', m.UndefinedName) |
1856 | - |
1857 | - |
1858 | - def test_classNameUndefinedInClassBody(self): |
1859 | - """ |
1860 | - If a class name is used in the body of that class's definition and |
1861 | - the name is not already defined, a warning is emitted. |
1862 | - """ |
1863 | - self.flakes(''' |
1864 | - class foo: |
1865 | - foo |
1866 | - ''', m.UndefinedName) |
1867 | - |
1868 | - |
1869 | - def test_classNameDefinedPreviously(self): |
1870 | - """ |
1871 | - If a class name is used in the body of that class's definition and |
1872 | - the name was previously defined in some other way, no warning is |
1873 | - emitted. |
1874 | - """ |
1875 | - self.flakes(''' |
1876 | - foo = None |
1877 | - class foo: |
1878 | - foo |
1879 | - ''') |
1880 | - |
1881 | - |
1882 | - def test_classRedefinition(self): |
1883 | - """ |
1884 | - If a class is defined twice in the same module, a warning is emitted. |
1885 | - """ |
1886 | - self.flakes( |
1887 | - ''' |
1888 | - class Foo: |
1889 | - pass |
1890 | - class Foo: |
1891 | - pass |
1892 | - ''', m.RedefinedWhileUnused) |
1893 | - |
1894 | - |
1895 | - def test_functionRedefinedAsClass(self): |
1896 | - """ |
1897 | - If a function is redefined as a class, a warning is emitted. |
1898 | - """ |
1899 | - self.flakes( |
1900 | - ''' |
1901 | - def Foo(): |
1902 | - pass |
1903 | - class Foo: |
1904 | - pass |
1905 | - ''', m.RedefinedWhileUnused) |
1906 | - |
1907 | - |
1908 | - def test_classRedefinedAsFunction(self): |
1909 | - """ |
1910 | - If a class is redefined as a function, a warning is emitted. |
1911 | - """ |
1912 | - self.flakes( |
1913 | - ''' |
1914 | - class Foo: |
1915 | - pass |
1916 | - def Foo(): |
1917 | - pass |
1918 | - ''', m.RedefinedWhileUnused) |
1919 | - |
1920 | - |
1921 | - def test_doubleAssignment(self): |
1922 | - """ |
1923 | - If a variable is re-assigned to without being used, no warning is |
1924 | - emitted. |
1925 | - """ |
1926 | - self.flakes( |
1927 | - ''' |
1928 | - x = 10 |
1929 | - x = 20 |
1930 | - ''', m.RedefinedWhileUnused) |
1931 | - test_doubleAssignment.todo = ( |
1932 | - "Too hard to make this warn but other cases stay silent") |
1933 | - |
1934 | - |
1935 | - def test_doubleAssignmentConditionally(self): |
1936 | - """ |
1937 | - If a variable is re-assigned within a conditional, no warning is |
1938 | - emitted. |
1939 | - """ |
1940 | - self.flakes( |
1941 | - ''' |
1942 | - x = 10 |
1943 | - if True: |
1944 | - x = 20 |
1945 | - ''') |
1946 | - |
1947 | - |
1948 | - def test_doubleAssignmentWithUse(self): |
1949 | - """ |
1950 | - If a variable is re-assigned to after being used, no warning is |
1951 | - emitted. |
1952 | - """ |
1953 | - self.flakes( |
1954 | - ''' |
1955 | - x = 10 |
1956 | - y = x * 2 |
1957 | - x = 20 |
1958 | - ''') |
1959 | - |
1960 | - |
1961 | - def test_comparison(self): |
1962 | - """ |
1963 | - If a defined name is used on either side of any of the six comparison |
1964 | - operators, no warning is emitted. |
1965 | - """ |
1966 | - self.flakes(''' |
1967 | - x = 10 |
1968 | - y = 20 |
1969 | - x < y |
1970 | - x <= y |
1971 | - x == y |
1972 | - x != y |
1973 | - x >= y |
1974 | - x > y |
1975 | - ''') |
1976 | - |
1977 | - |
1978 | - def test_identity(self): |
1979 | - """ |
1980 | - If a defined name is used on either side of an identity test, no |
1981 | - warning is emitted. |
1982 | - """ |
1983 | - self.flakes(''' |
1984 | - x = 10 |
1985 | - y = 20 |
1986 | - x is y |
1987 | - x is not y |
1988 | - ''') |
1989 | - |
1990 | - |
1991 | - def test_containment(self): |
1992 | - """ |
1993 | - If a defined name is used on either side of a containment test, no |
1994 | - warning is emitted. |
1995 | - """ |
1996 | - self.flakes(''' |
1997 | - x = 10 |
1998 | - y = 20 |
1999 | - x in y |
2000 | - x not in y |
2001 | - ''') |
2002 | - |
2003 | - |
2004 | - def test_loopControl(self): |
2005 | - """ |
2006 | - break and continue statements are supported. |
2007 | - """ |
2008 | - self.flakes(''' |
2009 | - for x in [1, 2]: |
2010 | - break |
2011 | - ''') |
2012 | - self.flakes(''' |
2013 | - for x in [1, 2]: |
2014 | - continue |
2015 | - ''') |
2016 | - |
2017 | - |
2018 | - def test_ellipsis(self): |
2019 | - """ |
2020 | - Ellipsis in a slice is supported. |
2021 | - """ |
2022 | - self.flakes(''' |
2023 | - [1, 2][...] |
2024 | - ''') |
2025 | - |
2026 | - |
2027 | - def test_extendedSlice(self): |
2028 | - """ |
2029 | - Extended slices are supported. |
2030 | - """ |
2031 | - self.flakes(''' |
2032 | - x = 3 |
2033 | - [1, 2][x,:] |
2034 | - ''') |
2035 | - |
2036 | - |
2037 | - |
2038 | -class TestUnusedAssignment(harness.Test): |
2039 | - """ |
2040 | - Tests for warning about unused assignments. |
2041 | - """ |
2042 | - |
2043 | - def test_unusedVariable(self): |
2044 | - """ |
2045 | - Warn when a variable in a function is assigned a value that's never |
2046 | - used. |
2047 | - """ |
2048 | - self.flakes(''' |
2049 | - def a(): |
2050 | - b = 1 |
2051 | - ''', m.UnusedVariable) |
2052 | - |
2053 | - |
2054 | - def test_assignToGlobal(self): |
2055 | - """ |
2056 | - Assigning to a global and then not using that global is perfectly |
2057 | - acceptable. Do not mistake it for an unused local variable. |
2058 | - """ |
2059 | - self.flakes(''' |
2060 | - b = 0 |
2061 | - def a(): |
2062 | - global b |
2063 | - b = 1 |
2064 | - ''') |
2065 | - |
2066 | - |
2067 | - def test_assignToMember(self): |
2068 | - """ |
2069 | - Assigning to a member of another object and then not using that member |
2070 | - variable is perfectly acceptable. Do not mistake it for an unused |
2071 | - local variable. |
2072 | - """ |
2073 | - # XXX: Adding this test didn't generate a failure. Maybe not |
2074 | - # necessary? |
2075 | - self.flakes(''' |
2076 | - class b: |
2077 | - pass |
2078 | - def a(): |
2079 | - b.foo = 1 |
2080 | - ''') |
2081 | - |
2082 | - |
2083 | - def test_assignInForLoop(self): |
2084 | - """ |
2085 | - Don't warn when a variable in a for loop is assigned to but not used. |
2086 | - """ |
2087 | - self.flakes(''' |
2088 | - def f(): |
2089 | - for i in range(10): |
2090 | - pass |
2091 | - ''') |
2092 | - |
2093 | - |
2094 | - def test_assignInListComprehension(self): |
2095 | - """ |
2096 | - Don't warn when a variable in a list comprehension is assigned to but |
2097 | - not used. |
2098 | - """ |
2099 | - self.flakes(''' |
2100 | - def f(): |
2101 | - [None for i in range(10)] |
2102 | - ''') |
2103 | - |
2104 | - |
2105 | - def test_generatorExpression(self): |
2106 | - """ |
2107 | - Don't warn when a variable in a generator expression is assigned to but not used. |
2108 | - """ |
2109 | - self.flakes(''' |
2110 | - def f(): |
2111 | - (None for i in range(10)) |
2112 | - ''') |
2113 | - |
2114 | - |
2115 | - def test_assignmentInsideLoop(self): |
2116 | - """ |
2117 | - Don't warn when a variable assignment occurs lexically after its use. |
2118 | - """ |
2119 | - self.flakes(''' |
2120 | - def f(): |
2121 | - x = None |
2122 | - for i in range(10): |
2123 | - if i > 2: |
2124 | - return x |
2125 | - x = i * 2 |
2126 | - ''') |
2127 | - |
2128 | - |
2129 | - def test_tupleUnpacking(self): |
2130 | - """ |
2131 | - Don't warn when a variable included in tuple unpacking is unused. It's |
2132 | - very common for variables in a tuple unpacking assignment to be unused |
2133 | - in good Python code, so warning will only create false positives. |
2134 | - """ |
2135 | - self.flakes(''' |
2136 | - def f(): |
2137 | - (x, y) = 1, 2 |
2138 | - ''') |
2139 | - |
2140 | - |
2141 | - def test_listUnpacking(self): |
2142 | - """ |
2143 | - Don't warn when a variable included in list unpacking is unused. |
2144 | - """ |
2145 | - self.flakes(''' |
2146 | - def f(): |
2147 | - [x, y] = [1, 2] |
2148 | - ''') |
2149 | - |
2150 | - |
2151 | - def test_closedOver(self): |
2152 | - """ |
2153 | - Don't warn when the assignment is used in an inner function. |
2154 | - """ |
2155 | - self.flakes(''' |
2156 | - def barMaker(): |
2157 | - foo = 5 |
2158 | - def bar(): |
2159 | - return foo |
2160 | - return bar |
2161 | - ''') |
2162 | - |
2163 | - |
2164 | - def test_doubleClosedOver(self): |
2165 | - """ |
2166 | - Don't warn when the assignment is used in an inner function, even if |
2167 | - that inner function itself is in an inner function. |
2168 | - """ |
2169 | - self.flakes(''' |
2170 | - def barMaker(): |
2171 | - foo = 5 |
2172 | - def bar(): |
2173 | - def baz(): |
2174 | - return foo |
2175 | - return bar |
2176 | - ''') |
2177 | - |
2178 | - |
2179 | - |
2180 | -class Python25Test(harness.Test): |
2181 | - """ |
2182 | - Tests for checking of syntax only available in Python 2.5 and newer. |
2183 | - """ |
2184 | - if version_info < (2, 5): |
2185 | - skip = "Python 2.5 required for if-else and with tests" |
2186 | - |
2187 | - def test_ifexp(self): |
2188 | - """ |
2189 | - Test C{foo if bar else baz} statements. |
2190 | - """ |
2191 | - self.flakes("a = 'moo' if True else 'oink'") |
2192 | - self.flakes("a = foo if True else 'oink'", m.UndefinedName) |
2193 | - self.flakes("a = 'moo' if True else bar", m.UndefinedName) |
2194 | - |
2195 | - |
2196 | - def test_withStatementNoNames(self): |
2197 | - """ |
2198 | - No warnings are emitted for using inside or after a nameless C{with} |
2199 | - statement a name defined beforehand. |
2200 | - """ |
2201 | - self.flakes(''' |
2202 | - from __future__ import with_statement |
2203 | - bar = None |
2204 | - with open("foo"): |
2205 | - bar |
2206 | - bar |
2207 | - ''') |
2208 | - |
2209 | - def test_withStatementSingleName(self): |
2210 | - """ |
2211 | - No warnings are emitted for using a name defined by a C{with} statement |
2212 | - within the suite or afterwards. |
2213 | - """ |
2214 | - self.flakes(''' |
2215 | - from __future__ import with_statement |
2216 | - with open('foo') as bar: |
2217 | - bar |
2218 | - bar |
2219 | - ''') |
2220 | - |
2221 | - |
2222 | - def test_withStatementAttributeName(self): |
2223 | - """ |
2224 | - No warnings are emitted for using an attribute as the target of a |
2225 | - C{with} statement. |
2226 | - """ |
2227 | - self.flakes(''' |
2228 | - from __future__ import with_statement |
2229 | - import foo |
2230 | - with open('foo') as foo.bar: |
2231 | - pass |
2232 | - ''') |
2233 | - |
2234 | - |
2235 | - def test_withStatementSubscript(self): |
2236 | - """ |
2237 | - No warnings are emitted for using a subscript as the target of a |
2238 | - C{with} statement. |
2239 | - """ |
2240 | - self.flakes(''' |
2241 | - from __future__ import with_statement |
2242 | - import foo |
2243 | - with open('foo') as foo[0]: |
2244 | - pass |
2245 | - ''') |
2246 | - |
2247 | - |
2248 | - def test_withStatementSubscriptUndefined(self): |
2249 | - """ |
2250 | - An undefined name warning is emitted if the subscript used as the |
2251 | - target of a C{with} statement is not defined. |
2252 | - """ |
2253 | - self.flakes(''' |
2254 | - from __future__ import with_statement |
2255 | - import foo |
2256 | - with open('foo') as foo[bar]: |
2257 | - pass |
2258 | - ''', m.UndefinedName) |
2259 | - |
2260 | - |
2261 | - def test_withStatementTupleNames(self): |
2262 | - """ |
2263 | - No warnings are emitted for using any of the tuple of names defined by |
2264 | - a C{with} statement within the suite or afterwards. |
2265 | - """ |
2266 | - self.flakes(''' |
2267 | - from __future__ import with_statement |
2268 | - with open('foo') as (bar, baz): |
2269 | - bar, baz |
2270 | - bar, baz |
2271 | - ''') |
2272 | - |
2273 | - |
2274 | - def test_withStatementListNames(self): |
2275 | - """ |
2276 | - No warnings are emitted for using any of the list of names defined by a |
2277 | - C{with} statement within the suite or afterwards. |
2278 | - """ |
2279 | - self.flakes(''' |
2280 | - from __future__ import with_statement |
2281 | - with open('foo') as [bar, baz]: |
2282 | - bar, baz |
2283 | - bar, baz |
2284 | - ''') |
2285 | - |
2286 | - |
2287 | - def test_withStatementComplicatedTarget(self): |
2288 | - """ |
2289 | - If the target of a C{with} statement uses any or all of the valid forms |
2290 | - for that part of the grammar (See |
2291 | - U{http://docs.python.org/reference/compound_stmts.html#the-with-statement}), |
2292 | - the names involved are checked both for definedness and any bindings |
2293 | - created are respected in the suite of the statement and afterwards. |
2294 | - """ |
2295 | - self.flakes(''' |
2296 | - from __future__ import with_statement |
2297 | - c = d = e = g = h = i = None |
2298 | - with open('foo') as [(a, b), c[d], e.f, g[h:i]]: |
2299 | - a, b, c, d, e, g, h, i |
2300 | - a, b, c, d, e, g, h, i |
2301 | - ''') |
2302 | - |
2303 | - |
2304 | - def test_withStatementSingleNameUndefined(self): |
2305 | - """ |
2306 | - An undefined name warning is emitted if the name first defined by a |
2307 | - C{with} statement is used before the C{with} statement. |
2308 | - """ |
2309 | - self.flakes(''' |
2310 | - from __future__ import with_statement |
2311 | - bar |
2312 | - with open('foo') as bar: |
2313 | - pass |
2314 | - ''', m.UndefinedName) |
2315 | - |
2316 | - |
2317 | - def test_withStatementTupleNamesUndefined(self): |
2318 | - """ |
2319 | - An undefined name warning is emitted if a name first defined by a the |
2320 | - tuple-unpacking form of the C{with} statement is used before the |
2321 | - C{with} statement. |
2322 | - """ |
2323 | - self.flakes(''' |
2324 | - from __future__ import with_statement |
2325 | - baz |
2326 | - with open('foo') as (bar, baz): |
2327 | - pass |
2328 | - ''', m.UndefinedName) |
2329 | - |
2330 | - |
2331 | - def test_withStatementSingleNameRedefined(self): |
2332 | - """ |
2333 | - A redefined name warning is emitted if a name bound by an import is |
2334 | - rebound by the name defined by a C{with} statement. |
2335 | - """ |
2336 | - self.flakes(''' |
2337 | - from __future__ import with_statement |
2338 | - import bar |
2339 | - with open('foo') as bar: |
2340 | - pass |
2341 | - ''', m.RedefinedWhileUnused) |
2342 | - |
2343 | - |
2344 | - def test_withStatementTupleNamesRedefined(self): |
2345 | - """ |
2346 | - A redefined name warning is emitted if a name bound by an import is |
2347 | - rebound by one of the names defined by the tuple-unpacking form of a |
2348 | - C{with} statement. |
2349 | - """ |
2350 | - self.flakes(''' |
2351 | - from __future__ import with_statement |
2352 | - import bar |
2353 | - with open('foo') as (bar, baz): |
2354 | - pass |
2355 | - ''', m.RedefinedWhileUnused) |
2356 | - |
2357 | - |
2358 | - def test_withStatementUndefinedInside(self): |
2359 | - """ |
2360 | - An undefined name warning is emitted if a name is used inside the |
2361 | - body of a C{with} statement without first being bound. |
2362 | - """ |
2363 | - self.flakes(''' |
2364 | - from __future__ import with_statement |
2365 | - with open('foo') as bar: |
2366 | - baz |
2367 | - ''', m.UndefinedName) |
2368 | - |
2369 | - |
2370 | - def test_withStatementNameDefinedInBody(self): |
2371 | - """ |
2372 | - A name defined in the body of a C{with} statement can be used after |
2373 | - the body ends without warning. |
2374 | - """ |
2375 | - self.flakes(''' |
2376 | - from __future__ import with_statement |
2377 | - with open('foo') as bar: |
2378 | - baz = 10 |
2379 | - baz |
2380 | - ''') |
2381 | - |
2382 | - |
2383 | - def test_withStatementUndefinedInExpression(self): |
2384 | - """ |
2385 | - An undefined name warning is emitted if a name in the I{test} |
2386 | - expression of a C{with} statement is undefined. |
2387 | - """ |
2388 | - self.flakes(''' |
2389 | - from __future__ import with_statement |
2390 | - with bar as baz: |
2391 | - pass |
2392 | - ''', m.UndefinedName) |
2393 | - |
2394 | - self.flakes(''' |
2395 | - from __future__ import with_statement |
2396 | - with bar as bar: |
2397 | - pass |
2398 | - ''', m.UndefinedName) |
2399 | - |
2400 | - |
2401 | - |
2402 | -class Python27Test(harness.Test): |
2403 | - """ |
2404 | - Tests for checking of syntax only available in Python 2.7 and newer. |
2405 | - """ |
2406 | - if version_info < (2, 7): |
2407 | - skip = "Python 2.7 required for dict/set comprehension tests" |
2408 | - |
2409 | - def test_dictComprehension(self): |
2410 | - """ |
2411 | - Dict comprehensions are properly handled. |
2412 | - """ |
2413 | - self.flakes(''' |
2414 | - a = {1: x for x in range(10)} |
2415 | - ''') |
2416 | - |
2417 | - def test_setComprehensionAndLiteral(self): |
2418 | - """ |
2419 | - Set comprehensions are properly handled. |
2420 | - """ |
2421 | - self.flakes(''' |
2422 | - a = {1, 2, 3} |
2423 | - b = {x for x in range(10)} |
2424 | - ''') |
2425 | |
2426 | === removed file 'Pyflakes/pyflakes/test/test_script.py' |
2427 | --- Pyflakes/pyflakes/test/test_script.py 2012-10-23 11:52:32 +0000 |
2428 | +++ Pyflakes/pyflakes/test/test_script.py 1970-01-01 00:00:00 +0000 |
2429 | @@ -1,563 +0,0 @@ |
2430 | -""" |
2431 | -Tests for L{pyflakes.scripts.pyflakes}. |
2432 | -""" |
2433 | - |
2434 | -import os |
2435 | -import sys |
2436 | -from StringIO import StringIO |
2437 | - |
2438 | -from twisted.internet import protocol |
2439 | -from twisted.internet.utils import ( |
2440 | - _callProtocolWithDeferred, |
2441 | - getProcessOutputAndValue, |
2442 | - ) |
2443 | -from twisted.python.filepath import FilePath |
2444 | -from twisted.trial.unittest import TestCase |
2445 | - |
2446 | -from pyflakes.messages import UnusedImport |
2447 | -from pyflakes.reporter import Reporter |
2448 | -from pyflakes.scripts.pyflakes import ( |
2449 | - checkPath, |
2450 | - checkRecursive, |
2451 | - iterSourceCode, |
2452 | - ) |
2453 | - |
2454 | - |
2455 | -def withStderrTo(stderr, f, *args, **kwargs): |
2456 | - """ |
2457 | - Call C{f} with C{sys.stderr} redirected to C{stderr}. |
2458 | - """ |
2459 | - (outer, sys.stderr) = (sys.stderr, stderr) |
2460 | - try: |
2461 | - return f(*args, **kwargs) |
2462 | - finally: |
2463 | - sys.stderr = outer |
2464 | - |
2465 | - |
2466 | - |
2467 | -class LoggingReporter(object): |
2468 | - """ |
2469 | - Implementation of Reporter that just appends any errors to a list. |
2470 | - """ |
2471 | - |
2472 | - def __init__(self, log): |
2473 | - """ |
2474 | - Construct a C{LoggingReporter}. |
2475 | - |
2476 | - @param log: A list to append log messages to. |
2477 | - """ |
2478 | - self.log = log |
2479 | - |
2480 | - |
2481 | - def flake(self, message): |
2482 | - self.log.append(('flake', str(message))) |
2483 | - |
2484 | - |
2485 | - def unexpectedError(self, filename, message): |
2486 | - self.log.append(('unexpectedError', filename, message)) |
2487 | - |
2488 | - |
2489 | - def syntaxError(self, filename, msg, lineno, offset, line): |
2490 | - self.log.append(('syntaxError', filename, msg, lineno, offset, line)) |
2491 | - |
2492 | - |
2493 | - |
2494 | -class TestIterSourceCode(TestCase): |
2495 | - """ |
2496 | - Tests for L{iterSourceCode}. |
2497 | - """ |
2498 | - |
2499 | - def test_emptyDirectory(self): |
2500 | - """ |
2501 | - There are no Python files in an empty directory. |
2502 | - """ |
2503 | - tempdir = FilePath(self.mktemp()) |
2504 | - tempdir.createDirectory() |
2505 | - self.assertEqual(list(iterSourceCode([tempdir.path])), []) |
2506 | - |
2507 | - |
2508 | - def test_singleFile(self): |
2509 | - """ |
2510 | - If the directory contains one Python file, C{iterSourceCode} will find |
2511 | - it. |
2512 | - """ |
2513 | - tempdir = FilePath(self.mktemp()) |
2514 | - tempdir.createDirectory() |
2515 | - tempdir.child('foo.py').touch() |
2516 | - self.assertEqual( |
2517 | - list(iterSourceCode([tempdir.path])), |
2518 | - [tempdir.child('foo.py').path]) |
2519 | - |
2520 | - |
2521 | - def test_onlyPythonSource(self): |
2522 | - """ |
2523 | - Files that are not Python source files are not included. |
2524 | - """ |
2525 | - tempdir = FilePath(self.mktemp()) |
2526 | - tempdir.createDirectory() |
2527 | - tempdir.child('foo.pyc').touch() |
2528 | - self.assertEqual(list(iterSourceCode([tempdir.path])), []) |
2529 | - |
2530 | - |
2531 | - def test_recurses(self): |
2532 | - """ |
2533 | - If the Python files are hidden deep down in child directories, we will |
2534 | - find them. |
2535 | - """ |
2536 | - tempdir = FilePath(self.mktemp()) |
2537 | - tempdir.createDirectory() |
2538 | - tempdir.child('foo').createDirectory() |
2539 | - tempdir.child('foo').child('a.py').touch() |
2540 | - tempdir.child('bar').createDirectory() |
2541 | - tempdir.child('bar').child('b.py').touch() |
2542 | - tempdir.child('c.py').touch() |
2543 | - self.assertEqual( |
2544 | - sorted(iterSourceCode([tempdir.path])), |
2545 | - sorted([tempdir.child('foo').child('a.py').path, |
2546 | - tempdir.child('bar').child('b.py').path, |
2547 | - tempdir.child('c.py').path])) |
2548 | - |
2549 | - |
2550 | - def test_multipleDirectories(self): |
2551 | - """ |
2552 | - L{iterSourceCode} can be given multiple directories. It will recurse |
2553 | - into each of them. |
2554 | - """ |
2555 | - tempdir = FilePath(self.mktemp()) |
2556 | - tempdir.createDirectory() |
2557 | - foo = tempdir.child('foo') |
2558 | - foo.createDirectory() |
2559 | - foo.child('a.py').touch() |
2560 | - bar = tempdir.child('bar') |
2561 | - bar.createDirectory() |
2562 | - bar.child('b.py').touch() |
2563 | - self.assertEqual( |
2564 | - sorted(iterSourceCode([foo.path, bar.path])), |
2565 | - sorted([foo.child('a.py').path, |
2566 | - bar.child('b.py').path])) |
2567 | - |
2568 | - |
2569 | - def test_explicitFiles(self): |
2570 | - """ |
2571 | - If one of the paths given to L{iterSourceCode} is not a directory but |
2572 | - a file, it will include that in its output. |
2573 | - """ |
2574 | - tempfile = FilePath(self.mktemp()) |
2575 | - tempfile.touch() |
2576 | - self.assertEqual(list(iterSourceCode([tempfile.path])), |
2577 | - [tempfile.path]) |
2578 | - |
2579 | - |
2580 | - |
2581 | -class TestReporter(TestCase): |
2582 | - """ |
2583 | - Tests for L{Reporter}. |
2584 | - """ |
2585 | - |
2586 | - def test_syntaxError(self): |
2587 | - """ |
2588 | - C{syntaxError} reports that there was a syntax error in the source |
2589 | - file. It reports to the error stream and includes the filename, line |
2590 | - number, error message, actual line of source and a caret pointing to |
2591 | - where the error is. |
2592 | - """ |
2593 | - err = StringIO() |
2594 | - reporter = Reporter(None, err) |
2595 | - reporter.syntaxError('foo.py', 'a problem', 3, 4, 'bad line of source') |
2596 | - self.assertEquals( |
2597 | - ("foo.py:3: a problem\n" |
2598 | - "bad line of source\n" |
2599 | - " ^\n"), |
2600 | - err.getvalue()) |
2601 | - |
2602 | - |
2603 | - def test_syntaxErrorNoOffset(self): |
2604 | - """ |
2605 | - C{syntaxError} doesn't include a caret pointing to the error if |
2606 | - C{offset} is passed as C{None}. |
2607 | - """ |
2608 | - err = StringIO() |
2609 | - reporter = Reporter(None, err) |
2610 | - reporter.syntaxError('foo.py', 'a problem', 3, None, |
2611 | - 'bad line of source') |
2612 | - self.assertEquals( |
2613 | - ("foo.py:3: a problem\n" |
2614 | - "bad line of source\n"), |
2615 | - err.getvalue()) |
2616 | - |
2617 | - |
2618 | - def test_multiLineSyntaxError(self): |
2619 | - """ |
2620 | - If there's a multi-line syntax error, then we only report the last |
2621 | - line. The offset is adjusted so that it is relative to the start of |
2622 | - the last line. |
2623 | - """ |
2624 | - err = StringIO() |
2625 | - lines = [ |
2626 | - 'bad line of source', |
2627 | - 'more bad lines of source', |
2628 | - ] |
2629 | - reporter = Reporter(None, err) |
2630 | - reporter.syntaxError('foo.py', 'a problem', 3, len(lines[0]) + 5, |
2631 | - '\n'.join(lines)) |
2632 | - self.assertEquals( |
2633 | - ("foo.py:3: a problem\n" + |
2634 | - lines[-1] + "\n" + |
2635 | - " ^\n"), |
2636 | - err.getvalue()) |
2637 | - |
2638 | - |
2639 | - def test_unexpectedError(self): |
2640 | - """ |
2641 | - C{unexpectedError} reports an error processing a source file. |
2642 | - """ |
2643 | - err = StringIO() |
2644 | - reporter = Reporter(None, err) |
2645 | - reporter.unexpectedError(u'source.py', u'error message') |
2646 | - self.assertEquals(u'source.py: error message\n', err.getvalue()) |
2647 | - |
2648 | - |
2649 | - def test_flake(self): |
2650 | - """ |
2651 | - C{flake} reports a code warning from Pyflakes. It is exactly the |
2652 | - str() of a L{pyflakes.messages.Message}. |
2653 | - """ |
2654 | - out = StringIO() |
2655 | - reporter = Reporter(out, None) |
2656 | - message = UnusedImport('foo.py', 42, 'bar') |
2657 | - reporter.flake(message) |
2658 | - self.assertEquals(out.getvalue(), "%s\n" % (message,)) |
2659 | - |
2660 | - |
2661 | - |
2662 | -class CheckTests(TestCase): |
2663 | - """ |
2664 | - Tests for L{check} and L{checkPath} which check a file for flakes. |
2665 | - """ |
2666 | - |
2667 | - def makeTempFile(self, content): |
2668 | - """ |
2669 | - Make a temporary file containing C{content} and return a path to it. |
2670 | - """ |
2671 | - path = FilePath(self.mktemp()) |
2672 | - path.setContent(content) |
2673 | - return path.path |
2674 | - |
2675 | - |
2676 | - def assertHasErrors(self, path, errorList): |
2677 | - """ |
2678 | - Assert that C{path} causes errors. |
2679 | - |
2680 | - @param path: A path to a file to check. |
2681 | - @param errorList: A list of errors expected to be printed to stderr. |
2682 | - """ |
2683 | - err = StringIO() |
2684 | - count = withStderrTo(err, checkPath, path) |
2685 | - self.assertEquals( |
2686 | - (count, err.getvalue()), (len(errorList), ''.join(errorList))) |
2687 | - |
2688 | - |
2689 | - def getErrors(self, path): |
2690 | - """ |
2691 | - Get any warnings or errors reported by pyflakes for the file at C{path}. |
2692 | - |
2693 | - @param path: The path to a Python file on disk that pyflakes will check. |
2694 | - @return: C{(count, log)}, where C{count} is the number of warnings or |
2695 | - errors generated, and log is a list of those warnings, presented |
2696 | - as structured data. See L{LoggingReporter} for more details. |
2697 | - """ |
2698 | - log = [] |
2699 | - reporter = LoggingReporter(log) |
2700 | - count = checkPath(path, reporter) |
2701 | - return count, log |
2702 | - |
2703 | - |
2704 | - def test_missingTrailingNewline(self): |
2705 | - """ |
2706 | - Source which doesn't end with a newline shouldn't cause any |
2707 | - exception to be raised nor an error indicator to be returned by |
2708 | - L{check}. |
2709 | - """ |
2710 | - fName = self.makeTempFile("def foo():\n\tpass\n\t") |
2711 | - self.assertHasErrors(fName, []) |
2712 | - |
2713 | - |
2714 | - def test_checkPathNonExisting(self): |
2715 | - """ |
2716 | - L{checkPath} handles non-existing files. |
2717 | - """ |
2718 | - count, errors = self.getErrors('extremo') |
2719 | - self.assertEquals(count, 1) |
2720 | - self.assertEquals( |
2721 | - errors, |
2722 | - [('unexpectedError', 'extremo', 'No such file or directory')]) |
2723 | - |
2724 | - |
2725 | - def test_multilineSyntaxError(self): |
2726 | - """ |
2727 | - Source which includes a syntax error which results in the raised |
2728 | - L{SyntaxError.text} containing multiple lines of source are reported |
2729 | - with only the last line of that source. |
2730 | - """ |
2731 | - source = """\ |
2732 | -def foo(): |
2733 | - ''' |
2734 | - |
2735 | -def bar(): |
2736 | - pass |
2737 | - |
2738 | -def baz(): |
2739 | - '''quux''' |
2740 | -""" |
2741 | - |
2742 | - # Sanity check - SyntaxError.text should be multiple lines, if it |
2743 | - # isn't, something this test was unprepared for has happened. |
2744 | - def evaluate(source): |
2745 | - exec source |
2746 | - exc = self.assertRaises(SyntaxError, evaluate, source) |
2747 | - self.assertTrue(exc.text.count('\n') > 1) |
2748 | - |
2749 | - sourcePath = self.makeTempFile(source) |
2750 | - self.assertHasErrors( |
2751 | - sourcePath, ["""\ |
2752 | -%s:8: invalid syntax |
2753 | - '''quux''' |
2754 | - ^ |
2755 | -""" |
2756 | - % (sourcePath,)]) |
2757 | - |
2758 | - |
2759 | - def test_eofSyntaxError(self): |
2760 | - """ |
2761 | - The error reported for source files which end prematurely causing a |
2762 | - syntax error reflects the cause for the syntax error. |
2763 | - """ |
2764 | - sourcePath = self.makeTempFile("def foo(") |
2765 | - self.assertHasErrors( |
2766 | - sourcePath, |
2767 | - ["""\ |
2768 | -%s:1: unexpected EOF while parsing |
2769 | -def foo( |
2770 | - ^ |
2771 | -""" % (sourcePath,)]) |
2772 | - |
2773 | - |
2774 | - def test_nonDefaultFollowsDefaultSyntaxError(self): |
2775 | - """ |
2776 | - Source which has a non-default argument following a default argument |
2777 | - should include the line number of the syntax error. However these |
2778 | - exceptions do not include an offset. |
2779 | - """ |
2780 | - source = """\ |
2781 | -def foo(bar=baz, bax): |
2782 | - pass |
2783 | -""" |
2784 | - sourcePath = self.makeTempFile(source) |
2785 | - self.assertHasErrors( |
2786 | - sourcePath, |
2787 | - ["""\ |
2788 | -%s:1: non-default argument follows default argument |
2789 | -def foo(bar=baz, bax): |
2790 | -""" % (sourcePath,)]) |
2791 | - |
2792 | - |
2793 | - def test_nonKeywordAfterKeywordSyntaxError(self): |
2794 | - """ |
2795 | - Source which has a non-keyword argument after a keyword argument should |
2796 | - include the line number of the syntax error. However these exceptions |
2797 | - do not include an offset. |
2798 | - """ |
2799 | - source = """\ |
2800 | -foo(bar=baz, bax) |
2801 | -""" |
2802 | - sourcePath = self.makeTempFile(source) |
2803 | - self.assertHasErrors( |
2804 | - sourcePath, |
2805 | - ["""\ |
2806 | -%s:1: non-keyword arg after keyword arg |
2807 | -foo(bar=baz, bax) |
2808 | -""" % (sourcePath,)]) |
2809 | - |
2810 | - |
2811 | - def test_permissionDenied(self): |
2812 | - """ |
2813 | - If the source file is not readable, this is reported on standard |
2814 | - error. |
2815 | - """ |
2816 | - sourcePath = FilePath(self.mktemp()) |
2817 | - sourcePath.setContent('') |
2818 | - sourcePath.chmod(0) |
2819 | - count, errors = self.getErrors(sourcePath.path) |
2820 | - self.assertEquals(count, 1) |
2821 | - self.assertEquals( |
2822 | - errors, |
2823 | - [('unexpectedError', sourcePath.path, "Permission denied")]) |
2824 | - |
2825 | - |
2826 | - def test_pyflakesWarning(self): |
2827 | - """ |
2828 | - If the source file has a pyflakes warning, this is reported as a |
2829 | - 'flake'. |
2830 | - """ |
2831 | - sourcePath = self.makeTempFile("import foo") |
2832 | - count, errors = self.getErrors(sourcePath) |
2833 | - self.assertEquals(count, 1) |
2834 | - self.assertEquals( |
2835 | - errors, [('flake', str(UnusedImport(sourcePath, 1, 'foo')))]) |
2836 | - |
2837 | - |
2838 | - def test_misencodedFile(self): |
2839 | - """ |
2840 | - If a source file contains bytes which cannot be decoded, this is |
2841 | - reported on stderr. |
2842 | - """ |
2843 | - source = u"""\ |
2844 | -# coding: ascii |
2845 | -x = "\N{SNOWMAN}" |
2846 | -""".encode('utf-8') |
2847 | - sourcePath = self.makeTempFile(source) |
2848 | - self.assertHasErrors( |
2849 | - sourcePath, ["%s: problem decoding source\n" % (sourcePath,)]) |
2850 | - |
2851 | - |
2852 | - def test_checkRecursive(self): |
2853 | - """ |
2854 | - L{checkRecursive} descends into each directory, finding Python files |
2855 | - and reporting problems. |
2856 | - """ |
2857 | - tempdir = FilePath(self.mktemp()) |
2858 | - tempdir.createDirectory() |
2859 | - tempdir.child('foo').createDirectory() |
2860 | - file1 = tempdir.child('foo').child('bar.py') |
2861 | - file1.setContent("import baz\n") |
2862 | - file2 = tempdir.child('baz.py') |
2863 | - file2.setContent("import contraband") |
2864 | - log = [] |
2865 | - reporter = LoggingReporter(log) |
2866 | - warnings = checkRecursive([tempdir.path], reporter) |
2867 | - self.assertEqual(warnings, 2) |
2868 | - self.assertEqual( |
2869 | - sorted(log), |
2870 | - sorted([('flake', str(UnusedImport(file1.path, 1, 'baz'))), |
2871 | - ('flake', |
2872 | - str(UnusedImport(file2.path, 1, 'contraband')))])) |
2873 | - |
2874 | - |
2875 | - |
2876 | -class _EverythingGetterWithStdin(protocol.ProcessProtocol): |
2877 | - """ |
2878 | - C{ProcessProtocol} that writes to stdin and gathers exit code, stdout and |
2879 | - stderr. |
2880 | - """ |
2881 | - |
2882 | - # Although Twisted provides a helper that spawns a subprocess, gathers its |
2883 | - # exit code, standard output and standard error |
2884 | - # (i.e. getProcessOutputAndValue), it does *not* provide one that data to |
2885 | - # be written to stdin first. |
2886 | - |
2887 | - def __init__(self, deferred, stdin): |
2888 | - self.deferred = deferred |
2889 | - self.outBuf = StringIO() |
2890 | - self.errBuf = StringIO() |
2891 | - self.outReceived = self.outBuf.write |
2892 | - self.errReceived = self.errBuf.write |
2893 | - self.stdin = stdin |
2894 | - |
2895 | - |
2896 | - def connectionMade(self): |
2897 | - self.transport.write(self.stdin) |
2898 | - self.transport.closeStdin() |
2899 | - |
2900 | - |
2901 | - def processEnded(self, reason): |
2902 | - out = self.outBuf.getvalue() |
2903 | - err = self.errBuf.getvalue() |
2904 | - e = reason.value |
2905 | - code = e.exitCode |
2906 | - if e.signal: |
2907 | - code = -e.signal |
2908 | - self.deferred.callback((out, err, code)) |
2909 | - |
2910 | - |
2911 | - |
2912 | -class IntegrationTests(TestCase): |
2913 | - """ |
2914 | - Tests of the pyflakes script that actually spawn the script. |
2915 | - """ |
2916 | - |
2917 | - def getPyflakesBinary(self): |
2918 | - """ |
2919 | - Return the path to the pyflakes binary. |
2920 | - """ |
2921 | - import pyflakes |
2922 | - package_dir = FilePath(pyflakes.__file__).parent() |
2923 | - return package_dir.sibling('bin').child('pyflakes').path |
2924 | - |
2925 | - |
2926 | - def runPyflakes(self, paths, stdin=None): |
2927 | - """ |
2928 | - Launch a subprocess running C{pyflakes}. |
2929 | - |
2930 | - @param args: Command-line arguments to pass to pyflakes. |
2931 | - @param kwargs: Options passed on to C{subprocess.Popen}. |
2932 | - @return: C{(returncode, stdout, stderr)} of the completed pyflakes |
2933 | - process. |
2934 | - """ |
2935 | - env = dict(os.environ) |
2936 | - env['PYTHONPATH'] = os.pathsep.join(sys.path) |
2937 | - command = [self.getPyflakesBinary()] |
2938 | - command.extend(paths) |
2939 | - if stdin: |
2940 | - d = _callProtocolWithDeferred( |
2941 | - lambda d: _EverythingGetterWithStdin(d, stdin), |
2942 | - sys.executable, command, env=env, path=None) |
2943 | - else: |
2944 | - d = getProcessOutputAndValue(sys.executable, command, env=env) |
2945 | - return d |
2946 | - |
2947 | - |
2948 | - def test_goodFile(self): |
2949 | - """ |
2950 | - When a Python source file is all good, the return code is zero and no |
2951 | - messages are printed to either stdout or stderr. |
2952 | - """ |
2953 | - tempfile = FilePath(self.mktemp()) |
2954 | - tempfile.touch() |
2955 | - d = self.runPyflakes([tempfile.path]) |
2956 | - return d.addCallback(self.assertEqual, ('', '', 0)) |
2957 | - |
2958 | - |
2959 | - def test_fileWithFlakes(self): |
2960 | - """ |
2961 | - When a Python source file has warnings, the return code is non-zero |
2962 | - and the warnings are printed to stdout. |
2963 | - """ |
2964 | - tempfile = FilePath(self.mktemp()) |
2965 | - tempfile.setContent("import contraband\n") |
2966 | - d = self.runPyflakes([tempfile.path]) |
2967 | - return d.addCallback( |
2968 | - self.assertEqual, |
2969 | - ("%s\n" % UnusedImport(tempfile.path, 1, 'contraband'), '', 1)) |
2970 | - |
2971 | - |
2972 | - def test_errors(self): |
2973 | - """ |
2974 | - When pyflakes finds errors with the files it's given, (if they don't |
2975 | - exist, say), then the return code is non-zero and the errors are |
2976 | - printed to stderr. |
2977 | - """ |
2978 | - tempfile = FilePath(self.mktemp()) |
2979 | - d = self.runPyflakes([tempfile.path]) |
2980 | - return d.addCallback( |
2981 | - self.assertEqual, |
2982 | - ('', '%s: No such file or directory\n' % (tempfile.path,), 1)) |
2983 | - |
2984 | - |
2985 | - def test_readFromStdin(self): |
2986 | - """ |
2987 | - If no arguments are passed to C{pyflakes} then it reads from stdin. |
2988 | - """ |
2989 | - d = self.runPyflakes([], stdin='import contraband') |
2990 | - return d.addCallback( |
2991 | - self.assertEqual, |
2992 | - ("%s\n" % UnusedImport('<stdin>', 1, 'contraband'), '', 1)) |
2993 | |
2994 | === removed file 'Pyflakes/pyflakes/test/test_undefined_names.py' |
2995 | --- Pyflakes/pyflakes/test/test_undefined_names.py 2011-12-04 20:27:45 +0000 |
2996 | +++ Pyflakes/pyflakes/test/test_undefined_names.py 1970-01-01 00:00:00 +0000 |
2997 | @@ -1,273 +0,0 @@ |
2998 | - |
2999 | -from _ast import PyCF_ONLY_AST |
3000 | - |
3001 | -from twisted.trial.unittest import TestCase |
3002 | - |
3003 | -from pyflakes import messages as m, checker |
3004 | -from pyflakes.test import harness |
3005 | - |
3006 | - |
3007 | -class Test(harness.Test): |
3008 | - def test_undefined(self): |
3009 | - self.flakes('bar', m.UndefinedName) |
3010 | - |
3011 | - def test_definedInListComp(self): |
3012 | - self.flakes('[a for a in range(10) if a]') |
3013 | - |
3014 | - |
3015 | - def test_functionsNeedGlobalScope(self): |
3016 | - self.flakes(''' |
3017 | - class a: |
3018 | - def b(): |
3019 | - fu |
3020 | - fu = 1 |
3021 | - ''') |
3022 | - |
3023 | - def test_builtins(self): |
3024 | - self.flakes('range(10)') |
3025 | - |
3026 | - |
3027 | - def test_builtinWindowsError(self): |
3028 | - """ |
3029 | - C{WindowsError} is sometimes a builtin name, so no warning is emitted |
3030 | - for using it. |
3031 | - """ |
3032 | - self.flakes('WindowsError') |
3033 | - |
3034 | - |
3035 | - def test_magicGlobalsFile(self): |
3036 | - """ |
3037 | - Use of the C{__file__} magic global should not emit an undefined name |
3038 | - warning. |
3039 | - """ |
3040 | - self.flakes('__file__') |
3041 | - |
3042 | - |
3043 | - def test_magicGlobalsBuiltins(self): |
3044 | - """ |
3045 | - Use of the C{__builtins__} magic global should not emit an undefined |
3046 | - name warning. |
3047 | - """ |
3048 | - self.flakes('__builtins__') |
3049 | - |
3050 | - |
3051 | - def test_magicGlobalsName(self): |
3052 | - """ |
3053 | - Use of the C{__name__} magic global should not emit an undefined name |
3054 | - warning. |
3055 | - """ |
3056 | - self.flakes('__name__') |
3057 | - |
3058 | - |
3059 | - def test_magicGlobalsPath(self): |
3060 | - """ |
3061 | - Use of the C{__path__} magic global should not emit an undefined name |
3062 | - warning, if you refer to it from a file called __init__.py. |
3063 | - """ |
3064 | - self.flakes('__path__', m.UndefinedName) |
3065 | - self.flakes('__path__', filename='package/__init__.py') |
3066 | - |
3067 | - |
3068 | - def test_globalImportStar(self): |
3069 | - '''Can't find undefined names with import *''' |
3070 | - self.flakes('from fu import *; bar', m.ImportStarUsed) |
3071 | - |
3072 | - def test_localImportStar(self): |
3073 | - '''A local import * still allows undefined names to be found in upper scopes''' |
3074 | - self.flakes(''' |
3075 | - def a(): |
3076 | - from fu import * |
3077 | - bar |
3078 | - ''', m.ImportStarUsed, m.UndefinedName) |
3079 | - |
3080 | - def test_unpackedParameter(self): |
3081 | - '''Unpacked function parameters create bindings''' |
3082 | - self.flakes(''' |
3083 | - def a((bar, baz)): |
3084 | - bar; baz |
3085 | - ''') |
3086 | - |
3087 | - def test_definedByGlobal(self): |
3088 | - '''"global" can make an otherwise undefined name in another function defined''' |
3089 | - self.flakes(''' |
3090 | - def a(): global fu; fu = 1 |
3091 | - def b(): fu |
3092 | - ''') |
3093 | - test_definedByGlobal.todo = '' |
3094 | - |
3095 | - def test_globalInGlobalScope(self): |
3096 | - """ |
3097 | - A global statement in the global scope is ignored. |
3098 | - """ |
3099 | - self.flakes(''' |
3100 | - global x |
3101 | - def foo(): |
3102 | - print x |
3103 | - ''', m.UndefinedName) |
3104 | - |
3105 | - def test_del(self): |
3106 | - '''del deletes bindings''' |
3107 | - self.flakes('a = 1; del a; a', m.UndefinedName) |
3108 | - |
3109 | - def test_delGlobal(self): |
3110 | - '''del a global binding from a function''' |
3111 | - self.flakes(''' |
3112 | - a = 1 |
3113 | - def f(): |
3114 | - global a |
3115 | - del a |
3116 | - a |
3117 | - ''') |
3118 | - |
3119 | - def test_delUndefined(self): |
3120 | - '''del an undefined name''' |
3121 | - self.flakes('del a', m.UndefinedName) |
3122 | - |
3123 | - def test_globalFromNestedScope(self): |
3124 | - '''global names are available from nested scopes''' |
3125 | - self.flakes(''' |
3126 | - a = 1 |
3127 | - def b(): |
3128 | - def c(): |
3129 | - a |
3130 | - ''') |
3131 | - |
3132 | - def test_laterRedefinedGlobalFromNestedScope(self): |
3133 | - """ |
3134 | - Test that referencing a local name that shadows a global, before it is |
3135 | - defined, generates a warning. |
3136 | - """ |
3137 | - self.flakes(''' |
3138 | - a = 1 |
3139 | - def fun(): |
3140 | - a |
3141 | - a = 2 |
3142 | - return a |
3143 | - ''', m.UndefinedLocal) |
3144 | - |
3145 | - def test_laterRedefinedGlobalFromNestedScope2(self): |
3146 | - """ |
3147 | - Test that referencing a local name in a nested scope that shadows a |
3148 | - global declared in an enclosing scope, before it is defined, generates |
3149 | - a warning. |
3150 | - """ |
3151 | - self.flakes(''' |
3152 | - a = 1 |
3153 | - def fun(): |
3154 | - global a |
3155 | - def fun2(): |
3156 | - a |
3157 | - a = 2 |
3158 | - return a |
3159 | - ''', m.UndefinedLocal) |
3160 | - |
3161 | - |
3162 | - def test_intermediateClassScopeIgnored(self): |
3163 | - """ |
3164 | - If a name defined in an enclosing scope is shadowed by a local variable |
3165 | - and the name is used locally before it is bound, an unbound local |
3166 | - warning is emitted, even if there is a class scope between the enclosing |
3167 | - scope and the local scope. |
3168 | - """ |
3169 | - self.flakes(''' |
3170 | - def f(): |
3171 | - x = 1 |
3172 | - class g: |
3173 | - def h(self): |
3174 | - a = x |
3175 | - x = None |
3176 | - print x, a |
3177 | - print x |
3178 | - ''', m.UndefinedLocal) |
3179 | - |
3180 | - |
3181 | - def test_doubleNestingReportsClosestName(self): |
3182 | - """ |
3183 | - Test that referencing a local name in a nested scope that shadows a |
3184 | - variable declared in two different outer scopes before it is defined |
3185 | - in the innermost scope generates an UnboundLocal warning which |
3186 | - refers to the nearest shadowed name. |
3187 | - """ |
3188 | - exc = self.flakes(''' |
3189 | - def a(): |
3190 | - x = 1 |
3191 | - def b(): |
3192 | - x = 2 # line 5 |
3193 | - def c(): |
3194 | - x |
3195 | - x = 3 |
3196 | - return x |
3197 | - return x |
3198 | - return x |
3199 | - ''', m.UndefinedLocal).messages[0] |
3200 | - self.assertEqual(exc.message_args, ('x', 5)) |
3201 | - |
3202 | - |
3203 | - def test_laterRedefinedGlobalFromNestedScope3(self): |
3204 | - """ |
3205 | - Test that referencing a local name in a nested scope that shadows a |
3206 | - global, before it is defined, generates a warning. |
3207 | - """ |
3208 | - self.flakes(''' |
3209 | - def fun(): |
3210 | - a = 1 |
3211 | - def fun2(): |
3212 | - a |
3213 | - a = 1 |
3214 | - return a |
3215 | - return a |
3216 | - ''', m.UndefinedLocal) |
3217 | - |
3218 | - def test_nestedClass(self): |
3219 | - '''nested classes can access enclosing scope''' |
3220 | - self.flakes(''' |
3221 | - def f(foo): |
3222 | - class C: |
3223 | - bar = foo |
3224 | - def f(self): |
3225 | - return foo |
3226 | - return C() |
3227 | - |
3228 | - f(123).f() |
3229 | - ''') |
3230 | - |
3231 | - def test_badNestedClass(self): |
3232 | - '''free variables in nested classes must bind at class creation''' |
3233 | - self.flakes(''' |
3234 | - def f(): |
3235 | - class C: |
3236 | - bar = foo |
3237 | - foo = 456 |
3238 | - return foo |
3239 | - f() |
3240 | - ''', m.UndefinedName) |
3241 | - |
3242 | - def test_definedAsStarArgs(self): |
3243 | - '''star and double-star arg names are defined''' |
3244 | - self.flakes(''' |
3245 | - def f(a, *b, **c): |
3246 | - print a, b, c |
3247 | - ''') |
3248 | - |
3249 | - def test_definedInGenExp(self): |
3250 | - """ |
3251 | - Using the loop variable of a generator expression results in no |
3252 | - warnings. |
3253 | - """ |
3254 | - self.flakes('(a for a in xrange(10) if a)') |
3255 | - |
3256 | - |
3257 | - |
3258 | -class NameTests(TestCase): |
3259 | - """ |
3260 | - Tests for some extra cases of name handling. |
3261 | - """ |
3262 | - def test_impossibleContext(self): |
3263 | - """ |
3264 | - A Name node with an unrecognized context results in a RuntimeError being |
3265 | - raised. |
3266 | - """ |
3267 | - tree = compile("x = 10", "<test>", "exec", PyCF_ONLY_AST) |
3268 | - # Make it into something unrecognizable. |
3269 | - tree.body[0].targets[0].ctx = object() |
3270 | - self.assertRaises(RuntimeError, checker.Checker, tree) |
3271 | |
3272 | === removed file 'Pyflakes/setup.py' |
3273 | --- Pyflakes/setup.py 2011-09-03 16:31:04 +0000 |
3274 | +++ Pyflakes/setup.py 1970-01-01 00:00:00 +0000 |
3275 | @@ -1,29 +0,0 @@ |
3276 | -#!/usr/bin/python |
3277 | -# Copyright 2005-2011 Divmod, Inc. See LICENSE file for details |
3278 | - |
3279 | -from distutils.core import setup |
3280 | - |
3281 | -setup( |
3282 | - name="pyflakes", |
3283 | - license="MIT", |
3284 | - version="0.5.0", |
3285 | - description="passive checker of Python programs", |
3286 | - author="Phil Frost", |
3287 | - author_email="indigo@bitglue.com", |
3288 | - maintainer="Divmod developers", |
3289 | - maintainer_email="divmod-dev@lists.launchpad.net", |
3290 | - url="https://launchpad.net/pyflakes", |
3291 | - packages=["pyflakes", "pyflakes.scripts", "pyflakes.test"], |
3292 | - scripts=["bin/pyflakes"], |
3293 | - long_description="""Pyflakes is program to analyze Python programs and detect various errors. It |
3294 | -works by parsing the source file, not importing it, so it is safe to use on |
3295 | -modules with side effects. It's also much faster.""", |
3296 | - classifiers=[ |
3297 | - "Development Status :: 6 - Mature", |
3298 | - "Environment :: Console", |
3299 | - "Intended Audience :: Developers", |
3300 | - "License :: OSI Approved :: MIT License", |
3301 | - "Programming Language :: Python", |
3302 | - "Topic :: Software Development", |
3303 | - "Topic :: Utilities", |
3304 | - ]) |
Discussion on the mailing list appears to have reached consensus, outstanding branches have been dealt with, and the pyflakes branch has already been created. Please land this with all due haste, to reduce any confusion about where the code now lives. Thank you!