Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

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

Open
monagai opened this issue Jun 29, 2023 · 8 comments
Open

Comments

@monagai
Copy link

monagai commented Jun 29, 2023

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 monagai changed the title B023: I cannot understand the reason B023: Why flake8 returns error only for a temporal variable for for loop? Jun 29, 2023
@monagai
Copy link
Author

monagai commented Jun 29, 2023

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
Copy link
Contributor

tomasr8 commented Jun 29, 2023

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: #380

@monagai
Copy link
Author

monagai commented Jun 30, 2023

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
Copy link
Author

monagai commented Jun 30, 2023

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
Copy link
Contributor

tomasr8 commented Jun 30, 2023

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
Copy link
Author

monagai commented Jun 30, 2023

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
Copy link
Collaborator

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

@jakkdl
Copy link
Contributor

jakkdl commented Oct 28, 2024

I don't think this can/should be fixed - we have no guarantees that the lambda will only be executed inside the loop when passing it to some unknown 3rd-party function:

lambdas_to_run_later = []
for i in range(10):
    lambdas_to_run_later.append(lambda: print(i))

for l in lambdas_to_run_later:
    l()  # oops, always prints 9

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants