Skip to content

STYLE: turn off PLW2901 (but keep some changes) #52262

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

Merged
merged 13 commits into from
Apr 12, 2023

Conversation

ErdiTk
Copy link
Contributor

@ErdiTk ErdiTk commented Mar 28, 2023

Continuation of work started on closed issue #51708.
Didn't find a new issue to link this PR, may I ask you @MarcoGorelli if it is fine to link it to the closed one or shall I wait for a new issue to be opened?

@ErdiTk ErdiTk force-pushed the gradually_enable_plw2901 branch from 6e93f07 to fc7a8d8 Compare March 28, 2023 20:25
@MarcoGorelli MarcoGorelli self-requested a review March 28, 2023 20:43
Copy link
Member

@MarcoGorelli MarcoGorelli left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

thanks

can you update the pyproject.toml file accordingly please?

@ErdiTk
Copy link
Contributor Author

ErdiTk commented Mar 28, 2023

thanks

can you update the pyproject.toml file accordingly please?

I will update it when I finish all the files under pandas/core/*. Give me few days for it, there are quite some to change :)

@MarcoGorelli
Copy link
Member

it's fine (and preferable) split it up into smaller chunks

we can split up the pandas/core/* ignore into multiple ones

@mroeschke mroeschke added the Code Style Code style, linting, code_checks label Mar 29, 2023
Copy link
Member

@MarcoGorelli MarcoGorelli left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

looks like the "
Code Checks / Docstring validation, typing, and other manual pre-commit hooks (pull_request) " is failing - code you give me a ping when that's one's fixed please?

@ErdiTk
Copy link
Contributor Author

ErdiTk commented Mar 31, 2023

looks like the "
Code Checks / Docstring validation, typing, and other manual pre-commit hooks (pull_request) " is failing - code you give me a ping when that's one's fixed please?

Sure, I think I know which changes might have impacted it. I will ping you around Tuesday, unfortunately I won't make it earlier.

@MarcoGorelli
Copy link
Member

sure, no hurry, thanks!

mangled_aggfuncs.append(aggfunc)
continue

partial_aggfunc = aggfunc
Copy link
Contributor Author

@ErdiTk ErdiTk Apr 4, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@MarcoGorelli by adding this line the error should be solved. At least locally the mypy error is gone. Not sure why but by simply creating partial_aggfunc from the call to partial(aggfunc) in the next line it removes the __name__ attribute. But if I firstly assign it as equal to aggfunc as I am doing here it works fine. Are you aware of any similar behavior?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The reason this fixes it is because it turns off the type checker - agg_func is of type Any (which turns off the type checker), and so partial_aggfunc will also be of type Any, and so mypy will pass (because it doesn't check anything about this variable)

You can verify this by adding reveal_type:

        partial_aggfunc = aggfunc
        reveal_type(partial_aggfunc)
        partial_aggfunc = partial(aggfunc)
        reveal_type(partial_aggfunc)

which will show

pandas/core/apply.py:1438: note: Revealed type is "Any"
pandas/core/apply.py:1440: note: Revealed type is "Any"

If we remove this line, then partial_aggfunc will be inferred to be of type Partial[Any]

I'd suggest just ignoring the type checker here, like

        partial_aggfunc = partial(aggfunc)
        # "partial[Any]" has no attribute "__name__"
        partial_aggfunc.__name__ = f"<lambda_{idx}>"  # type: ignore[attr-defined]

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh thank you a lot for the suggestion! I will implement it like this. Sorry but I am still learning how to properly handle those issues.

Copy link
Member

@MarcoGorelli MarcoGorelli left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

thanks for your PR

I've left a couple of comments, there should be enough to work on here

mangled_aggfuncs.append(aggfunc)
continue

partial_aggfunc = aggfunc
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The reason this fixes it is because it turns off the type checker - agg_func is of type Any (which turns off the type checker), and so partial_aggfunc will also be of type Any, and so mypy will pass (because it doesn't check anything about this variable)

You can verify this by adding reveal_type:

        partial_aggfunc = aggfunc
        reveal_type(partial_aggfunc)
        partial_aggfunc = partial(aggfunc)
        reveal_type(partial_aggfunc)

which will show

pandas/core/apply.py:1438: note: Revealed type is "Any"
pandas/core/apply.py:1440: note: Revealed type is "Any"

If we remove this line, then partial_aggfunc will be inferred to be of type Partial[Any]

I'd suggest just ignoring the type checker here, like

        partial_aggfunc = partial(aggfunc)
        # "partial[Any]" has no attribute "__name__"
        partial_aggfunc.__name__ = f"<lambda_{idx}>"  # type: ignore[attr-defined]

Comment on lines 1438 to 1439
partial_aggfunc = partial(aggfunc)
partial_aggfunc.__name__ = f"<lambda_{idx}>"
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

also, I don't think the logic is right here, please try to keep the logic the same as the original

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The original one was:

i = 0
for aggfunc in aggfuncs:
        if com.get_callable_name(aggfunc) == "<lambda>":
            aggfunc = partial(aggfunc)
            aggfunc.__name__ = f"<lambda_{i}>"
            i += 1
        mangled_aggfuncs.append(aggfunc)

I removed the variable i, replacing it by idx generated by the call to enumerate. Then I inverted the if clause, making it a if not. In this way I can insert inside the condition the single line:
mangled_aggfuncs.append(aggfunc)
and then continue the loop. So I moved what was inside the if outside. Sorry I understand it's not super clear, but I thought would look nicer to have a lighter content inside the if statement. If you want I can revert the logic.

Comment on lines 1108 to 1109
y, m = parsing.quarter_to_myear(y, q, freqstr)
_, m = parsing.quarter_to_myear(y, q, freqstr)
val = libperiod.period_ordinal(y, m, 1, 1, 1, 1, 0, 0, base)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this doesn't look right

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

My bad, indeed the variable y can be changed inside the function quarter_to_myear. Updated! Thanks for the heads up!

Comment on lines 1432 to 1440
for aggfunc in aggfuncs:
if com.get_callable_name(aggfunc) == "<lambda>":
aggfunc = partial(aggfunc)
aggfunc.__name__ = f"<lambda_{i}>"
i += 1
mangled_aggfuncs.append(aggfunc)
for idx, aggfunc in enumerate(aggfuncs):
if not com.get_callable_name(aggfunc) == "<lambda>":
mangled_aggfuncs.append(aggfunc)
continue

partial_aggfunc = partial(aggfunc)
# "partial[Any]" has no attribute "__name__"
partial_aggfunc.__name__ = f"<lambda_{idx}>" # type: ignore[attr-defined]
mangled_aggfuncs.append(partial_aggfunc)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this isn't the same logic - before, i was only incremented if com.get_callable_name(aggfunc) == "<lambda>", whereas now you're incrementing idx on every iteration

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh correct indeed, thanks I will revert to the original logic. Shall I add also a test to catch this?

@@ -1105,8 +1105,8 @@ def _range_from_fields(
freqstr = freq.freqstr
year, quarter = _make_field_arrays(year, quarter)
for y, q in zip(year, quarter):
y, m = parsing.quarter_to_myear(y, q, freqstr)
val = libperiod.period_ordinal(y, m, 1, 1, 1, 1, 0, 0, base)
y_parsed, m = parsing.quarter_to_myear(y, q, freqstr)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

maybe calendar_year, calendar_month = parsing.quarter_to_myear(y, q, freqstr)?

Copy link
Member

@MarcoGorelli MarcoGorelli left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

thanks for working on this

I'm going to go back to my previous comment #51797 (review) , I'm not sure we want to enable this in CI

some of these changes are nice

shall we keep the

where[idx] = _validate_where(w)

change (which is quite nice), revert the rest, and move PLW2901 to the 'intentionally turned off' section of pyproject.toml?

# intentionally turned off

@ErdiTk
Copy link
Contributor Author

ErdiTk commented Apr 11, 2023

Ok, I reverted most of the changes except on few files.
Under # intentionally turned off I added "redefined-loop-name", but I saw the errors still appearing when running pre-commit run ruff --all-files, so I kept "PLW2901" also under the to ignore section of ruff. Please let me know if this is the correct way. Also let me know if the few changes listed are fine.

@MarcoGorelli MarcoGorelli added this to the 2.1 milestone Apr 12, 2023
@MarcoGorelli MarcoGorelli changed the title Gradually enable PLW2901 on some files STYLE: turn off PLW2901 (but keep some changes) Apr 12, 2023
@@ -1423,10 +1423,10 @@ def relabel_result(
# mean 1.5
# mean 1.5
if reorder_mask:
fun = [
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

not sure we can do this, fun is still used below

Copy link
Member

@MarcoGorelli MarcoGorelli left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

looks fine, just made some minor fixup, thanks @ErdiTk

@MarcoGorelli MarcoGorelli merged commit 8d4cab5 into pandas-dev:main Apr 12, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Code Style Code style, linting, code_checks
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants