flake8_simplify 0.30.0__tar.gz → 0.31.1__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {flake8_simplify-0.30.0 → flake8_simplify-0.31.1}/PKG-INFO +10 -10
- {flake8_simplify-0.30.0 → flake8_simplify-0.31.1}/README.md +1 -2
- flake8_simplify-0.31.1/flake8_simplify/__init__.py +45 -0
- flake8_simplify-0.31.1/flake8_simplify/registry.py +71 -0
- {flake8_simplify-0.30.0 → flake8_simplify-0.31.1}/flake8_simplify/rules/ast_assign.py +25 -30
- {flake8_simplify-0.30.0 → flake8_simplify-0.31.1}/flake8_simplify/rules/ast_bool_op.py +46 -54
- {flake8_simplify-0.30.0 → flake8_simplify-0.31.1}/flake8_simplify/rules/ast_call.py +40 -84
- flake8_simplify-0.31.1/flake8_simplify/rules/ast_classdef.py +19 -0
- {flake8_simplify-0.30.0 → flake8_simplify-0.31.1}/flake8_simplify/rules/ast_compare.py +15 -24
- flake8_simplify-0.31.1/flake8_simplify/rules/ast_expr.py +64 -0
- {flake8_simplify-0.30.0 → flake8_simplify-0.31.1}/flake8_simplify/rules/ast_for.py +80 -80
- flake8_simplify-0.31.1/flake8_simplify/rules/ast_if.py +505 -0
- flake8_simplify-0.31.1/flake8_simplify/rules/ast_ifexp.py +61 -0
- {flake8_simplify-0.30.0 → flake8_simplify-0.31.1}/flake8_simplify/rules/ast_subscript.py +10 -14
- flake8_simplify-0.31.1/flake8_simplify/rules/ast_try.py +94 -0
- flake8_simplify-0.31.1/flake8_simplify/rules/ast_unary_op.py +82 -0
- {flake8_simplify-0.30.0 → flake8_simplify-0.31.1}/flake8_simplify/rules/ast_with.py +7 -8
- {flake8_simplify-0.30.0 → flake8_simplify-0.31.1}/flake8_simplify/utils.py +68 -74
- flake8_simplify-0.31.1/pyproject.toml +118 -0
- flake8_simplify-0.30.0/pyproject.toml → flake8_simplify-0.31.1/pyproject.toml.orig +31 -23
- flake8_simplify-0.30.0/.coveragerc +0 -22
- flake8_simplify-0.30.0/.flake8 +0 -6
- flake8_simplify-0.30.0/.github/ISSUE_TEMPLATE/adjust-rule.md +0 -25
- flake8_simplify-0.30.0/.github/ISSUE_TEMPLATE/rule-request.md +0 -22
- flake8_simplify-0.30.0/.github/dependabot.yml +0 -9
- flake8_simplify-0.30.0/.github/workflows/lint.yml +0 -36
- flake8_simplify-0.30.0/.github/workflows/unit-test.yml +0 -34
- flake8_simplify-0.30.0/.gitignore +0 -142
- flake8_simplify-0.30.0/.pre-commit-config.yaml +0 -43
- flake8_simplify-0.30.0/CHANGELOG.md +0 -109
- flake8_simplify-0.30.0/Makefile +0 -26
- flake8_simplify-0.30.0/flake8_simplify/__init__.py +0 -170
- flake8_simplify-0.30.0/flake8_simplify/constants.py +0 -5
- flake8_simplify-0.30.0/flake8_simplify/rules/ast_classdef.py +0 -22
- flake8_simplify-0.30.0/flake8_simplify/rules/ast_expr.py +0 -100
- flake8_simplify-0.30.0/flake8_simplify/rules/ast_if.py +0 -512
- flake8_simplify-0.30.0/flake8_simplify/rules/ast_ifexp.py +0 -65
- flake8_simplify-0.30.0/flake8_simplify/rules/ast_try.py +0 -93
- flake8_simplify-0.30.0/flake8_simplify/rules/ast_unary_op.py +0 -103
- flake8_simplify-0.30.0/mutmut-test.sh +0 -3
- flake8_simplify-0.30.0/requirements/dev.in +0 -8
- flake8_simplify-0.30.0/requirements/dev.txt +0 -91
- flake8_simplify-0.30.0/requirements/lint.in +0 -14
- flake8_simplify-0.30.0/requirements/lint.txt +0 -62
- flake8_simplify-0.30.0/tests/__init__.py +0 -10
- flake8_simplify-0.30.0/tests/test_100_rules.py +0 -517
- flake8_simplify-0.30.0/tests/test_200_rules.py +0 -70
- flake8_simplify-0.30.0/tests/test_300_rules.py +0 -18
- flake8_simplify-0.30.0/tests/test_400_rules.py +0 -130
- flake8_simplify-0.30.0/tests/test_900_rules.py +0 -243
- flake8_simplify-0.30.0/tests/test_simplify.py +0 -112
- flake8_simplify-0.30.0/tox.ini +0 -18
- {flake8_simplify-0.30.0 → flake8_simplify-0.31.1}/LICENSE +0 -0
- {flake8_simplify-0.30.0 → flake8_simplify-0.31.1}/flake8_simplify/rules/__init__.py +0 -0
|
@@ -1,35 +1,36 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: flake8_simplify
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.31.1
|
|
4
4
|
Summary: flake8 plugin which checks for code that can be simplified
|
|
5
5
|
Keywords: flake8
|
|
6
|
+
Author: Martin Thoma
|
|
6
7
|
Author-email: Martin Thoma <info@martin-thoma.de>
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
Description-Content-Type: text/markdown
|
|
8
|
+
License-Expression: MIT
|
|
9
|
+
License-File: LICENSE
|
|
10
10
|
Classifier: Development Status :: 4 - Beta
|
|
11
11
|
Classifier: Environment :: Console
|
|
12
12
|
Classifier: Intended Audience :: Developers
|
|
13
|
-
Classifier: License :: OSI Approved :: MIT License
|
|
14
13
|
Classifier: Natural Language :: English
|
|
15
14
|
Classifier: Operating System :: OS Independent
|
|
16
15
|
Classifier: Programming Language :: Python :: 3
|
|
17
16
|
Classifier: Programming Language :: Python :: 3 :: Only
|
|
18
|
-
Classifier: Programming Language :: Python :: 3.9
|
|
19
17
|
Classifier: Programming Language :: Python :: 3.10
|
|
20
18
|
Classifier: Programming Language :: Python :: 3.11
|
|
21
19
|
Classifier: Programming Language :: Python :: 3.12
|
|
22
20
|
Classifier: Programming Language :: Python :: 3.13
|
|
21
|
+
Classifier: Programming Language :: Python :: 3.14
|
|
23
22
|
Classifier: Topic :: Software Development
|
|
24
23
|
Classifier: Framework :: Flake8
|
|
25
|
-
License-File: LICENSE
|
|
26
24
|
Requires-Dist: flake8>=3.7
|
|
25
|
+
Maintainer: Martin Thoma
|
|
26
|
+
Maintainer-email: Martin Thoma <info@martin-thoma.de>
|
|
27
|
+
Requires-Python: >=3.10
|
|
27
28
|
Project-URL: Homepage, https://github.com/MartinThoma/flake8-simplify
|
|
29
|
+
Description-Content-Type: text/markdown
|
|
28
30
|
|
|
29
31
|
[](https://badge.fury.io/py/flake8-simplify)
|
|
30
32
|
[](https://github.com/MartinThoma/flake8-simplify)
|
|
31
33
|
[](https://github.com/MartinThoma/flake8-simplify/actions)
|
|
32
|
-
[](https://github.com/psf/black)
|
|
33
34
|
|
|
34
35
|
# flake8-simplify
|
|
35
36
|
|
|
@@ -43,7 +44,7 @@ Install with `pip`:
|
|
|
43
44
|
pip install flake8-simplify
|
|
44
45
|
```
|
|
45
46
|
|
|
46
|
-
Python 3.
|
|
47
|
+
Python 3.10 to 3.14 are supported.
|
|
47
48
|
|
|
48
49
|
|
|
49
50
|
## Usage
|
|
@@ -653,4 +654,3 @@ dict.get(key, None)
|
|
|
653
654
|
# Good
|
|
654
655
|
dict.get(key)
|
|
655
656
|
```
|
|
656
|
-
|
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
[](https://badge.fury.io/py/flake8-simplify)
|
|
2
2
|
[](https://github.com/MartinThoma/flake8-simplify)
|
|
3
3
|
[](https://github.com/MartinThoma/flake8-simplify/actions)
|
|
4
|
-
[](https://github.com/psf/black)
|
|
5
4
|
|
|
6
5
|
# flake8-simplify
|
|
7
6
|
|
|
@@ -15,7 +14,7 @@ Install with `pip`:
|
|
|
15
14
|
pip install flake8-simplify
|
|
16
15
|
```
|
|
17
16
|
|
|
18
|
-
Python 3.
|
|
17
|
+
Python 3.10 to 3.14 are supported.
|
|
19
18
|
|
|
20
19
|
|
|
21
20
|
## Usage
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
import ast
|
|
2
|
+
import importlib.metadata as importlib_metadata
|
|
3
|
+
from collections.abc import Generator
|
|
4
|
+
from typing import Any
|
|
5
|
+
|
|
6
|
+
from flake8_simplify.registry import get_rules
|
|
7
|
+
from flake8_simplify.utils import add_meta
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
class Visitor(ast.NodeVisitor):
|
|
11
|
+
"""Run every rule registered for a node type on each node of that type."""
|
|
12
|
+
|
|
13
|
+
def __init__(self) -> None:
|
|
14
|
+
self.errors: list[tuple[int, int, str]] = []
|
|
15
|
+
self._rules = get_rules()
|
|
16
|
+
|
|
17
|
+
def visit(self, node: ast.AST) -> Any:
|
|
18
|
+
for rule in self._rules.get(type(node), ()):
|
|
19
|
+
for violation in rule.check(node):
|
|
20
|
+
self.errors.append(
|
|
21
|
+
(
|
|
22
|
+
violation.node.lineno,
|
|
23
|
+
violation.node.col_offset,
|
|
24
|
+
f"{rule.code} {violation.message}",
|
|
25
|
+
)
|
|
26
|
+
)
|
|
27
|
+
self.generic_visit(node)
|
|
28
|
+
|
|
29
|
+
|
|
30
|
+
class Plugin:
|
|
31
|
+
name = __name__
|
|
32
|
+
version = importlib_metadata.version(__name__) # type: ignore
|
|
33
|
+
|
|
34
|
+
def __init__(self, tree: ast.AST):
|
|
35
|
+
self._tree = tree
|
|
36
|
+
|
|
37
|
+
def run(self) -> Generator[tuple[int, int, str, type[Any]], None, None]:
|
|
38
|
+
visitor = Visitor()
|
|
39
|
+
|
|
40
|
+
# Add parent
|
|
41
|
+
add_meta(self._tree)
|
|
42
|
+
visitor.visit(self._tree)
|
|
43
|
+
|
|
44
|
+
for line, col, msg in visitor.errors:
|
|
45
|
+
yield line, col, msg, type(self)
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Registry of all rules.
|
|
3
|
+
|
|
4
|
+
A rule is a generator function which receives a node of the given type and
|
|
5
|
+
yields a ``Violation`` for every problem it finds. It registers itself with
|
|
6
|
+
the ``rule`` decorator; modules in ``flake8_simplify/rules/`` are discovered
|
|
7
|
+
automatically, so adding a rule never requires touching any other file.
|
|
8
|
+
|
|
9
|
+
@rule("SIM120", ast.ClassDef)
|
|
10
|
+
def get_sim120(node: ast.ClassDef) -> Iterator[Violation]:
|
|
11
|
+
if ...:
|
|
12
|
+
yield Violation(node, "Use 'class Foo:' ...")
|
|
13
|
+
"""
|
|
14
|
+
|
|
15
|
+
import ast
|
|
16
|
+
import functools
|
|
17
|
+
import importlib
|
|
18
|
+
import pkgutil
|
|
19
|
+
from collections import defaultdict
|
|
20
|
+
from collections.abc import Callable, Iterator
|
|
21
|
+
from dataclasses import dataclass
|
|
22
|
+
from typing import Any, NamedTuple
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
class Violation(NamedTuple):
|
|
26
|
+
"""A problem found by a rule, reported at the position of ``node``."""
|
|
27
|
+
|
|
28
|
+
node: ast.expr | ast.stmt
|
|
29
|
+
message: str
|
|
30
|
+
|
|
31
|
+
|
|
32
|
+
@dataclass(frozen=True)
|
|
33
|
+
class Rule:
|
|
34
|
+
code: str
|
|
35
|
+
node_type: type[ast.AST]
|
|
36
|
+
check: Callable[[Any], Iterator[Violation]]
|
|
37
|
+
|
|
38
|
+
|
|
39
|
+
_RULES: list[Rule] = []
|
|
40
|
+
|
|
41
|
+
|
|
42
|
+
def rule(
|
|
43
|
+
code: str,
|
|
44
|
+
node_type: type[ast.AST],
|
|
45
|
+
) -> Callable[
|
|
46
|
+
[Callable[[Any], Iterator[Violation]]],
|
|
47
|
+
Callable[[Any], Iterator[Violation]],
|
|
48
|
+
]:
|
|
49
|
+
"""Register a function as the check for ``code`` on ``node_type`` nodes."""
|
|
50
|
+
|
|
51
|
+
def register(
|
|
52
|
+
check: Callable[[Any], Iterator[Violation]],
|
|
53
|
+
) -> Callable[[Any], Iterator[Violation]]:
|
|
54
|
+
_RULES.append(Rule(code, node_type, check))
|
|
55
|
+
return check
|
|
56
|
+
|
|
57
|
+
return register
|
|
58
|
+
|
|
59
|
+
|
|
60
|
+
@functools.cache
|
|
61
|
+
def get_rules() -> dict[type[ast.AST], list[Rule]]:
|
|
62
|
+
"""Get all rules, grouped by the type of node they check."""
|
|
63
|
+
from flake8_simplify import rules
|
|
64
|
+
|
|
65
|
+
for module in pkgutil.iter_modules(rules.__path__):
|
|
66
|
+
importlib.import_module(f"{rules.__name__}.{module.name}")
|
|
67
|
+
|
|
68
|
+
by_node_type: dict[type[ast.AST], list[Rule]] = defaultdict(list)
|
|
69
|
+
for registered in _RULES:
|
|
70
|
+
by_node_type[registered.node_type].append(registered)
|
|
71
|
+
return by_node_type
|
|
@@ -1,9 +1,18 @@
|
|
|
1
1
|
import ast
|
|
2
|
+
from collections.abc import Iterator
|
|
2
3
|
|
|
3
|
-
from flake8_simplify.
|
|
4
|
+
from flake8_simplify.registry import Violation, rule
|
|
5
|
+
from flake8_simplify.utils import (
|
|
6
|
+
expression_uses_variable,
|
|
7
|
+
get_next_sibling,
|
|
8
|
+
get_parent,
|
|
9
|
+
in_same_block,
|
|
10
|
+
to_source,
|
|
11
|
+
)
|
|
4
12
|
|
|
5
13
|
|
|
6
|
-
|
|
14
|
+
@rule("SIM904", ast.Assign)
|
|
15
|
+
def get_sim904(node: ast.Assign) -> Iterator[Violation]:
|
|
7
16
|
"""
|
|
8
17
|
Assign values to dictionary directly at initialization.
|
|
9
18
|
|
|
@@ -36,9 +45,8 @@ def get_sim904(node: ast.Assign) -> list[tuple[int, int, str]]:
|
|
|
36
45
|
),
|
|
37
46
|
]
|
|
38
47
|
"""
|
|
39
|
-
RULE = "
|
|
40
|
-
|
|
41
|
-
n2 = node.next_sibling # type: ignore
|
|
48
|
+
RULE = "Initialize dictionary '{dict_name}' directly"
|
|
49
|
+
n2 = get_next_sibling(node)
|
|
42
50
|
if not (
|
|
43
51
|
isinstance(node.value, ast.Dict)
|
|
44
52
|
and isinstance(n2, ast.Assign)
|
|
@@ -48,25 +56,20 @@ def get_sim904(node: ast.Assign) -> list[tuple[int, int, str]]:
|
|
|
48
56
|
and isinstance(n2.targets[0].value, ast.Name)
|
|
49
57
|
and isinstance(node.targets[0], ast.Name)
|
|
50
58
|
and n2.targets[0].value.id == node.targets[0].id
|
|
59
|
+
and in_same_block(node, n2)
|
|
51
60
|
):
|
|
52
|
-
return
|
|
61
|
+
return
|
|
53
62
|
|
|
54
63
|
dict_name = to_source(node.targets[0])
|
|
55
64
|
# Capture cases where the assigned value uses another dictionary value
|
|
56
65
|
if expression_uses_variable(n2.value, dict_name):
|
|
57
|
-
return
|
|
66
|
+
return
|
|
58
67
|
|
|
59
|
-
|
|
60
|
-
(
|
|
61
|
-
node.lineno,
|
|
62
|
-
node.col_offset,
|
|
63
|
-
RULE.format(dict_name=dict_name),
|
|
64
|
-
)
|
|
65
|
-
)
|
|
66
|
-
return errors
|
|
68
|
+
yield Violation(node, RULE.format(dict_name=dict_name))
|
|
67
69
|
|
|
68
70
|
|
|
69
|
-
|
|
71
|
+
@rule("SIM909", ast.Assign)
|
|
72
|
+
def get_sim909(node: ast.Assign) -> Iterator[Violation]:
|
|
70
73
|
"""
|
|
71
74
|
Avoid reflexive assignments
|
|
72
75
|
|
|
@@ -86,8 +89,7 @@ def get_sim909(node: Assign) -> list[tuple[int, int, str]]:
|
|
|
86
89
|
),
|
|
87
90
|
]
|
|
88
91
|
"""
|
|
89
|
-
RULE = "
|
|
90
|
-
errors: list[tuple[int, int, str]] = []
|
|
92
|
+
RULE = "Remove reflexive assignment '{code}'"
|
|
91
93
|
|
|
92
94
|
names = []
|
|
93
95
|
if isinstance(node.value, (ast.Name, ast.Subscript, ast.Tuple)):
|
|
@@ -96,18 +98,11 @@ def get_sim909(node: Assign) -> list[tuple[int, int, str]]:
|
|
|
96
98
|
names.append(to_source(target))
|
|
97
99
|
|
|
98
100
|
if len(names) == len(set(names)):
|
|
99
|
-
return
|
|
101
|
+
return
|
|
100
102
|
|
|
101
|
-
if isinstance(node
|
|
102
|
-
return
|
|
103
|
+
if isinstance(get_parent(node), ast.ClassDef):
|
|
104
|
+
return
|
|
103
105
|
|
|
104
|
-
code = to_source(node
|
|
106
|
+
code = to_source(node)
|
|
105
107
|
|
|
106
|
-
|
|
107
|
-
(
|
|
108
|
-
node.lineno,
|
|
109
|
-
node.col_offset,
|
|
110
|
-
RULE.format(code=code),
|
|
111
|
-
)
|
|
112
|
-
)
|
|
113
|
-
return errors
|
|
108
|
+
yield Violation(node, RULE.format(code=code))
|
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
import ast
|
|
2
2
|
from collections import defaultdict
|
|
3
|
+
from collections.abc import Iterator
|
|
3
4
|
|
|
4
|
-
from flake8_simplify.
|
|
5
|
+
from flake8_simplify.registry import Violation, rule
|
|
5
6
|
from flake8_simplify.utils import (
|
|
6
7
|
_get_duplicated_isinstance_call_by_node,
|
|
7
8
|
is_same_expression,
|
|
@@ -9,24 +10,24 @@ from flake8_simplify.utils import (
|
|
|
9
10
|
)
|
|
10
11
|
|
|
11
12
|
|
|
13
|
+
@rule("SIM101", ast.BoolOp)
|
|
12
14
|
def get_sim101(
|
|
13
15
|
node: ast.BoolOp,
|
|
14
|
-
) ->
|
|
16
|
+
) -> Iterator[Violation]:
|
|
15
17
|
"""Get a positions where the duplicate isinstance problem appears."""
|
|
16
|
-
errors: list[tuple[int, int, str]] = []
|
|
17
18
|
if not isinstance(node.op, ast.Or):
|
|
18
|
-
return
|
|
19
|
+
return
|
|
19
20
|
|
|
20
21
|
RULE = (
|
|
21
|
-
"
|
|
22
|
+
"Multiple isinstance-calls which can be merged into a single "
|
|
22
23
|
"call for variable '{var}'"
|
|
23
24
|
)
|
|
24
25
|
for var in _get_duplicated_isinstance_call_by_node(node):
|
|
25
|
-
|
|
26
|
-
return errors
|
|
26
|
+
yield Violation(node, RULE.format(var=var))
|
|
27
27
|
|
|
28
28
|
|
|
29
|
-
|
|
29
|
+
@rule("SIM109", ast.BoolOp)
|
|
30
|
+
def get_sim109(node: ast.BoolOp) -> Iterator[Violation]:
|
|
30
31
|
"""
|
|
31
32
|
Check if multiple equalities with the same value are combined via "or".
|
|
32
33
|
|
|
@@ -46,9 +47,8 @@ def get_sim109(node: ast.BoolOp) -> list[tuple[int, int, str]]:
|
|
|
46
47
|
],
|
|
47
48
|
)
|
|
48
49
|
"""
|
|
49
|
-
errors: list[tuple[int, int, str]] = []
|
|
50
50
|
if not isinstance(node.op, ast.Or):
|
|
51
|
-
return
|
|
51
|
+
return
|
|
52
52
|
equalities = [
|
|
53
53
|
value
|
|
54
54
|
for value in node.values
|
|
@@ -64,25 +64,22 @@ def get_sim109(node: ast.BoolOp) -> list[tuple[int, int, str]]:
|
|
|
64
64
|
and isinstance(eq.comparators[0], ast.Name)
|
|
65
65
|
):
|
|
66
66
|
id2vals[eq.left.id].append(eq.comparators[0])
|
|
67
|
-
RULE = "
|
|
67
|
+
RULE = "Use '{value} in {values}' instead of '{or_op}'"
|
|
68
68
|
for value, values in id2vals.items():
|
|
69
69
|
if len(values) == 1:
|
|
70
70
|
continue
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
node
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
values=f"({to_source(ast.Tuple(elts=values))})", # type: ignore
|
|
79
|
-
),
|
|
80
|
-
)
|
|
71
|
+
yield Violation(
|
|
72
|
+
node,
|
|
73
|
+
RULE.format(
|
|
74
|
+
or_op=to_source(node),
|
|
75
|
+
value=value,
|
|
76
|
+
values=f"({to_source(ast.Tuple(elts=values))})", # type: ignore
|
|
77
|
+
),
|
|
81
78
|
)
|
|
82
|
-
return errors
|
|
83
79
|
|
|
84
80
|
|
|
85
|
-
|
|
81
|
+
@rule("SIM220", ast.BoolOp)
|
|
82
|
+
def get_sim220(node: ast.BoolOp) -> Iterator[Violation]:
|
|
86
83
|
"""
|
|
87
84
|
Get a list of all calls of the type "a and not a".
|
|
88
85
|
|
|
@@ -97,9 +94,8 @@ def get_sim220(node: ast.BoolOp) -> list[tuple[int, int, str]]:
|
|
|
97
94
|
],
|
|
98
95
|
)
|
|
99
96
|
"""
|
|
100
|
-
errors: list[tuple[int, int, str]] = []
|
|
101
97
|
if not (isinstance(node.op, ast.And) and len(node.values) >= 2):
|
|
102
|
-
return
|
|
98
|
+
return
|
|
103
99
|
# We have a boolean And. Let's make sure there is two times the same
|
|
104
100
|
# expression, but once with a "not"
|
|
105
101
|
negated_expressions = []
|
|
@@ -110,19 +106,19 @@ def get_sim220(node: ast.BoolOp) -> list[tuple[int, int, str]]:
|
|
|
110
106
|
else:
|
|
111
107
|
non_negated_expressions.append(exp)
|
|
112
108
|
if len(negated_expressions) == 0:
|
|
113
|
-
return
|
|
109
|
+
return
|
|
114
110
|
|
|
115
|
-
RULE = "
|
|
111
|
+
RULE = "Use 'False' instead of '{a} and not {a}'"
|
|
116
112
|
for negated_expression in negated_expressions:
|
|
117
113
|
for non_negated_expression in non_negated_expressions:
|
|
118
114
|
if is_same_expression(negated_expression, non_negated_expression):
|
|
119
115
|
a = to_source(negated_expression)
|
|
120
|
-
|
|
121
|
-
return
|
|
122
|
-
return errors
|
|
116
|
+
yield Violation(node, RULE.format(a=a))
|
|
117
|
+
return
|
|
123
118
|
|
|
124
119
|
|
|
125
|
-
|
|
120
|
+
@rule("SIM221", ast.BoolOp)
|
|
121
|
+
def get_sim221(node: ast.BoolOp) -> Iterator[Violation]:
|
|
126
122
|
"""
|
|
127
123
|
Get a list of all calls of the type "a or not a".
|
|
128
124
|
|
|
@@ -137,9 +133,8 @@ def get_sim221(node: ast.BoolOp) -> list[tuple[int, int, str]]:
|
|
|
137
133
|
],
|
|
138
134
|
)
|
|
139
135
|
"""
|
|
140
|
-
errors: list[tuple[int, int, str]] = []
|
|
141
136
|
if not (isinstance(node.op, ast.Or) and len(node.values) >= 2):
|
|
142
|
-
return
|
|
137
|
+
return
|
|
143
138
|
# We have a boolean OR. Let's make sure there is two times the same
|
|
144
139
|
# expression, but once with a "not"
|
|
145
140
|
negated_expressions = []
|
|
@@ -150,19 +145,19 @@ def get_sim221(node: ast.BoolOp) -> list[tuple[int, int, str]]:
|
|
|
150
145
|
else:
|
|
151
146
|
non_negated_expressions.append(exp)
|
|
152
147
|
if len(negated_expressions) == 0:
|
|
153
|
-
return
|
|
148
|
+
return
|
|
154
149
|
|
|
155
|
-
RULE = "
|
|
150
|
+
RULE = "Use 'True' instead of '{a} or not {a}'"
|
|
156
151
|
for negated_expression in negated_expressions:
|
|
157
152
|
for non_negated_expression in non_negated_expressions:
|
|
158
153
|
if is_same_expression(negated_expression, non_negated_expression):
|
|
159
154
|
a = to_source(negated_expression)
|
|
160
|
-
|
|
161
|
-
return
|
|
162
|
-
return errors
|
|
155
|
+
yield Violation(node, RULE.format(a=a))
|
|
156
|
+
return
|
|
163
157
|
|
|
164
158
|
|
|
165
|
-
|
|
159
|
+
@rule("SIM222", ast.BoolOp)
|
|
160
|
+
def get_sim222(node: ast.BoolOp) -> Iterator[Violation]:
|
|
166
161
|
"""
|
|
167
162
|
Get a list of all calls of the type "... or True".
|
|
168
163
|
|
|
@@ -177,19 +172,18 @@ def get_sim222(node: ast.BoolOp) -> list[tuple[int, int, str]]:
|
|
|
177
172
|
],
|
|
178
173
|
)
|
|
179
174
|
"""
|
|
180
|
-
errors: list[tuple[int, int, str]] = []
|
|
181
175
|
if not (isinstance(node.op, ast.Or)):
|
|
182
|
-
return
|
|
176
|
+
return
|
|
183
177
|
|
|
184
|
-
RULE = "
|
|
178
|
+
RULE = "Use 'True' instead of '... or True'"
|
|
185
179
|
for exp in node.values:
|
|
186
|
-
if isinstance(exp,
|
|
187
|
-
|
|
188
|
-
return
|
|
189
|
-
return errors
|
|
180
|
+
if isinstance(exp, ast.Constant) and exp.value is True:
|
|
181
|
+
yield Violation(node, RULE)
|
|
182
|
+
return
|
|
190
183
|
|
|
191
184
|
|
|
192
|
-
|
|
185
|
+
@rule("SIM223", ast.BoolOp)
|
|
186
|
+
def get_sim223(node: ast.BoolOp) -> Iterator[Violation]:
|
|
193
187
|
"""
|
|
194
188
|
Get a list of all calls of the type "... and False".
|
|
195
189
|
|
|
@@ -204,13 +198,11 @@ def get_sim223(node: ast.BoolOp) -> list[tuple[int, int, str]]:
|
|
|
204
198
|
],
|
|
205
199
|
)
|
|
206
200
|
"""
|
|
207
|
-
errors: list[tuple[int, int, str]] = []
|
|
208
201
|
if not (isinstance(node.op, ast.And)):
|
|
209
|
-
return
|
|
202
|
+
return
|
|
210
203
|
|
|
211
|
-
RULE = "
|
|
204
|
+
RULE = "Use 'False' instead of '... and False'"
|
|
212
205
|
for exp in node.values:
|
|
213
|
-
if isinstance(exp,
|
|
214
|
-
|
|
215
|
-
return
|
|
216
|
-
return errors
|
|
206
|
+
if isinstance(exp, ast.Constant) and exp.value is False:
|
|
207
|
+
yield Violation(node, RULE)
|
|
208
|
+
return
|