From bfce7ed222faad5d9043c9e89c11a11fabcd21c4 Mon Sep 17 00:00:00 2001 From: David Liu Date: Sun, 10 Dec 2023 12:59:30 -0500 Subject: [PATCH] Ensure naming-convention-violation does not check variables in main block --- CHANGELOG.md | 1 + python_ta/checkers/invalid_name_checker.py | 4 +++- .../test_invalid_name_checker.py | 12 ++++++++++++ 3 files changed, 16 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 2f53690c8..7608842f4 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -23,6 +23,7 @@ and adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). - Fix bug in ending location setting for `Attribute` and `DelAttr` nodes when the same attribute was accessed twice on the same line. +- Fix bug where the `naming-convention-violation` checker was checking variables defined in a module's main block. This was inconsistent with the `forbidden-global-variables` checker. ## [2.6.4] - 2024-11-10 diff --git a/python_ta/checkers/invalid_name_checker.py b/python_ta/checkers/invalid_name_checker.py index a60063d5d..6ba0347ed 100644 --- a/python_ta/checkers/invalid_name_checker.py +++ b/python_ta/checkers/invalid_name_checker.py @@ -9,6 +9,8 @@ from pylint.checkers.utils import only_required_for_messages from pylint.lint import PyLinter +from python_ta.utils import _is_in_main + # Bad variable names. BAD_NAMES = {"l", "I", "O"} @@ -334,7 +336,7 @@ def visit_assignname(self, node: nodes.AssignName) -> None: self._check_name("argument", node.name, node) # Check names defined in module scope - elif isinstance(frame, nodes.Module): + elif isinstance(frame, nodes.Module) and not _is_in_main(node): # Check names defined in Assign nodes if isinstance(assign_type, nodes.Assign): inferred_assign_type = utils.safe_infer(assign_type.value) diff --git a/tests/test_custom_checkers/test_invalid_name_checker.py b/tests/test_custom_checkers/test_invalid_name_checker.py index 129e2eee8..32a256a5d 100644 --- a/tests/test_custom_checkers/test_invalid_name_checker.py +++ b/tests/test_custom_checkers/test_invalid_name_checker.py @@ -481,6 +481,18 @@ def test_typealias_name_underscore(self) -> None: with self.assertNoMessages(): self.checker.visit_assignname(assignname_node) + def test_name_in_main_block(self) -> None: + """Test that the checker does not report a top-level variable that is assigned within + a main block.""" + src = """ + if __name__ == '__main__': + const_not_upper = "it is not" + """ + mod = astroid.parse(src) + assignname_node, *_ = mod.nodes_of_class(nodes.AssignName) + with self.assertNoMessages(): + self.checker.visit_assignname(assignname_node) + def test_module_name_no_snippet() -> None: """Test that PythonTA does not build a snippet for the message added by this checker."""