From c3e257925e313a19f42dd17d20179152f5f5db2f Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Thu, 6 Jun 2024 22:03:21 +0000 Subject: [PATCH] [unnecessary-list-index-lookup] Fix crashes for uninferrable 'start' value in 'enumerate' (#9704) (#9707) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --------- Co-authored-by: Daniƫl van Noord <13665637+DanielNoord@users.noreply.github.com> (cherry picked from commit 9f8dcbd6a9d37d56a14b747b83d97d6b8527a2ab) Co-authored-by: Pierre Sassoulas --- doc/whatsnew/fragments/9078.bugfix | 4 ++++ pylint/checkers/refactoring/refactoring_checker.py | 4 +++- .../u/unnecessary/unnecessary_list_index_lookup.py | 11 +++++++++++ 3 files changed, 18 insertions(+), 1 deletion(-) create mode 100644 doc/whatsnew/fragments/9078.bugfix diff --git a/doc/whatsnew/fragments/9078.bugfix b/doc/whatsnew/fragments/9078.bugfix new file mode 100644 index 0000000000..2e48abc887 --- /dev/null +++ b/doc/whatsnew/fragments/9078.bugfix @@ -0,0 +1,4 @@ +Fixed a crash when the ``start`` value in an ``enumerate`` was non-constant and impossible to infer +(like in``enumerate(apples, start=int(random_apple_index)``) for ``unnecessary-list-index-lookup``. + +Closes #9078 diff --git a/pylint/checkers/refactoring/refactoring_checker.py b/pylint/checkers/refactoring/refactoring_checker.py index 9ffcecce12..a8bce74854 100644 --- a/pylint/checkers/refactoring/refactoring_checker.py +++ b/pylint/checkers/refactoring/refactoring_checker.py @@ -2454,7 +2454,9 @@ def _get_start_value(self, node: nodes.NodeNG) -> tuple[int | None, Confidence]: and isinstance(node.operand, (nodes.Attribute, nodes.Name)) ): inferred = utils.safe_infer(node) - start_val = inferred.value if inferred else None + # inferred can be an astroid.base.Instance as in 'enumerate(x, int(y))' or + # not correctly inferred (None) + start_val = inferred.value if isinstance(inferred, nodes.Const) else None return start_val, INFERENCE if isinstance(node, nodes.UnaryOp): return node.operand.value, HIGH diff --git a/tests/functional/u/unnecessary/unnecessary_list_index_lookup.py b/tests/functional/u/unnecessary/unnecessary_list_index_lookup.py index 3201d5407d..b9f8b73251 100644 --- a/tests/functional/u/unnecessary/unnecessary_list_index_lookup.py +++ b/tests/functional/u/unnecessary/unnecessary_list_index_lookup.py @@ -156,3 +156,14 @@ def _get_extra_attrs(self, extra_columns): for idx, val in enumerate(my_list): if (val := 42) and my_list[idx] == 'b': print(1) + +def regression_9078(apples, cant_infer_this): + """Regression test for https://github.com/pylint-dev/pylint/issues/9078.""" + for _, _ in enumerate(apples, int(cant_infer_this)): + ... + +def random_uninferrable_start(pears): + import random # pylint: disable=import-outside-toplevel + + for _, _ in enumerate(pears, random.choice([5, 42])): + ...