Compare commits
12 Commits
dhruv/synt
...
dhruv/b018
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
9cb191c496 | ||
|
|
ff2bb6867c | ||
|
|
574843049e | ||
|
|
9e7821f4a6 | ||
|
|
403f0dccd8 | ||
|
|
46fcd19ca6 | ||
|
|
d9ec3d56b0 | ||
|
|
cd87b787d9 | ||
|
|
dd6d411026 | ||
|
|
cfceb437a8 | ||
|
|
48b0660228 | ||
|
|
24899efe50 |
3
.github/workflows/ci.yaml
vendored
3
.github/workflows/ci.yaml
vendored
@@ -167,6 +167,9 @@ jobs:
|
||||
- uses: Swatinem/rust-cache@v2
|
||||
- name: "Run tests"
|
||||
shell: bash
|
||||
env:
|
||||
# Workaround for <https://github.com/nextest-rs/nextest/issues/1493>.
|
||||
RUSTUP_WINDOWS_PATH_ADD_BIN: 1
|
||||
run: |
|
||||
cargo nextest run --all-features --profile ci
|
||||
cargo test --all-features --doc
|
||||
|
||||
@@ -6,8 +6,8 @@ class Foo2:
|
||||
"""abc"""
|
||||
|
||||
a = 2
|
||||
"str" # Str (no raise)
|
||||
f"{int}" # JoinedStr (no raise)
|
||||
"str" # StringLiteral
|
||||
f"{int}" # FString
|
||||
1j # Number (complex)
|
||||
1 # Number (int)
|
||||
1.0 # Number (float)
|
||||
@@ -34,8 +34,8 @@ def foo1():
|
||||
def foo2():
|
||||
"""my docstring"""
|
||||
a = 2
|
||||
"str" # Str (no raise)
|
||||
f"{int}" # JoinedStr (no raise)
|
||||
"str" # StringLiteral
|
||||
f"{int}" # FString
|
||||
1j # Number (complex)
|
||||
1 # Number (int)
|
||||
1.0 # Number (float)
|
||||
|
||||
93
crates/ruff_linter/resources/test/fixtures/flake8_bugbear/B018_attribute_docstring.py
vendored
Normal file
93
crates/ruff_linter/resources/test/fixtures/flake8_bugbear/B018_attribute_docstring.py
vendored
Normal file
@@ -0,0 +1,93 @@
|
||||
# These test cases not only check for `B018` but also verifies that the semantic model
|
||||
# correctly identifies certain strings as attribute docstring. And, by way of not
|
||||
# raising the `B018` violation, it can be verified.
|
||||
|
||||
a: int
|
||||
"a: docstring"
|
||||
|
||||
b = 1
|
||||
"b: docstring" " continue"
|
||||
"b: not a docstring"
|
||||
|
||||
c: int = 1
|
||||
"c: docstring"
|
||||
|
||||
_a: int
|
||||
"_a: docstring"
|
||||
|
||||
if True:
|
||||
d = 1
|
||||
"d: not a docstring"
|
||||
|
||||
(e := 1)
|
||||
"e: not a docstring"
|
||||
|
||||
f = 0
|
||||
f += 1
|
||||
"f: not a docstring"
|
||||
|
||||
g.h = 1
|
||||
"g.h: not a docstring"
|
||||
|
||||
(i) = 1
|
||||
"i: docstring"
|
||||
|
||||
(j): int = 1
|
||||
"j: docstring"
|
||||
|
||||
(k): int
|
||||
"k: docstring"
|
||||
|
||||
l = m = 1
|
||||
"l m: not a docstring"
|
||||
|
||||
n.a = n.b = n.c = 1
|
||||
"n.*: not a docstring"
|
||||
|
||||
(o, p) = (1, 2)
|
||||
"o p: not a docstring"
|
||||
|
||||
[q, r] = [1, 2]
|
||||
"q r: not a docstring"
|
||||
|
||||
*s = 1
|
||||
"s: not a docstring"
|
||||
|
||||
|
||||
class Foo:
|
||||
a = 1
|
||||
"Foo.a: docstring"
|
||||
|
||||
b: int
|
||||
"Foo.b: docstring"
|
||||
"Foo.b: not a docstring"
|
||||
|
||||
c: int = 1
|
||||
"Foo.c: docstring"
|
||||
|
||||
def __init__(self) -> None:
|
||||
# This is actually a docstring but we currently don't detect it.
|
||||
self.x = 1
|
||||
"self.x: not a docstring"
|
||||
|
||||
t = 2
|
||||
"t: not a docstring"
|
||||
|
||||
def random(self):
|
||||
self.y = 2
|
||||
"self.y: not a docstring"
|
||||
|
||||
u = 2
|
||||
"u: not a docstring"
|
||||
|
||||
def add(self, y: int):
|
||||
self.x += y
|
||||
|
||||
|
||||
def function():
|
||||
v = 2
|
||||
"v: not a docstring"
|
||||
|
||||
|
||||
function.a = 1
|
||||
"function.a: not a docstring"
|
||||
@@ -63,3 +63,16 @@ if (a and
|
||||
#: Okay
|
||||
def f():
|
||||
return 1
|
||||
|
||||
# Soft keywords
|
||||
|
||||
#: E271
|
||||
type Number = int
|
||||
|
||||
#: E273
|
||||
type Number = int
|
||||
|
||||
#: E275
|
||||
match(foo):
|
||||
case(1):
|
||||
pass
|
||||
|
||||
@@ -46,3 +46,15 @@ regex = '\\\_'
|
||||
|
||||
#: W605:1:7
|
||||
u'foo\ bar'
|
||||
|
||||
#: W605:1:13
|
||||
(
|
||||
"foo \
|
||||
bar \. baz"
|
||||
)
|
||||
|
||||
#: W605:1:6
|
||||
"foo \. bar \t"
|
||||
|
||||
#: W605:1:13
|
||||
"foo \t bar \."
|
||||
|
||||
@@ -38,3 +38,12 @@ z = (
|
||||
else
|
||||
y
|
||||
)
|
||||
|
||||
# FURB110
|
||||
z = (
|
||||
x
|
||||
if x
|
||||
else y
|
||||
if y > 0
|
||||
else None
|
||||
)
|
||||
|
||||
@@ -13,6 +13,7 @@ mod tests {
|
||||
use crate::assert_messages;
|
||||
use crate::registry::Rule;
|
||||
|
||||
use crate::settings::types::PreviewMode;
|
||||
use crate::settings::LinterSettings;
|
||||
use crate::test::test_path;
|
||||
|
||||
@@ -62,6 +63,7 @@ mod tests {
|
||||
#[test_case(Rule::UselessContextlibSuppress, Path::new("B022.py"))]
|
||||
#[test_case(Rule::UselessExpression, Path::new("B018.ipynb"))]
|
||||
#[test_case(Rule::UselessExpression, Path::new("B018.py"))]
|
||||
#[test_case(Rule::UselessExpression, Path::new("B018_attribute_docstring.py"))]
|
||||
#[test_case(Rule::LoopIteratorMutation, Path::new("B909.py"))]
|
||||
fn rules(rule_code: Rule, path: &Path) -> Result<()> {
|
||||
let snapshot = format!("{}_{}", rule_code.noqa_code(), path.to_string_lossy());
|
||||
@@ -73,6 +75,26 @@ mod tests {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[test_case(Rule::UselessExpression, Path::new("B018.ipynb"))]
|
||||
#[test_case(Rule::UselessExpression, Path::new("B018.py"))]
|
||||
#[test_case(Rule::UselessExpression, Path::new("B018_attribute_docstring.py"))]
|
||||
fn preview_rules(rule_code: Rule, path: &Path) -> Result<()> {
|
||||
let snapshot = format!(
|
||||
"preview__{}_{}",
|
||||
rule_code.noqa_code(),
|
||||
path.to_string_lossy()
|
||||
);
|
||||
let diagnostics = test_path(
|
||||
Path::new("flake8_bugbear").join(path).as_path(),
|
||||
&LinterSettings {
|
||||
preview: PreviewMode::Enabled,
|
||||
..LinterSettings::for_rule(rule_code)
|
||||
},
|
||||
)?;
|
||||
assert_messages!(snapshot, diagnostics);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn zip_without_explicit_strict() -> Result<()> {
|
||||
let snapshot = "B905.py";
|
||||
|
||||
@@ -16,6 +16,9 @@ use super::super::helpers::at_last_top_level_expression_in_cell;
|
||||
/// by mistake. Assign a useless expression to a variable, or remove it
|
||||
/// entirely.
|
||||
///
|
||||
/// In [preview mode], this rule will also flag string literals and f-strings that
|
||||
/// are not used as a docstring or an attribute docstring.
|
||||
///
|
||||
/// ## Example
|
||||
/// ```python
|
||||
/// 1 + 1
|
||||
@@ -45,6 +48,8 @@ use super::super::helpers::at_last_top_level_expression_in_cell;
|
||||
/// with errors.ExceptionRaisedContext():
|
||||
/// _ = obj.attribute
|
||||
/// ```
|
||||
///
|
||||
/// [preview]: https://docs.astral.sh/ruff/preview/
|
||||
#[violation]
|
||||
pub struct UselessExpression {
|
||||
kind: Kind,
|
||||
@@ -69,15 +74,16 @@ impl Violation for UselessExpression {
|
||||
/// B018
|
||||
pub(crate) fn useless_expression(checker: &mut Checker, value: &Expr) {
|
||||
// Ignore comparisons, as they're handled by `useless_comparison`.
|
||||
if value.is_compare_expr() {
|
||||
if matches!(value, Expr::Compare(_) | Expr::EllipsisLiteral(_)) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Ignore strings, to avoid false positives with docstrings.
|
||||
if matches!(
|
||||
value,
|
||||
Expr::FString(_) | Expr::StringLiteral(_) | Expr::EllipsisLiteral(_)
|
||||
) {
|
||||
if checker.settings.preview.is_enabled() {
|
||||
if checker.semantic().in_pep_257_docstring() || checker.semantic().in_attribute_docstring()
|
||||
{
|
||||
return;
|
||||
}
|
||||
} else if matches!(value, Expr::StringLiteral(_) | Expr::FString(_)) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
@@ -3,8 +3,8 @@ source: crates/ruff_linter/src/rules/flake8_bugbear/mod.rs
|
||||
---
|
||||
B018.py:11:5: B018 Found useless expression. Either assign it to a variable or remove it.
|
||||
|
|
||||
9 | "str" # Str (no raise)
|
||||
10 | f"{int}" # JoinedStr (no raise)
|
||||
9 | "str" # StringLiteral
|
||||
10 | f"{int}" # FString
|
||||
11 | 1j # Number (complex)
|
||||
| ^^ B018
|
||||
12 | 1 # Number (int)
|
||||
@@ -13,7 +13,7 @@ B018.py:11:5: B018 Found useless expression. Either assign it to a variable or r
|
||||
|
||||
B018.py:12:5: B018 Found useless expression. Either assign it to a variable or remove it.
|
||||
|
|
||||
10 | f"{int}" # JoinedStr (no raise)
|
||||
10 | f"{int}" # FString
|
||||
11 | 1j # Number (complex)
|
||||
12 | 1 # Number (int)
|
||||
| ^ B018
|
||||
@@ -117,8 +117,8 @@ B018.py:27:5: B018 Found useless expression. Either assign it to a variable or r
|
||||
|
||||
B018.py:39:5: B018 Found useless expression. Either assign it to a variable or remove it.
|
||||
|
|
||||
37 | "str" # Str (no raise)
|
||||
38 | f"{int}" # JoinedStr (no raise)
|
||||
37 | "str" # StringLiteral
|
||||
38 | f"{int}" # FString
|
||||
39 | 1j # Number (complex)
|
||||
| ^^ B018
|
||||
40 | 1 # Number (int)
|
||||
@@ -127,7 +127,7 @@ B018.py:39:5: B018 Found useless expression. Either assign it to a variable or r
|
||||
|
||||
B018.py:40:5: B018 Found useless expression. Either assign it to a variable or remove it.
|
||||
|
|
||||
38 | f"{int}" # JoinedStr (no raise)
|
||||
38 | f"{int}" # FString
|
||||
39 | 1j # Number (complex)
|
||||
40 | 1 # Number (int)
|
||||
| ^ B018
|
||||
@@ -254,5 +254,3 @@ B018.py:65:5: B018 Found useless expression. Either assign it to a variable or r
|
||||
65 | "foo" + "bar" # BinOp (raise)
|
||||
| ^^^^^^^^^^^^^ B018
|
||||
|
|
||||
|
||||
|
||||
|
||||
@@ -0,0 +1,11 @@
|
||||
---
|
||||
source: crates/ruff_linter/src/rules/flake8_bugbear/mod.rs
|
||||
---
|
||||
B018_attribute_docstring.py:22:2: B018 Found useless expression. Either assign it to a variable or remove it.
|
||||
|
|
||||
20 | "d: not a docstring"
|
||||
21 |
|
||||
22 | (e := 1)
|
||||
| ^^^^^^ B018
|
||||
23 | "e: not a docstring"
|
||||
|
|
||||
@@ -0,0 +1,32 @@
|
||||
---
|
||||
source: crates/ruff_linter/src/rules/flake8_bugbear/mod.rs
|
||||
---
|
||||
B018.ipynb:5:1: B018 Found useless expression. Either assign it to a variable or remove it.
|
||||
|
|
||||
3 | x
|
||||
4 | # Only skip the last expression
|
||||
5 | x # B018
|
||||
| ^ B018
|
||||
6 | x
|
||||
7 | # Nested expressions isn't relevant
|
||||
|
|
||||
|
||||
B018.ipynb:9:5: B018 Found useless expression. Either assign it to a variable or remove it.
|
||||
|
|
||||
7 | # Nested expressions isn't relevant
|
||||
8 | if True:
|
||||
9 | x
|
||||
| ^ B018
|
||||
10 | # Semicolons shouldn't affect the output
|
||||
11 | x;
|
||||
|
|
||||
|
||||
B018.ipynb:13:1: B018 Found useless expression. Either assign it to a variable or remove it.
|
||||
|
|
||||
11 | x;
|
||||
12 | # Semicolons with multiple expressions
|
||||
13 | x; x
|
||||
| ^ B018
|
||||
14 | # Comments, newlines and whitespace
|
||||
15 | x # comment
|
||||
|
|
||||
@@ -0,0 +1,295 @@
|
||||
---
|
||||
source: crates/ruff_linter/src/rules/flake8_bugbear/mod.rs
|
||||
---
|
||||
B018.py:10:5: B018 Found useless expression. Either assign it to a variable or remove it.
|
||||
|
|
||||
8 | a = 2
|
||||
9 | "str" # StringLiteral
|
||||
10 | f"{int}" # FString
|
||||
| ^^^^^^^^ B018
|
||||
11 | 1j # Number (complex)
|
||||
12 | 1 # Number (int)
|
||||
|
|
||||
|
||||
B018.py:11:5: B018 Found useless expression. Either assign it to a variable or remove it.
|
||||
|
|
||||
9 | "str" # StringLiteral
|
||||
10 | f"{int}" # FString
|
||||
11 | 1j # Number (complex)
|
||||
| ^^ B018
|
||||
12 | 1 # Number (int)
|
||||
13 | 1.0 # Number (float)
|
||||
|
|
||||
|
||||
B018.py:12:5: B018 Found useless expression. Either assign it to a variable or remove it.
|
||||
|
|
||||
10 | f"{int}" # FString
|
||||
11 | 1j # Number (complex)
|
||||
12 | 1 # Number (int)
|
||||
| ^ B018
|
||||
13 | 1.0 # Number (float)
|
||||
14 | b"foo" # Binary
|
||||
|
|
||||
|
||||
B018.py:13:5: B018 Found useless expression. Either assign it to a variable or remove it.
|
||||
|
|
||||
11 | 1j # Number (complex)
|
||||
12 | 1 # Number (int)
|
||||
13 | 1.0 # Number (float)
|
||||
| ^^^ B018
|
||||
14 | b"foo" # Binary
|
||||
15 | True # NameConstant (True)
|
||||
|
|
||||
|
||||
B018.py:14:5: B018 Found useless expression. Either assign it to a variable or remove it.
|
||||
|
|
||||
12 | 1 # Number (int)
|
||||
13 | 1.0 # Number (float)
|
||||
14 | b"foo" # Binary
|
||||
| ^^^^^^ B018
|
||||
15 | True # NameConstant (True)
|
||||
16 | False # NameConstant (False)
|
||||
|
|
||||
|
||||
B018.py:15:5: B018 Found useless expression. Either assign it to a variable or remove it.
|
||||
|
|
||||
13 | 1.0 # Number (float)
|
||||
14 | b"foo" # Binary
|
||||
15 | True # NameConstant (True)
|
||||
| ^^^^ B018
|
||||
16 | False # NameConstant (False)
|
||||
17 | None # NameConstant (None)
|
||||
|
|
||||
|
||||
B018.py:16:5: B018 Found useless expression. Either assign it to a variable or remove it.
|
||||
|
|
||||
14 | b"foo" # Binary
|
||||
15 | True # NameConstant (True)
|
||||
16 | False # NameConstant (False)
|
||||
| ^^^^^ B018
|
||||
17 | None # NameConstant (None)
|
||||
18 | [1, 2] # list
|
||||
|
|
||||
|
||||
B018.py:17:5: B018 Found useless expression. Either assign it to a variable or remove it.
|
||||
|
|
||||
15 | True # NameConstant (True)
|
||||
16 | False # NameConstant (False)
|
||||
17 | None # NameConstant (None)
|
||||
| ^^^^ B018
|
||||
18 | [1, 2] # list
|
||||
19 | {1, 2} # set
|
||||
|
|
||||
|
||||
B018.py:18:5: B018 Found useless expression. Either assign it to a variable or remove it.
|
||||
|
|
||||
16 | False # NameConstant (False)
|
||||
17 | None # NameConstant (None)
|
||||
18 | [1, 2] # list
|
||||
| ^^^^^^ B018
|
||||
19 | {1, 2} # set
|
||||
20 | {"foo": "bar"} # dict
|
||||
|
|
||||
|
||||
B018.py:19:5: B018 Found useless expression. Either assign it to a variable or remove it.
|
||||
|
|
||||
17 | None # NameConstant (None)
|
||||
18 | [1, 2] # list
|
||||
19 | {1, 2} # set
|
||||
| ^^^^^^ B018
|
||||
20 | {"foo": "bar"} # dict
|
||||
|
|
||||
|
||||
B018.py:20:5: B018 Found useless expression. Either assign it to a variable or remove it.
|
||||
|
|
||||
18 | [1, 2] # list
|
||||
19 | {1, 2} # set
|
||||
20 | {"foo": "bar"} # dict
|
||||
| ^^^^^^^^^^^^^^ B018
|
||||
|
|
||||
|
||||
B018.py:24:5: B018 Found useless expression. Either assign it to a variable or remove it.
|
||||
|
|
||||
23 | class Foo3:
|
||||
24 | 123
|
||||
| ^^^ B018
|
||||
25 | a = 2
|
||||
26 | "str"
|
||||
|
|
||||
|
||||
B018.py:27:5: B018 Found useless expression. Either assign it to a variable or remove it.
|
||||
|
|
||||
25 | a = 2
|
||||
26 | "str"
|
||||
27 | 1
|
||||
| ^ B018
|
||||
|
|
||||
|
||||
B018.py:37:5: B018 Found useless expression. Either assign it to a variable or remove it.
|
||||
|
|
||||
35 | """my docstring"""
|
||||
36 | a = 2
|
||||
37 | "str" # StringLiteral
|
||||
| ^^^^^ B018
|
||||
38 | f"{int}" # FString
|
||||
39 | 1j # Number (complex)
|
||||
|
|
||||
|
||||
B018.py:38:5: B018 Found useless expression. Either assign it to a variable or remove it.
|
||||
|
|
||||
36 | a = 2
|
||||
37 | "str" # StringLiteral
|
||||
38 | f"{int}" # FString
|
||||
| ^^^^^^^^ B018
|
||||
39 | 1j # Number (complex)
|
||||
40 | 1 # Number (int)
|
||||
|
|
||||
|
||||
B018.py:39:5: B018 Found useless expression. Either assign it to a variable or remove it.
|
||||
|
|
||||
37 | "str" # StringLiteral
|
||||
38 | f"{int}" # FString
|
||||
39 | 1j # Number (complex)
|
||||
| ^^ B018
|
||||
40 | 1 # Number (int)
|
||||
41 | 1.0 # Number (float)
|
||||
|
|
||||
|
||||
B018.py:40:5: B018 Found useless expression. Either assign it to a variable or remove it.
|
||||
|
|
||||
38 | f"{int}" # FString
|
||||
39 | 1j # Number (complex)
|
||||
40 | 1 # Number (int)
|
||||
| ^ B018
|
||||
41 | 1.0 # Number (float)
|
||||
42 | b"foo" # Binary
|
||||
|
|
||||
|
||||
B018.py:41:5: B018 Found useless expression. Either assign it to a variable or remove it.
|
||||
|
|
||||
39 | 1j # Number (complex)
|
||||
40 | 1 # Number (int)
|
||||
41 | 1.0 # Number (float)
|
||||
| ^^^ B018
|
||||
42 | b"foo" # Binary
|
||||
43 | True # NameConstant (True)
|
||||
|
|
||||
|
||||
B018.py:42:5: B018 Found useless expression. Either assign it to a variable or remove it.
|
||||
|
|
||||
40 | 1 # Number (int)
|
||||
41 | 1.0 # Number (float)
|
||||
42 | b"foo" # Binary
|
||||
| ^^^^^^ B018
|
||||
43 | True # NameConstant (True)
|
||||
44 | False # NameConstant (False)
|
||||
|
|
||||
|
||||
B018.py:43:5: B018 Found useless expression. Either assign it to a variable or remove it.
|
||||
|
|
||||
41 | 1.0 # Number (float)
|
||||
42 | b"foo" # Binary
|
||||
43 | True # NameConstant (True)
|
||||
| ^^^^ B018
|
||||
44 | False # NameConstant (False)
|
||||
45 | None # NameConstant (None)
|
||||
|
|
||||
|
||||
B018.py:44:5: B018 Found useless expression. Either assign it to a variable or remove it.
|
||||
|
|
||||
42 | b"foo" # Binary
|
||||
43 | True # NameConstant (True)
|
||||
44 | False # NameConstant (False)
|
||||
| ^^^^^ B018
|
||||
45 | None # NameConstant (None)
|
||||
46 | [1, 2] # list
|
||||
|
|
||||
|
||||
B018.py:45:5: B018 Found useless expression. Either assign it to a variable or remove it.
|
||||
|
|
||||
43 | True # NameConstant (True)
|
||||
44 | False # NameConstant (False)
|
||||
45 | None # NameConstant (None)
|
||||
| ^^^^ B018
|
||||
46 | [1, 2] # list
|
||||
47 | {1, 2} # set
|
||||
|
|
||||
|
||||
B018.py:46:5: B018 Found useless expression. Either assign it to a variable or remove it.
|
||||
|
|
||||
44 | False # NameConstant (False)
|
||||
45 | None # NameConstant (None)
|
||||
46 | [1, 2] # list
|
||||
| ^^^^^^ B018
|
||||
47 | {1, 2} # set
|
||||
48 | {"foo": "bar"} # dict
|
||||
|
|
||||
|
||||
B018.py:47:5: B018 Found useless expression. Either assign it to a variable or remove it.
|
||||
|
|
||||
45 | None # NameConstant (None)
|
||||
46 | [1, 2] # list
|
||||
47 | {1, 2} # set
|
||||
| ^^^^^^ B018
|
||||
48 | {"foo": "bar"} # dict
|
||||
|
|
||||
|
||||
B018.py:48:5: B018 Found useless expression. Either assign it to a variable or remove it.
|
||||
|
|
||||
46 | [1, 2] # list
|
||||
47 | {1, 2} # set
|
||||
48 | {"foo": "bar"} # dict
|
||||
| ^^^^^^^^^^^^^^ B018
|
||||
|
|
||||
|
||||
B018.py:52:5: B018 Found useless expression. Either assign it to a variable or remove it.
|
||||
|
|
||||
51 | def foo3():
|
||||
52 | 123
|
||||
| ^^^ B018
|
||||
53 | a = 2
|
||||
54 | "str"
|
||||
|
|
||||
|
||||
B018.py:54:5: B018 Found useless expression. Either assign it to a variable or remove it.
|
||||
|
|
||||
52 | 123
|
||||
53 | a = 2
|
||||
54 | "str"
|
||||
| ^^^^^ B018
|
||||
55 | 3
|
||||
|
|
||||
|
||||
B018.py:55:5: B018 Found useless expression. Either assign it to a variable or remove it.
|
||||
|
|
||||
53 | a = 2
|
||||
54 | "str"
|
||||
55 | 3
|
||||
| ^ B018
|
||||
|
|
||||
|
||||
B018.py:63:5: B018 Found useless expression. Either assign it to a variable or remove it.
|
||||
|
|
||||
62 | def foo5():
|
||||
63 | foo.bar # Attribute (raise)
|
||||
| ^^^^^^^ B018
|
||||
64 | object().__class__ # Attribute (raise)
|
||||
65 | "foo" + "bar" # BinOp (raise)
|
||||
|
|
||||
|
||||
B018.py:64:5: B018 Found useless attribute access. Either assign it to a variable or remove it.
|
||||
|
|
||||
62 | def foo5():
|
||||
63 | foo.bar # Attribute (raise)
|
||||
64 | object().__class__ # Attribute (raise)
|
||||
| ^^^^^^^^^^^^^^^^^^ B018
|
||||
65 | "foo" + "bar" # BinOp (raise)
|
||||
|
|
||||
|
||||
B018.py:65:5: B018 Found useless expression. Either assign it to a variable or remove it.
|
||||
|
|
||||
63 | foo.bar # Attribute (raise)
|
||||
64 | object().__class__ # Attribute (raise)
|
||||
65 | "foo" + "bar" # BinOp (raise)
|
||||
| ^^^^^^^^^^^^^ B018
|
||||
|
|
||||
@@ -0,0 +1,165 @@
|
||||
---
|
||||
source: crates/ruff_linter/src/rules/flake8_bugbear/mod.rs
|
||||
---
|
||||
B018_attribute_docstring.py:10:1: B018 Found useless expression. Either assign it to a variable or remove it.
|
||||
|
|
||||
8 | b = 1
|
||||
9 | "b: docstring" " continue"
|
||||
10 | "b: not a docstring"
|
||||
| ^^^^^^^^^^^^^^^^^^^^ B018
|
||||
11 |
|
||||
12 | c: int = 1
|
||||
|
|
||||
|
||||
B018_attribute_docstring.py:20:5: B018 Found useless expression. Either assign it to a variable or remove it.
|
||||
|
|
||||
18 | if True:
|
||||
19 | d = 1
|
||||
20 | "d: not a docstring"
|
||||
| ^^^^^^^^^^^^^^^^^^^^ B018
|
||||
21 |
|
||||
22 | (e := 1)
|
||||
|
|
||||
|
||||
B018_attribute_docstring.py:22:2: B018 Found useless expression. Either assign it to a variable or remove it.
|
||||
|
|
||||
20 | "d: not a docstring"
|
||||
21 |
|
||||
22 | (e := 1)
|
||||
| ^^^^^^ B018
|
||||
23 | "e: not a docstring"
|
||||
|
|
||||
|
||||
B018_attribute_docstring.py:23:1: B018 Found useless expression. Either assign it to a variable or remove it.
|
||||
|
|
||||
22 | (e := 1)
|
||||
23 | "e: not a docstring"
|
||||
| ^^^^^^^^^^^^^^^^^^^^ B018
|
||||
24 |
|
||||
25 | f = 0
|
||||
|
|
||||
|
||||
B018_attribute_docstring.py:27:1: B018 Found useless expression. Either assign it to a variable or remove it.
|
||||
|
|
||||
25 | f = 0
|
||||
26 | f += 1
|
||||
27 | "f: not a docstring"
|
||||
| ^^^^^^^^^^^^^^^^^^^^ B018
|
||||
28 |
|
||||
29 | g.h = 1
|
||||
|
|
||||
|
||||
B018_attribute_docstring.py:30:1: B018 Found useless expression. Either assign it to a variable or remove it.
|
||||
|
|
||||
29 | g.h = 1
|
||||
30 | "g.h: not a docstring"
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^ B018
|
||||
31 |
|
||||
32 | (i) = 1
|
||||
|
|
||||
|
||||
B018_attribute_docstring.py:42:1: B018 Found useless expression. Either assign it to a variable or remove it.
|
||||
|
|
||||
41 | l = m = 1
|
||||
42 | "l m: not a docstring"
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^ B018
|
||||
43 |
|
||||
44 | n.a = n.b = n.c = 1
|
||||
|
|
||||
|
||||
B018_attribute_docstring.py:45:1: B018 Found useless expression. Either assign it to a variable or remove it.
|
||||
|
|
||||
44 | n.a = n.b = n.c = 1
|
||||
45 | "n.*: not a docstring"
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^ B018
|
||||
46 |
|
||||
47 | (o, p) = (1, 2)
|
||||
|
|
||||
|
||||
B018_attribute_docstring.py:48:1: B018 Found useless expression. Either assign it to a variable or remove it.
|
||||
|
|
||||
47 | (o, p) = (1, 2)
|
||||
48 | "o p: not a docstring"
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^ B018
|
||||
49 |
|
||||
50 | [q, r] = [1, 2]
|
||||
|
|
||||
|
||||
B018_attribute_docstring.py:51:1: B018 Found useless expression. Either assign it to a variable or remove it.
|
||||
|
|
||||
50 | [q, r] = [1, 2]
|
||||
51 | "q r: not a docstring"
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^ B018
|
||||
52 |
|
||||
53 | *s = 1
|
||||
|
|
||||
|
||||
B018_attribute_docstring.py:54:1: B018 Found useless expression. Either assign it to a variable or remove it.
|
||||
|
|
||||
53 | *s = 1
|
||||
54 | "s: not a docstring"
|
||||
| ^^^^^^^^^^^^^^^^^^^^ B018
|
||||
|
|
||||
|
||||
B018_attribute_docstring.py:63:5: B018 Found useless expression. Either assign it to a variable or remove it.
|
||||
|
|
||||
61 | b: int
|
||||
62 | "Foo.b: docstring"
|
||||
63 | "Foo.b: not a docstring"
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^ B018
|
||||
64 |
|
||||
65 | c: int = 1
|
||||
|
|
||||
|
||||
B018_attribute_docstring.py:71:9: B018 Found useless expression. Either assign it to a variable or remove it.
|
||||
|
|
||||
69 | # This is actually a docstring but we currently don't detect it.
|
||||
70 | self.x = 1
|
||||
71 | "self.x: not a docstring"
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^ B018
|
||||
72 |
|
||||
73 | t = 2
|
||||
|
|
||||
|
||||
B018_attribute_docstring.py:74:9: B018 Found useless expression. Either assign it to a variable or remove it.
|
||||
|
|
||||
73 | t = 2
|
||||
74 | "t: not a docstring"
|
||||
| ^^^^^^^^^^^^^^^^^^^^ B018
|
||||
75 |
|
||||
76 | def random(self):
|
||||
|
|
||||
|
||||
B018_attribute_docstring.py:78:9: B018 Found useless expression. Either assign it to a variable or remove it.
|
||||
|
|
||||
76 | def random(self):
|
||||
77 | self.y = 2
|
||||
78 | "self.y: not a docstring"
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^ B018
|
||||
79 |
|
||||
80 | u = 2
|
||||
|
|
||||
|
||||
B018_attribute_docstring.py:81:9: B018 Found useless expression. Either assign it to a variable or remove it.
|
||||
|
|
||||
80 | u = 2
|
||||
81 | "u: not a docstring"
|
||||
| ^^^^^^^^^^^^^^^^^^^^ B018
|
||||
82 |
|
||||
83 | def add(self, y: int):
|
||||
|
|
||||
|
||||
B018_attribute_docstring.py:89:5: B018 Found useless expression. Either assign it to a variable or remove it.
|
||||
|
|
||||
87 | def function():
|
||||
88 | v = 2
|
||||
89 | "v: not a docstring"
|
||||
| ^^^^^^^^^^^^^^^^^^^^ B018
|
||||
|
|
||||
|
||||
B018_attribute_docstring.py:93:1: B018 Found useless expression. Either assign it to a variable or remove it.
|
||||
|
|
||||
92 | function.a = 1
|
||||
93 | "function.a: not a docstring"
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ B018
|
||||
|
|
||||
@@ -181,6 +181,7 @@ fn check(
|
||||
|
||||
// If we're at the end of line, skip.
|
||||
if matches!(next_char, '\n' | '\r') {
|
||||
contains_valid_escape_sequence = true;
|
||||
continue;
|
||||
}
|
||||
|
||||
|
||||
@@ -52,7 +52,7 @@ pub(crate) fn missing_whitespace_after_keyword(
|
||||
let tok0_kind = tok0.kind();
|
||||
let tok1_kind = tok1.kind();
|
||||
|
||||
if tok0_kind.is_non_soft_keyword()
|
||||
if tok0_kind.is_keyword()
|
||||
&& !(tok0_kind.is_singleton()
|
||||
|| matches!(tok0_kind, TokenKind::Async | TokenKind::Await)
|
||||
|| tok0_kind == TokenKind::Except && tok1_kind == TokenKind::Star
|
||||
|
||||
@@ -445,7 +445,7 @@ impl LogicalLinesBuilder {
|
||||
|
||||
if matches!(kind, TokenKind::Comma | TokenKind::Semi | TokenKind::Colon) {
|
||||
line.flags.insert(TokenFlags::PUNCTUATION);
|
||||
} else if kind.is_non_soft_keyword() {
|
||||
} else if kind.is_keyword() {
|
||||
line.flags.insert(TokenFlags::KEYWORD);
|
||||
}
|
||||
|
||||
|
||||
@@ -127,8 +127,8 @@ pub(crate) fn whitespace_around_keywords(line: &LogicalLine, context: &mut Logic
|
||||
let mut after_keyword = false;
|
||||
|
||||
for token in line.tokens() {
|
||||
let is_non_soft_keyword = token.kind().is_non_soft_keyword();
|
||||
if is_non_soft_keyword {
|
||||
let is_keyword = token.kind().is_keyword();
|
||||
if is_keyword {
|
||||
if !after_keyword {
|
||||
match line.leading_whitespace(token) {
|
||||
(Whitespace::Tab, offset) => {
|
||||
@@ -184,6 +184,6 @@ pub(crate) fn whitespace_around_keywords(line: &LogicalLine, context: &mut Logic
|
||||
}
|
||||
}
|
||||
|
||||
after_keyword = is_non_soft_keyword;
|
||||
after_keyword = is_keyword;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -11,18 +11,6 @@ use ruff_text_size::{TextRange, TextSize};
|
||||
/// According to [PEP 8], spaces are preferred over tabs (unless used to remain
|
||||
/// consistent with code that is already indented with tabs).
|
||||
///
|
||||
/// ## Example
|
||||
/// ```python
|
||||
/// if True:
|
||||
/// a = 1
|
||||
/// ```
|
||||
///
|
||||
/// Use instead:
|
||||
/// ```python
|
||||
/// if True:
|
||||
/// a = 1
|
||||
/// ```
|
||||
///
|
||||
/// ## Formatter compatibility
|
||||
/// We recommend against using this rule alongside the [formatter]. The
|
||||
/// formatter enforces consistent indentation, making the rule redundant.
|
||||
|
||||
@@ -190,4 +190,22 @@ E27.py:35:14: E271 [*] Multiple spaces after keyword
|
||||
37 37 | from w import(e, f)
|
||||
38 38 | #: E275
|
||||
|
||||
E27.py:70:5: E271 [*] Multiple spaces after keyword
|
||||
|
|
||||
69 | #: E271
|
||||
70 | type Number = int
|
||||
| ^^ E271
|
||||
71 |
|
||||
72 | #: E273
|
||||
|
|
||||
= help: Replace with single space
|
||||
|
||||
ℹ Safe fix
|
||||
67 67 | # Soft keywords
|
||||
68 68 |
|
||||
69 69 | #: E271
|
||||
70 |-type Number = int
|
||||
70 |+type Number = int
|
||||
71 71 |
|
||||
72 72 | #: E273
|
||||
73 73 | type Number = int
|
||||
|
||||
@@ -106,4 +106,22 @@ E27.py:30:10: E273 [*] Tab after keyword
|
||||
32 32 | from u import (a, b)
|
||||
33 33 | from v import c, d
|
||||
|
||||
E27.py:73:5: E273 [*] Tab after keyword
|
||||
|
|
||||
72 | #: E273
|
||||
73 | type Number = int
|
||||
| ^^^^ E273
|
||||
74 |
|
||||
75 | #: E275
|
||||
|
|
||||
= help: Replace with single space
|
||||
|
||||
ℹ Safe fix
|
||||
70 70 | type Number = int
|
||||
71 71 |
|
||||
72 72 | #: E273
|
||||
73 |-type Number = int
|
||||
73 |+type Number = int
|
||||
74 74 |
|
||||
75 75 | #: E275
|
||||
76 76 | match(foo):
|
||||
|
||||
@@ -106,4 +106,39 @@ E27.py:54:5: E275 [*] Missing whitespace after keyword
|
||||
56 56 | def f():
|
||||
57 57 | print((yield))
|
||||
|
||||
E27.py:76:1: E275 [*] Missing whitespace after keyword
|
||||
|
|
||||
75 | #: E275
|
||||
76 | match(foo):
|
||||
| ^^^^^ E275
|
||||
77 | case(1):
|
||||
78 | pass
|
||||
|
|
||||
= help: Added missing whitespace after keyword
|
||||
|
||||
ℹ Safe fix
|
||||
73 73 | type Number = int
|
||||
74 74 |
|
||||
75 75 | #: E275
|
||||
76 |-match(foo):
|
||||
76 |+match (foo):
|
||||
77 77 | case(1):
|
||||
78 78 | pass
|
||||
|
||||
E27.py:77:5: E275 [*] Missing whitespace after keyword
|
||||
|
|
||||
75 | #: E275
|
||||
76 | match(foo):
|
||||
77 | case(1):
|
||||
| ^^^^ E275
|
||||
78 | pass
|
||||
|
|
||||
= help: Added missing whitespace after keyword
|
||||
|
||||
ℹ Safe fix
|
||||
74 74 |
|
||||
75 75 | #: E275
|
||||
76 76 | match(foo):
|
||||
77 |- case(1):
|
||||
77 |+ case (1):
|
||||
78 78 | pass
|
||||
|
||||
@@ -145,6 +145,8 @@ W605_0.py:48:6: W605 [*] Invalid escape sequence: `\ `
|
||||
47 | #: W605:1:7
|
||||
48 | u'foo\ bar'
|
||||
| ^^ W605
|
||||
49 |
|
||||
50 | #: W605:1:13
|
||||
|
|
||||
= help: Use a raw string literal
|
||||
|
||||
@@ -154,5 +156,61 @@ W605_0.py:48:6: W605 [*] Invalid escape sequence: `\ `
|
||||
47 47 | #: W605:1:7
|
||||
48 |-u'foo\ bar'
|
||||
48 |+r'foo\ bar'
|
||||
49 49 |
|
||||
50 50 | #: W605:1:13
|
||||
51 51 | (
|
||||
|
||||
W605_0.py:53:9: W605 [*] Invalid escape sequence: `\.`
|
||||
|
|
||||
51 | (
|
||||
52 | "foo \
|
||||
53 | bar \. baz"
|
||||
| ^^ W605
|
||||
54 | )
|
||||
|
|
||||
= help: Add backslash to escape sequence
|
||||
|
||||
ℹ Safe fix
|
||||
50 50 | #: W605:1:13
|
||||
51 51 | (
|
||||
52 52 | "foo \
|
||||
53 |- bar \. baz"
|
||||
53 |+ bar \\. baz"
|
||||
54 54 | )
|
||||
55 55 |
|
||||
56 56 | #: W605:1:6
|
||||
|
||||
W605_0.py:57:6: W605 [*] Invalid escape sequence: `\.`
|
||||
|
|
||||
56 | #: W605:1:6
|
||||
57 | "foo \. bar \t"
|
||||
| ^^ W605
|
||||
58 |
|
||||
59 | #: W605:1:13
|
||||
|
|
||||
= help: Add backslash to escape sequence
|
||||
|
||||
ℹ Safe fix
|
||||
54 54 | )
|
||||
55 55 |
|
||||
56 56 | #: W605:1:6
|
||||
57 |-"foo \. bar \t"
|
||||
57 |+"foo \\. bar \t"
|
||||
58 58 |
|
||||
59 59 | #: W605:1:13
|
||||
60 60 | "foo \t bar \."
|
||||
|
||||
W605_0.py:60:13: W605 [*] Invalid escape sequence: `\.`
|
||||
|
|
||||
59 | #: W605:1:13
|
||||
60 | "foo \t bar \."
|
||||
| ^^ W605
|
||||
|
|
||||
= help: Add backslash to escape sequence
|
||||
|
||||
ℹ Safe fix
|
||||
57 57 | "foo \. bar \t"
|
||||
58 58 |
|
||||
59 59 | #: W605:1:13
|
||||
60 |-"foo \t bar \."
|
||||
60 |+"foo \t bar \\."
|
||||
|
||||
@@ -1,9 +1,14 @@
|
||||
use std::borrow::Cow;
|
||||
|
||||
use ruff_diagnostics::{Applicability, Diagnostic, Edit, Fix, FixAvailability, Violation};
|
||||
use ruff_macros::{derive_message_formats, violation};
|
||||
use ruff_python_ast as ast;
|
||||
use ruff_python_ast::comparable::ComparableExpr;
|
||||
use ruff_python_ast::helpers::contains_effect;
|
||||
use ruff_python_ast::parenthesize::parenthesized_range;
|
||||
use ruff_python_ast::Expr;
|
||||
use ruff_python_index::Indexer;
|
||||
use ruff_source_file::Locator;
|
||||
use ruff_text_size::Ranged;
|
||||
|
||||
use crate::checkers::ast::Checker;
|
||||
@@ -64,29 +69,13 @@ pub(crate) fn if_exp_instead_of_or_operator(checker: &mut Checker, if_expr: &ast
|
||||
|
||||
let mut diagnostic = Diagnostic::new(IfExpInsteadOfOrOperator, *range);
|
||||
|
||||
// Grab the range of the `test` and `orelse` expressions.
|
||||
let left = parenthesized_range(
|
||||
test.into(),
|
||||
if_expr.into(),
|
||||
checker.indexer().comment_ranges(),
|
||||
checker.locator().contents(),
|
||||
)
|
||||
.unwrap_or(test.range());
|
||||
let right = parenthesized_range(
|
||||
orelse.into(),
|
||||
if_expr.into(),
|
||||
checker.indexer().comment_ranges(),
|
||||
checker.locator().contents(),
|
||||
)
|
||||
.unwrap_or(orelse.range());
|
||||
|
||||
// Replace with `{test} or {orelse}`.
|
||||
diagnostic.set_fix(Fix::applicable_edit(
|
||||
Edit::range_replacement(
|
||||
format!(
|
||||
"{} or {}",
|
||||
checker.locator().slice(left),
|
||||
checker.locator().slice(right),
|
||||
parenthesize_test(test, if_expr, checker.indexer(), checker.locator()),
|
||||
parenthesize_test(orelse, if_expr, checker.indexer(), checker.locator()),
|
||||
),
|
||||
if_expr.range(),
|
||||
),
|
||||
@@ -99,3 +88,30 @@ pub(crate) fn if_exp_instead_of_or_operator(checker: &mut Checker, if_expr: &ast
|
||||
|
||||
checker.diagnostics.push(diagnostic);
|
||||
}
|
||||
|
||||
/// Parenthesize an expression for use in an `or` operator (e.g., parenthesize `x` in `x or y`),
|
||||
/// if it's required to maintain the correct order of operations.
|
||||
///
|
||||
/// If the expression is already parenthesized, it will be returned as-is regardless of whether
|
||||
/// the parentheses are required.
|
||||
///
|
||||
/// See: <https://docs.python.org/3/reference/expressions.html#operator-precedence>
|
||||
fn parenthesize_test<'a>(
|
||||
expr: &Expr,
|
||||
if_expr: &ast::ExprIf,
|
||||
indexer: &Indexer,
|
||||
locator: &Locator<'a>,
|
||||
) -> Cow<'a, str> {
|
||||
if let Some(range) = parenthesized_range(
|
||||
expr.into(),
|
||||
if_expr.into(),
|
||||
indexer.comment_ranges(),
|
||||
locator.contents(),
|
||||
) {
|
||||
Cow::Borrowed(locator.slice(range))
|
||||
} else if matches!(expr, Expr::If(_) | Expr::Lambda(_) | Expr::Named(_)) {
|
||||
Cow::Owned(format!("({})", locator.slice(expr.range())))
|
||||
} else {
|
||||
Cow::Borrowed(locator.slice(expr.range()))
|
||||
}
|
||||
}
|
||||
|
||||
@@ -177,3 +177,33 @@ FURB110.py:34:5: FURB110 [*] Replace ternary `if` expression with `or` operator
|
||||
39 |- y
|
||||
34 |+ x or y
|
||||
40 35 | )
|
||||
41 36 |
|
||||
42 37 | # FURB110
|
||||
|
||||
FURB110.py:44:5: FURB110 [*] Replace ternary `if` expression with `or` operator
|
||||
|
|
||||
42 | # FURB110
|
||||
43 | z = (
|
||||
44 | x
|
||||
| _____^
|
||||
45 | | if x
|
||||
46 | | else y
|
||||
47 | | if y > 0
|
||||
48 | | else None
|
||||
| |_____________^ FURB110
|
||||
49 | )
|
||||
|
|
||||
= help: Replace with `or` operator
|
||||
|
||||
ℹ Safe fix
|
||||
41 41 |
|
||||
42 42 | # FURB110
|
||||
43 43 | z = (
|
||||
44 |- x
|
||||
45 |- if x
|
||||
46 |- else y
|
||||
44 |+ x or (y
|
||||
47 45 | if y > 0
|
||||
48 |- else None
|
||||
46 |+ else None)
|
||||
49 47 | )
|
||||
|
||||
@@ -145,7 +145,20 @@ def markdown_check_result(result: Result) -> str:
|
||||
|
||||
# Limit the number of items displayed per project to between 10 and 50
|
||||
# based on the proportion of total changes present in this project
|
||||
max_display_per_project = max(10, int((project_changes / total_changes) * 50))
|
||||
max_display_per_project = max(
|
||||
10,
|
||||
int(
|
||||
(
|
||||
# TODO(zanieb): We take the `max` here to avoid division by zero errors where
|
||||
# `total_changes` is zero but `total_affected_rules` is non-zero so we did not
|
||||
# skip display. This shouldn't really happen and indicates a problem in the
|
||||
# calculation of these values. Instead of skipping entirely when `total_changes`
|
||||
# is zero, we'll attempt to report the results to help diagnose the problem.
|
||||
project_changes / max(total_changes, 1)
|
||||
)
|
||||
* 50
|
||||
),
|
||||
)
|
||||
|
||||
# Limit the number of items displayed per rule to between 5 and the max for
|
||||
# the project based on the number of rules affected (less rules, more per rule)
|
||||
|
||||
@@ -30,7 +30,6 @@ DEFAULT_TARGETS = [
|
||||
repo=Repository(owner="bokeh", name="bokeh", ref="branch-3.3"),
|
||||
check_options=CheckOptions(select="ALL"),
|
||||
),
|
||||
Project(repo=Repository(owner="commaai", name="openpilot", ref="master")),
|
||||
Project(
|
||||
repo=Repository(owner="demisto", name="content", ref="master"),
|
||||
format_options=FormatOptions(
|
||||
@@ -117,4 +116,11 @@ DEFAULT_TARGETS = [
|
||||
],
|
||||
},
|
||||
),
|
||||
Project(repo=Repository(owner="agronholm", name="anyio", ref="master")),
|
||||
Project(repo=Repository(owner="python-trio", name="trio", ref="master")),
|
||||
Project(repo=Repository(owner="wntrblm", name="nox", ref="main")),
|
||||
Project(repo=Repository(owner="pytest-dev", name="pytest", ref="main")),
|
||||
Project(repo=Repository(owner="encode", name="httpx", ref="master")),
|
||||
Project(repo=Repository(owner="mesonbuild", name="meson-python", ref="main")),
|
||||
Project(repo=Repository(owner="pdm-project", name="pdm", ref="main")),
|
||||
]
|
||||
|
||||
@@ -74,7 +74,6 @@ KNOWN_FORMATTING_VIOLATIONS = [
|
||||
"redundant-backslash",
|
||||
"shebang-leading-whitespace",
|
||||
"surrounding-whitespace",
|
||||
"tab-indentation",
|
||||
"too-few-spaces-before-inline-comment",
|
||||
"too-many-blank-lines",
|
||||
"too-many-boolean-expressions",
|
||||
|
||||
@@ -124,7 +124,6 @@ REPOSITORIES: list[Repository] = [
|
||||
Repository("aws", "aws-sam-cli", "develop"),
|
||||
Repository("bloomberg", "pytest-memray", "main"),
|
||||
Repository("bokeh", "bokeh", "branch-3.3", select="ALL"),
|
||||
Repository("commaai", "openpilot", "master"),
|
||||
Repository("demisto", "content", "master"),
|
||||
Repository("docker", "docker-py", "main"),
|
||||
Repository("freedomofpress", "securedrop", "develop"),
|
||||
|
||||
Reference in New Issue
Block a user