diff options
-rw-r--r-- | pyflakes/checker.py | 28 | ||||
-rw-r--r-- | pyflakes/test/test_imports.py | 15 |
2 files changed, 27 insertions, 16 deletions
diff --git a/pyflakes/checker.py b/pyflakes/checker.py index 2060ce4..3dd968d 100644 --- a/pyflakes/checker.py +++ b/pyflakes/checker.py @@ -390,10 +390,10 @@ class ExportBinding(Binding): can be determined statically, they will be treated as names for export and additional checking applied to them. - The only C{__all__} assignment that can be recognized is one which takes - the value of a literal list containing literal strings. For example:: + The only recognized C{__all__} assignment via list concatenation is in the + following format: - __all__ = ["foo", "bar"] + __all__ = ['a'] + ['b'] + ['c'] Names which are imported and not otherwise used but appear in the value of C{__all__} will not have an unused import warning reported for them. @@ -405,9 +405,25 @@ class ExportBinding(Binding): else: self.names = [] if isinstance(source.value, (ast.List, ast.Tuple)): - for node in source.value.elts: - if isinstance(node, ast.Str): - self.names.append(node.s) + self.names += ast.literal_eval(source.value) + # If concatenating lists + elif isinstance(source.value, ast.BinOp): + currentValue = source.value + while isinstance(currentValue.right, ast.List): + left = currentValue.left + right = currentValue.right + self.names += ast.literal_eval(right) + # If more lists are being added + if isinstance(left, ast.BinOp): + currentValue = left + # If just two lists are being added + elif isinstance(left, ast.List): + self.names += ast.literal_eval(left) + # All lists accounted for - done + break + # If not list concatenation + else: + break super(ExportBinding, self).__init__(name, source) diff --git a/pyflakes/test/test_imports.py b/pyflakes/test/test_imports.py index 86e1d37..f83e77e 100644 --- a/pyflakes/test/test_imports.py +++ b/pyflakes/test/test_imports.py @@ -1068,19 +1068,14 @@ class TestSpecialAll(TestCase): __all__ += ['c', 'd'] ''', m.UndefinedExport, m.UndefinedExport) - def test_unrecognizable(self): + def test_concatenationAssignment(self): """ - If C{__all__} is defined in a way that can't be recognized statically, - it is ignored. + The C{__all__} variable is defined through list concatenation. """ self.flakes(''' - import foo - __all__ = ["f" + "oo"] - ''', m.UnusedImport) - self.flakes(''' - import foo - __all__ = [] + ["foo"] - ''', m.UnusedImport) + import sys + __all__ = ['a'] + ['b'] + ['c'] + ''', m.UndefinedExport, m.UndefinedExport, m.UndefinedExport, m.UnusedImport) def test_unboundExported(self): """ |