| 1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207 |
- from pyflakes import messages as m
- from pyflakes.checker import (
- FutureImportation,
- Importation,
- ImportationFrom,
- StarImportation,
- SubmoduleImportation,
- )
- from pyflakes.test.harness import TestCase, skip
- class TestImportationObject(TestCase):
- def test_import_basic(self):
- binding = Importation('a', None, 'a')
- assert binding.source_statement == 'import a'
- assert str(binding) == 'a'
- def test_import_as(self):
- binding = Importation('c', None, 'a')
- assert binding.source_statement == 'import a as c'
- assert str(binding) == 'a as c'
- def test_import_submodule(self):
- binding = SubmoduleImportation('a.b', None)
- assert binding.source_statement == 'import a.b'
- assert str(binding) == 'a.b'
- def test_import_submodule_as(self):
- # A submodule import with an as clause is not a SubmoduleImportation
- binding = Importation('c', None, 'a.b')
- assert binding.source_statement == 'import a.b as c'
- assert str(binding) == 'a.b as c'
- def test_import_submodule_as_source_name(self):
- binding = Importation('a', None, 'a.b')
- assert binding.source_statement == 'import a.b as a'
- assert str(binding) == 'a.b as a'
- def test_importfrom_relative(self):
- binding = ImportationFrom('a', None, '.', 'a')
- assert binding.source_statement == 'from . import a'
- assert str(binding) == '.a'
- def test_importfrom_relative_parent(self):
- binding = ImportationFrom('a', None, '..', 'a')
- assert binding.source_statement == 'from .. import a'
- assert str(binding) == '..a'
- def test_importfrom_relative_with_module(self):
- binding = ImportationFrom('b', None, '..a', 'b')
- assert binding.source_statement == 'from ..a import b'
- assert str(binding) == '..a.b'
- def test_importfrom_relative_with_module_as(self):
- binding = ImportationFrom('c', None, '..a', 'b')
- assert binding.source_statement == 'from ..a import b as c'
- assert str(binding) == '..a.b as c'
- def test_importfrom_member(self):
- binding = ImportationFrom('b', None, 'a', 'b')
- assert binding.source_statement == 'from a import b'
- assert str(binding) == 'a.b'
- def test_importfrom_submodule_member(self):
- binding = ImportationFrom('c', None, 'a.b', 'c')
- assert binding.source_statement == 'from a.b import c'
- assert str(binding) == 'a.b.c'
- def test_importfrom_member_as(self):
- binding = ImportationFrom('c', None, 'a', 'b')
- assert binding.source_statement == 'from a import b as c'
- assert str(binding) == 'a.b as c'
- def test_importfrom_submodule_member_as(self):
- binding = ImportationFrom('d', None, 'a.b', 'c')
- assert binding.source_statement == 'from a.b import c as d'
- assert str(binding) == 'a.b.c as d'
- def test_importfrom_star(self):
- binding = StarImportation('a.b', None)
- assert binding.source_statement == 'from a.b import *'
- assert str(binding) == 'a.b.*'
- def test_importfrom_star_relative(self):
- binding = StarImportation('.b', None)
- assert binding.source_statement == 'from .b import *'
- assert str(binding) == '.b.*'
- def test_importfrom_future(self):
- binding = FutureImportation('print_function', None, None)
- assert binding.source_statement == 'from __future__ import print_function'
- assert str(binding) == '__future__.print_function'
- def test_unusedImport_underscore(self):
- """
- The magic underscore var should be reported as unused when used as an
- import alias.
- """
- self.flakes('import fu as _', m.UnusedImport)
- class Test(TestCase):
- def test_unusedImport(self):
- self.flakes('import fu, bar', m.UnusedImport, m.UnusedImport)
- self.flakes('from baz import fu, bar', m.UnusedImport, m.UnusedImport)
- def test_unusedImport_relative(self):
- self.flakes('from . import fu', m.UnusedImport)
- self.flakes('from . import fu as baz', m.UnusedImport)
- self.flakes('from .. import fu', m.UnusedImport)
- self.flakes('from ... import fu', m.UnusedImport)
- self.flakes('from .. import fu as baz', m.UnusedImport)
- self.flakes('from .bar import fu', m.UnusedImport)
- self.flakes('from ..bar import fu', m.UnusedImport)
- self.flakes('from ...bar import fu', m.UnusedImport)
- self.flakes('from ...bar import fu as baz', m.UnusedImport)
- checker = self.flakes('from . import fu', m.UnusedImport)
- error = checker.messages[0]
- assert error.message == '%r imported but unused'
- assert error.message_args == ('.fu', )
- checker = self.flakes('from . import fu as baz', m.UnusedImport)
- error = checker.messages[0]
- assert error.message == '%r imported but unused'
- assert error.message_args == ('.fu as baz', )
- 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)
- def test_aliasedImportShadowModule(self):
- """Imported aliases can shadow the source of the import."""
- self.flakes('from moo import fu as moo; moo')
- self.flakes('import fu as fu; fu')
- self.flakes('import fu.bar as fu; fu')
- def test_usedImport(self):
- self.flakes('import fu; print(fu)')
- self.flakes('from baz import fu; print(fu)')
- self.flakes('import fu; del fu')
- def test_usedImport_relative(self):
- self.flakes('from . import fu; assert fu')
- self.flakes('from .bar import fu; assert fu')
- self.flakes('from .. import fu; assert fu')
- self.flakes('from ..bar import fu as baz; assert baz')
- def test_redefinedWhileUnused(self):
- self.flakes('import fu; fu = 3', m.RedefinedWhileUnused)
- self.flakes('import fu; fu, bar = 3', m.RedefinedWhileUnused)
- self.flakes('import fu; [fu, bar] = 3', m.RedefinedWhileUnused)
- def test_redefinedIf(self):
- """
- Test that importing a module twice within an if
- block does raise a warning.
- """
- self.flakes('''
- i = 2
- if i==1:
- import os
- import os
- os.path''', m.RedefinedWhileUnused)
- def test_redefinedIfElse(self):
- """
- Test that importing a module twice in if
- and else blocks does not raise a warning.
- """
- self.flakes('''
- i = 2
- if i==1:
- import os
- else:
- import os
- os.path''')
- def test_redefinedTry(self):
- """
- Test that importing a module twice in a try block
- does raise a warning.
- """
- self.flakes('''
- try:
- import os
- import os
- except:
- pass
- os.path''', m.RedefinedWhileUnused)
- def test_redefinedTryExcept(self):
- """
- Test that importing a module twice in a try
- and except block does not raise a warning.
- """
- self.flakes('''
- try:
- import os
- except:
- import os
- os.path''')
- def test_redefinedTryNested(self):
- """
- Test that importing a module twice using a nested
- try/except and if blocks does not issue a warning.
- """
- self.flakes('''
- try:
- if True:
- if True:
- import os
- except:
- import os
- os.path''')
- def test_redefinedTryExceptMulti(self):
- self.flakes("""
- try:
- from aa import mixer
- except AttributeError:
- from bb import mixer
- except RuntimeError:
- from cc import mixer
- except:
- from dd import mixer
- mixer(123)
- """)
- def test_redefinedTryElse(self):
- self.flakes("""
- try:
- from aa import mixer
- except ImportError:
- pass
- else:
- from bb import mixer
- mixer(123)
- """, m.RedefinedWhileUnused)
- def test_redefinedTryExceptElse(self):
- self.flakes("""
- try:
- import funca
- except ImportError:
- from bb import funca
- from bb import funcb
- else:
- from bbb import funcb
- print(funca, funcb)
- """)
- def test_redefinedTryExceptFinally(self):
- self.flakes("""
- try:
- from aa import a
- except ImportError:
- from bb import a
- finally:
- a = 42
- print(a)
- """)
- def test_redefinedTryExceptElseFinally(self):
- self.flakes("""
- try:
- import b
- except ImportError:
- b = Ellipsis
- from bb import a
- else:
- from aa import a
- finally:
- a = 42
- print(a, b)
- """)
- def test_redefinedByFunction(self):
- self.flakes('''
- import fu
- def fu():
- pass
- ''', m.RedefinedWhileUnused)
- def test_redefinedInNestedFunction(self):
- """
- Test that shadowing a global name with a nested function definition
- generates a warning.
- """
- self.flakes('''
- import fu
- def bar():
- def baz():
- def fu():
- pass
- ''', m.RedefinedWhileUnused, m.UnusedImport)
- def test_redefinedInNestedFunctionTwice(self):
- """
- Test that shadowing a global name with a nested function definition
- generates a warning.
- """
- self.flakes('''
- import fu
- def bar():
- import fu
- def baz():
- def fu():
- pass
- ''',
- m.RedefinedWhileUnused, m.RedefinedWhileUnused,
- m.UnusedImport, m.UnusedImport)
- def test_redefinedButUsedLater(self):
- """
- Test that a global import which is redefined locally,
- but used later in another scope does not generate a warning.
- """
- self.flakes('''
- import unittest, transport
- class GetTransportTestCase(unittest.TestCase):
- def test_get_transport(self):
- transport = 'transport'
- self.assertIsNotNone(transport)
- class TestTransportMethodArgs(unittest.TestCase):
- def test_send_defaults(self):
- transport.Transport()
- ''')
- def test_redefinedByClass(self):
- self.flakes('''
- import fu
- class fu:
- pass
- ''', m.RedefinedWhileUnused)
- def test_redefinedBySubclass(self):
- """
- If an imported name is redefined by a class statement which also uses
- that name in the bases list, no warning is emitted.
- """
- self.flakes('''
- from fu import bar
- class bar(bar):
- pass
- ''')
- def test_redefinedInClass(self):
- """
- Test that shadowing a global with a class attribute does not produce a
- warning.
- """
- self.flakes('''
- import fu
- class bar:
- fu = 1
- print(fu)
- ''')
- def test_importInClass(self):
- """
- Test that import within class is a locally scoped attribute.
- """
- self.flakes('''
- class bar:
- import fu
- ''')
- self.flakes('''
- class bar:
- import fu
- fu
- ''', m.UndefinedName)
- def test_usedInFunction(self):
- self.flakes('''
- import fu
- def fun():
- print(fu)
- ''')
- def test_shadowedByParameter(self):
- self.flakes('''
- import fu
- def fun(fu):
- print(fu)
- ''', m.UnusedImport, m.RedefinedWhileUnused)
- self.flakes('''
- import fu
- def fun(fu):
- print(fu)
- print(fu)
- ''')
- def test_newAssignment(self):
- self.flakes('fu = None')
- def test_usedInGetattr(self):
- self.flakes('import fu; fu.bar.baz')
- self.flakes('import fu; "bar".fu.baz', m.UnusedImport)
- def test_usedInSlice(self):
- self.flakes('import fu; print(fu.bar[1:])')
- def test_usedInIfBody(self):
- self.flakes('''
- import fu
- if True: print(fu)
- ''')
- def test_usedInIfConditional(self):
- self.flakes('''
- import fu
- if fu: pass
- ''')
- def test_usedInElifConditional(self):
- self.flakes('''
- import fu
- if False: pass
- elif fu: pass
- ''')
- def test_usedInElse(self):
- self.flakes('''
- import fu
- if False: pass
- else: print(fu)
- ''')
- def test_usedInCall(self):
- self.flakes('import fu; fu.bar()')
- def test_usedInClass(self):
- self.flakes('''
- import fu
- class bar:
- bar = fu
- ''')
- def test_usedInClassBase(self):
- self.flakes('''
- import fu
- class bar(object, fu.baz):
- pass
- ''')
- def test_notUsedInNestedScope(self):
- self.flakes('''
- import fu
- def bleh():
- pass
- print(fu)
- ''')
- def test_usedInFor(self):
- self.flakes('''
- import fu
- for bar in range(9):
- print(fu)
- ''')
- def test_usedInForElse(self):
- self.flakes('''
- import fu
- for bar in range(10):
- pass
- else:
- print(fu)
- ''')
- def test_redefinedByFor(self):
- self.flakes('''
- import fu
- for fu in range(2):
- pass
- ''', m.ImportShadowedByLoopVar)
- def test_shadowedByFor(self):
- """
- Test that shadowing a global name with a for loop variable generates a
- warning.
- """
- self.flakes('''
- import fu
- fu.bar()
- for fu in ():
- pass
- ''', m.ImportShadowedByLoopVar)
- def test_shadowedByForDeep(self):
- """
- Test that shadowing a global name with a for loop variable nested in a
- tuple unpack generates a warning.
- """
- self.flakes('''
- import fu
- fu.bar()
- for (x, y, z, (a, b, c, (fu,))) in ():
- pass
- ''', m.ImportShadowedByLoopVar)
- # Same with a list instead of a tuple
- self.flakes('''
- import fu
- fu.bar()
- for [x, y, z, (a, b, c, (fu,))] in ():
- pass
- ''', m.ImportShadowedByLoopVar)
- def test_usedInReturn(self):
- self.flakes('''
- import fu
- def fun():
- return fu
- ''')
- def test_usedInOperators(self):
- self.flakes('import fu; 3 + fu.bar')
- self.flakes('import fu; 3 % fu.bar')
- self.flakes('import fu; 3 - fu.bar')
- self.flakes('import fu; 3 * fu.bar')
- self.flakes('import fu; 3 ** fu.bar')
- self.flakes('import fu; 3 / fu.bar')
- self.flakes('import fu; 3 // fu.bar')
- self.flakes('import fu; -fu.bar')
- self.flakes('import fu; ~fu.bar')
- self.flakes('import fu; 1 == fu.bar')
- self.flakes('import fu; 1 | fu.bar')
- self.flakes('import fu; 1 & fu.bar')
- self.flakes('import fu; 1 ^ fu.bar')
- self.flakes('import fu; 1 >> fu.bar')
- self.flakes('import fu; 1 << fu.bar')
- def test_usedInAssert(self):
- self.flakes('import fu; assert fu.bar')
- def test_usedInSubscript(self):
- self.flakes('import fu; fu.bar[1]')
- def test_usedInLogic(self):
- self.flakes('import fu; fu and False')
- self.flakes('import fu; fu or False')
- self.flakes('import fu; not fu.bar')
- def test_usedInList(self):
- self.flakes('import fu; [fu]')
- def test_usedInTuple(self):
- self.flakes('import fu; (fu,)')
- def test_usedInTry(self):
- self.flakes('''
- import fu
- try: fu
- except: pass
- ''')
- def test_usedInExcept(self):
- self.flakes('''
- import fu
- try: fu
- except: pass
- ''')
- def test_redefinedByExcept(self):
- expected = [m.RedefinedWhileUnused]
- # The exc variable is unused inside the exception handler.
- expected.append(m.UnusedVariable)
- self.flakes('''
- import fu
- try: pass
- except Exception as fu: pass
- ''', *expected)
- def test_usedInRaise(self):
- self.flakes('''
- import fu
- raise fu.bar
- ''')
- def test_usedInYield(self):
- self.flakes('''
- import fu
- def gen():
- yield fu
- ''')
- def test_usedInDict(self):
- self.flakes('import fu; {fu:None}')
- self.flakes('import fu; {1:fu}')
- def test_usedInParameterDefault(self):
- self.flakes('''
- import fu
- def f(bar=fu):
- pass
- ''')
- def test_usedInAttributeAssign(self):
- self.flakes('import fu; fu.bar = 1')
- def test_usedInKeywordArg(self):
- self.flakes('import fu; fu.bar(stuff=fu)')
- def test_usedInAssignment(self):
- self.flakes('import fu; bar=fu')
- self.flakes('import fu; n=0; n+=fu')
- def test_usedInListComp(self):
- self.flakes('import fu; [fu for _ in range(1)]')
- self.flakes('import fu; [1 for _ in range(1) if fu]')
- def test_usedInTryFinally(self):
- self.flakes('''
- import fu
- try: pass
- finally: fu
- ''')
- self.flakes('''
- import fu
- try: fu
- finally: pass
- ''')
- def test_usedInWhile(self):
- self.flakes('''
- import fu
- while 0:
- fu
- ''')
- self.flakes('''
- import fu
- while fu: pass
- ''')
- def test_usedInGlobal(self):
- """
- A 'global' statement shadowing an unused import should not prevent it
- from being reported.
- """
- self.flakes('''
- import fu
- def f(): global fu
- ''', m.UnusedImport)
- def test_usedAndGlobal(self):
- """
- A 'global' statement shadowing a used import should not cause it to be
- reported as unused.
- """
- self.flakes('''
- import foo
- def f(): global foo
- def g(): foo.is_used()
- ''')
- def test_assignedToGlobal(self):
- """
- Binding an import to a declared global should not cause it to be
- reported as unused.
- """
- self.flakes('''
- def f(): global foo; import foo
- def g(): foo.is_used()
- ''')
- def test_usedInExec(self):
- exec_stmt = 'exec("print(1)", fu.bar)'
- self.flakes('import fu; %s' % exec_stmt)
- def test_usedInLambda(self):
- self.flakes('import fu; lambda: fu')
- def test_shadowedByLambda(self):
- self.flakes('import fu; lambda fu: fu',
- m.UnusedImport, m.RedefinedWhileUnused)
- self.flakes('import fu; lambda fu: fu\nfu()')
- def test_usedInSliceObj(self):
- self.flakes('import fu; "meow"[::fu]')
- def test_unusedInNestedScope(self):
- self.flakes('''
- def bar():
- import fu
- fu
- ''', m.UnusedImport, m.UndefinedName)
- def test_methodsDontUseClassScope(self):
- self.flakes('''
- class bar:
- import fu
- def fun(self):
- fu
- ''', m.UndefinedName)
- def test_nestedFunctionsNestScope(self):
- self.flakes('''
- def a():
- def b():
- fu
- import fu
- ''')
- def test_nestedClassAndFunctionScope(self):
- self.flakes('''
- def a():
- import fu
- class b:
- def c(self):
- print(fu)
- ''')
- def test_importStar(self):
- """Use of import * at module level is reported."""
- self.flakes('from fu import *', m.ImportStarUsed, m.UnusedImport)
- self.flakes('''
- try:
- from fu import *
- except:
- pass
- ''', m.ImportStarUsed, m.UnusedImport)
- checker = self.flakes('from fu import *',
- m.ImportStarUsed, m.UnusedImport)
- error = checker.messages[0]
- assert error.message.startswith("'from %s import *' used; unable ")
- assert error.message_args == ('fu', )
- error = checker.messages[1]
- assert error.message == '%r imported but unused'
- assert error.message_args == ('fu.*', )
- def test_importStar_relative(self):
- """Use of import * from a relative import is reported."""
- self.flakes('from .fu import *', m.ImportStarUsed, m.UnusedImport)
- self.flakes('''
- try:
- from .fu import *
- except:
- pass
- ''', m.ImportStarUsed, m.UnusedImport)
- checker = self.flakes('from .fu import *',
- m.ImportStarUsed, m.UnusedImport)
- error = checker.messages[0]
- assert error.message.startswith("'from %s import *' used; unable ")
- assert error.message_args == ('.fu', )
- error = checker.messages[1]
- assert error.message == '%r imported but unused'
- assert error.message_args == ('.fu.*', )
- checker = self.flakes('from .. import *',
- m.ImportStarUsed, m.UnusedImport)
- error = checker.messages[0]
- assert error.message.startswith("'from %s import *' used; unable ")
- assert error.message_args == ('..', )
- error = checker.messages[1]
- assert error.message == '%r imported but unused'
- assert error.message_args == ('from .. import *', )
- def test_localImportStar(self):
- """import * is only allowed at module level."""
- self.flakes('''
- def a():
- from fu import *
- ''', m.ImportStarNotPermitted)
- self.flakes('''
- class a:
- from fu import *
- ''', m.ImportStarNotPermitted)
- checker = self.flakes('''
- class a:
- from .. import *
- ''', m.ImportStarNotPermitted)
- error = checker.messages[0]
- assert error.message == "'from %s import *' only allowed at module level"
- assert error.message_args == ('..', )
- def test_packageImport(self):
- """
- If a dotted name is imported and used, no warning is reported.
- """
- self.flakes('''
- import fu.bar
- fu.bar
- ''')
- def test_unusedPackageImport(self):
- """
- If a dotted name is imported and not used, an unused import warning is
- reported.
- """
- self.flakes('import fu.bar', m.UnusedImport)
- def test_duplicateSubmoduleImport(self):
- """
- If a submodule of a package is imported twice, an unused import warning
- and a redefined while unused warning are reported.
- """
- self.flakes('''
- import fu.bar, fu.bar
- fu.bar
- ''', m.RedefinedWhileUnused)
- self.flakes('''
- import fu.bar
- import fu.bar
- fu.bar
- ''', m.RedefinedWhileUnused)
- def test_differentSubmoduleImport(self):
- """
- If two different submodules of a package are imported, no duplicate
- import warning is reported for the package.
- """
- self.flakes('''
- import fu.bar, fu.baz
- fu.bar, fu.baz
- ''')
- self.flakes('''
- import fu.bar
- import fu.baz
- fu.bar, fu.baz
- ''')
- def test_used_package_with_submodule_import(self):
- """
- Usage of package marks submodule imports as used.
- """
- self.flakes('''
- import fu
- import fu.bar
- fu.x
- ''')
- self.flakes('''
- import fu.bar
- import fu
- fu.x
- ''')
- def test_used_package_with_submodule_import_of_alias(self):
- """
- Usage of package by alias marks submodule imports as used.
- """
- self.flakes('''
- import foo as f
- import foo.bar
- f.bar.do_something()
- ''')
- self.flakes('''
- import foo as f
- import foo.bar.blah
- f.bar.blah.do_something()
- ''')
- def test_unused_package_with_submodule_import(self):
- """
- When a package and its submodule are imported, only report once.
- """
- checker = self.flakes('''
- import fu
- import fu.bar
- ''', m.UnusedImport)
- error = checker.messages[0]
- assert error.message == '%r imported but unused'
- assert error.message_args == ('fu.bar', )
- assert error.lineno == 5 if self.withDoctest else 3
- def test_assignRHSFirst(self):
- self.flakes('import fu; fu = fu')
- self.flakes('import fu; fu, bar = fu')
- self.flakes('import fu; [fu, bar] = fu')
- self.flakes('import fu; fu += fu')
- def test_tryingMultipleImports(self):
- self.flakes('''
- try:
- import fu
- except ImportError:
- import bar as fu
- fu
- ''')
- def test_nonGlobalDoesNotRedefine(self):
- self.flakes('''
- import fu
- def a():
- fu = 3
- return fu
- fu
- ''')
- def test_functionsRunLater(self):
- self.flakes('''
- def a():
- fu
- import fu
- ''')
- def test_functionNamesAreBoundNow(self):
- self.flakes('''
- import fu
- def fu():
- fu
- fu
- ''', m.RedefinedWhileUnused)
- def test_ignoreNonImportRedefinitions(self):
- self.flakes('a = 1; a = 2')
- @skip("todo")
- def test_importingForImportError(self):
- self.flakes('''
- try:
- import fu
- except ImportError:
- pass
- ''')
- def test_importedInClass(self):
- """Imports in class scope can be used through self."""
- self.flakes('''
- class c:
- import i
- def __init__(self):
- self.i
- ''')
- def test_importUsedInMethodDefinition(self):
- """
- Method named 'foo' with default args referring to module named 'foo'.
- """
- self.flakes('''
- import foo
- class Thing(object):
- def foo(self, parser=foo.parse_foo):
- pass
- ''')
- def test_futureImport(self):
- """__future__ is special."""
- self.flakes('from __future__ import division')
- self.flakes('''
- "docstring is allowed before future import"
- from __future__ import division
- ''')
- def test_futureImportFirst(self):
- """
- __future__ imports must come before anything else.
- """
- self.flakes('''
- x = 5
- from __future__ import division
- ''', m.LateFutureImport)
- self.flakes('''
- from foo import bar
- from __future__ import division
- bar
- ''', m.LateFutureImport)
- def test_futureImportUsed(self):
- """__future__ is special, but names are injected in the namespace."""
- self.flakes('''
- from __future__ import division
- from __future__ import print_function
- assert print_function is not division
- ''')
- def test_futureImportUndefined(self):
- """Importing undefined names from __future__ fails."""
- self.flakes('''
- from __future__ import print_statement
- ''', m.FutureFeatureNotDefined)
- def test_futureImportStar(self):
- """Importing '*' from __future__ fails."""
- self.flakes('''
- from __future__ import *
- ''', m.FutureFeatureNotDefined)
- class TestSpecialAll(TestCase):
- """
- Tests for suppression of unused import warnings by C{__all__}.
- """
- def test_ignoredInFunction(self):
- """
- An C{__all__} definition does not suppress unused import warnings in a
- function scope.
- """
- self.flakes('''
- def foo():
- import bar
- __all__ = ["bar"]
- ''', m.UnusedImport, m.UnusedVariable)
- def test_ignoredInClass(self):
- """
- An C{__all__} definition in a class does not suppress unused import warnings.
- """
- self.flakes('''
- import bar
- class foo:
- __all__ = ["bar"]
- ''', m.UnusedImport)
- def test_ignored_when_not_directly_assigned(self):
- self.flakes('''
- import bar
- (__all__,) = ("foo",)
- ''', m.UnusedImport)
- def test_warningSuppressed(self):
- """
- If a name is imported and unused but is named in C{__all__}, no warning
- is reported.
- """
- self.flakes('''
- import foo
- __all__ = ["foo"]
- ''')
- self.flakes('''
- import foo
- __all__ = ("foo",)
- ''')
- def test_augmentedAssignment(self):
- """
- The C{__all__} variable is defined incrementally.
- """
- self.flakes('''
- import a
- import c
- __all__ = ['a']
- __all__ += ['b']
- if 1 < 3:
- __all__ += ['c', 'd']
- ''', m.UndefinedExport, m.UndefinedExport)
- def test_list_concatenation_assignment(self):
- """
- The C{__all__} variable is defined through list concatenation.
- """
- self.flakes('''
- import sys
- __all__ = ['a'] + ['b'] + ['c']
- ''', m.UndefinedExport, m.UndefinedExport, m.UndefinedExport, m.UnusedImport)
- def test_tuple_concatenation_assignment(self):
- """
- The C{__all__} variable is defined through tuple concatenation.
- """
- self.flakes('''
- import sys
- __all__ = ('a',) + ('b',) + ('c',)
- ''', m.UndefinedExport, m.UndefinedExport, m.UndefinedExport, m.UnusedImport)
- def test_all_with_attributes(self):
- self.flakes('''
- from foo import bar
- __all__ = [bar.__name__]
- ''')
- def test_all_with_names(self):
- # not actually valid, but shouldn't produce a crash
- self.flakes('''
- from foo import bar
- __all__ = [bar]
- ''')
- def test_all_with_attributes_added(self):
- self.flakes('''
- from foo import bar
- from bar import baz
- __all__ = [bar.__name__] + [baz.__name__]
- ''')
- def test_all_mixed_attributes_and_strings(self):
- self.flakes('''
- from foo import bar
- from foo import baz
- __all__ = ['bar', baz.__name__]
- ''')
- def test_unboundExported(self):
- """
- If C{__all__} includes a name which is not bound, a warning is emitted.
- """
- self.flakes('''
- __all__ = ["foo"]
- ''', m.UndefinedExport)
- # Skip this in __init__.py though, since the rules there are a little
- # different.
- for filename in ["foo/__init__.py", "__init__.py"]:
- self.flakes('''
- __all__ = ["foo"]
- ''', filename=filename)
- def test_importStarExported(self):
- """
- Report undefined if import * is used
- """
- self.flakes('''
- from math import *
- __all__ = ['sin', 'cos']
- csc(1)
- ''', m.ImportStarUsed, m.ImportStarUsage, m.ImportStarUsage, m.ImportStarUsage)
- def test_importStarNotExported(self):
- """Report unused import when not needed to satisfy __all__."""
- self.flakes('''
- from foolib import *
- a = 1
- __all__ = ['a']
- ''', m.ImportStarUsed, m.UnusedImport)
- def test_usedInGenExp(self):
- """
- Using a global in a generator expression results in no warnings.
- """
- 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, m.UnusedImport)
- def test_usedAsDecorator(self):
- """
- Using a global name in a decorator statement results in no warnings,
- but using an undefined name in a decorator statement results in an
- undefined name warning.
- """
- self.flakes('''
- from interior import decorate
- @decorate
- def f():
- return "hello"
- ''')
- self.flakes('''
- from interior import decorate
- @decorate('value')
- def f():
- return "hello"
- ''')
- self.flakes('''
- @decorate
- def f():
- return "hello"
- ''', m.UndefinedName)
- def test_usedAsClassDecorator(self):
- """
- Using an imported name as a class decorator results in no warnings,
- but using an undefined name as a class decorator results in an
- undefined name warning.
- """
- self.flakes('''
- from interior import decorate
- @decorate
- class foo:
- pass
- ''')
- self.flakes('''
- from interior import decorate
- @decorate("foo")
- class bar:
- pass
- ''')
- self.flakes('''
- @decorate
- class foo:
- pass
- ''', m.UndefinedName)
|