PyCQA / flake8-bugbear

A plugin for Flake8 finding likely bugs and design problems in your program. Contains warnings that don't belong in pyflakes and pycodestyle.
MIT License
1.06k stars 104 forks source link

B031 does not take into account if-else statements #465

Open amyasnikov opened 6 months ago

amyasnikov commented 6 months ago

Bugbear reports false-positive "more that one" usage of the generator even if it occurs inside 2 different branches of the if-else statement.

This code

import itertools

for _, group in itertools.groupby([]):
    if True:
        print(group, True)
    else:
        print(group, False)

produces

b031.py:7:15: B031 Using the generator returned from `itertools.groupby()` more than once will do nothing on the second usage. Save the result to a list, if the result is needed multiple times.

but it's obvious that group cannot be used twice here.

flake8 --version:

7.0.0 (flake8-bugbear: 24.2.6, mccabe: 0.7.0, pycodestyle: 2.11.1, pyflakes: 3.2.0) CPython 3.11.2 on Linux
mick88 commented 1 month ago

On a related note, I am also getting false positive for code that only type-annotates the iterable. It iterates only once, but B031 is triggered:

        for form_id, form_obs in groupby(observations, key=lambda obs: obs.form):
            form_id: int
            form_obs: Iterable[Observation]
            pks: Iterable[int] = list(o.pk for o in form_obs)
cooperlees commented 1 month ago

Thanks for reporting. Both are things we could tighten. PRs welcome.