--- checker.py 2016-12-08 16:10:49.314419009 -0800 +++ checker.newnew 2016-12-08 15:53:40.006418997 -0800 @@ -593,7 +593,7 @@ # Look for imported names that aren't used. for value in scope.values(): if isinstance(value, Importation): - used = value.used or value.name in all_names + used = value.used or value.name in all_names or scope.importStarred if not used: messg = messages.UnusedImport self.report(messg, value.source, str(value)) @@ -732,15 +732,16 @@ for scope in self.scopeStack[-1::-1]: for binding in scope.values(): - if isinstance(binding, StarImportation): + if isinstance(binding, StarImportation) and not binding.verified: # mark '*' imports as used for each scope binding.used = (self.scope, node) from_list.append(binding.fullName) # report * usage, with a list of possible sources - from_list = ', '.join(sorted(from_list)) - self.report(messages.ImportStarUsage, node, name, from_list) - return + if from_list: + from_list = ', '.join(sorted(from_list)) + self.report(messages.ImportStarUsage, node, name, from_list) + return if name == '__path__' and os.path.basename(self.filename) == '__init__.py': # the special name __path__ is valid only in packages @@ -1271,10 +1272,23 @@ self.report(messages.ImportStarNotPermitted, node, module) continue - + for p in sys.path: + if os.path.exists(os.path.join(p, module)): + __all__ = {} + exec('from %s import *' % module, {}, __all__) + for n in sorted(__all__): + self.addBinding( + node, + ImportationFrom(n, node, module, n), + ) + verified = True + break + else: + self.report(messages.ImportStarUsed, node, module) + verified = False self.scope.importStarred = True - self.report(messages.ImportStarUsed, node, module) importation = StarImportation(module, node) + importation.verified = verified else: importation = ImportationFrom(name, node, module, alias.name)