Use the flake8 tool on the master branch

This commit is contained in:
Stephane Wirtel 2010-08-12 17:07:03 +02:00
parent 4f6d1eb6cc
commit ed429af48c
9 changed files with 91 additions and 132 deletions

View file

@ -10,6 +10,7 @@ import pep8
checker = __import__('flake8.checker').checker
def check(codeString, filename):
"""
Check the Python source given by C{codeString} for flakes.
@ -65,11 +66,13 @@ def check(codeString, filename):
return valid_warnings
def _noqa(warning):
# XXX quick dirty hack, just need to keep the line in the warning
line = open(warning.filename).readlines()[warning.lineno-1]
line = open(warning.filename).readlines()[warning.lineno - 1]
return line.strip().lower().endswith('# noqa')
def checkPath(filename):
"""
Check the given path, printing out any warnings detected.
@ -105,5 +108,4 @@ def main():
stdin = sys.stdin.read()
warnings += check(stdin, '<stdin>')
raise SystemExit(warnings > 0)

View file

@ -14,10 +14,11 @@ try:
import ast
iter_child_nodes = ast.iter_child_nodes
except (ImportError, AttributeError):
def iter_child_nodes(node, astcls=_ast.AST):
"""
Yield all direct child nodes of *node*, that is, all fields that are nodes
and all items of fields that are lists of nodes.
Yield all direct child nodes of *node*, that is, all fields that are
nodes and all items of fields that are lists of nodes.
"""
for name in node._fields:
field = getattr(node, name, None)
@ -45,24 +46,21 @@ class Binding(object):
self.source = source
self.used = False
def __str__(self):
return self.name
def __repr__(self):
return '<%s object %r from line %r at 0x%x>' % (self.__class__.__name__,
self.name,
self.source.lineno,
id(self))
return '<%s object %r from line %r at 0x%x>' % (
self.__class__.__name__,
self.name,
self.source.lineno,
id(self))
class UnBinding(Binding):
'''Created by the 'del' operator.'''
class Importation(Binding):
"""
A binding created by an import statement.
@ -77,14 +75,12 @@ class Importation(Binding):
super(Importation, self).__init__(name, source)
class Argument(Binding):
"""
Represents binding a name as an argument.
"""
class Assignment(Binding):
"""
Represents binding a name with an explicit assignment.
@ -95,12 +91,10 @@ class Assignment(Binding):
"""
class FunctionDefinition(Binding):
pass
class ExportBinding(Binding):
"""
A binding created by an C{__all__} assignment. If the names in the list
@ -127,25 +121,22 @@ class ExportBinding(Binding):
return names
class Scope(dict):
importStarred = False # set to True when import * is found
def __repr__(self):
return '<%s at 0x%x %s>' % (self.__class__.__name__, id(self), dict.__repr__(self))
return '<%s at 0x%x %s>' % (self.__class__.__name__,
id(self),
dict.__repr__(self))
def __init__(self):
super(Scope, self).__init__()
class ClassScope(Scope):
pass
class FunctionScope(Scope):
"""
I represent a name scope for a function.
@ -157,7 +148,6 @@ class FunctionScope(Scope):
self.globals = {}
class ModuleScope(Scope):
pass
@ -166,7 +156,6 @@ class ModuleScope(Scope):
_MAGIC_GLOBALS = ['__file__', '__builtins__']
class Checker(object):
"""
I check the cleanliness and sanity of Python code.
@ -204,7 +193,6 @@ class Checker(object):
self.popScope()
self.check_dead_scopes()
def deferFunction(self, callable):
'''
Schedule a function handler to be called just before completion.
@ -216,7 +204,6 @@ class Checker(object):
'''
self._deferredFunctions.append((callable, self.scopeStack[:]))
def deferAssignment(self, callable):
"""
Schedule an assignment handler to be called just after deferred
@ -224,7 +211,6 @@ class Checker(object):
"""
self._deferredAssignments.append((callable, self.scopeStack[:]))
def _runDeferred(self, deferred):
"""
Run the callables in C{deferred} using their associated scope stack.
@ -233,7 +219,6 @@ class Checker(object):
self.scopeStack = scope
handler()
def scope(self):
return self.scopeStack[-1]
scope = property(scope)
@ -241,7 +226,6 @@ class Checker(object):
def popScope(self):
self.dead_scopes.append(self.scopeStack.pop())
def check_dead_scopes(self):
"""
Look at scopes which have been fully examined and report names in them
@ -271,7 +255,6 @@ class Checker(object):
importation.source.lineno,
importation.name)
def pushFunctionScope(self):
self.scopeStack.append(FunctionScope())
@ -352,18 +335,21 @@ class Checker(object):
if (isinstance(self.scope.get(value.name), FunctionDefinition)
and isinstance(value, FunctionDefinition)):
self.report(messages.RedefinedFunction,
lineno, value.name, self.scope[value.name].source.lineno)
lineno, value.name,
self.scope[value.name].source.lineno)
if not isinstance(self.scope, ClassScope):
for scope in self.scopeStack[::-1]:
existing = scope.get(value.name)
if (isinstance(existing, Importation)
and not existing.used
and (not isinstance(value, Importation) or value.fullName == existing.fullName)
and (not isinstance(value, Importation) \
or value.fullName == existing.fullName)
and reportRedef):
self.report(messages.RedefinedWhileUnused,
lineno, value.name, scope[value.name].source.lineno)
lineno, value.name,
scope[value.name].source.lineno)
if isinstance(value, UnBinding):
try:
@ -400,6 +386,7 @@ class Checker(object):
Process bindings for loop variables.
"""
vars = []
def collectLoopVars(n):
if isinstance(n, _ast.Name):
vars.append(n.id)
@ -461,10 +448,14 @@ class Checker(object):
# the special name __path__ is valid only in packages
pass
else:
self.report(messages.UndefinedName, node.lineno, node.id)
self.report(messages.UndefinedName,
node.lineno,
node.id)
elif isinstance(node.ctx, (_ast.Store, _ast.AugStore)):
# if the name hasn't already been defined in the current scope
if isinstance(self.scope, FunctionScope) and node.id not in self.scope:
if isinstance(self.scope, FunctionScope) and \
node.id not in self.scope:
# for each function or module scope above us
for scope in self.scopeStack[:-1]:
if not isinstance(scope, (FunctionScope, ModuleScope)):
@ -484,7 +475,10 @@ class Checker(object):
break
if isinstance(node.parent,
(_ast.For, _ast.comprehension, _ast.Tuple, _ast.List)):
(_ast.For,
_ast.comprehension,
_ast.Tuple,
_ast.List)):
binding = Binding(node.id, node)
elif (node.id == '__all__' and
isinstance(self.scope, ModuleScope)):
@ -501,12 +495,11 @@ class Checker(object):
else:
self.addBinding(node.lineno, UnBinding(node.id, node))
else:
# must be a Param context -- this only happens for names in function
# arguments, but these aren't dispatched through here
# must be a Param context -- this only happens for names
# in function arguments, but these aren't dispatched through here
raise RuntimeError(
"Got impossible expression context: %r" % (node.ctx,))
def FUNCTIONDEF(self, node):
# the decorators attribute is called decorator_list as of Python 2.6
if hasattr(node, 'decorators'):
@ -543,7 +536,8 @@ class Checker(object):
if node.args.kwarg:
args.append(node.args.kwarg)
for name in args:
self.addBinding(node.lineno, Argument(name, node), reportRedef=False)
self.addBinding(node.lineno, Argument(name, node),
reportRedef=False)
if isinstance(node.body, list):
# case for FunctionDefs
for stmt in node.body:
@ -551,6 +545,7 @@ class Checker(object):
else:
# case for Lambdas
self.handleNode(node.body, node)
def checkUnusedAssignments():
"""
Check to see if any assignments have not been used.
@ -565,7 +560,6 @@ class Checker(object):
self.deferFunction(runFunction)
def CLASSDEF(self, node):
"""
Check names used in a class definition, including its decorators, base
@ -589,8 +583,9 @@ class Checker(object):
self.handleNode(target, node)
def AUGASSIGN(self, node):
# AugAssign is awkward: must set the context explicitly and visit twice,
# once with AugLoad context, once with AugStore context
# AugAssign is awkward: must set the context explicitly
# and visit twice, once with AugLoad context, once with
# AugStore context
node.target.ctx = _ast.AugLoad()
self.handleNode(node.target, node)
self.handleNode(node.value, node)

View file

@ -1,17 +1,22 @@
# (c) 2005 Divmod, Inc. See LICENSE file for details
class Message(object):
message = ''
message_args = ()
def __init__(self, filename, lineno):
self.filename = filename
self.lineno = lineno
def __str__(self):
return '%s:%s: %s' % (self.filename, self.lineno, self.message % self.message_args)
return '%s:%s: %s' % (self.filename, self.lineno,
self.message % self.message_args)
class UnusedImport(Message):
message = '%r imported but unused'
def __init__(self, filename, lineno, name):
Message.__init__(self, filename, lineno)
self.message_args = (name,)
@ -19,6 +24,7 @@ class UnusedImport(Message):
class RedefinedWhileUnused(Message):
message = 'redefinition of unused %r from line %r'
def __init__(self, filename, lineno, name, orig_lineno):
Message.__init__(self, filename, lineno)
self.message_args = (name, orig_lineno)
@ -26,6 +32,7 @@ class RedefinedWhileUnused(Message):
class ImportShadowedByLoopVar(Message):
message = 'import %r from line %r shadowed by loop variable'
def __init__(self, filename, lineno, name, orig_lineno):
Message.__init__(self, filename, lineno)
self.message_args = (name, orig_lineno)
@ -33,6 +40,7 @@ class ImportShadowedByLoopVar(Message):
class ImportStarUsed(Message):
message = "'from %s import *' used; unable to detect undefined names"
def __init__(self, filename, lineno, modname):
Message.__init__(self, filename, lineno)
self.message_args = (modname,)
@ -40,22 +48,24 @@ class ImportStarUsed(Message):
class UndefinedName(Message):
message = 'undefined name %r'
def __init__(self, filename, lineno, name):
Message.__init__(self, filename, lineno)
self.message_args = (name,)
class UndefinedExport(Message):
message = 'undefined name %r in __all__'
def __init__(self, filename, lineno, name):
Message.__init__(self, filename, lineno)
self.message_args = (name,)
class UndefinedLocal(Message):
message = "local variable %r (defined in enclosing scope on line %r) referenced before assignment"
message = "local variable %r (defined in enclosing scope on line %r) " \
"referenced before assignment"
def __init__(self, filename, lineno, name, orig_lineno):
Message.__init__(self, filename, lineno)
self.message_args = (name, orig_lineno)
@ -63,6 +73,7 @@ class UndefinedLocal(Message):
class DuplicateArgument(Message):
message = 'duplicate argument %r in function definition'
def __init__(self, filename, lineno, name):
Message.__init__(self, filename, lineno)
self.message_args = (name,)
@ -70,6 +81,7 @@ class DuplicateArgument(Message):
class RedefinedFunction(Message):
message = 'redefinition of function %r from line %r'
def __init__(self, filename, lineno, name, orig_lineno):
Message.__init__(self, filename, lineno)
self.message_args = (name, orig_lineno)
@ -77,6 +89,7 @@ class RedefinedFunction(Message):
class LateFutureImport(Message):
message = 'future import(s) %r after other statements'
def __init__(self, filename, lineno, names):
Message.__init__(self, filename, lineno)
self.message_args = (names,)
@ -89,6 +102,7 @@ class UnusedVariable(Message):
"""
message = 'local variable %r is assigned to but never used'
def __init__(self, filename, lineno, names):
Message.__init__(self, filename, lineno)
self.message_args = (names,)

View file

@ -985,6 +985,7 @@ def input_file(filename):
message("%s: error %s not found" % (filename, code))
return errors
def input_dir(dirname):
"""
Check all Python source files in this directory and all subdirectories.

View file

@ -23,5 +23,6 @@ for input:
expected outputs:
%s
but got:
%s''' % (input, repr(expectedOutputs), '\n'.join([str(o) for o in w.messages])))
%s''' % (input, repr(expectedOutputs), '\n'.join(map(str, w.messages))))
return w

View file

@ -4,6 +4,7 @@ from sys import version_info
from pyflakes import messages as m
from pyflakes.test import harness
class Test(harness.Test):
def test_unusedImport(self):
@ -11,8 +12,10 @@ class Test(harness.Test):
self.flakes('from baz import fu, bar', m.UnusedImport, m.UnusedImport)
def test_aliasedImport(self):
self.flakes('import fu as FU, bar as FU', m.RedefinedWhileUnused, m.UnusedImport)
self.flakes('from moo import fu as FU, bar as FU', m.RedefinedWhileUnused, m.UnusedImport)
self.flakes('import fu as FU, bar as FU',
m.RedefinedWhileUnused, m.UnusedImport)
self.flakes('from moo import fu as FU, bar as FU',
m.RedefinedWhileUnused, m.UnusedImport)
def test_usedImport(self):
self.flakes('import fu; print fu')
@ -51,7 +54,6 @@ class Test(harness.Test):
pass
''', m.RedefinedWhileUnused)
def test_redefinedBySubclass(self):
"""
If an imported name is redefined by a class statement which also uses
@ -63,7 +65,6 @@ class Test(harness.Test):
pass
''')
def test_redefinedInClass(self):
"""
Test that shadowing a global with a class attribute does not produce a
@ -306,8 +307,8 @@ class Test(harness.Test):
self.flakes('import fu; [1 for _ in range(1) if fu]')
def test_redefinedByListComp(self):
self.flakes('import fu; [1 for fu in range(1)]', m.RedefinedWhileUnused)
self.flakes('import fu; [1 for fu in range(1)]',
m.RedefinedWhileUnused)
def test_usedInTryFinally(self):
self.flakes('''
@ -390,7 +391,6 @@ class Test(harness.Test):
def test_importStar(self):
self.flakes('from fu import *', m.ImportStarUsed)
def test_packageImport(self):
"""
If a dotted name is imported and used, no warning is reported.
@ -400,7 +400,6 @@ class Test(harness.Test):
fu.bar
''')
def test_unusedPackageImport(self):
"""
If a dotted name is imported and not used, an unused import warning is
@ -408,7 +407,6 @@ class Test(harness.Test):
"""
self.flakes('import fu.bar', m.UnusedImport)
def test_duplicateSubmoduleImport(self):
"""
If a submodule of a package is imported twice, an unused import warning
@ -424,7 +422,6 @@ class Test(harness.Test):
fu.bar
''', m.RedefinedWhileUnused)
def test_differentSubmoduleImport(self):
"""
If two different submodules of a package are imported, no duplicate
@ -524,7 +521,6 @@ class Test(harness.Test):
''', m.LateFutureImport)
class TestSpecialAll(harness.Test):
"""
Tests for suppression of unused import warnings by C{__all__}.
@ -540,7 +536,6 @@ class TestSpecialAll(harness.Test):
__all__ = ["bar"]
''', m.UnusedImport, m.UnusedVariable)
def test_ignoredInClass(self):
"""
An C{__all__} definition does not suppress unused import warnings in a
@ -552,7 +547,6 @@ class TestSpecialAll(harness.Test):
__all__ = ["bar"]
''', m.UnusedImport)
def test_warningSuppressed(self):
"""
If a name is imported and unused but is named in C{__all__}, no warning
@ -563,7 +557,6 @@ class TestSpecialAll(harness.Test):
__all__ = ["foo"]
''')
def test_unrecognizable(self):
"""
If C{__all__} is defined in a way that can't be recognized statically,
@ -578,7 +571,6 @@ class TestSpecialAll(harness.Test):
__all__ = [] + ["foo"]
''', m.UnusedImport)
def test_unboundExported(self):
"""
If C{__all__} includes a name which is not bound, a warning is emitted.
@ -594,7 +586,6 @@ class TestSpecialAll(harness.Test):
__all__ = ["foo"]
''', filename=filename)
def test_usedInGenExp(self):
"""
Using a global in a generator expression results in no warnings.
@ -602,14 +593,13 @@ class TestSpecialAll(harness.Test):
self.flakes('import fu; (fu for _ in range(1))')
self.flakes('import fu; (1 for _ in range(1) if fu)')
def test_redefinedByGenExp(self):
"""
Re-using a global name as the loop variable for a generator
expression results in a redefinition warning.
"""
self.flakes('import fu; (1 for fu in range(1))', m.RedefinedWhileUnused)
self.flakes('import fu; (1 for fu in range(1))',
m.RedefinedWhileUnused)
def test_usedAsDecorator(self):
"""
@ -645,7 +635,6 @@ class Python26Tests(harness.Test):
if version_info < (2, 6):
skip = "Python 2.6 required for class decorator tests."
def test_usedAsClassDecorator(self):
"""
Using an imported name as a class decorator results in no warnings,

View file

@ -23,7 +23,8 @@ class Test(harness.Test):
a; a=1
f()
''', m.UndefinedName)
test_localReferencedBeforeAssignment.todo = 'this requires finding all assignments in the function body first'
test_localReferencedBeforeAssignment.todo = 'this requires finding all ' \
'assignments in the function body first'
def test_redefinedFunction(self):
"""
@ -73,7 +74,6 @@ class Test(harness.Test):
'''Don't die on unary +'''
self.flakes('+1')
def test_undefinedBaseClass(self):
"""
If a name in the base list of a class definition is undefined, a
@ -84,7 +84,6 @@ class Test(harness.Test):
pass
''', m.UndefinedName)
def test_classNameUndefinedInClassBody(self):
"""
If a class name is used in the body of that class's definition and
@ -95,7 +94,6 @@ class Test(harness.Test):
foo
''', m.UndefinedName)
def test_classNameDefinedPreviously(self):
"""
If a class name is used in the body of that class's definition and
@ -108,7 +106,6 @@ class Test(harness.Test):
foo
''')
def test_comparison(self):
"""
If a defined name is used on either side of any of the six comparison
@ -125,7 +122,6 @@ class Test(harness.Test):
x > y
''')
def test_identity(self):
"""
If a deefined name is used on either side of an identity test, no
@ -138,7 +134,6 @@ class Test(harness.Test):
x is not y
''')
def test_containment(self):
"""
If a defined name is used on either side of a containment test, no
@ -151,7 +146,6 @@ class Test(harness.Test):
x not in y
''')
def test_loopControl(self):
"""
break and continue statements are supported.
@ -165,7 +159,6 @@ class Test(harness.Test):
continue
''')
def test_ellipsis(self):
"""
Ellipsis in a slice is supported.
@ -174,7 +167,6 @@ class Test(harness.Test):
[1, 2][...]
''')
def test_extendedSlice(self):
"""
Extended slices are supported.
@ -185,7 +177,6 @@ class Test(harness.Test):
''')
class TestUnusedAssignment(harness.Test):
"""
Tests for warning about unused assignments.
@ -201,7 +192,6 @@ class TestUnusedAssignment(harness.Test):
b = 1
''', m.UnusedVariable)
def test_assignToGlobal(self):
"""
Assigning to a global and then not using that global is perfectly
@ -214,7 +204,6 @@ class TestUnusedAssignment(harness.Test):
b = 1
''')
def test_assignToMember(self):
"""
Assigning to a member of another object and then not using that member
@ -230,7 +219,6 @@ class TestUnusedAssignment(harness.Test):
b.foo = 1
''')
def test_assignInForLoop(self):
"""
Don't warn when a variable in a for loop is assigned to but not used.
@ -241,7 +229,6 @@ class TestUnusedAssignment(harness.Test):
pass
''')
def test_assignInListComprehension(self):
"""
Don't warn when a variable in a list comprehension is assigned to but
@ -252,17 +239,16 @@ class TestUnusedAssignment(harness.Test):
[None for i in range(10)]
''')
def test_generatorExpression(self):
"""
Don't warn when a variable in a generator expression is assigned to but not used.
Don't warn when a variable in a generator expression is assigned to
but not used.
"""
self.flakes('''
def f():
(None for i in range(10))
''')
def test_assignmentInsideLoop(self):
"""
Don't warn when a variable assignment occurs lexically after its use.
@ -276,7 +262,6 @@ class TestUnusedAssignment(harness.Test):
x = i * 2
''')
def test_tupleUnpacking(self):
"""
Don't warn when a variable included in tuple unpacking is unused. It's
@ -288,7 +273,6 @@ class TestUnusedAssignment(harness.Test):
(x, y) = 1, 2
''')
def test_listUnpacking(self):
"""
Don't warn when a variable included in list unpacking is unused.
@ -298,7 +282,6 @@ class TestUnusedAssignment(harness.Test):
[x, y] = [1, 2]
''')
def test_closedOver(self):
"""
Don't warn when the assignment is used in an inner function.
@ -311,7 +294,6 @@ class TestUnusedAssignment(harness.Test):
return bar
''')
def test_doubleClosedOver(self):
"""
Don't warn when the assignment is used in an inner function, even if
@ -327,7 +309,6 @@ class TestUnusedAssignment(harness.Test):
''')
class Python25Test(harness.Test):
"""
Tests for checking of syntax only available in Python 2.5 and newer.
@ -343,7 +324,6 @@ class Python25Test(harness.Test):
self.flakes("a = foo if True else 'oink'", m.UndefinedName)
self.flakes("a = 'moo' if True else bar", m.UndefinedName)
def test_withStatementNoNames(self):
"""
No warnings are emitted for using inside or after a nameless C{with}
@ -369,7 +349,6 @@ class Python25Test(harness.Test):
bar
''')
def test_withStatementAttributeName(self):
"""
No warnings are emitted for using an attribute as the target of a
@ -382,7 +361,6 @@ class Python25Test(harness.Test):
pass
''')
def test_withStatementSubscript(self):
"""
No warnings are emitted for using a subscript as the target of a
@ -395,7 +373,6 @@ class Python25Test(harness.Test):
pass
''')
def test_withStatementSubscriptUndefined(self):
"""
An undefined name warning is emitted if the subscript used as the
@ -408,7 +385,6 @@ class Python25Test(harness.Test):
pass
''', m.UndefinedName)
def test_withStatementTupleNames(self):
"""
No warnings are emitted for using any of the tuple of names defined by
@ -421,7 +397,6 @@ class Python25Test(harness.Test):
bar, baz
''')
def test_withStatementListNames(self):
"""
No warnings are emitted for using any of the list of names defined by a
@ -434,7 +409,6 @@ class Python25Test(harness.Test):
bar, baz
''')
def test_withStatementComplicatedTarget(self):
"""
If the target of a C{with} statement uses any or all of the valid forms
@ -451,7 +425,6 @@ class Python25Test(harness.Test):
a, b, c, d, e, g, h, i
''')
def test_withStatementSingleNameUndefined(self):
"""
An undefined name warning is emitted if the name first defined by a
@ -464,7 +437,6 @@ class Python25Test(harness.Test):
pass
''', m.UndefinedName)
def test_withStatementTupleNamesUndefined(self):
"""
An undefined name warning is emitted if a name first defined by a the
@ -478,7 +450,6 @@ class Python25Test(harness.Test):
pass
''', m.UndefinedName)
def test_withStatementSingleNameRedefined(self):
"""
A redefined name warning is emitted if a name bound by an import is
@ -491,7 +462,6 @@ class Python25Test(harness.Test):
pass
''', m.RedefinedWhileUnused)
def test_withStatementTupleNamesRedefined(self):
"""
A redefined name warning is emitted if a name bound by an import is
@ -505,7 +475,6 @@ class Python25Test(harness.Test):
pass
''', m.RedefinedWhileUnused)
def test_withStatementUndefinedInside(self):
"""
An undefined name warning is emitted if a name is used inside the
@ -517,7 +486,6 @@ class Python25Test(harness.Test):
baz
''', m.UndefinedName)
def test_withStatementNameDefinedInBody(self):
"""
A name defined in the body of a C{with} statement can be used after
@ -530,7 +498,6 @@ class Python25Test(harness.Test):
baz
''')
def test_withStatementUndefinedInExpression(self):
"""
An undefined name warning is emitted if a name in the I{test}
@ -549,7 +516,6 @@ class Python25Test(harness.Test):
''', m.UndefinedName)
class Python27Test(harness.Test):
"""
Tests for checking of syntax only available in Python 2.7 and newer.

View file

@ -11,6 +11,7 @@ from twisted.trial.unittest import TestCase
from pyflakes.scripts.pyflakes import checkPath
def withStderrTo(stderr, f):
"""
Call C{f} with C{sys.stderr} redirected to C{stderr}.
@ -22,7 +23,6 @@ def withStderrTo(stderr, f):
sys.stderr = outer
class CheckTests(TestCase):
"""
Tests for L{check} and L{checkPath} which check a file for flakes.
@ -37,17 +37,16 @@ class CheckTests(TestCase):
FilePath(fName).setContent("def foo():\n\tpass\n\t")
self.assertFalse(checkPath(fName))
def test_checkPathNonExisting(self):
"""
L{checkPath} handles non-existing files.
"""
err = StringIO()
count = withStderrTo(err, lambda: checkPath('extremo'))
self.assertEquals(err.getvalue(), 'extremo: No such file or directory\n')
self.assertEquals(err.getvalue(),
'extremo: No such file or directory\n')
self.assertEquals(count, 1)
def test_multilineSyntaxError(self):
"""
Source which includes a syntax error which results in the raised
@ -86,7 +85,6 @@ def baz():
^
""" % (sourcePath.path,))
def test_eofSyntaxError(self):
"""
The error reported for source files which end prematurely causing a
@ -106,7 +104,6 @@ def foo(
^
""" % (sourcePath.path,))
def test_nonDefaultFollowsDefaultSyntaxError(self):
"""
Source which has a non-default argument following a default argument
@ -129,7 +126,6 @@ def foo(bar=baz, bax):
def foo(bar=baz, bax):
""" % (sourcePath.path,))
def test_nonKeywordAfterKeywordSyntaxError(self):
"""
Source which has a non-keyword argument after a keyword argument should
@ -151,7 +147,6 @@ foo(bar=baz, bax)
foo(bar=baz, bax)
""" % (sourcePath.path,))
def test_permissionDenied(self):
"""
If the a source file is not readable, this is reported on standard
@ -166,7 +161,6 @@ foo(bar=baz, bax)
self.assertEquals(
err.getvalue(), "%s: Permission denied\n" % (sourcePath.path,))
def test_misencodedFile(self):
"""
If a source file contains bytes which cannot be decoded, this is
@ -182,4 +176,5 @@ x = "\N{SNOWMAN}"
count = withStderrTo(err, lambda: checkPath(sourcePath.path))
self.assertEquals(count, 1)
self.assertEquals(
err.getvalue(), "%s: problem decoding source\n" % (sourcePath.path,))
err.getvalue(),
"%s: problem decoding source\n" % (sourcePath.path,))

View file

@ -14,7 +14,6 @@ class Test(harness.Test):
def test_definedInListComp(self):
self.flakes('[a for a in range(10) if a]')
def test_functionsNeedGlobalScope(self):
self.flakes('''
class a:
@ -26,7 +25,6 @@ class Test(harness.Test):
def test_builtins(self):
self.flakes('range(10)')
def test_magicGlobalsFile(self):
"""
Use of the C{__file__} magic global should not emit an undefined name
@ -34,7 +32,6 @@ class Test(harness.Test):
"""
self.flakes('__file__')
def test_magicGlobalsBuiltins(self):
"""
Use of the C{__builtins__} magic global should not emit an undefined
@ -42,7 +39,6 @@ class Test(harness.Test):
"""
self.flakes('__builtins__')
def test_magicGlobalsName(self):
"""
Use of the C{__name__} magic global should not emit an undefined name
@ -50,7 +46,6 @@ class Test(harness.Test):
"""
self.flakes('__name__')
def test_magicGlobalsPath(self):
"""
Use of the C{__path__} magic global should not emit an undefined name
@ -59,13 +54,15 @@ class Test(harness.Test):
self.flakes('__path__', m.UndefinedName)
self.flakes('__path__', filename='package/__init__.py')
def test_globalImportStar(self):
'''Can't find undefined names with import *'''
self.flakes('from fu import *; bar', m.ImportStarUsed)
def test_localImportStar(self):
'''A local import * still allows undefined names to be found in upper scopes'''
'''
A local import * still allows undefined names to be found
in upper scopes
'''
self.flakes('''
def a():
from fu import *
@ -80,7 +77,10 @@ class Test(harness.Test):
''')
def test_definedByGlobal(self):
'''"global" can make an otherwise undefined name in another function defined'''
'''
"global" can make an otherwise undefined name
in another function defined
'''
self.flakes('''
def a(): global fu; fu = 1
def b(): fu
@ -153,13 +153,12 @@ class Test(harness.Test):
return a
''', m.UndefinedLocal)
def test_intermediateClassScopeIgnored(self):
"""
If a name defined in an enclosing scope is shadowed by a local variable
and the name is used locally before it is bound, an unbound local
warning is emitted, even if there is a class scope between the enclosing
scope and the local scope.
warning is emitted, even if there is a class scope between
the enclosing scope and the local scope.
"""
self.flakes('''
def f():
@ -172,7 +171,6 @@ class Test(harness.Test):
print x
''', m.UndefinedLocal)
def test_doubleNestingReportsClosestName(self):
"""
Test that referencing a local name in a nested scope that shadows a
@ -194,7 +192,6 @@ class Test(harness.Test):
''', m.UndefinedLocal).messages[0]
self.assertEqual(exc.message_args, ('x', 5))
def test_laterRedefinedGlobalFromNestedScope3(self):
"""
Test that referencing a local name in a nested scope that shadows a
@ -249,15 +246,14 @@ class Test(harness.Test):
self.flakes('(a for a in xrange(10) if a)')
class NameTests(TestCase):
"""
Tests for some extra cases of name handling.
"""
def test_impossibleContext(self):
"""
A Name node with an unrecognized context results in a RuntimeError being
raised.
A Name node with an unrecognized context results in a RuntimeError
being raised.
"""
tree = compile("x = 10", "<test>", "exec", PyCF_ONLY_AST)
# Make it into something unrecognizable.