flake8-simplify icon indicating copy to clipboard operation
flake8-simplify copied to clipboard

[Adjust Rule] SIM113 does not work on empty iterables

Open dargueta opened this issue 2 years ago • 0 comments

Desired change

  • Rule(s): SIM113
  • Adjustment: Do not trigger SIM113 if the counter is used outside the loop.

Explanation

A for loop only assigns the value variables if the loop iterates. If the iterable is empty, the loop never executes, and the variable is not assigned to. This works the same way even if you use enumerate(). Thus, if your iterable is empty, the counter variable will never be assigned to and your code will break.

Example

Suppose I'm given an iterable -- any iterable, could be a generator -- and I need to count the number of items I've processed in the loop, then do something with it. This always works, but (understandably) triggers SIM113:

n = 0
for x in stuff:
    print(f"{n}: {x!r}")
    n += 1

print(f"Processed {n} items")

However, if we change it to what the linter wants:

for i, x in enumerate(stuff, start=1):
    print(f"{i} {x!r}")

print(f"Processed {i} items")

If stuff is empty, i will never be assigned to, and the last line will trigger a NameError. My code needs to accept any iterable, including unsized ones, so I can't do a length check beforehand.

dargueta avatar Apr 08 '22 16:04 dargueta