mirror of https://github.com/astral-sh/ruff
sim300 constant likelihood levels
This commit is contained in:
parent
5aaf99b856
commit
760ff26c06
|
|
@ -13,9 +13,10 @@ YODA > age # SIM300
|
|||
YODA >= age # SIM300
|
||||
JediOrder.YODA == age # SIM300
|
||||
0 < (number - 100) # SIM300
|
||||
SomeClass().settings.SOME_CONSTANT_VALUE > (60 * 60) # SIM300
|
||||
B<A[0][0]or B
|
||||
B or(B)<A[0][0]
|
||||
['upper'] == UPPER_LIST
|
||||
{} == DummyHandler.CONFIG
|
||||
|
||||
# OK
|
||||
compare == "yoda"
|
||||
|
|
@ -31,3 +32,8 @@ age <= YODA
|
|||
YODA == YODA
|
||||
age == JediOrder.YODA
|
||||
(number - 100) > 0
|
||||
UPPER_LIST == ['upper']
|
||||
DummyHandler.CONFIG == {}
|
||||
{"thats": "acceptable"} == DummyHandler.CONFIG
|
||||
SECONDS_IN_DAY == 60 * 60 * 24
|
||||
SomeClass().settings.SOME_CONSTANT_VALUE > (60 * 60)
|
||||
|
|
@ -1,3 +1,5 @@
|
|||
use std::cmp;
|
||||
|
||||
use anyhow::Result;
|
||||
use libcst_native::CompOp;
|
||||
|
||||
|
|
@ -78,18 +80,51 @@ impl Violation for YodaConditions {
|
|||
}
|
||||
}
|
||||
|
||||
/// Return `true` if an [`Expr`] is a constant or a constant-like name.
|
||||
fn is_constant_like(expr: &Expr) -> bool {
|
||||
/// Comparisons left hand side must not be more [`ConstantLikelihood`] than their right hand side
|
||||
#[derive(PartialEq, Eq, PartialOrd, Ord, Debug)]
|
||||
enum ConstantLikelihood {
|
||||
Unlikely = 0,
|
||||
Probably = 1, // CAMEL_CASED vars
|
||||
Definitely = 2, // literals, empty dicts and tuples...
|
||||
}
|
||||
|
||||
fn how_likely_constant_str(s: &str) -> ConstantLikelihood {
|
||||
if str::is_cased_uppercase(s) {
|
||||
ConstantLikelihood::Probably
|
||||
} else {
|
||||
ConstantLikelihood::Unlikely
|
||||
}
|
||||
}
|
||||
|
||||
/// Return [`Expr`] [`ConstantLikelihood`] level depending on simple heuristics.
|
||||
fn how_likely_constant(expr: &Expr) -> ConstantLikelihood {
|
||||
if expr.is_literal_expr() {
|
||||
return ConstantLikelihood::Definitely;
|
||||
}
|
||||
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::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
|
||||
.iter()
|
||||
.map(how_likely_constant)
|
||||
.min()
|
||||
.unwrap_or(ConstantLikelihood::Definitely),
|
||||
Expr::Dict(ast::ExprDict { values: vs, .. }) => {
|
||||
if vs.is_empty() {
|
||||
ConstantLikelihood::Definitely
|
||||
} else {
|
||||
ConstantLikelihood::Probably
|
||||
}
|
||||
}
|
||||
Expr::BinOp(ast::ExprBinOp { left, right, .. }) => {
|
||||
cmp::min(how_likely_constant(left), how_likely_constant(right))
|
||||
}
|
||||
Expr::UnaryOp(ast::ExprUnaryOp {
|
||||
op: UnaryOp::UAdd | UnaryOp::USub | UnaryOp::Invert,
|
||||
operand,
|
||||
range: _,
|
||||
}) => operand.is_literal_expr(),
|
||||
_ => expr.is_literal_expr(),
|
||||
}) => how_likely_constant(operand),
|
||||
_ => ConstantLikelihood::Unlikely,
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -180,7 +215,7 @@ pub(crate) fn yoda_conditions(
|
|||
return;
|
||||
}
|
||||
|
||||
if !is_constant_like(left) || is_constant_like(right) {
|
||||
if how_likely_constant(left) <= how_likely_constant(right) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -247,7 +247,7 @@ SIM300.py:13:1: SIM300 [*] Yoda conditions are discouraged, use `age <= YODA` in
|
|||
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
|
||||
16 16 | B<A[0][0]or B
|
||||
|
||||
SIM300.py:14:1: SIM300 [*] Yoda conditions are discouraged, use `age == JediOrder.YODA` instead
|
||||
|
|
||||
|
|
@ -256,7 +256,7 @@ SIM300.py:14:1: SIM300 [*] Yoda conditions are discouraged, use `age == JediOrde
|
|||
14 | JediOrder.YODA == age # SIM300
|
||||
| ^^^^^^^^^^^^^^^^^^^^^ SIM300
|
||||
15 | 0 < (number - 100) # SIM300
|
||||
16 | SomeClass().settings.SOME_CONSTANT_VALUE > (60 * 60) # SIM300
|
||||
16 | B<A[0][0]or B
|
||||
|
|
||||
= help: Replace Yoda condition with `age == JediOrder.YODA`
|
||||
|
||||
|
|
@ -267,8 +267,8 @@ SIM300.py:14:1: SIM300 [*] Yoda conditions are discouraged, use `age == JediOrde
|
|||
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<A[0][0]or B
|
||||
16 16 | B<A[0][0]or B
|
||||
17 17 | B or(B)<A[0][0]
|
||||
|
||||
SIM300.py:15:1: SIM300 [*] Yoda conditions are discouraged, use `(number - 100) > 0` instead
|
||||
|
|
||||
|
|
@ -276,8 +276,8 @@ SIM300.py:15:1: SIM300 [*] Yoda conditions are discouraged, use `(number - 100)
|
|||
14 | JediOrder.YODA == age # SIM300
|
||||
15 | 0 < (number - 100) # SIM300
|
||||
| ^^^^^^^^^^^^^^^^^^ SIM300
|
||||
16 | SomeClass().settings.SOME_CONSTANT_VALUE > (60 * 60) # SIM300
|
||||
17 | B<A[0][0]or B
|
||||
16 | B<A[0][0]or B
|
||||
17 | B or(B)<A[0][0]
|
||||
|
|
||||
= help: Replace Yoda condition with `(number - 100) > 0`
|
||||
|
||||
|
|
@ -287,70 +287,91 @@ SIM300.py:15:1: SIM300 [*] Yoda conditions are discouraged, use `(number - 100)
|
|||
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<A[0][0]or B
|
||||
18 18 | B or(B)<A[0][0]
|
||||
16 16 | B<A[0][0]or B
|
||||
17 17 | B or(B)<A[0][0]
|
||||
18 18 | ['upper'] == UPPER_LIST
|
||||
|
||||
SIM300.py:16:1: SIM300 [*] Yoda conditions are discouraged
|
||||
SIM300.py:16:1: SIM300 [*] Yoda conditions are discouraged, use `A[0][0] > B` instead
|
||||
|
|
||||
14 | JediOrder.YODA == age # SIM300
|
||||
15 | 0 < (number - 100) # SIM300
|
||||
16 | SomeClass().settings.SOME_CONSTANT_VALUE > (60 * 60) # SIM300
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ SIM300
|
||||
17 | B<A[0][0]or B
|
||||
18 | B or(B)<A[0][0]
|
||||
16 | B<A[0][0]or B
|
||||
| ^^^^^^^^^ SIM300
|
||||
17 | B or(B)<A[0][0]
|
||||
18 | ['upper'] == UPPER_LIST
|
||||
|
|
||||
= help: Replace Yoda condition
|
||||
= help: Replace Yoda condition with `A[0][0] > B`
|
||||
|
||||
ℹ Safe fix
|
||||
13 13 | YODA >= 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<A[0][0]or B
|
||||
18 18 | B or(B)<A[0][0]
|
||||
19 19 |
|
||||
16 |-B<A[0][0]or B
|
||||
16 |+A[0][0] > B or B
|
||||
17 17 | B or(B)<A[0][0]
|
||||
18 18 | ['upper'] == UPPER_LIST
|
||||
19 19 | {} == DummyHandler.CONFIG
|
||||
|
||||
SIM300.py:17:1: SIM300 [*] Yoda conditions are discouraged, use `A[0][0] > B` instead
|
||||
SIM300.py:17:5: SIM300 [*] Yoda conditions are discouraged, use `A[0][0] > (B)` instead
|
||||
|
|
||||
15 | 0 < (number - 100) # SIM300
|
||||
16 | SomeClass().settings.SOME_CONSTANT_VALUE > (60 * 60) # SIM300
|
||||
17 | B<A[0][0]or B
|
||||
| ^^^^^^^^^ SIM300
|
||||
18 | B or(B)<A[0][0]
|
||||
|
|
||||
= help: Replace Yoda condition with `A[0][0] > 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<A[0][0]or B
|
||||
17 |+A[0][0] > B or B
|
||||
18 18 | B or(B)<A[0][0]
|
||||
19 19 |
|
||||
20 20 | # OK
|
||||
|
||||
SIM300.py:18:5: SIM300 [*] Yoda conditions are discouraged, use `A[0][0] > (B)` instead
|
||||
|
|
||||
16 | SomeClass().settings.SOME_CONSTANT_VALUE > (60 * 60) # SIM300
|
||||
17 | B<A[0][0]or B
|
||||
18 | B or(B)<A[0][0]
|
||||
16 | B<A[0][0]or B
|
||||
17 | B or(B)<A[0][0]
|
||||
| ^^^^^^^^^^^ SIM300
|
||||
19 |
|
||||
20 | # OK
|
||||
18 | ['upper'] == UPPER_LIST
|
||||
19 | {} == DummyHandler.CONFIG
|
||||
|
|
||||
= help: Replace Yoda condition with `A[0][0] > (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 17 | B<A[0][0]or B
|
||||
18 |-B or(B)<A[0][0]
|
||||
18 |+B or A[0][0] > (B)
|
||||
19 19 |
|
||||
20 20 | # OK
|
||||
21 21 | compare == "yoda"
|
||||
16 16 | B<A[0][0]or B
|
||||
17 |-B or(B)<A[0][0]
|
||||
17 |+B or A[0][0] > (B)
|
||||
18 18 | ['upper'] == UPPER_LIST
|
||||
19 19 | {} == DummyHandler.CONFIG
|
||||
20 20 |
|
||||
|
||||
SIM300.py:18:1: SIM300 [*] Yoda conditions are discouraged, use `UPPER_LIST == ['upper']` instead
|
||||
|
|
||||
16 | B<A[0][0]or B
|
||||
17 | B or(B)<A[0][0]
|
||||
18 | ['upper'] == UPPER_LIST
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^ SIM300
|
||||
19 | {} == DummyHandler.CONFIG
|
||||
|
|
||||
= help: Replace Yoda condition with `UPPER_LIST == ['upper']`
|
||||
|
||||
ℹ Safe fix
|
||||
15 15 | 0 < (number - 100) # SIM300
|
||||
16 16 | B<A[0][0]or B
|
||||
17 17 | B or(B)<A[0][0]
|
||||
18 |-['upper'] == UPPER_LIST
|
||||
18 |+UPPER_LIST == ['upper']
|
||||
19 19 | {} == DummyHandler.CONFIG
|
||||
20 20 |
|
||||
21 21 | # OK
|
||||
|
||||
SIM300.py:19:1: SIM300 [*] Yoda conditions are discouraged, use `DummyHandler.CONFIG == {}` instead
|
||||
|
|
||||
17 | B or(B)<A[0][0]
|
||||
18 | ['upper'] == UPPER_LIST
|
||||
19 | {} == DummyHandler.CONFIG
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^ SIM300
|
||||
20 |
|
||||
21 | # OK
|
||||
|
|
||||
= help: Replace Yoda condition with `DummyHandler.CONFIG == {}`
|
||||
|
||||
ℹ Safe fix
|
||||
16 16 | B<A[0][0]or B
|
||||
17 17 | B or(B)<A[0][0]
|
||||
18 18 | ['upper'] == UPPER_LIST
|
||||
19 |-{} == DummyHandler.CONFIG
|
||||
19 |+DummyHandler.CONFIG == {}
|
||||
20 20 |
|
||||
21 21 | # OK
|
||||
22 22 | compare == "yoda"
|
||||
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue