diff --git a/crates/ruff_linter/resources/test/fixtures/flake8_simplify/SIM300.py b/crates/ruff_linter/resources/test/fixtures/flake8_simplify/SIM300.py
index a9cd7df87209e..f44cf7ef41e2f 100644
--- a/crates/ruff_linter/resources/test/fixtures/flake8_simplify/SIM300.py
+++ b/crates/ruff_linter/resources/test/fixtures/flake8_simplify/SIM300.py
@@ -1,6 +1,5 @@
# Errors
"yoda" == compare # SIM300
-"yoda" == compare # SIM300
42 == age # SIM300
("a", "b") == compare # SIM300
"yoda" <= compare # SIM300
@@ -13,10 +12,17 @@
YODA >= age # SIM300
JediOrder.YODA == age # SIM300
0 < (number - 100) # SIM300
-SomeClass().settings.SOME_CONSTANT_VALUE > (60 * 60) # SIM300
B 0
+SECONDS_IN_DAY == 60 * 60 * 24 # Error in 0.1.8
+SomeClass().settings.SOME_CONSTANT_VALUE > (60 * 60) # Error in 0.1.8
+{"non-empty-dict": "is-ok"} == DummyHandler.CONFIG
diff --git a/crates/ruff_linter/src/rules/flake8_simplify/mod.rs b/crates/ruff_linter/src/rules/flake8_simplify/mod.rs
index e23eeaa4973b3..c472b56c0d079 100644
--- a/crates/ruff_linter/src/rules/flake8_simplify/mod.rs
+++ b/crates/ruff_linter/src/rules/flake8_simplify/mod.rs
@@ -56,6 +56,7 @@ mod tests {
}
#[test_case(Rule::InDictKeys, Path::new("SIM118.py"))]
+ #[test_case(Rule::YodaConditions, Path::new("SIM300.py"))]
#[test_case(Rule::IfElseBlockInsteadOfDictGet, Path::new("SIM401.py"))]
#[test_case(Rule::DictGetWithNoneDefault, Path::new("SIM910.py"))]
fn preview_rules(rule_code: Rule, path: &Path) -> Result<()> {
diff --git a/crates/ruff_linter/src/rules/flake8_simplify/rules/yoda_conditions.rs b/crates/ruff_linter/src/rules/flake8_simplify/rules/yoda_conditions.rs
index c196823de7378..1dfbeb35597ac 100644
--- a/crates/ruff_linter/src/rules/flake8_simplify/rules/yoda_conditions.rs
+++ b/crates/ruff_linter/src/rules/flake8_simplify/rules/yoda_conditions.rs
@@ -1,3 +1,5 @@
+use std::cmp;
+
use anyhow::Result;
use libcst_native::CompOp;
@@ -14,6 +16,7 @@ use crate::cst::helpers::or_space;
use crate::cst::matchers::{match_comparison, transform_expression};
use crate::fix::edits::pad;
use crate::fix::snippet::SourceCodeSnippet;
+use crate::settings::types::PreviewMode;
/// ## What it does
/// Checks for conditions that position a constant on the left-hand side of the
@@ -78,18 +81,65 @@ impl Violation for YodaConditions {
}
}
-/// Return `true` if an [`Expr`] is a constant or a constant-like name.
-fn is_constant_like(expr: &Expr) -> bool {
- match expr {
- Expr::Attribute(ast::ExprAttribute { attr, .. }) => str::is_cased_uppercase(attr),
- Expr::Tuple(ast::ExprTuple { elts, .. }) => elts.iter().all(is_constant_like),
- Expr::Name(ast::ExprName { id, .. }) => str::is_cased_uppercase(id),
- Expr::UnaryOp(ast::ExprUnaryOp {
- op: UnaryOp::UAdd | UnaryOp::USub | UnaryOp::Invert,
- operand,
- range: _,
- }) => operand.is_literal_expr(),
- _ => expr.is_literal_expr(),
+/// Comparisons left-hand side must not be more [`ConstantLikelihood`] than the right-hand side.
+#[derive(PartialEq, Eq, PartialOrd, Ord, Debug)]
+enum ConstantLikelihood {
+ /// 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,
+
+ /// The expression is definitely a constant (e.g., `42` or `"foo"`).
+ Definitely = 2,
+}
+
+impl ConstantLikelihood {
+ /// Determine the [`ConstantLikelihood`] of an expression.
+ fn from_expression(expr: &Expr, preview: PreviewMode) -> 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(|expr| ConstantLikelihood::from_expression(expr, preview))
+ .min()
+ .unwrap_or(ConstantLikelihood::Definitely),
+ Expr::List(ast::ExprList { elts, .. }) if preview.is_enabled() => elts
+ .iter()
+ .map(|expr| ConstantLikelihood::from_expression(expr, preview))
+ .min()
+ .unwrap_or(ConstantLikelihood::Definitely),
+ Expr::Dict(ast::ExprDict { values: vs, .. }) if preview.is_enabled() => {
+ if vs.is_empty() {
+ ConstantLikelihood::Definitely
+ } else {
+ ConstantLikelihood::Probably
+ }
+ }
+ Expr::BinOp(ast::ExprBinOp { left, right, .. }) => cmp::min(
+ ConstantLikelihood::from_expression(left, preview),
+ ConstantLikelihood::from_expression(right, preview),
+ ),
+ Expr::UnaryOp(ast::ExprUnaryOp {
+ op: UnaryOp::UAdd | UnaryOp::USub | UnaryOp::Invert,
+ operand,
+ range: _,
+ }) => ConstantLikelihood::from_expression(operand, preview),
+ _ => ConstantLikelihood::Unlikely,
+ }
+ }
+
+ /// Determine the [`ConstantLikelihood`] of an identifier.
+ fn from_identifier(identifier: &str) -> Self {
+ if str::is_cased_uppercase(identifier) {
+ ConstantLikelihood::Probably
+ } else {
+ ConstantLikelihood::Unlikely
+ }
}
}
@@ -180,7 +230,9 @@ pub(crate) fn yoda_conditions(
return;
}
- if !is_constant_like(left) || is_constant_like(right) {
+ if ConstantLikelihood::from_expression(left, checker.settings.preview)
+ <= ConstantLikelihood::from_expression(right, checker.settings.preview)
+ {
return;
}
diff --git a/crates/ruff_linter/src/rules/flake8_simplify/snapshots/ruff_linter__rules__flake8_simplify__tests__SIM300_SIM300.py.snap b/crates/ruff_linter/src/rules/flake8_simplify/snapshots/ruff_linter__rules__flake8_simplify__tests__SIM300_SIM300.py.snap
index 036cabca9d461..29c42f6a745ff 100644
--- a/crates/ruff_linter/src/rules/flake8_simplify/snapshots/ruff_linter__rules__flake8_simplify__tests__SIM300_SIM300.py.snap
+++ b/crates/ruff_linter/src/rules/flake8_simplify/snapshots/ruff_linter__rules__flake8_simplify__tests__SIM300_SIM300.py.snap
@@ -6,8 +6,8 @@ SIM300.py:2:1: SIM300 [*] Yoda conditions are discouraged, use `compare == "yoda
1 | # Errors
2 | "yoda" == compare # SIM300
| ^^^^^^^^^^^^^^^^^ SIM300
-3 | "yoda" == compare # SIM300
-4 | 42 == age # SIM300
+3 | 42 == age # SIM300
+4 | ("a", "b") == compare # SIM300
|
= help: Replace Yoda condition with `compare == "yoda"`
@@ -15,342 +15,340 @@ SIM300.py:2:1: SIM300 [*] Yoda conditions are discouraged, use `compare == "yoda
1 1 | # Errors
2 |-"yoda" == compare # SIM300
2 |+compare == "yoda" # SIM300
-3 3 | "yoda" == compare # SIM300
-4 4 | 42 == age # SIM300
-5 5 | ("a", "b") == compare # SIM300
+3 3 | 42 == age # SIM300
+4 4 | ("a", "b") == compare # SIM300
+5 5 | "yoda" <= compare # SIM300
-SIM300.py:3:1: SIM300 [*] Yoda conditions are discouraged, use `compare == "yoda"` instead
+SIM300.py:3:1: SIM300 [*] Yoda conditions are discouraged, use `age == 42` instead
|
1 | # Errors
2 | "yoda" == compare # SIM300
-3 | "yoda" == compare # SIM300
- | ^^^^^^^^^^^^^^^^^ SIM300
-4 | 42 == age # SIM300
-5 | ("a", "b") == compare # SIM300
- |
- = help: Replace Yoda condition with `compare == "yoda"`
-
-ℹ Safe fix
-1 1 | # Errors
-2 2 | "yoda" == compare # SIM300
-3 |-"yoda" == compare # SIM300
- 3 |+compare == "yoda" # SIM300
-4 4 | 42 == age # SIM300
-5 5 | ("a", "b") == compare # SIM300
-6 6 | "yoda" <= compare # SIM300
-
-SIM300.py:4:1: SIM300 [*] Yoda conditions are discouraged, use `age == 42` instead
- |
-2 | "yoda" == compare # SIM300
-3 | "yoda" == compare # SIM300
-4 | 42 == age # SIM300
+3 | 42 == age # SIM300
| ^^^^^^^^^ SIM300
-5 | ("a", "b") == compare # SIM300
-6 | "yoda" <= compare # SIM300
+4 | ("a", "b") == compare # SIM300
+5 | "yoda" <= compare # SIM300
|
= help: Replace Yoda condition with `age == 42`
ℹ Safe fix
1 1 | # Errors
2 2 | "yoda" == compare # SIM300
-3 3 | "yoda" == compare # SIM300
-4 |-42 == age # SIM300
- 4 |+age == 42 # SIM300
-5 5 | ("a", "b") == compare # SIM300
-6 6 | "yoda" <= compare # SIM300
-7 7 | "yoda" < compare # SIM300
-
-SIM300.py:5:1: SIM300 [*] Yoda conditions are discouraged, use `compare == ("a", "b")` instead
+3 |-42 == age # SIM300
+ 3 |+age == 42 # SIM300
+4 4 | ("a", "b") == compare # SIM300
+5 5 | "yoda" <= compare # SIM300
+6 6 | "yoda" < compare # SIM300
+
+SIM300.py:4:1: SIM300 [*] Yoda conditions are discouraged, use `compare == ("a", "b")` instead
|
-3 | "yoda" == compare # SIM300
-4 | 42 == age # SIM300
-5 | ("a", "b") == compare # SIM300
+2 | "yoda" == compare # SIM300
+3 | 42 == age # SIM300
+4 | ("a", "b") == compare # SIM300
| ^^^^^^^^^^^^^^^^^^^^^ SIM300
-6 | "yoda" <= compare # SIM300
-7 | "yoda" < compare # SIM300
+5 | "yoda" <= compare # SIM300
+6 | "yoda" < compare # SIM300
|
= help: Replace Yoda condition with `compare == ("a", "b")`
ℹ Safe fix
+1 1 | # Errors
2 2 | "yoda" == compare # SIM300
-3 3 | "yoda" == compare # SIM300
-4 4 | 42 == age # SIM300
-5 |-("a", "b") == compare # SIM300
- 5 |+compare == ("a", "b") # SIM300
-6 6 | "yoda" <= compare # SIM300
-7 7 | "yoda" < compare # SIM300
-8 8 | 42 > age # SIM300
-
-SIM300.py:6:1: SIM300 [*] Yoda conditions are discouraged, use `compare >= "yoda"` instead
+3 3 | 42 == age # SIM300
+4 |-("a", "b") == compare # SIM300
+ 4 |+compare == ("a", "b") # SIM300
+5 5 | "yoda" <= compare # SIM300
+6 6 | "yoda" < compare # SIM300
+7 7 | 42 > age # SIM300
+
+SIM300.py:5:1: SIM300 [*] Yoda conditions are discouraged, use `compare >= "yoda"` instead
|
-4 | 42 == age # SIM300
-5 | ("a", "b") == compare # SIM300
-6 | "yoda" <= compare # SIM300
+3 | 42 == age # SIM300
+4 | ("a", "b") == compare # SIM300
+5 | "yoda" <= compare # SIM300
| ^^^^^^^^^^^^^^^^^ SIM300
-7 | "yoda" < compare # SIM300
-8 | 42 > age # SIM300
+6 | "yoda" < compare # SIM300
+7 | 42 > age # SIM300
|
= help: Replace Yoda condition with `compare >= "yoda"`
ℹ Safe fix
-3 3 | "yoda" == compare # SIM300
-4 4 | 42 == age # SIM300
-5 5 | ("a", "b") == compare # SIM300
-6 |-"yoda" <= compare # SIM300
- 6 |+compare >= "yoda" # SIM300
-7 7 | "yoda" < compare # SIM300
-8 8 | 42 > age # SIM300
-9 9 | -42 > age # SIM300
-
-SIM300.py:7:1: SIM300 [*] Yoda conditions are discouraged, use `compare > "yoda"` instead
+2 2 | "yoda" == compare # SIM300
+3 3 | 42 == age # SIM300
+4 4 | ("a", "b") == compare # SIM300
+5 |-"yoda" <= compare # SIM300
+ 5 |+compare >= "yoda" # SIM300
+6 6 | "yoda" < compare # SIM300
+7 7 | 42 > age # SIM300
+8 8 | -42 > age # SIM300
+
+SIM300.py:6:1: SIM300 [*] Yoda conditions are discouraged, use `compare > "yoda"` instead
|
-5 | ("a", "b") == compare # SIM300
-6 | "yoda" <= compare # SIM300
-7 | "yoda" < compare # SIM300
+4 | ("a", "b") == compare # SIM300
+5 | "yoda" <= compare # SIM300
+6 | "yoda" < compare # SIM300
| ^^^^^^^^^^^^^^^^ SIM300
-8 | 42 > age # SIM300
-9 | -42 > age # SIM300
+7 | 42 > age # SIM300
+8 | -42 > age # SIM300
|
= help: Replace Yoda condition with `compare > "yoda"`
ℹ Safe fix
-4 4 | 42 == age # SIM300
-5 5 | ("a", "b") == compare # SIM300
-6 6 | "yoda" <= compare # SIM300
-7 |-"yoda" < compare # SIM300
- 7 |+compare > "yoda" # SIM300
-8 8 | 42 > age # SIM300
-9 9 | -42 > age # SIM300
-10 10 | +42 > age # SIM300
-
-SIM300.py:8:1: SIM300 [*] Yoda conditions are discouraged, use `age < 42` instead
- |
- 6 | "yoda" <= compare # SIM300
- 7 | "yoda" < compare # SIM300
- 8 | 42 > age # SIM300
- | ^^^^^^^^ SIM300
- 9 | -42 > age # SIM300
-10 | +42 > age # SIM300
- |
- = help: Replace Yoda condition with `age < 42`
+3 3 | 42 == age # SIM300
+4 4 | ("a", "b") == compare # SIM300
+5 5 | "yoda" <= compare # SIM300
+6 |-"yoda" < compare # SIM300
+ 6 |+compare > "yoda" # SIM300
+7 7 | 42 > age # SIM300
+8 8 | -42 > age # SIM300
+9 9 | +42 > age # SIM300
+
+SIM300.py:7:1: SIM300 [*] Yoda conditions are discouraged, use `age < 42` instead
+ |
+5 | "yoda" <= compare # SIM300
+6 | "yoda" < compare # SIM300
+7 | 42 > age # SIM300
+ | ^^^^^^^^ SIM300
+8 | -42 > age # SIM300
+9 | +42 > age # SIM300
+ |
+ = help: Replace Yoda condition with `age < 42`
ℹ Safe fix
-5 5 | ("a", "b") == compare # SIM300
-6 6 | "yoda" <= compare # SIM300
-7 7 | "yoda" < compare # SIM300
-8 |-42 > age # SIM300
- 8 |+age < 42 # SIM300
-9 9 | -42 > age # SIM300
-10 10 | +42 > age # SIM300
-11 11 | YODA == age # SIM300
-
-SIM300.py:9:1: SIM300 [*] Yoda conditions are discouraged, use `age < -42` instead
+4 4 | ("a", "b") == compare # SIM300
+5 5 | "yoda" <= compare # SIM300
+6 6 | "yoda" < compare # SIM300
+7 |-42 > age # SIM300
+ 7 |+age < 42 # SIM300
+8 8 | -42 > age # SIM300
+9 9 | +42 > age # SIM300
+10 10 | YODA == age # SIM300
+
+SIM300.py:8:1: SIM300 [*] Yoda conditions are discouraged, use `age < -42` instead
|
- 7 | "yoda" < compare # SIM300
- 8 | 42 > age # SIM300
- 9 | -42 > age # SIM300
+ 6 | "yoda" < compare # SIM300
+ 7 | 42 > age # SIM300
+ 8 | -42 > age # SIM300
| ^^^^^^^^^ SIM300
-10 | +42 > age # SIM300
-11 | YODA == age # SIM300
+ 9 | +42 > age # SIM300
+10 | YODA == age # SIM300
|
= help: Replace Yoda condition with `age < -42`
ℹ Safe fix
-6 6 | "yoda" <= compare # SIM300
-7 7 | "yoda" < compare # SIM300
-8 8 | 42 > age # SIM300
-9 |--42 > age # SIM300
- 9 |+age < -42 # SIM300
-10 10 | +42 > age # SIM300
-11 11 | YODA == age # SIM300
-12 12 | YODA > age # SIM300
-
-SIM300.py:10:1: SIM300 [*] Yoda conditions are discouraged, use `age < +42` instead
+5 5 | "yoda" <= compare # SIM300
+6 6 | "yoda" < compare # SIM300
+7 7 | 42 > age # SIM300
+8 |--42 > age # SIM300
+ 8 |+age < -42 # SIM300
+9 9 | +42 > age # SIM300
+10 10 | YODA == age # SIM300
+11 11 | YODA > age # SIM300
+
+SIM300.py:9:1: SIM300 [*] Yoda conditions are discouraged, use `age < +42` instead
|
- 8 | 42 > age # SIM300
- 9 | -42 > age # SIM300
-10 | +42 > age # SIM300
+ 7 | 42 > age # SIM300
+ 8 | -42 > age # SIM300
+ 9 | +42 > age # SIM300
| ^^^^^^^^^ SIM300
-11 | YODA == age # SIM300
-12 | YODA > age # SIM300
+10 | YODA == age # SIM300
+11 | YODA > age # SIM300
|
= help: Replace Yoda condition with `age < +42`
ℹ Safe fix
-7 7 | "yoda" < compare # SIM300
-8 8 | 42 > age # SIM300
-9 9 | -42 > age # SIM300
-10 |-+42 > age # SIM300
- 10 |+age < +42 # SIM300
-11 11 | YODA == age # SIM300
-12 12 | YODA > age # SIM300
-13 13 | YODA >= age # SIM300
-
-SIM300.py:11:1: SIM300 [*] Yoda conditions are discouraged, use `age == YODA` instead
+6 6 | "yoda" < compare # SIM300
+7 7 | 42 > age # SIM300
+8 8 | -42 > age # SIM300
+9 |-+42 > age # SIM300
+ 9 |+age < +42 # SIM300
+10 10 | YODA == age # SIM300
+11 11 | YODA > age # SIM300
+12 12 | YODA >= age # SIM300
+
+SIM300.py:10:1: SIM300 [*] Yoda conditions are discouraged, use `age == YODA` instead
|
- 9 | -42 > age # SIM300
-10 | +42 > age # SIM300
-11 | YODA == age # SIM300
+ 8 | -42 > age # SIM300
+ 9 | +42 > age # SIM300
+10 | YODA == age # SIM300
| ^^^^^^^^^^^ SIM300
-12 | YODA > age # SIM300
-13 | YODA >= age # SIM300
+11 | YODA > age # SIM300
+12 | YODA >= age # SIM300
|
= help: Replace Yoda condition with `age == YODA`
ℹ Safe fix
-8 8 | 42 > age # SIM300
-9 9 | -42 > age # SIM300
-10 10 | +42 > age # SIM300
-11 |-YODA == age # SIM300
- 11 |+age == YODA # SIM300
-12 12 | YODA > age # SIM300
-13 13 | YODA >= age # SIM300
-14 14 | JediOrder.YODA == age # SIM300
-
-SIM300.py:12:1: SIM300 [*] Yoda conditions are discouraged, use `age < YODA` instead
+7 7 | 42 > age # SIM300
+8 8 | -42 > age # SIM300
+9 9 | +42 > age # SIM300
+10 |-YODA == age # SIM300
+ 10 |+age == YODA # SIM300
+11 11 | YODA > age # SIM300
+12 12 | YODA >= age # SIM300
+13 13 | JediOrder.YODA == age # SIM300
+
+SIM300.py:11:1: SIM300 [*] Yoda conditions are discouraged, use `age < YODA` instead
|
-10 | +42 > age # SIM300
-11 | YODA == age # SIM300
-12 | YODA > age # SIM300
+ 9 | +42 > age # SIM300
+10 | YODA == age # SIM300
+11 | YODA > age # SIM300
| ^^^^^^^^^^ SIM300
-13 | YODA >= age # SIM300
-14 | JediOrder.YODA == age # SIM300
+12 | YODA >= age # SIM300
+13 | JediOrder.YODA == age # SIM300
|
= help: Replace Yoda condition with `age < YODA`
ℹ Safe fix
-9 9 | -42 > age # SIM300
-10 10 | +42 > age # SIM300
-11 11 | YODA == age # SIM300
-12 |-YODA > age # SIM300
- 12 |+age < YODA # SIM300
-13 13 | YODA >= age # SIM300
-14 14 | JediOrder.YODA == age # SIM300
-15 15 | 0 < (number - 100) # SIM300
-
-SIM300.py:13:1: SIM300 [*] Yoda conditions are discouraged, use `age <= YODA` instead
+8 8 | -42 > age # SIM300
+9 9 | +42 > age # SIM300
+10 10 | YODA == age # SIM300
+11 |-YODA > age # SIM300
+ 11 |+age < YODA # SIM300
+12 12 | YODA >= age # SIM300
+13 13 | JediOrder.YODA == age # SIM300
+14 14 | 0 < (number - 100) # SIM300
+
+SIM300.py:12:1: SIM300 [*] Yoda conditions are discouraged, use `age <= YODA` instead
|
-11 | YODA == age # SIM300
-12 | YODA > age # SIM300
-13 | YODA >= age # SIM300
+10 | YODA == age # SIM300
+11 | YODA > age # SIM300
+12 | YODA >= age # SIM300
| ^^^^^^^^^^^ SIM300
-14 | JediOrder.YODA == age # SIM300
-15 | 0 < (number - 100) # SIM300
+13 | JediOrder.YODA == age # SIM300
+14 | 0 < (number - 100) # SIM300
|
= help: Replace Yoda condition with `age <= YODA`
ℹ Safe fix
-10 10 | +42 > age # SIM300
-11 11 | YODA == age # SIM300
-12 12 | YODA > age # SIM300
-13 |-YODA >= age # SIM300
- 13 |+age <= YODA # SIM300
-14 14 | JediOrder.YODA == age # SIM300
-15 15 | 0 < (number - 100) # SIM300
-16 16 | SomeClass().settings.SOME_CONSTANT_VALUE > (60 * 60) # SIM300
-
-SIM300.py:14:1: SIM300 [*] Yoda conditions are discouraged, use `age == JediOrder.YODA` instead
+9 9 | +42 > age # SIM300
+10 10 | YODA == age # SIM300
+11 11 | YODA > age # SIM300
+12 |-YODA >= age # SIM300
+ 12 |+age <= YODA # SIM300
+13 13 | JediOrder.YODA == age # SIM300
+14 14 | 0 < (number - 100) # SIM300
+15 15 | B age # SIM300
-13 | YODA >= age # SIM300
-14 | JediOrder.YODA == age # SIM300
+11 | YODA > age # SIM300
+12 | YODA >= age # SIM300
+13 | JediOrder.YODA == age # SIM300
| ^^^^^^^^^^^^^^^^^^^^^ SIM300
-15 | 0 < (number - 100) # SIM300
-16 | SomeClass().settings.SOME_CONSTANT_VALUE > (60 * 60) # SIM300
+14 | 0 < (number - 100) # SIM300
+15 | B age # SIM300
-13 13 | YODA >= age # SIM300
-14 |-JediOrder.YODA == age # SIM300
- 14 |+age == JediOrder.YODA # SIM300
-15 15 | 0 < (number - 100) # SIM300
-16 16 | SomeClass().settings.SOME_CONSTANT_VALUE > (60 * 60) # SIM300
-17 17 | B 0` instead
+10 10 | YODA == age # SIM300
+11 11 | YODA > age # SIM300
+12 12 | YODA >= age # SIM300
+13 |-JediOrder.YODA == age # SIM300
+ 13 |+age == JediOrder.YODA # SIM300
+14 14 | 0 < (number - 100) # SIM300
+15 15 | B 0` instead
|
-13 | YODA >= age # SIM300
-14 | JediOrder.YODA == age # SIM300
-15 | 0 < (number - 100) # SIM300
+12 | YODA >= age # SIM300
+13 | JediOrder.YODA == age # SIM300
+14 | 0 < (number - 100) # SIM300
| ^^^^^^^^^^^^^^^^^^ SIM300
-16 | SomeClass().settings.SOME_CONSTANT_VALUE > (60 * 60) # SIM300
-17 | B 0`
ℹ Safe fix
-12 12 | YODA > age # SIM300
-13 13 | YODA >= age # SIM300
-14 14 | JediOrder.YODA == age # SIM300
-15 |-0 < (number - 100) # SIM300
- 15 |+(number - 100) > 0 # SIM300
-16 16 | SomeClass().settings.SOME_CONSTANT_VALUE > (60 * 60) # SIM300
-17 17 | B (60 * 60) # SIM300
- | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ SIM300
-17 | B= age # SIM300
-14 14 | JediOrder.YODA == age # SIM300
-15 15 | 0 < (number - 100) # SIM300
-16 |-SomeClass().settings.SOME_CONSTANT_VALUE > (60 * 60) # SIM300
- 16 |+(60 * 60) < SomeClass().settings.SOME_CONSTANT_VALUE # SIM300
-17 17 | B B` instead
+11 11 | YODA > age # SIM300
+12 12 | YODA >= age # SIM300
+13 13 | JediOrder.YODA == age # SIM300
+14 |-0 < (number - 100) # SIM300
+ 14 |+(number - 100) > 0 # SIM300
+15 15 | B B` instead
|
-15 | 0 < (number - 100) # SIM300
-16 | SomeClass().settings.SOME_CONSTANT_VALUE > (60 * 60) # SIM300
-17 | B B`
ℹ Safe fix
-14 14 | JediOrder.YODA == age # SIM300
-15 15 | 0 < (number - 100) # SIM300
-16 16 | SomeClass().settings.SOME_CONSTANT_VALUE > (60 * 60) # SIM300
-17 |-B B or B
-18 18 | B or(B) (B)` instead
+12 12 | YODA >= age # SIM300
+13 13 | JediOrder.YODA == age # SIM300
+14 14 | 0 < (number - 100) # SIM300
+15 |-B B or B
+16 16 | B or(B) (B)` instead
|
-16 | SomeClass().settings.SOME_CONSTANT_VALUE > (60 * 60) # SIM300
-17 | B (B)`
ℹ Safe fix
-15 15 | 0 < (number - 100) # SIM300
-16 16 | SomeClass().settings.SOME_CONSTANT_VALUE > (60 * 60) # SIM300
-17 17 | B (B)
-19 19 |
-20 20 | # OK
-21 21 | compare == "yoda"
+13 13 | JediOrder.YODA == age # SIM300
+14 14 | 0 < (number - 100) # SIM300
+15 15 | B (B)
+17 17 |
+18 18 | # Errors in preview
+19 19 | ['upper'] == UPPER_LIST
+
+SIM300.py:23:1: SIM300 [*] Yoda conditions are discouraged, use `['upper'] == UPPER_LIST` instead
+ |
+22 | # Errors in stable
+23 | UPPER_LIST == ['upper']
+ | ^^^^^^^^^^^^^^^^^^^^^^^ SIM300
+24 | DummyHandler.CONFIG == {}
+ |
+ = help: Replace Yoda condition with `['upper'] == UPPER_LIST`
+
+ℹ Safe fix
+20 20 | {} == DummyHandler.CONFIG
+21 21 |
+22 22 | # Errors in stable
+23 |-UPPER_LIST == ['upper']
+ 23 |+['upper'] == UPPER_LIST
+24 24 | DummyHandler.CONFIG == {}
+25 25 |
+26 26 | # OK
+
+SIM300.py:24:1: SIM300 [*] Yoda conditions are discouraged, use `{} == DummyHandler.CONFIG` instead
+ |
+22 | # Errors in stable
+23 | UPPER_LIST == ['upper']
+24 | DummyHandler.CONFIG == {}
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^ SIM300
+25 |
+26 | # OK
+ |
+ = help: Replace Yoda condition with `{} == DummyHandler.CONFIG`
+
+ℹ Safe fix
+21 21 |
+22 22 | # Errors in stable
+23 23 | UPPER_LIST == ['upper']
+24 |-DummyHandler.CONFIG == {}
+ 24 |+{} == DummyHandler.CONFIG
+25 25 |
+26 26 | # OK
+27 27 | compare == "yoda"
diff --git a/crates/ruff_linter/src/rules/flake8_simplify/snapshots/ruff_linter__rules__flake8_simplify__tests__preview__SIM300_SIM300.py.snap b/crates/ruff_linter/src/rules/flake8_simplify/snapshots/ruff_linter__rules__flake8_simplify__tests__preview__SIM300_SIM300.py.snap
new file mode 100644
index 0000000000000..9fff6b4ef059a
--- /dev/null
+++ b/crates/ruff_linter/src/rules/flake8_simplify/snapshots/ruff_linter__rules__flake8_simplify__tests__preview__SIM300_SIM300.py.snap
@@ -0,0 +1,354 @@
+---
+source: crates/ruff_linter/src/rules/flake8_simplify/mod.rs
+---
+SIM300.py:2:1: SIM300 [*] Yoda conditions are discouraged, use `compare == "yoda"` instead
+ |
+1 | # Errors
+2 | "yoda" == compare # SIM300
+ | ^^^^^^^^^^^^^^^^^ SIM300
+3 | 42 == age # SIM300
+4 | ("a", "b") == compare # SIM300
+ |
+ = help: Replace Yoda condition with `compare == "yoda"`
+
+ℹ Safe fix
+1 1 | # Errors
+2 |-"yoda" == compare # SIM300
+ 2 |+compare == "yoda" # SIM300
+3 3 | 42 == age # SIM300
+4 4 | ("a", "b") == compare # SIM300
+5 5 | "yoda" <= compare # SIM300
+
+SIM300.py:3:1: SIM300 [*] Yoda conditions are discouraged, use `age == 42` instead
+ |
+1 | # Errors
+2 | "yoda" == compare # SIM300
+3 | 42 == age # SIM300
+ | ^^^^^^^^^ SIM300
+4 | ("a", "b") == compare # SIM300
+5 | "yoda" <= compare # SIM300
+ |
+ = help: Replace Yoda condition with `age == 42`
+
+ℹ Safe fix
+1 1 | # Errors
+2 2 | "yoda" == compare # SIM300
+3 |-42 == age # SIM300
+ 3 |+age == 42 # SIM300
+4 4 | ("a", "b") == compare # SIM300
+5 5 | "yoda" <= compare # SIM300
+6 6 | "yoda" < compare # SIM300
+
+SIM300.py:4:1: SIM300 [*] Yoda conditions are discouraged, use `compare == ("a", "b")` instead
+ |
+2 | "yoda" == compare # SIM300
+3 | 42 == age # SIM300
+4 | ("a", "b") == compare # SIM300
+ | ^^^^^^^^^^^^^^^^^^^^^ SIM300
+5 | "yoda" <= compare # SIM300
+6 | "yoda" < compare # SIM300
+ |
+ = help: Replace Yoda condition with `compare == ("a", "b")`
+
+ℹ Safe fix
+1 1 | # Errors
+2 2 | "yoda" == compare # SIM300
+3 3 | 42 == age # SIM300
+4 |-("a", "b") == compare # SIM300
+ 4 |+compare == ("a", "b") # SIM300
+5 5 | "yoda" <= compare # SIM300
+6 6 | "yoda" < compare # SIM300
+7 7 | 42 > age # SIM300
+
+SIM300.py:5:1: SIM300 [*] Yoda conditions are discouraged, use `compare >= "yoda"` instead
+ |
+3 | 42 == age # SIM300
+4 | ("a", "b") == compare # SIM300
+5 | "yoda" <= compare # SIM300
+ | ^^^^^^^^^^^^^^^^^ SIM300
+6 | "yoda" < compare # SIM300
+7 | 42 > age # SIM300
+ |
+ = help: Replace Yoda condition with `compare >= "yoda"`
+
+ℹ Safe fix
+2 2 | "yoda" == compare # SIM300
+3 3 | 42 == age # SIM300
+4 4 | ("a", "b") == compare # SIM300
+5 |-"yoda" <= compare # SIM300
+ 5 |+compare >= "yoda" # SIM300
+6 6 | "yoda" < compare # SIM300
+7 7 | 42 > age # SIM300
+8 8 | -42 > age # SIM300
+
+SIM300.py:6:1: SIM300 [*] Yoda conditions are discouraged, use `compare > "yoda"` instead
+ |
+4 | ("a", "b") == compare # SIM300
+5 | "yoda" <= compare # SIM300
+6 | "yoda" < compare # SIM300
+ | ^^^^^^^^^^^^^^^^ SIM300
+7 | 42 > age # SIM300
+8 | -42 > age # SIM300
+ |
+ = help: Replace Yoda condition with `compare > "yoda"`
+
+ℹ Safe fix
+3 3 | 42 == age # SIM300
+4 4 | ("a", "b") == compare # SIM300
+5 5 | "yoda" <= compare # SIM300
+6 |-"yoda" < compare # SIM300
+ 6 |+compare > "yoda" # SIM300
+7 7 | 42 > age # SIM300
+8 8 | -42 > age # SIM300
+9 9 | +42 > age # SIM300
+
+SIM300.py:7:1: SIM300 [*] Yoda conditions are discouraged, use `age < 42` instead
+ |
+5 | "yoda" <= compare # SIM300
+6 | "yoda" < compare # SIM300
+7 | 42 > age # SIM300
+ | ^^^^^^^^ SIM300
+8 | -42 > age # SIM300
+9 | +42 > age # SIM300
+ |
+ = help: Replace Yoda condition with `age < 42`
+
+ℹ Safe fix
+4 4 | ("a", "b") == compare # SIM300
+5 5 | "yoda" <= compare # SIM300
+6 6 | "yoda" < compare # SIM300
+7 |-42 > age # SIM300
+ 7 |+age < 42 # SIM300
+8 8 | -42 > age # SIM300
+9 9 | +42 > age # SIM300
+10 10 | YODA == age # SIM300
+
+SIM300.py:8:1: SIM300 [*] Yoda conditions are discouraged, use `age < -42` instead
+ |
+ 6 | "yoda" < compare # SIM300
+ 7 | 42 > age # SIM300
+ 8 | -42 > age # SIM300
+ | ^^^^^^^^^ SIM300
+ 9 | +42 > age # SIM300
+10 | YODA == age # SIM300
+ |
+ = help: Replace Yoda condition with `age < -42`
+
+ℹ Safe fix
+5 5 | "yoda" <= compare # SIM300
+6 6 | "yoda" < compare # SIM300
+7 7 | 42 > age # SIM300
+8 |--42 > age # SIM300
+ 8 |+age < -42 # SIM300
+9 9 | +42 > age # SIM300
+10 10 | YODA == age # SIM300
+11 11 | YODA > age # SIM300
+
+SIM300.py:9:1: SIM300 [*] Yoda conditions are discouraged, use `age < +42` instead
+ |
+ 7 | 42 > age # SIM300
+ 8 | -42 > age # SIM300
+ 9 | +42 > age # SIM300
+ | ^^^^^^^^^ SIM300
+10 | YODA == age # SIM300
+11 | YODA > age # SIM300
+ |
+ = help: Replace Yoda condition with `age < +42`
+
+ℹ Safe fix
+6 6 | "yoda" < compare # SIM300
+7 7 | 42 > age # SIM300
+8 8 | -42 > age # SIM300
+9 |-+42 > age # SIM300
+ 9 |+age < +42 # SIM300
+10 10 | YODA == age # SIM300
+11 11 | YODA > age # SIM300
+12 12 | YODA >= age # SIM300
+
+SIM300.py:10:1: SIM300 [*] Yoda conditions are discouraged, use `age == YODA` instead
+ |
+ 8 | -42 > age # SIM300
+ 9 | +42 > age # SIM300
+10 | YODA == age # SIM300
+ | ^^^^^^^^^^^ SIM300
+11 | YODA > age # SIM300
+12 | YODA >= age # SIM300
+ |
+ = help: Replace Yoda condition with `age == YODA`
+
+ℹ Safe fix
+7 7 | 42 > age # SIM300
+8 8 | -42 > age # SIM300
+9 9 | +42 > age # SIM300
+10 |-YODA == age # SIM300
+ 10 |+age == YODA # SIM300
+11 11 | YODA > age # SIM300
+12 12 | YODA >= age # SIM300
+13 13 | JediOrder.YODA == age # SIM300
+
+SIM300.py:11:1: SIM300 [*] Yoda conditions are discouraged, use `age < YODA` instead
+ |
+ 9 | +42 > age # SIM300
+10 | YODA == age # SIM300
+11 | YODA > age # SIM300
+ | ^^^^^^^^^^ SIM300
+12 | YODA >= age # SIM300
+13 | JediOrder.YODA == age # SIM300
+ |
+ = help: Replace Yoda condition with `age < YODA`
+
+ℹ Safe fix
+8 8 | -42 > age # SIM300
+9 9 | +42 > age # SIM300
+10 10 | YODA == age # SIM300
+11 |-YODA > age # SIM300
+ 11 |+age < YODA # SIM300
+12 12 | YODA >= age # SIM300
+13 13 | JediOrder.YODA == age # SIM300
+14 14 | 0 < (number - 100) # SIM300
+
+SIM300.py:12:1: SIM300 [*] Yoda conditions are discouraged, use `age <= YODA` instead
+ |
+10 | YODA == age # SIM300
+11 | YODA > age # SIM300
+12 | YODA >= age # SIM300
+ | ^^^^^^^^^^^ SIM300
+13 | JediOrder.YODA == age # SIM300
+14 | 0 < (number - 100) # SIM300
+ |
+ = help: Replace Yoda condition with `age <= YODA`
+
+ℹ Safe fix
+9 9 | +42 > age # SIM300
+10 10 | YODA == age # SIM300
+11 11 | YODA > age # SIM300
+12 |-YODA >= age # SIM300
+ 12 |+age <= YODA # SIM300
+13 13 | JediOrder.YODA == age # SIM300
+14 14 | 0 < (number - 100) # SIM300
+15 15 | B age # SIM300
+12 | YODA >= age # SIM300
+13 | JediOrder.YODA == age # SIM300
+ | ^^^^^^^^^^^^^^^^^^^^^ SIM300
+14 | 0 < (number - 100) # SIM300
+15 | B age # SIM300
+12 12 | YODA >= age # SIM300
+13 |-JediOrder.YODA == age # SIM300
+ 13 |+age == JediOrder.YODA # SIM300
+14 14 | 0 < (number - 100) # SIM300
+15 15 | B 0` instead
+ |
+12 | YODA >= age # SIM300
+13 | JediOrder.YODA == age # SIM300
+14 | 0 < (number - 100) # SIM300
+ | ^^^^^^^^^^^^^^^^^^ SIM300
+15 | B 0`
+
+ℹ Safe fix
+11 11 | YODA > age # SIM300
+12 12 | YODA >= age # SIM300
+13 13 | JediOrder.YODA == age # SIM300
+14 |-0 < (number - 100) # SIM300
+ 14 |+(number - 100) > 0 # SIM300
+15 15 | B B` instead
+ |
+13 | JediOrder.YODA == age # SIM300
+14 | 0 < (number - 100) # SIM300
+15 | B B`
+
+ℹ Safe fix
+12 12 | YODA >= age # SIM300
+13 13 | JediOrder.YODA == age # SIM300
+14 14 | 0 < (number - 100) # SIM300
+15 |-B B or B
+16 16 | B or(B) (B)` instead
+ |
+14 | 0 < (number - 100) # SIM300
+15 | B (B)`
+
+ℹ Safe fix
+13 13 | JediOrder.YODA == age # SIM300
+14 14 | 0 < (number - 100) # SIM300
+15 15 | B (B)
+17 17 |
+18 18 | # Errors in preview
+19 19 | ['upper'] == UPPER_LIST
+
+SIM300.py:19:1: SIM300 [*] Yoda conditions are discouraged, use `UPPER_LIST == ['upper']` instead
+ |
+18 | # Errors in preview
+19 | ['upper'] == UPPER_LIST
+ | ^^^^^^^^^^^^^^^^^^^^^^^ SIM300
+20 | {} == DummyHandler.CONFIG
+ |
+ = help: Replace Yoda condition with `UPPER_LIST == ['upper']`
+
+ℹ Safe fix
+16 16 | B or(B)