-
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
[pylint
] Add unnecessary_ellipsis
(W2301
)
#4726
Conversation
PR Check ResultsEcosystemℹ️ ecosystem check detected changes. (+27, -0, 0 error(s)) airflow (+20, -0)
+ airflow/hooks/base.py:158:9: PLW2301 [*] Unnecessary ellipsis constant.
+ airflow/hooks/base.py:178:9: PLW2301 [*] Unnecessary ellipsis constant.
+ airflow/jobs/scheduler_job_runner.py:1542:13: PLW2301 [*] Unnecessary ellipsis constant.
+ airflow/metrics/protocols.py:40:9: PLW2301 [*] Unnecessary ellipsis constant.
+ airflow/metrics/protocols.py:44:9: PLW2301 [*] Unnecessary ellipsis constant.
+ airflow/notifications/basenotifier.py:80:9: PLW2301 [*] Unnecessary ellipsis constant.
+ airflow/providers/amazon/aws/hooks/batch_client.py:119:9: PLW2301 [*] Unnecessary ellipsis constant.
+ airflow/providers/amazon/aws/hooks/batch_client.py:131:9: PLW2301 [*] Unnecessary ellipsis constant.
+ airflow/providers/amazon/aws/hooks/batch_client.py:62:9: PLW2301 [*] Unnecessary ellipsis constant.
+ airflow/providers/amazon/aws/hooks/batch_client.py:88:9: PLW2301 [*] Unnecessary ellipsis constant.
+ airflow/providers/amazon/aws/hooks/ecs.py:230:9: PLW2301 [*] Unnecessary ellipsis constant.
+ airflow/providers/amazon/aws/hooks/ecs.py:234:9: PLW2301 [*] Unnecessary ellipsis constant.
+ airflow/providers/amazon/aws/hooks/ecs.py:238:9: PLW2301 [*] Unnecessary ellipsis constant.
+ airflow/providers/amazon/aws/hooks/ecs.py:242:9: PLW2301 [*] Unnecessary ellipsis constant.
+ airflow/providers/amazon/aws/hooks/ecs.py:246:9: PLW2301 [*] Unnecessary ellipsis constant.
+ airflow/providers/amazon/aws/hooks/ecs.py:250:9: PLW2301 [*] Unnecessary ellipsis constant.
+ airflow/serialization/json_schema.py:43:9: PLW2301 [*] Unnecessary ellipsis constant.
+ airflow/serialization/json_schema.py:47:9: PLW2301 [*] Unnecessary ellipsis constant.
+ airflow/serialization/json_schema.py:51:9: PLW2301 [*] Unnecessary ellipsis constant.
+ docs/exts/substitution_extensions.py:118:9: PLW2301 [*] Unnecessary ellipsis constant. disnake (+2, -0)
+ examples/interactions/injections.py:96:5: PLW2301 [*] Unnecessary ellipsis constant.
+ tests/test_utils.py:66:9: PLW2301 [*] Unnecessary ellipsis constant. scikit-build-core (+5, -0)
+ src/scikit_build_core/settings/sources.py:161:9: PLW2301 [*] Unnecessary ellipsis constant.
+ src/scikit_build_core/settings/sources.py:168:9: PLW2301 [*] Unnecessary ellipsis constant.
+ src/scikit_build_core/settings/sources.py:176:9: PLW2301 [*] Unnecessary ellipsis constant.
+ src/scikit_build_core/settings/sources.py:184:9: PLW2301 [*] Unnecessary ellipsis constant.
+ src/scikit_build_core/settings/sources.py:191:9: PLW2301 [*] Unnecessary ellipsis constant.
BenchmarkLinux
Windows
|
if let Stmt::FunctionDef(ast::StmtFunctionDef { body, .. }) | ||
| Stmt::AsyncFunctionDef(ast::StmtAsyncFunctionDef { body, .. }) | ||
| Stmt::ClassDef(ast::StmtClassDef { body, .. }) | ||
| Stmt::AsyncFor(ast::StmtAsyncFor { body, .. }) | ||
| Stmt::While(ast::StmtWhile { body, .. }) | ||
| Stmt::With(ast::StmtWith { body, .. }) | ||
| Stmt::AsyncWith(ast::StmtAsyncWith { body, .. }) | ||
| Stmt::If(ast::StmtIf { body, .. }) | ||
| Stmt::Try(ast::StmtTry { body, .. }) | ||
| Stmt::TryStar(ast::StmtTryStar { body, .. }) = stmt | ||
{ | ||
process_body(checker, stmt, body, expr); | ||
} | ||
if let Stmt::If(ast::StmtIf { orelse, .. }) = stmt { | ||
process_body(checker, stmt, orelse, expr); | ||
} | ||
|
||
if let Stmt::Match(ast::StmtMatch { cases, .. }) = stmt { | ||
for case in cases { | ||
let ast::MatchCase { body, .. } = case; | ||
process_body(checker, stmt, body, expr); | ||
} | ||
} | ||
if let Stmt::Try(ast::StmtTry { handlers, .. }) = stmt { | ||
for handler in handlers { | ||
let Excepthandler::ExceptHandler(ast::ExcepthandlerExceptHandler { body, .. }) = | ||
handler; | ||
process_body(checker, stmt, body, expr); | ||
} | ||
} | ||
} |
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.
Nit: I think it would be clearer to write this as a match
instead. It emphasizes that the branches are mutually exclusive:
if let Stmt::FunctionDef(ast::StmtFunctionDef { body, .. }) | |
| Stmt::AsyncFunctionDef(ast::StmtAsyncFunctionDef { body, .. }) | |
| Stmt::ClassDef(ast::StmtClassDef { body, .. }) | |
| Stmt::AsyncFor(ast::StmtAsyncFor { body, .. }) | |
| Stmt::While(ast::StmtWhile { body, .. }) | |
| Stmt::With(ast::StmtWith { body, .. }) | |
| Stmt::AsyncWith(ast::StmtAsyncWith { body, .. }) | |
| Stmt::If(ast::StmtIf { body, .. }) | |
| Stmt::Try(ast::StmtTry { body, .. }) | |
| Stmt::TryStar(ast::StmtTryStar { body, .. }) = stmt | |
{ | |
process_body(checker, stmt, body, expr); | |
} | |
if let Stmt::If(ast::StmtIf { orelse, .. }) = stmt { | |
process_body(checker, stmt, orelse, expr); | |
} | |
if let Stmt::Match(ast::StmtMatch { cases, .. }) = stmt { | |
for case in cases { | |
let ast::MatchCase { body, .. } = case; | |
process_body(checker, stmt, body, expr); | |
} | |
} | |
if let Stmt::Try(ast::StmtTry { handlers, .. }) = stmt { | |
for handler in handlers { | |
let Excepthandler::ExceptHandler(ast::ExcepthandlerExceptHandler { body, .. }) = | |
handler; | |
process_body(checker, stmt, body, expr); | |
} | |
} | |
} | |
match stmt { | |
Stmt::FunctionDef(ast::StmtFunctionDef { body, .. }) | |
| Stmt::AsyncFunctionDef(ast::StmtAsyncFunctionDef { body, .. }) | |
| Stmt::ClassDef(ast::StmtClassDef { body, .. }) | |
| Stmt::AsyncFor(ast::StmtAsyncFor { body, .. }) | |
| Stmt::While(ast::StmtWhile { body, .. }) | |
| Stmt::With(ast::StmtWith { body, .. }) | |
| Stmt::AsyncWith(ast::StmtAsyncWith { body, .. }) | |
| Stmt::Try(ast::StmtTry { body, .. }) | |
| Stmt::TryStar(ast::StmtTryStar { body, .. }) => process_body(checker, stmt, body, expr), | |
| Stmt::If(ast::StmtIf { body, orelse, .. }) => { | |
process_body(checker, stmt, body, expr) | |
process_body(checker, stmt, orelse, expr); | |
}, | |
Stmt::Match(ast::StmtMatch { cases, .. }) => { | |
for case in cases { | |
let ast::MatchCase { body, .. } = case; | |
process_body(checker, stmt, body, expr); | |
} | |
}, | |
Stmt::Try(ast::StmtTry { body, handlers ..} => { | |
process_body(checker, stmt, body, expr) | |
for handler in handlers { | |
let Excepthandler::ExceptHandler(ast::ExcepthandlerExceptHandler { body, .. }) = | |
handler; | |
process_body(checker, stmt, body, expr); | |
} | |
} |
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.
I've tried replacing with the following match
:
match stmt {
Stmt::FunctionDef(ast::StmtFunctionDef { body, .. })
| Stmt::AsyncFunctionDef(ast::StmtAsyncFunctionDef { body, .. })
| Stmt::ClassDef(ast::StmtClassDef { body, .. })
| Stmt::AsyncFor(ast::StmtAsyncFor { body, .. })
| Stmt::While(ast::StmtWhile { body, .. })
| Stmt::With(ast::StmtWith { body, .. })
| Stmt::AsyncWith(ast::StmtAsyncWith { body, .. })
| Stmt::If(ast::StmtIf { body, .. })
| Stmt::Try(ast::StmtTry { body, .. })
| Stmt::TryStar(ast::StmtTryStar { body, .. }) => {
process_body(checker, stmt, body, expr);
}
Stmt::If(ast::StmtIf { orelse, .. }) => {
process_body(checker, stmt, orelse, expr);
}
Stmt::Match(ast::StmtMatch { cases, .. }) => {
for case in cases {
let ast::MatchCase { body, .. } = case;
process_body(checker, stmt, body, expr);
}
}
Stmt::Try(ast::StmtTry { handlers, .. }) => {
for handler in handlers {
let Excepthandler::ExceptHandler(ast::ExcepthandlerExceptHandler {
body, ..
}) = handler;
process_body(checker, stmt, body, expr);
}
}
_ => {}
}
However this results in
error: unreachable pattern
--> crates/ruff/src/rules/pylint/rules/unnecessary_ellipsis.rs:134:13
|
134 | Stmt::If(ast::StmtIf { orelse, .. }) => {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
= note: `-D unreachable-patterns` implied by `-D warnings`
error: unreachable pattern
--> crates/ruff/src/rules/pylint/rules/unnecessary_ellipsis.rs:143:13
|
143 | Stmt::Try(ast::StmtTry { handlers, .. }) => {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
/// For example: A function consisting of an ellipsis followed by a | ||
/// return statement on the next line. | ||
pub(crate) fn unnecessary_ellipsis(checker: &mut Checker, expr: &Expr) { | ||
if let Some(stmt) = checker.semantic_model().stmt_parent() { |
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.
I wonder how expensive stmt_parent
is when called for every stmt. I rescheduled the benchmarks to see if it is a one-off or is indeed a perf regression.
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.
@MichaReiser Is it too slow to be merged ?
It looks reasonable though I'm not sure how to deal with the overlap between this rule and |
@charliermarsh It would be great if a single rule could alias multiple more specific rules. |
|
Are there other rules with partial overlap that could be used as reference/precedent ? |
I think this is superseded by #8641 now. Sorry this one got a little lost :/ let me know if you have any questions or concerns! |
Summary
This PR is part of #970, it adds the
PLW2301
warning rule along with its fix.Test Plan
The test fixture uses the one from pylint, whit a few added tests.