MartinThoma / flake8-simplify

❄ A flake8 plugin that helps you to simplify code
MIT License
186 stars 19 forks source link

[Adjust Rule] SIM113 does not work on empty iterables #139

Open dargueta opened 2 years ago

dargueta commented 2 years ago

Desired change

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.