diff --git a/CHANGELOG.md b/CHANGELOG.md index c623707..4454293 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -11,6 +11,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Fixed - False positive when bad builtin is overwritten by import ([#16](https://github.com/duo-labs/dlint/issues/16)) - False negative when bad module attribute uses import alias ([#2](https://github.com/duo-labs/dlint/issues/2)) +- False positive when bad module attribute not imported ([#14](https://github.com/duo-labs/dlint/issues/14)) ## [0.6.0] - 2019-08-12 ### Added diff --git a/dlint/linters/helpers/bad_module_attribute_use.py b/dlint/linters/helpers/bad_module_attribute_use.py index db5d472..e995fd9 100644 --- a/dlint/linters/helpers/bad_module_attribute_use.py +++ b/dlint/linters/helpers/bad_module_attribute_use.py @@ -78,7 +78,9 @@ def visit_Attribute(self, node): def illegal_module(mod): return ( - module_path == mod + # Assuming you can't have a period ('.') in names brought + # into a module's namespace + (module_path == mod and (self.namespace.name_imported(mod) or '.' in mod)) or module_path in self.illegal_import_aliases ) diff --git a/tests/test_helpers/test_bad_module_attribute_use.py b/tests/test_helpers/test_bad_module_attribute_use.py index 21a402b..1e921f8 100644 --- a/tests/test_helpers/test_bad_module_attribute_use.py +++ b/tests/test_helpers/test_bad_module_attribute_use.py @@ -347,6 +347,27 @@ def test_bad_module_class_use(self): assert result == expected + def test_module_attribute_missing_import_usage(self): + python_node = self.get_ast_node( + """ + import baz + from qux import quine + + var = 'echo "TEST"' + + foo = None + foo.bar(var) + """ + ) + + linter = get_bad_module_attribute_use_implementation({'foo': ['bar']}) + linter.visit(python_node) + + result = linter.get_results() + expected = [] + + assert result == expected + if __name__ == "__main__": unittest.main()