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])): + ...