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.05k stars 103 forks source link

B023: Why flake8 returns error only for a temporal variable for for loop? #396

Open monagai opened 1 year ago

monagai commented 1 year ago

flake8 causes error: B023 Function definition does not bind loop variable 'chk_key' for the following code.

        ret_df = pd.DataFrame(index=target_df.index)
        for chk_key in [nalod, nlod]:
            ret_df[chk_key] = (
                False if conf_dict[chk_key] is None
                else info_df.apply(
                        lambda x:
                        float(
                            x['INFO.dict'].get(chk_key, np.nan)
                        ) < conf_dict[chk_key],
                        axis=1
                )
            )

I cannot understand the reason. chk_key is only a temporal variable for for loop. How should I fix it? I'd like to fix it as soon as possible.

I set a value to chk_key at the top of the function for trial. However, flake8 returns the same message.

monagai commented 1 year ago

I think the above code has the same structure as the following code. However, flake8 does not return error message for this. What is the difference?

a = 'aaa'
b = 'bbb'

for i in [a, b]:
    print(f'i = {i}')
tomasr8 commented 1 year ago

Hi, the difference is that in the first example you reference the loop variable inside a lambda which could in theory lead to issues (not in your case though since it's not called outside the loop). FWIW, there's already an issue regarding B023 false positives: https://github.com/PyCQA/flake8-bugbear/issues/380

monagai commented 1 year ago

I really thank you for your quick and proper reply!! > @tomasr8

the loop variable inside a lambda

I understand the situation.

Due to another flake8 error(.../python3.9/site-packages/pep8.py:110: FutureWarning: Possible nested set at position 1 EXTRANEOUS_WHITESPACE_REGEX = re.compile(r'[[({] | []}),;:]')) in my current environment, I will try some countermeasures later.

Thank you.

monagai commented 1 year ago

Is it a correct or ideal output for flake8 developers? Or is it something like a bug or a problem to be fixed? (I don't blame developers. Just only a question.)

tomasr8 commented 1 year ago

Yes it should ideally not be raised in this case, but distinguishing the false positives from true positives is not that straightforward (see the linked issue for more details)

monagai commented 1 year ago

I really thank you for your proper comment.

distinguishing the false positives from true positives is not that straightforward

I understand it.

With your comment, I can avoid B023 error changing the code to lambda x, y=chk_key: .... Thank you for your help!

cooperlees commented 1 year ago

Would accept making the check handle lambdas better if it's possible.