-
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
SIM300: CONSTANT_CASE variables are improperly flagged for yoda violation #9164
SIM300: CONSTANT_CASE variables are improperly flagged for yoda violation #9164
Conversation
|
code | total | + violation | - violation | + fix | - fix |
---|---|---|---|---|---|
SIM300 | 15 | 15 | 0 | 0 | 0 |
Linter (preview)
ℹ️ ecosystem check detected linter changes. (+474 -2 violations, +0 -0 fixes in 8 projects; 33 projects unchanged)
apache/airflow (+359 -0 violations, +0 -0 fixes)
ruff check --no-cache --exit-zero --preview --select ALL
+ dev/breeze/tests/test_packages.py:112:12: SIM300 [*] Yoda conditions are discouraged + dev/breeze/tests/test_packages.py:117:12: SIM300 [*] Yoda conditions are discouraged + dev/breeze/tests/test_packages.py:122:12: SIM300 [*] Yoda conditions are discouraged + helm_tests/airflow_aux/test_cleanup_pods.py:182:16: SIM300 [*] Yoda conditions are discouraged + helm_tests/airflow_aux/test_cleanup_pods.py:226:16: SIM300 [*] Yoda conditions are discouraged + helm_tests/airflow_aux/test_cleanup_pods.py:229:16: SIM300 [*] Yoda conditions are discouraged + helm_tests/airflow_aux/test_cleanup_pods.py:240:16: SIM300 [*] Yoda conditions are discouraged + helm_tests/airflow_aux/test_create_user_job.py:164:16: SIM300 [*] Yoda conditions are discouraged + helm_tests/airflow_aux/test_create_user_job.py:179:16: SIM300 [*] Yoda conditions are discouraged + helm_tests/airflow_aux/test_create_user_job.py:193:16: SIM300 [*] Yoda conditions are discouraged + helm_tests/airflow_aux/test_create_user_job.py:206:16: SIM300 [*] Yoda conditions are discouraged + helm_tests/airflow_aux/test_create_user_job.py:209:16: SIM300 [*] Yoda conditions are discouraged + helm_tests/airflow_aux/test_create_user_job.py:335:16: SIM300 [*] Yoda conditions are discouraged + helm_tests/airflow_aux/test_create_user_job.py:336:16: SIM300 [*] Yoda conditions are discouraged + helm_tests/airflow_aux/test_create_user_job.py:356:16: SIM300 [*] Yoda conditions are discouraged + helm_tests/airflow_aux/test_logs_persistent_volume_claim.py:66:16: SIM300 [*] Yoda conditions are discouraged + helm_tests/airflow_aux/test_migrate_database_job.py:155:16: SIM300 [*] Yoda conditions are discouraged + helm_tests/airflow_aux/test_migrate_database_job.py:179:16: SIM300 [*] Yoda conditions are discouraged + helm_tests/airflow_aux/test_migrate_database_job.py:217:16: SIM300 [*] Yoda conditions are discouraged + helm_tests/airflow_aux/test_migrate_database_job.py:231:16: SIM300 [*] Yoda conditions are discouraged + helm_tests/airflow_aux/test_migrate_database_job.py:244:16: SIM300 [*] Yoda conditions are discouraged + helm_tests/airflow_aux/test_migrate_database_job.py:247:16: SIM300 [*] Yoda conditions are discouraged + helm_tests/airflow_aux/test_migrate_database_job.py:317:16: SIM300 [*] Yoda conditions are discouraged + helm_tests/airflow_aux/test_migrate_database_job.py:318:16: SIM300 [*] Yoda conditions are discouraged + helm_tests/airflow_aux/test_pod_launcher_role.py:51:20: SIM300 [*] Yoda conditions are discouraged, use `docs == []` instead + helm_tests/airflow_aux/test_pod_template_file.py:537:16: SIM300 [*] Yoda conditions are discouraged, use `jmespath.search("spec.affinity", docs[0]) == {}` instead + helm_tests/airflow_aux/test_pod_template_file.py:656:16: SIM300 [*] Yoda conditions are discouraged + helm_tests/airflow_aux/test_pod_template_file.py:674:16: SIM300 [*] Yoda conditions are discouraged + helm_tests/airflow_aux/test_pod_template_file.py:686:16: SIM300 [*] Yoda conditions are discouraged + helm_tests/airflow_aux/test_pod_template_file.py:734:16: SIM300 [*] Yoda conditions are discouraged + helm_tests/airflow_aux/test_pod_template_file.py:751:16: SIM300 [*] Yoda conditions are discouraged + helm_tests/airflow_aux/test_pod_template_file.py:91:16: SIM300 [*] Yoda conditions are discouraged + helm_tests/airflow_core/test_dag_processor.py:108:16: SIM300 [*] Yoda conditions are discouraged + helm_tests/airflow_core/test_dag_processor.py:126:16: SIM300 [*] Yoda conditions are discouraged + helm_tests/airflow_core/test_dag_processor.py:336:16: SIM300 [*] Yoda conditions are discouraged + helm_tests/airflow_core/test_dag_processor.py:371:16: SIM300 [*] Yoda conditions are discouraged + helm_tests/airflow_core/test_dag_processor.py:420:16: SIM300 [*] Yoda conditions are discouraged ... 322 additional changes omitted for project
bokeh/bokeh (+15 -2 violations, +0 -0 fixes)
ruff check --no-cache --exit-zero --preview --select ALL
+ tests/unit/bokeh/application/handlers/test_server_request_handler.py:121:16: SIM300 [*] Yoda conditions are discouraged + tests/unit/bokeh/document/test_document.py:717:16: SIM300 [*] Yoda conditions are discouraged, use `foos == [42,43]` instead - tests/unit/bokeh/io/test_doc.py:54:12: SIM300 [*] Yoda conditions are discouraged, use `[] == bid._PATCHED_CURDOCS` instead + tests/unit/bokeh/models/test_sources.py:100:16: SIM300 [*] Yoda conditions are discouraged, use `list(ds.data['index']) == [0, 1]` instead + tests/unit/bokeh/models/test_sources.py:112:16: SIM300 [*] Yoda conditions are discouraged, use `list(ds.data['index']) == [0, 1]` instead + tests/unit/bokeh/models/test_sources.py:124:16: SIM300 [*] Yoda conditions are discouraged, use `list(ds.data['level_0']) == [0, 1]` instead + tests/unit/bokeh/models/test_sources.py:138:16: SIM300 [*] Yoda conditions are discouraged, use `list(ds.data['level_0']) == [0, 1]` instead + tests/unit/bokeh/models/test_sources.py:151:16: SIM300 [*] Yoda conditions are discouraged, use `list(ds.data['index']) == [0, 1]` instead + tests/unit/bokeh/models/test_sources.py:166:16: SIM300 [*] Yoda conditions are discouraged, use `list(ds.data['index']) == [0, 1]` instead + tests/unit/bokeh/models/test_sources.py:86:16: SIM300 [*] Yoda conditions are discouraged, use `list(ds.data['index']) == [0, 1]` instead ... 7 additional changes omitted for project
demisto/content (+89 -0 violations, +0 -0 fixes)
ruff check --no-cache --exit-zero --preview
+ Packs/Algosec/Scripts/AlgosecGetTicket/AlgosecGetTicket_test.py:18:12: SIM300 [*] Yoda conditions are discouraged, use `content == {'some_info': 'info: test'}` instead + Packs/ApiModules/Scripts/CSVFeedApiModule/CSVFeedApiModule_test.py:241:20: SIM300 [*] Yoda conditions are discouraged, use `indicators[0]['fields']['tags'] == []` instead + Packs/ApiModules/Scripts/HTTPFeedApiModule/HTTPFeedApiModule_test.py:169:12: SIM300 [*] Yoda conditions are discouraged, use `client.get_feed_config() == {}` instead + Packs/AzureNetworkSecurityGroups/Integrations/AzureNetworkSecurityGroups/AzureNetworkSecurityGroups_test.py:73:12: SIM300 [*] Yoda conditions are discouraged + Packs/Base/Scripts/GetIncidentsByQuery/GetIncidentsByQuery_test.py:152:12: SIM300 [*] Yoda conditions are discouraged, use `entry['Contents'][0]['context'] == {}` instead + Packs/CarbonBlackProtect/Scripts/CBPCatalogFindHash/CBPCatalogFindHash_test.py:14:12: SIM300 [*] Yoda conditions are discouraged + Packs/CheckPointSandBlast/Integrations/CheckPointSandBlast/CheckPointSandBlast_test.py:122:12: SIM300 [*] Yoda conditions are discouraged + Packs/CiscoASA/Integrations/CiscoASA/CiscoASA_test.py:129:12: SIM300 [*] Yoda conditions are discouraged, use `command_results.outputs == []` instead + Packs/CommonScripts/Scripts/DomainReputation/DomainReputation_test.py:34:12: SIM300 [*] Yoda conditions are discouraged, use `results_mock.call_args[0][0] == []` instead + Packs/CommonScripts/Scripts/ExtractIndicatorsFromTextFile/ExtractIndicatorsFromTextFile_test.py:27:12: SIM300 [*] Yoda conditions are discouraged ... 79 additional changes omitted for project
model-bakers/model_bakery (+1 -0 violations, +0 -0 fixes)
ruff check --no-cache --exit-zero --preview
+ tests/test_baker.py:800:16: SIM300 [*] Yoda conditions are discouraged, use `instance.fk == ["foo"]` instead
reflex-dev/reflex (+1 -0 violations, +0 -0 fixes)
ruff check --no-cache --exit-zero --preview
+ reflex/app_module_for_backend.py:7:4: SIM300 [*] Yoda conditions are discouraged, use `constants.CompileVars.APP != "app"` instead
rotki/rotki (+2 -0 violations, +0 -0 fixes)
ruff check --no-cache --exit-zero --preview
+ rotkehlchen/tests/db/test_db_upgrades.py:580:12: SIM300 [*] Yoda conditions are discouraged, use `[x[0] for x in manual_balance_ids] == [1, 2, 3]` instead + rotkehlchen/tests/unit/test_eth2.py:760:16: SIM300 [*] Yoda conditions are discouraged, use `hidden_ids == [2]` instead
sphinx-doc/sphinx (+2 -0 violations, +0 -0 fixes)
ruff check --no-cache --exit-zero --preview
+ sphinx/ext/napoleon/docstring.py:1236:17: SIM300 [*] Yoda conditions are discouraged, use `[line1, line2] == ['', '']` instead + sphinx/util/__init__.py:205:16: SIM300 [*] Yoda conditions are discouraged, use `begend == ['', '']` instead
zulip/zulip (+5 -0 violations, +0 -0 fixes)
ruff check --no-cache --exit-zero --preview --select ALL
+ zerver/views/realm_emoji.py:47:8: SIM300 [*] Yoda conditions are discouraged + zerver/views/realm_icon.py:25:8: SIM300 [*] Yoda conditions are discouraged + zerver/views/realm_logo.py:31:8: SIM300 [*] Yoda conditions are discouraged + zerver/views/upload.py:318:8: SIM300 [*] Yoda conditions are discouraged + zerver/views/user_settings.py:413:8: SIM300 [*] Yoda conditions are discouraged
Changes by rule (1 rules affected)
code | total | + violation | - violation | + fix | - fix |
---|---|---|---|---|---|
SIM300 | 476 | 474 | 2 | 0 | 0 |
} | ||
|
||
/// Return [`Expr`] [`ConstantLikelihood`] level depending on simple heuristics. | ||
fn how_likely_constant(expr: &Expr) -> ConstantLikelihood { |
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'd probably add an associated method on ConstantLikelihood
, like:
impl ConstantLikelihood {
fn from_expression(expr: &Expr) -> Self { ... }
}
It helps with discoverability, since this is kind of a constructor.
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.
like this?
ruff/crates/ruff_linter/src/rules/flake8_simplify/rules/yoda_conditions.rs
Lines 96 to 143 in 7879f9e
impl ConstantLikelihood { | |
fn from_expression(expr: &Expr, is_preview_enabled: bool) -> Self { | |
match expr { | |
_ if expr.is_literal_expr() => ConstantLikelihood::Definitely, | |
Expr::Attribute(ast::ExprAttribute { attr, .. }) => { | |
ConstantLikelihood::from_identifier(attr) | |
} | |
Expr::Name(ast::ExprName { id, .. }) => ConstantLikelihood::from_identifier(id), | |
Expr::Tuple(ast::ExprTuple { elts, .. }) => elts | |
.iter() | |
.map(|x| ConstantLikelihood::from_expression(x, is_preview_enabled)) | |
.min() | |
.unwrap_or(ConstantLikelihood::Definitely), | |
Expr::List(ast::ExprList { elts, .. }) if is_preview_enabled => elts | |
.iter() | |
.map(|x| ConstantLikelihood::from_expression(x, is_preview_enabled)) | |
.min() | |
.unwrap_or(ConstantLikelihood::Definitely), | |
Expr::Dict(ast::ExprDict { values: vs, .. }) if is_preview_enabled => { | |
if vs.is_empty() { | |
ConstantLikelihood::Definitely | |
} else { | |
ConstantLikelihood::Probably | |
} | |
} | |
Expr::BinOp(ast::ExprBinOp { left, right, .. }) => cmp::min( | |
ConstantLikelihood::from_expression(left, is_preview_enabled), | |
ConstantLikelihood::from_expression(right, is_preview_enabled), | |
), | |
Expr::UnaryOp(ast::ExprUnaryOp { | |
op: UnaryOp::UAdd | UnaryOp::USub | UnaryOp::Invert, | |
operand, | |
range: _, | |
}) => ConstantLikelihood::from_expression(operand, is_preview_enabled), | |
_ => ConstantLikelihood::Unlikely, | |
} | |
} | |
fn from_identifier(identifier: &str) -> Self { | |
if str::is_cased_uppercase(identifier) { | |
ConstantLikelihood::Probably | |
} else { | |
ConstantLikelihood::Unlikely | |
} | |
} | |
} | |
/// Generate a fix to reverse a comparison. |
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.
Yup, exactly!
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.
If we didn't need preview
, we could also do...
impl From<&Expr> for ConstantLikelihood {
...
}
That would enable us to do things like expr.into()
.
Expr::Name(ast::ExprName { id, .. }) => str::is_cased_uppercase(id), | ||
Expr::Attribute(ast::ExprAttribute { attr, .. }) => how_likely_constant_str(attr), | ||
Expr::Name(ast::ExprName { id, .. }) => how_likely_constant_str(id), | ||
Expr::Tuple(ast::ExprTuple { elts, .. }) | Expr::List(ast::ExprList { elts, .. }) => elts |
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 think we should consider omitting lists and dictionaries, or at the very least they should be added under preview mode to avoid new violations.
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.
Ahh, I guess the use of list
was actually the motivating issue here. So, alternatively, can we try gating this whole change under preview
, to avoid disruption for folks on stable?
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.
moved lists and dicts to preview
} | ||
Expr::BinOp(ast::ExprBinOp { left, right, .. }) => { | ||
cmp::min(how_likely_constant(left), how_likely_constant(right)) | ||
} |
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.
Nice.
fn how_likely_constant(expr: &Expr) -> ConstantLikelihood { | ||
if expr.is_literal_expr() { | ||
return ConstantLikelihood::Definitely; | ||
} |
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.
Entirely personal style but I'd probably just put this in the match
with all the cases rather than adding an early return. I just find it a bit clearer.
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.
Feel free to correct me, I'm here to learn 🙂
Would you say this is idiomatic:
ruff/crates/ruff_linter/src/rules/flake8_simplify/rules/yoda_conditions.rs
Lines 98 to 100 in 7879f9e
match expr { | |
_ if expr.is_literal_expr() => ConstantLikelihood::Definitely, | |
Expr::Attribute(ast::ExprAttribute { attr, .. }) => { |
(trying to DRY this invocation from multiple patterns)
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.
Yeah, I think what you have here with the match
is a nice approach.
enum ConstantLikelihood { | ||
Unlikely = 0, | ||
Probably = 1, // CAMEL_CASED vars | ||
Definitely = 2, // literals, empty dicts and tuples... |
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: make these rustdocs? Like:
/// The expression is unlikely to be a constant (e.g., `foo` or `foo(bar)`).
Unlikely = 0
/// The expression is likely to be a constant (e.g., `FOO`).
Probably = 1,
...
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.
done. feel free to correct my English there...
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 think it's a great change!
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 excellent, thank you!
3952ad9
to
0a0b042
Compare
…ect's constant follow-up of fix added in astral-sh#9164 Signed-off-by: Mikael Arguedas <[email protected]>
Summary
fixes #6956
details in issue
Following an advice in #6956 (comment),
this change separates expressions to 3 levels of "constant likelihood":
a comparison is marked yoda if the level is strictly higher on its left hand side
following #6956 (comment) marking compound expressions of literals (e.g.
60 * 60
) as constantsthis change current behaviour on
SomeClass().settings.SOME_CONSTANT_VALUE > (60 * 60)
in the fixture from error to ok