From aa292013c310a4431db5663019e75dbcf19a7017 Mon Sep 17 00:00:00 2001 From: Nazia Povey Date: Wed, 27 Sep 2023 02:33:04 -0400 Subject: [PATCH] Fix crash in refactoring checker from unaryop with variable (#9075) Fixes: ``` File "python3.10/site-packages/pylint/utils/ast_walker.py", line 91, in walk callback(astroid) File "python3.10/site-packages/pylint/checkers/refactoring/refactoring_checker.py", line 700, in visit_for self._check_unnecessary_list_index_lookup(node) File "python3.10/site-packages/pylint/checkers/refactoring/refactoring_checker.py", line 2227, in _check_unnecessary_list_index_lookup has_start_arg, confidence = self._enumerate_with_start(node) File "python3.10/site-packages/pylint/checkers/refactoring/refactoring_checker.py", line 2352, in _enumerate_with_start start_val, confidence = self._get_start_value(keyword.value) File "python3.10/site-packages/pylint/checkers/refactoring/refactoring_checker.py", line 2369, in _get_start_value return node.operand.value, HIGH AttributeError: 'Name' object has no attribute 'value' ``` Crash is reproducible if you have something like this: ```python x=5 for _ in enumerate(range, start=-x): ... ``` As a workaround, remove the unary op before `for` loop (i.e. change the variable used). Closes #9074 Co-authored-by: Hashem Nasarat --- doc/whatsnew/fragments/9074.bugfix | 3 +++ pylint/checkers/refactoring/refactoring_checker.py | 2 +- .../regression_9074_refactor_loop_with_unary_variable.py | 7 +++++++ .../regression_9074_refactor_loop_with_unary_variable.txt | 0 4 files changed, 11 insertions(+), 1 deletion(-) create mode 100644 doc/whatsnew/fragments/9074.bugfix create mode 100644 tests/functional/r/regression/regression_9074_refactor_loop_with_unary_variable.py create mode 100644 tests/functional/r/regression/regression_9074_refactor_loop_with_unary_variable.txt diff --git a/doc/whatsnew/fragments/9074.bugfix b/doc/whatsnew/fragments/9074.bugfix new file mode 100644 index 0000000000..16b3432fb7 --- /dev/null +++ b/doc/whatsnew/fragments/9074.bugfix @@ -0,0 +1,3 @@ +Fix crash in refactoring checker when unary operand used with variable in for loop. + +Closes #9074 diff --git a/pylint/checkers/refactoring/refactoring_checker.py b/pylint/checkers/refactoring/refactoring_checker.py index 2772cd837a..428d44c6fa 100644 --- a/pylint/checkers/refactoring/refactoring_checker.py +++ b/pylint/checkers/refactoring/refactoring_checker.py @@ -2356,7 +2356,7 @@ def _get_start_value(self, node: nodes.NodeNG) -> tuple[int | None, Confidence]: if ( isinstance(node, (nodes.Name, nodes.Call, nodes.Attribute)) or isinstance(node, nodes.UnaryOp) - and isinstance(node.operand, nodes.Attribute) + and isinstance(node.operand, (nodes.Attribute, nodes.Name)) ): inferred = utils.safe_infer(node) start_val = inferred.value if inferred else None diff --git a/tests/functional/r/regression/regression_9074_refactor_loop_with_unary_variable.py b/tests/functional/r/regression/regression_9074_refactor_loop_with_unary_variable.py new file mode 100644 index 0000000000..8fe929bd9e --- /dev/null +++ b/tests/functional/r/regression/regression_9074_refactor_loop_with_unary_variable.py @@ -0,0 +1,7 @@ +"""Regression test.""" +def crash_on_unary_op_with_name(): + """Should not crash with -idx.""" + mylist = [] + idx = 5 + for _i, _val in enumerate(mylist, start=-idx): + pass diff --git a/tests/functional/r/regression/regression_9074_refactor_loop_with_unary_variable.txt b/tests/functional/r/regression/regression_9074_refactor_loop_with_unary_variable.txt new file mode 100644 index 0000000000..e69de29bb2