-
Notifications
You must be signed in to change notification settings - Fork 1.1k
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
[perflint
] implement quick-fix for manual-list-comprehension
(PERF401
)
#13919
base: main
Are you sure you want to change the base?
Conversation
Nice, thank you. |
Again, I'm not sure where to add tests for fixes. |
You can extend the existing tests. The testing framework runs your lint rule against the file and snapshots all created diagnostics with their fixes.
|
|
code | total | + violation | - violation | + fix | - fix |
---|---|---|---|---|---|
PERF401 | 98 | 49 | 49 | 0 | 0 |
Linter (preview)
ℹ️ ecosystem check detected linter changes. (+49 -49 violations, +0 -0 fixes in 3 projects; 51 projects unchanged)
apache/airflow (+31 -31 violations, +0 -0 fixes)
ruff check --no-cache --exit-zero --ignore RUF9 --output-format concise --preview --select ALL
- dev/breeze/src/airflow_breeze/commands/ci_commands.py:374:25: PERF401 Use a list comprehension to create a transformed list + dev/breeze/src/airflow_breeze/commands/ci_commands.py:374:25: PERF401 Use a list extend to create a transformed list - dev/breeze/src/airflow_breeze/commands/release_management_commands.py:3058:9: PERF401 Use a list comprehension to create a transformed list + dev/breeze/src/airflow_breeze/commands/release_management_commands.py:3058:9: PERF401 Use a list extend to create a transformed list - dev/breeze/src/airflow_breeze/commands/sbom_commands.py:973:13: PERF401 Use a list comprehension to create a transformed list + dev/breeze/src/airflow_breeze/commands/sbom_commands.py:973:13: PERF401 Use a list extend to create a transformed list - dev/breeze/src/airflow_breeze/params/shell_params.py:385:13: PERF401 Use a list comprehension to create a transformed list + dev/breeze/src/airflow_breeze/params/shell_params.py:385:13: PERF401 Use a list extend to create a transformed list - dev/breeze/src/airflow_breeze/utils/exclude_from_matrix.py:32:9: PERF401 Use a list comprehension to create a transformed list + dev/breeze/src/airflow_breeze/utils/exclude_from_matrix.py:32:9: PERF401 Use a list extend to create a transformed list - dev/breeze/src/airflow_breeze/utils/packages.py:326:9: PERF401 Use a list comprehension to create a transformed list + dev/breeze/src/airflow_breeze/utils/packages.py:326:9: PERF401 Use a list extend to create a transformed list - dev/breeze/src/airflow_breeze/utils/reproducible.py:126:17: PERF401 Use a list comprehension to create a transformed list + dev/breeze/src/airflow_breeze/utils/reproducible.py:126:17: PERF401 Use a list extend to create a transformed list - dev/breeze/src/airflow_breeze/utils/selective_checks.py:1077:17: PERF401 Use a list comprehension to create a transformed list + dev/breeze/src/airflow_breeze/utils/selective_checks.py:1077:17: PERF401 Use a list extend to create a transformed list - docs/exts/docs_build/fetch_inventories.py:103:9: PERF401 Use a list comprehension to create a transformed list + docs/exts/docs_build/fetch_inventories.py:103:9: PERF401 Use a list extend to create a transformed list - docs/exts/docs_build/fetch_inventories.py:111:9: PERF401 Use a list comprehension to create a transformed list + docs/exts/docs_build/fetch_inventories.py:111:9: PERF401 Use a list extend to create a transformed list - docs/exts/docs_build/fetch_inventories.py:119:9: PERF401 Use a list comprehension to create a transformed list + docs/exts/docs_build/fetch_inventories.py:119:9: PERF401 Use a list extend to create a transformed list - providers/src/airflow/providers/amazon/aws/hooks/s3.py:486:21: PERF401 Use a list comprehension to create a transformed list + providers/src/airflow/providers/amazon/aws/hooks/s3.py:486:21: PERF401 Use a list extend to create a transformed list - providers/src/airflow/providers/amazon/aws/hooks/s3.py:669:21: PERF401 Use a list comprehension to create a transformed list + providers/src/airflow/providers/amazon/aws/hooks/s3.py:669:21: PERF401 Use a list extend to create a transformed list - providers/src/airflow/providers/amazon/aws/log/s3_task_handler.py:122:17: PERF401 Use a list comprehension to create a transformed list + providers/src/airflow/providers/amazon/aws/log/s3_task_handler.py:122:17: PERF401 Use a list extend to create a transformed list - providers/src/airflow/providers/amazon/aws/operators/sagemaker.py:1210:17: PERF401 Use a list comprehension to create a transformed list + providers/src/airflow/providers/amazon/aws/operators/sagemaker.py:1210:17: PERF401 Use a list extend to create a transformed list - providers/src/airflow/providers/amazon/aws/operators/sagemaker.py:379:17: PERF401 Use a list comprehension to create a transformed list ... 31 additional changes omitted for project
apache/superset (+11 -11 violations, +0 -0 fixes)
ruff check --no-cache --exit-zero --ignore RUF9 --output-format concise --preview --select ALL
- scripts/benchmark_migration.py:128:21: PERF401 Use a list comprehension to create a transformed list + scripts/benchmark_migration.py:128:21: PERF401 Use a list extend to create a transformed list - superset/db_engine_specs/base.py:107:9: PERF401 Use a list comprehension to create a transformed list + superset/db_engine_specs/base.py:107:9: PERF401 Use a list extend to create a transformed list - superset/tasks/cache.py:192:17: PERF401 Use a list comprehension to create a transformed list + superset/tasks/cache.py:192:17: PERF401 Use a list extend to create a transformed list - superset/utils/core.py:1184:17: PERF401 Use a list comprehension to create a transformed list + superset/utils/core.py:1184:17: PERF401 Use a list extend to create a transformed list - tests/integration_tests/charts/api_tests.py:351:13: PERF401 Use a list comprehension to create a transformed list + tests/integration_tests/charts/api_tests.py:351:13: PERF401 Use a list extend to create a transformed list - tests/integration_tests/charts/api_tests.py:465:13: PERF401 Use a list comprehension to create a transformed list ... 11 additional changes omitted for project
bokeh/bokeh (+7 -7 violations, +0 -0 fixes)
ruff check --no-cache --exit-zero --ignore RUF9 --output-format concise --preview --select ALL
- src/bokeh/layouts.py:475:25: PERF401 Use a list comprehension to create a transformed list + src/bokeh/layouts.py:475:25: PERF401 Use a list extend to create a transformed list - src/bokeh/plotting/_figure.py:479:17: PERF401 Use a list comprehension to create a transformed list + src/bokeh/plotting/_figure.py:479:17: PERF401 Use a list extend to create a transformed list - src/bokeh/plotting/_figure.py:485:17: PERF401 Use a list comprehension to create a transformed list + src/bokeh/plotting/_figure.py:485:17: PERF401 Use a list extend to create a transformed list - src/bokeh/server/contexts.py:310:17: PERF401 Use a list comprehension to create a transformed list + src/bokeh/server/contexts.py:310:17: PERF401 Use a list extend to create a transformed list - src/bokeh/settings.py:780:21: PERF401 Use a list comprehension to create a transformed list + src/bokeh/settings.py:780:21: PERF401 Use a list extend to create a transformed list ... 4 additional changes omitted for project
Changes by rule (1 rules affected)
code | total | + violation | - violation | + fix | - fix |
---|---|---|---|---|---|
PERF401 | 98 | 49 | 49 | 0 | 0 |
One thing that I wasn't sure how to handle is cases where there is control flow between the binding and the loop. def f(early_return):
result = []
if early_return:
return
for i in range(10):
result.append(i+1) Currently, this fix offers to rewrite the code: def f(early_return):
result = [i+1 for i in range(10)]
if early_return:
return How do you think this case ought to be handled? |
PERF401
] implement quick-fix for manual-list-comprehension
(PERF401
)perflint
] implement quick-fix for manual-list-comprehension
(PERF401
)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This looks great. Thanks for working on this fix.
I have a few smaller code improvements that are up to you. The one change we should make is to gate the fix behind preview to give us a chance to catch any errors before rolling it out to all users.
#[derive_message_formats] | ||
fn message(&self) -> String { | ||
let ManualListComprehension { is_async } = self; | ||
let ManualListComprehension { is_async, .. } = self; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Let's adjust the message to make use of the new comprehension_type
as well to avoid inconsistency between the message and the fix title.
crates/ruff_linter/src/rules/perflint/rules/manual_list_comprehension.rs
Outdated
Show resolved
Hide resolved
crates/ruff_linter/src/rules/perflint/rules/manual_list_comprehension.rs
Outdated
Show resolved
Hide resolved
crates/ruff_linter/src/rules/perflint/rules/manual_list_comprehension.rs
Outdated
Show resolved
Hide resolved
...er/src/rules/perflint/snapshots/ruff_linter__rules__perflint__tests__PERF401_PERF401.py.snap
Outdated
Show resolved
Hide resolved
I've modified the code to preserve comments and not leave a newline when removing the for loop. The tests seem to be failing because the fix is now gated behind a preview--is there a way to allow the test to set the preview flag, or should I temporarily change the fix availability to "sometimes"? |
@w0nder1ng You'll need to add a new test case where the preview flag is enabled. Refer to the following as an example: ruff/crates/ruff_linter/src/rules/ruff/mod.rs Lines 386 to 402 in 8d7dda9
|
How should I deal with the existing test case? |
You would have to mark the rule as sometimes fixable. I suggest to add a |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is great
crates/ruff_linter/src/rules/perflint/rules/manual_list_comprehension.rs
Outdated
Show resolved
Hide resolved
crates/ruff_linter/src/rules/perflint/rules/manual_list_comprehension.rs
Outdated
Show resolved
Hide resolved
crates/ruff_linter/src/rules/perflint/rules/manual_list_comprehension.rs
Outdated
Show resolved
Hide resolved
crates/ruff_linter/src/rules/perflint/rules/manual_list_comprehension.rs
Outdated
Show resolved
Hide resolved
crates/ruff_linter/src/rules/perflint/rules/manual_list_comprehension.rs
Outdated
Show resolved
Hide resolved
crates/ruff_linter/src/rules/perflint/rules/manual_list_comprehension.rs
Outdated
Show resolved
Hide resolved
I changed the diagnostic message, does the new one make more sense? Also, do you know why the tests aren't running? |
@w0nder1ng there are merge conflicts which needs to be resolved to get the CI running |
Summary
I implemented a fix to rewrite for-loops where PERF401 applies into
list.extend
s. Since the target is guaranteed to be a list, and the lint (seemingly) guarantees that the iterator doesn't reference itself, this should be valid for all for-loops where the lint is applicable. It would be nice to implement this to rewrite the entire for-loop/variable assignment into a single list comprehensions, but I thought of several cases where this would affect how the code works, so this would need more consideration to write.Test Plan
I tried this on local files and it seemed to work, but I couldn't find where tests for
ruff check --fix
lints go. I'd be happy to add tests if someone points me in the right direction.