Skip to content

Commit 45c28a3

Browse files
jayvdbsigmavirus24
authored andcommitted
Suppress RedefinedWhileUnused for submodule import (#62)
Fixes lp:1578051 aec68a7 added module names to error messages, which included a new class SubmoduleImportation to handle the special case of submodule imports. It correctly handled the case of a submodule import occurring after the root module was imported, but didnt handle the opposite case of the submodule import occurring before the root module was imported.
1 parent 4361b6d commit 45c28a3

File tree

2 files changed

+24
-4
lines changed

2 files changed

+24
-4
lines changed

pyflakes/checker.py

Lines changed: 18 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -142,6 +142,9 @@ def __init__(self, name, source, full_name=None):
142142
super(Importation, self).__init__(name, source)
143143

144144
def redefines(self, other):
145+
if isinstance(other, SubmoduleImportation):
146+
# See note in SubmoduleImportation about RedefinedWhileUnused
147+
return self.fullName == other.fullName
145148
return isinstance(other, Definition) and self.name == other.name
146149

147150
def _has_alias(self):
@@ -165,13 +168,24 @@ def __str__(self):
165168

166169

167170
class SubmoduleImportation(Importation):
171+
"""
172+
A binding created by a submodule import statement.
173+
174+
A submodule import is a special case where the root module is implicitly
175+
imported, without an 'as' clause, and the submodule is also imported.
176+
Python does not restrict which attributes of the root module may be used.
177+
178+
This class is only used when the submodule import is without an 'as' clause.
179+
180+
pyflakes handles this case by registering the root module name in the scope,
181+
allowing any attribute of the root module to be accessed.
182+
183+
RedefinedWhileUnused is suppressed in `redefines` unless the submodule
184+
name is also the same, to avoid false positives.
185+
"""
168186

169187
def __init__(self, name, source):
170188
# A dot should only appear in the name when it is a submodule import
171-
# without an 'as' clause, which is a special type of import where the
172-
# root module is implicitly imported, and the submodules are also
173-
# accessible because Python does not restrict which attributes of the
174-
# root module may be used.
175189
assert '.' in name and (not source or isinstance(source, ast.Import))
176190
package_name = name.split('.')[0]
177191
super(SubmoduleImportation, self).__init__(package_name, source)

pyflakes/test/test_imports.py

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -767,6 +767,12 @@ def test_used_package_with_submodule_import(self):
767767
fu.x
768768
''')
769769

770+
self.flakes('''
771+
import fu.bar
772+
import fu
773+
fu.x
774+
''')
775+
770776
def test_unused_package_with_submodule_import(self):
771777
"""
772778
When a package and its submodule are imported, only report once.

0 commit comments

Comments
 (0)