/pyflakes/test/test_other.py
Python | 575 lines | 509 code | 7 blank | 59 comment | 19 complexity | 2197ea333deaed1044ff4fbc80f5b794 MD5 | raw file
- # (c) 2005-2010 Divmod, Inc.
- # See LICENSE file for details
- """
- Tests for various Pyflakes behavior.
- """
- from sys import version_info
- from pyflakes import messages as m
- from pyflakes.test import harness
- class Test(harness.Test):
- def test_duplicateArgs(self):
- self.flakes('def fu(bar, bar): pass', m.DuplicateArgument)
- def test_localReferencedBeforeAssignment(self):
- self.flakes('''
- a = 1
- def f():
- a; a=1
- f()
- ''', m.UndefinedName)
- test_localReferencedBeforeAssignment.todo = 'this requires finding all assignments in the function body first'
- def test_redefinedFunction(self):
- """
- Test that shadowing a function definition with another one raises a
- warning.
- """
- self.flakes('''
- def a(): pass
- def a(): pass
- ''', m.RedefinedFunction)
- def test_redefinedClassFunction(self):
- """
- Test that shadowing a function definition in a class suite with another
- one raises a warning.
- """
- self.flakes('''
- class A:
- def a(): pass
- def a(): pass
- ''', m.RedefinedFunction)
- def test_functionDecorator(self):
- """
- Test that shadowing a function definition with a decorated version of
- that function does not raise a warning.
- """
- self.flakes('''
- from somewhere import somedecorator
- def a(): pass
- a = somedecorator(a)
- ''')
- def test_classFunctionDecorator(self):
- """
- Test that shadowing a function definition in a class suite with a
- decorated version of that function does not raise a warning.
- """
- self.flakes('''
- class A:
- def a(): pass
- a = classmethod(a)
- ''')
- def test_unaryPlus(self):
- '''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
- warning is emitted.
- """
- self.flakes('''
- class foo(foo):
- pass
- ''', m.UndefinedName)
- def test_classNameUndefinedInClassBody(self):
- """
- If a class name is used in the body of that class's definition and
- the name is not already defined, a warning is emitted.
- """
- self.flakes('''
- class foo:
- foo
- ''', m.UndefinedName)
- def test_classNameDefinedPreviously(self):
- """
- If a class name is used in the body of that class's definition and
- the name was previously defined in some other way, no warning is
- emitted.
- """
- self.flakes('''
- foo = None
- class foo:
- foo
- ''')
- def test_comparison(self):
- """
- If a defined name is used on either side of any of the six comparison
- operators, no warning is emitted.
- """
- self.flakes('''
- x = 10
- y = 20
- x < y
- x <= y
- x == y
- x != y
- x >= y
- x > y
- ''')
- def test_identity(self):
- """
- If a deefined name is used on either side of an identity test, no
- warning is emitted.
- """
- self.flakes('''
- x = 10
- y = 20
- x is y
- x is not y
- ''')
- def test_containment(self):
- """
- If a defined name is used on either side of a containment test, no
- warning is emitted.
- """
- self.flakes('''
- x = 10
- y = 20
- x in y
- x not in y
- ''')
- def test_loopControl(self):
- """
- break and continue statements are supported.
- """
- self.flakes('''
- for x in [1, 2]:
- break
- ''')
- self.flakes('''
- for x in [1, 2]:
- continue
- ''')
- def test_ellipsis(self):
- """
- Ellipsis in a slice is supported.
- """
- self.flakes('''
- [1, 2][...]
- ''')
- def test_extendedSlice(self):
- """
- Extended slices are supported.
- """
- self.flakes('''
- x = 3
- [1, 2][x,:]
- ''')
- class TestUnusedAssignment(harness.Test):
- """
- Tests for warning about unused assignments.
- """
- def test_unusedVariable(self):
- """
- Warn when a variable in a function is assigned a value that's never
- used.
- """
- self.flakes('''
- def a():
- b = 1
- ''', m.UnusedVariable)
- def test_assignToGlobal(self):
- """
- Assigning to a global and then not using that global is perfectly
- acceptable. Do not mistake it for an unused local variable.
- """
- self.flakes('''
- b = 0
- def a():
- global b
- b = 1
- ''')
- def test_assignToMember(self):
- """
- Assigning to a member of another object and then not using that member
- variable is perfectly acceptable. Do not mistake it for an unused
- local variable.
- """
- # XXX: Adding this test didn't generate a failure. Maybe not
- # necessary?
- self.flakes('''
- class b:
- pass
- def a():
- b.foo = 1
- ''')
- def test_assignInForLoop(self):
- """
- Don't warn when a variable in a for loop is assigned to but not used.
- """
- self.flakes('''
- def f():
- for i in range(10):
- pass
- ''')
- def test_assignInListComprehension(self):
- """
- Don't warn when a variable in a list comprehension is assigned to but
- not used.
- """
- self.flakes('''
- def f():
- [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.
- """
- 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.
- """
- self.flakes('''
- def f():
- x = None
- for i in range(10):
- if i > 2:
- return x
- x = i * 2
- ''')
- def test_tupleUnpacking(self):
- """
- Don't warn when a variable included in tuple unpacking is unused. It's
- very common for variables in a tuple unpacking assignment to be unused
- in good Python code, so warning will only create false positives.
- """
- self.flakes('''
- def f():
- (x, y) = 1, 2
- ''')
- def test_listUnpacking(self):
- """
- Don't warn when a variable included in list unpacking is unused.
- """
- self.flakes('''
- def f():
- [x, y] = [1, 2]
- ''')
- def test_closedOver(self):
- """
- Don't warn when the assignment is used in an inner function.
- """
- self.flakes('''
- def barMaker():
- foo = 5
- def bar():
- return foo
- return bar
- ''')
- def test_doubleClosedOver(self):
- """
- Don't warn when the assignment is used in an inner function, even if
- that inner function itself is in an inner function.
- """
- self.flakes('''
- def barMaker():
- foo = 5
- def bar():
- def baz():
- return foo
- return bar
- ''')
- class Python25Test(harness.Test):
- """
- Tests for checking of syntax only available in Python 2.5 and newer.
- """
- if version_info < (2, 5):
- skip = "Python 2.5 required for if-else and with tests"
- def test_ifexp(self):
- """
- Test C{foo if bar else baz} statements.
- """
- self.flakes("a = 'moo' if True else 'oink'")
- 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}
- statement a name defined beforehand.
- """
- self.flakes('''
- from __future__ import with_statement
- bar = None
- with open("foo"):
- bar
- bar
- ''')
- def test_withStatementSingleName(self):
- """
- No warnings are emitted for using a name defined by a C{with} statement
- within the suite or afterwards.
- """
- self.flakes('''
- from __future__ import with_statement
- with open('foo') as bar:
- bar
- bar
- ''')
- def test_withStatementAttributeName(self):
- """
- No warnings are emitted for using an attribute as the target of a
- C{with} statement.
- """
- self.flakes('''
- from __future__ import with_statement
- import foo
- with open('foo') as foo.bar:
- pass
- ''')
- def test_withStatementSubscript(self):
- """
- No warnings are emitted for using a subscript as the target of a
- C{with} statement.
- """
- self.flakes('''
- from __future__ import with_statement
- import foo
- with open('foo') as foo[0]:
- pass
- ''')
- def test_withStatementSubscriptUndefined(self):
- """
- An undefined name warning is emitted if the subscript used as the
- target of a C{with} statement is not defined.
- """
- self.flakes('''
- from __future__ import with_statement
- import foo
- with open('foo') as foo[bar]:
- pass
- ''', m.UndefinedName)
- def test_withStatementTupleNames(self):
- """
- No warnings are emitted for using any of the tuple of names defined by
- a C{with} statement within the suite or afterwards.
- """
- self.flakes('''
- from __future__ import with_statement
- with open('foo') as (bar, baz):
- bar, baz
- bar, baz
- ''')
- def test_withStatementListNames(self):
- """
- No warnings are emitted for using any of the list of names defined by a
- C{with} statement within the suite or afterwards.
- """
- self.flakes('''
- from __future__ import with_statement
- with open('foo') as [bar, baz]:
- bar, baz
- bar, baz
- ''')
- def test_withStatementComplicatedTarget(self):
- """
- If the target of a C{with} statement uses any or all of the valid forms
- for that part of the grammar (See
- U{http://docs.python.org/reference/compound_stmts.html#the-with-statement}),
- the names involved are checked both for definedness and any bindings
- created are respected in the suite of the statement and afterwards.
- """
- self.flakes('''
- from __future__ import with_statement
- c = d = e = g = h = i = None
- with open('foo') as [(a, b), c[d], e.f, g[h:i]]:
- a, b, c, d, e, g, h, i
- 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
- C{with} statement is used before the C{with} statement.
- """
- self.flakes('''
- from __future__ import with_statement
- bar
- with open('foo') as bar:
- pass
- ''', m.UndefinedName)
- def test_withStatementTupleNamesUndefined(self):
- """
- An undefined name warning is emitted if a name first defined by a the
- tuple-unpacking form of the C{with} statement is used before the
- C{with} statement.
- """
- self.flakes('''
- from __future__ import with_statement
- baz
- with open('foo') as (bar, baz):
- pass
- ''', m.UndefinedName)
- def test_withStatementSingleNameRedefined(self):
- """
- A redefined name warning is emitted if a name bound by an import is
- rebound by the name defined by a C{with} statement.
- """
- self.flakes('''
- from __future__ import with_statement
- import bar
- with open('foo') as bar:
- pass
- ''', m.RedefinedWhileUnused)
- def test_withStatementTupleNamesRedefined(self):
- """
- A redefined name warning is emitted if a name bound by an import is
- rebound by one of the names defined by the tuple-unpacking form of a
- C{with} statement.
- """
- self.flakes('''
- from __future__ import with_statement
- import bar
- with open('foo') as (bar, baz):
- pass
- ''', m.RedefinedWhileUnused)
- def test_withStatementUndefinedInside(self):
- """
- An undefined name warning is emitted if a name is used inside the
- body of a C{with} statement without first being bound.
- """
- self.flakes('''
- from __future__ import with_statement
- with open('foo') as bar:
- baz
- ''', m.UndefinedName)
- def test_withStatementNameDefinedInBody(self):
- """
- A name defined in the body of a C{with} statement can be used after
- the body ends without warning.
- """
- self.flakes('''
- from __future__ import with_statement
- with open('foo') as bar:
- baz = 10
- baz
- ''')
- def test_withStatementUndefinedInExpression(self):
- """
- An undefined name warning is emitted if a name in the I{test}
- expression of a C{with} statement is undefined.
- """
- self.flakes('''
- from __future__ import with_statement
- with bar as baz:
- pass
- ''', m.UndefinedName)
- self.flakes('''
- from __future__ import with_statement
- with bar as bar:
- pass
- ''', m.UndefinedName)
- class Python27Test(harness.Test):
- """
- Tests for checking of syntax only available in Python 2.7 and newer.
- """
- if version_info < (2, 7):
- skip = "Python 2.7 required for dict/set comprehension tests"
- def test_dictComprehension(self):
- """
- Dict comprehensions are properly handled.
- """
- self.flakes('''
- a = {1: x for x in range(10)}
- ''')
- def test_setComprehensionAndLiteral(self):
- """
- Set comprehensions are properly handled.
- """
- self.flakes('''
- a = {1, 2, 3}
- b = {x for x in range(10)}
- ''')