flake8_simplify 0.22.0__tar.gz → 0.31.0__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.
Files changed (48) hide show
  1. {flake8_simplify-0.22.0 → flake8_simplify-0.31.0}/PKG-INFO +14 -17
  2. {flake8_simplify-0.22.0 → flake8_simplify-0.31.0}/README.md +3 -6
  3. {flake8_simplify-0.22.0 → flake8_simplify-0.31.0}/flake8_simplify/__init__.py +5 -14
  4. flake8_simplify-0.31.0/flake8_simplify/constants.py +5 -0
  5. {flake8_simplify-0.22.0 → flake8_simplify-0.31.0}/flake8_simplify/rules/ast_assign.py +21 -7
  6. {flake8_simplify-0.22.0 → flake8_simplify-0.31.0}/flake8_simplify/rules/ast_bool_op.py +14 -17
  7. {flake8_simplify-0.22.0 → flake8_simplify-0.31.0}/flake8_simplify/rules/ast_call.py +16 -18
  8. {flake8_simplify-0.22.0 → flake8_simplify-0.31.0}/flake8_simplify/rules/ast_classdef.py +2 -4
  9. {flake8_simplify-0.22.0 → flake8_simplify-0.31.0}/flake8_simplify/rules/ast_compare.py +4 -7
  10. {flake8_simplify-0.22.0 → flake8_simplify-0.31.0}/flake8_simplify/rules/ast_expr.py +2 -5
  11. {flake8_simplify-0.22.0 → flake8_simplify-0.31.0}/flake8_simplify/rules/ast_for.py +6 -9
  12. {flake8_simplify-0.22.0 → flake8_simplify-0.31.0}/flake8_simplify/rules/ast_if.py +27 -30
  13. {flake8_simplify-0.22.0 → flake8_simplify-0.31.0}/flake8_simplify/rules/ast_ifexp.py +6 -9
  14. {flake8_simplify-0.22.0 → flake8_simplify-0.31.0}/flake8_simplify/rules/ast_subscript.py +4 -12
  15. {flake8_simplify-0.22.0 → flake8_simplify-0.31.0}/flake8_simplify/rules/ast_try.py +4 -7
  16. {flake8_simplify-0.22.0 → flake8_simplify-0.31.0}/flake8_simplify/rules/ast_unary_op.py +8 -11
  17. {flake8_simplify-0.22.0 → flake8_simplify-0.31.0}/flake8_simplify/rules/ast_with.py +2 -5
  18. {flake8_simplify-0.22.0 → flake8_simplify-0.31.0}/flake8_simplify/utils.py +15 -23
  19. flake8_simplify-0.31.0/pyproject.toml +115 -0
  20. flake8_simplify-0.22.0/pyproject.toml → flake8_simplify-0.31.0/pyproject.toml.orig +38 -25
  21. flake8_simplify-0.22.0/.coveragerc +0 -22
  22. flake8_simplify-0.22.0/.flake8 +0 -6
  23. flake8_simplify-0.22.0/.github/ISSUE_TEMPLATE/adjust-rule.md +0 -25
  24. flake8_simplify-0.22.0/.github/ISSUE_TEMPLATE/rule-request.md +0 -22
  25. flake8_simplify-0.22.0/.github/dependabot.yml +0 -9
  26. flake8_simplify-0.22.0/.github/workflows/lint.yml +0 -36
  27. flake8_simplify-0.22.0/.github/workflows/unit-test.yml +0 -34
  28. flake8_simplify-0.22.0/.gitignore +0 -142
  29. flake8_simplify-0.22.0/.isort.cfg +0 -11
  30. flake8_simplify-0.22.0/.pre-commit-config.yaml +0 -51
  31. flake8_simplify-0.22.0/CHANGELOG.md +0 -109
  32. flake8_simplify-0.22.0/Makefile +0 -26
  33. flake8_simplify-0.22.0/flake8_simplify/constants.py +0 -12
  34. flake8_simplify-0.22.0/mutmut-test.sh +0 -3
  35. flake8_simplify-0.22.0/requirements/dev.in +0 -8
  36. flake8_simplify-0.22.0/requirements/dev.txt +0 -91
  37. flake8_simplify-0.22.0/requirements/lint.in +0 -15
  38. flake8_simplify-0.22.0/requirements/lint.txt +0 -83
  39. flake8_simplify-0.22.0/tests/__init__.py +0 -13
  40. flake8_simplify-0.22.0/tests/test_100_rules.py +0 -523
  41. flake8_simplify-0.22.0/tests/test_200_rules.py +0 -71
  42. flake8_simplify-0.22.0/tests/test_300_rules.py +0 -19
  43. flake8_simplify-0.22.0/tests/test_400_rules.py +0 -131
  44. flake8_simplify-0.22.0/tests/test_900_rules.py +0 -237
  45. flake8_simplify-0.22.0/tests/test_simplify.py +0 -114
  46. flake8_simplify-0.22.0/tox.ini +0 -18
  47. {flake8_simplify-0.22.0 → flake8_simplify-0.31.0}/LICENSE +0 -0
  48. {flake8_simplify-0.22.0 → flake8_simplify-0.31.0}/flake8_simplify/rules/__init__.py +0 -0
@@ -1,36 +1,36 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: flake8_simplify
3
- Version: 0.22.0
3
+ Version: 0.31.0
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
- Maintainer-email: Martin Thoma <info@martin-thoma.de>
8
- Requires-Python: >=3.6.1
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.8
19
- Classifier: Programming Language :: Python :: 3.9
20
17
  Classifier: Programming Language :: Python :: 3.10
21
18
  Classifier: Programming Language :: Python :: 3.11
19
+ Classifier: Programming Language :: Python :: 3.12
20
+ Classifier: Programming Language :: Python :: 3.13
21
+ Classifier: Programming Language :: Python :: 3.14
22
22
  Classifier: Topic :: Software Development
23
23
  Classifier: Framework :: Flake8
24
- License-File: LICENSE
25
- Requires-Dist: astor>=0.1
26
24
  Requires-Dist: flake8>=3.7
27
- Requires-Dist: importlib-metadata>=0.9; python_version < "3.8"
25
+ Maintainer: Martin Thoma
26
+ Maintainer-email: Martin Thoma <info@martin-thoma.de>
27
+ Requires-Python: >=3.10
28
28
  Project-URL: Homepage, https://github.com/MartinThoma/flake8-simplify
29
+ Description-Content-Type: text/markdown
29
30
 
30
31
  [![PyPI version](https://badge.fury.io/py/flake8-simplify.svg)](https://badge.fury.io/py/flake8-simplify)
31
32
  [![Code on Github](https://img.shields.io/badge/Code-GitHub-brightgreen)](https://github.com/MartinThoma/flake8-simplify)
32
33
  [![Actions Status](https://github.com/MartinThoma/flake8-simplify/workflows/Unit%20Tests/badge.svg)](https://github.com/MartinThoma/flake8-simplify/actions)
33
- [![Code style: black](https://img.shields.io/badge/code%20style-black-000000.svg)](https://github.com/psf/black)
34
34
 
35
35
  # flake8-simplify
36
36
 
@@ -44,7 +44,7 @@ Install with `pip`:
44
44
  pip install flake8-simplify
45
45
  ```
46
46
 
47
- Python 3.8 to 3.11 are supported.
47
+ Python 3.10 to 3.14 are supported.
48
48
 
49
49
 
50
50
  ## Usage
@@ -377,13 +377,11 @@ Thank you for pointing this one out, [Aaron Gokaslan](https://github.com/Skylion
377
377
 
378
378
  ```python
379
379
  # Bad
380
- class FooBar(object):
381
- ...
380
+ class FooBar(object): ...
382
381
 
383
382
 
384
383
  # Good
385
- class FooBar:
386
- ...
384
+ class FooBar: ...
387
385
  ```
388
386
 
389
387
  Both notations are equivalent in Python 3, but the second one is shorter.
@@ -656,4 +654,3 @@ dict.get(key, None)
656
654
  # Good
657
655
  dict.get(key)
658
656
  ```
659
-
@@ -1,7 +1,6 @@
1
1
  [![PyPI version](https://badge.fury.io/py/flake8-simplify.svg)](https://badge.fury.io/py/flake8-simplify)
2
2
  [![Code on Github](https://img.shields.io/badge/Code-GitHub-brightgreen)](https://github.com/MartinThoma/flake8-simplify)
3
3
  [![Actions Status](https://github.com/MartinThoma/flake8-simplify/workflows/Unit%20Tests/badge.svg)](https://github.com/MartinThoma/flake8-simplify/actions)
4
- [![Code style: black](https://img.shields.io/badge/code%20style-black-000000.svg)](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.8 to 3.11 are supported.
17
+ Python 3.10 to 3.14 are supported.
19
18
 
20
19
 
21
20
  ## Usage
@@ -348,13 +347,11 @@ Thank you for pointing this one out, [Aaron Gokaslan](https://github.com/Skylion
348
347
 
349
348
  ```python
350
349
  # Bad
351
- class FooBar(object):
352
- ...
350
+ class FooBar(object): ...
353
351
 
354
352
 
355
353
  # Good
356
- class FooBar:
357
- ...
354
+ class FooBar: ...
358
355
  ```
359
356
 
360
357
  Both notations are equivalent in Python 3, but the second one is shorter.
@@ -1,10 +1,9 @@
1
- # Core Library
2
1
  import ast
2
+ import importlib.metadata as importlib_metadata
3
3
  import logging
4
- import sys
5
- from typing import Any, Generator, List, Tuple, Type
4
+ from collections.abc import Generator
5
+ from typing import Any
6
6
 
7
- # First party
8
7
  from flake8_simplify.rules.ast_assign import get_sim904, get_sim909
9
8
  from flake8_simplify.rules.ast_bool_op import (
10
9
  get_sim101,
@@ -54,17 +53,9 @@ from flake8_simplify.utils import Assign, Call, For, If, UnaryOp
54
53
  logger = logging.getLogger(__name__)
55
54
 
56
55
 
57
- if sys.version_info < (3, 8): # pragma: no cover (<PY38)
58
- # Third party
59
- import importlib_metadata
60
- else: # pragma: no cover (PY38+)
61
- # Core Library
62
- import importlib.metadata as importlib_metadata
63
-
64
-
65
56
  class Visitor(ast.NodeVisitor):
66
57
  def __init__(self) -> None:
67
- self.errors: List[Tuple[int, int, str]] = []
58
+ self.errors: list[tuple[int, int, str]] = []
68
59
 
69
60
  def visit_Assign(self, node: ast.Assign) -> Any:
70
61
  self.errors += get_sim904(node)
@@ -153,7 +144,7 @@ class Plugin:
153
144
  def __init__(self, tree: ast.AST):
154
145
  self._tree = tree
155
146
 
156
- def run(self) -> Generator[Tuple[int, int, str, Type[Any]], None, None]:
147
+ def run(self) -> Generator[tuple[int, int, str, type[Any]], None, None]:
157
148
  visitor = Visitor()
158
149
 
159
150
  # Add parent
@@ -0,0 +1,5 @@
1
+ import ast
2
+
3
+ BOOL_CONST_TYPES = (ast.Constant,)
4
+ AST_CONST_TYPES = (ast.Constant,)
5
+ STR_TYPES = (ast.Constant,)
@@ -1,12 +1,25 @@
1
- # Core Library
2
1
  import ast
3
- from typing import List, Tuple
4
2
 
5
- # First party
6
3
  from flake8_simplify.utils import Assign, expression_uses_variable, to_source
7
4
 
8
5
 
9
- def get_sim904(node: ast.Assign) -> List[Tuple[int, int, str]]:
6
+ def _in_same_block(first: ast.stmt, second: ast.stmt) -> bool:
7
+ """
8
+ Check that both statements are part of the same statement list.
9
+
10
+ Siblings are linked across the fields of a node, so the last statement of
11
+ ``body`` has the first statement of ``orelse`` as next sibling.
12
+ """
13
+ parent = getattr(first, "parent", None)
14
+ if parent is None:
15
+ return True
16
+ for _, value in ast.iter_fields(parent):
17
+ if isinstance(value, list) and first in value:
18
+ return second in value
19
+ return True
20
+
21
+
22
+ def get_sim904(node: ast.Assign) -> list[tuple[int, int, str]]:
10
23
  """
11
24
  Assign values to dictionary directly at initialization.
12
25
 
@@ -40,7 +53,7 @@ def get_sim904(node: ast.Assign) -> List[Tuple[int, int, str]]:
40
53
  ]
41
54
  """
42
55
  RULE = "SIM904 Initialize dictionary '{dict_name}' directly"
43
- errors: List[Tuple[int, int, str]] = []
56
+ errors: list[tuple[int, int, str]] = []
44
57
  n2 = node.next_sibling # type: ignore
45
58
  if not (
46
59
  isinstance(node.value, ast.Dict)
@@ -51,6 +64,7 @@ def get_sim904(node: ast.Assign) -> List[Tuple[int, int, str]]:
51
64
  and isinstance(n2.targets[0].value, ast.Name)
52
65
  and isinstance(node.targets[0], ast.Name)
53
66
  and n2.targets[0].value.id == node.targets[0].id
67
+ and _in_same_block(node, n2)
54
68
  ):
55
69
  return errors
56
70
 
@@ -69,7 +83,7 @@ def get_sim904(node: ast.Assign) -> List[Tuple[int, int, str]]:
69
83
  return errors
70
84
 
71
85
 
72
- def get_sim909(node: Assign) -> List[Tuple[int, int, str]]:
86
+ def get_sim909(node: Assign) -> list[tuple[int, int, str]]:
73
87
  """
74
88
  Avoid reflexive assignments
75
89
 
@@ -90,7 +104,7 @@ def get_sim909(node: Assign) -> List[Tuple[int, int, str]]:
90
104
  ]
91
105
  """
92
106
  RULE = "SIM909 Remove reflexive assignment '{code}'"
93
- errors: List[Tuple[int, int, str]] = []
107
+ errors: list[tuple[int, int, str]] = []
94
108
 
95
109
  names = []
96
110
  if isinstance(node.value, (ast.Name, ast.Subscript, ast.Tuple)):
@@ -1,9 +1,6 @@
1
- # Core Library
2
1
  import ast
3
2
  from collections import defaultdict
4
- from typing import Dict, List, Tuple
5
3
 
6
- # First party
7
4
  from flake8_simplify.constants import BOOL_CONST_TYPES
8
5
  from flake8_simplify.utils import (
9
6
  _get_duplicated_isinstance_call_by_node,
@@ -14,9 +11,9 @@ from flake8_simplify.utils import (
14
11
 
15
12
  def get_sim101(
16
13
  node: ast.BoolOp,
17
- ) -> List[Tuple[int, int, str]]:
14
+ ) -> list[tuple[int, int, str]]:
18
15
  """Get a positions where the duplicate isinstance problem appears."""
19
- errors: List[Tuple[int, int, str]] = []
16
+ errors: list[tuple[int, int, str]] = []
20
17
  if not isinstance(node.op, ast.Or):
21
18
  return errors
22
19
 
@@ -29,7 +26,7 @@ def get_sim101(
29
26
  return errors
30
27
 
31
28
 
32
- def get_sim109(node: ast.BoolOp) -> List[Tuple[int, int, str]]:
29
+ def get_sim109(node: ast.BoolOp) -> list[tuple[int, int, str]]:
33
30
  """
34
31
  Check if multiple equalities with the same value are combined via "or".
35
32
 
@@ -49,7 +46,7 @@ def get_sim109(node: ast.BoolOp) -> List[Tuple[int, int, str]]:
49
46
  ],
50
47
  )
51
48
  """
52
- errors: List[Tuple[int, int, str]] = []
49
+ errors: list[tuple[int, int, str]] = []
53
50
  if not isinstance(node.op, ast.Or):
54
51
  return errors
55
52
  equalities = [
@@ -59,7 +56,7 @@ def get_sim109(node: ast.BoolOp) -> List[Tuple[int, int, str]]:
59
56
  and len(value.ops) == 1
60
57
  and isinstance(value.ops[0], ast.Eq)
61
58
  ]
62
- id2vals: Dict[str, List[ast.Name]] = defaultdict(list)
59
+ id2vals: dict[str, list[ast.Name]] = defaultdict(list)
63
60
  for eq in equalities:
64
61
  if (
65
62
  isinstance(eq.left, ast.Name)
@@ -78,14 +75,14 @@ def get_sim109(node: ast.BoolOp) -> List[Tuple[int, int, str]]:
78
75
  RULE.format(
79
76
  or_op=to_source(node),
80
77
  value=value,
81
- values=f"({to_source(ast.Tuple(elts=values))})",
78
+ values=f"({to_source(ast.Tuple(elts=values))})", # type: ignore
82
79
  ),
83
80
  )
84
81
  )
85
82
  return errors
86
83
 
87
84
 
88
- def get_sim220(node: ast.BoolOp) -> List[Tuple[int, int, str]]:
85
+ def get_sim220(node: ast.BoolOp) -> list[tuple[int, int, str]]:
89
86
  """
90
87
  Get a list of all calls of the type "a and not a".
91
88
 
@@ -100,7 +97,7 @@ def get_sim220(node: ast.BoolOp) -> List[Tuple[int, int, str]]:
100
97
  ],
101
98
  )
102
99
  """
103
- errors: List[Tuple[int, int, str]] = []
100
+ errors: list[tuple[int, int, str]] = []
104
101
  if not (isinstance(node.op, ast.And) and len(node.values) >= 2):
105
102
  return errors
106
103
  # We have a boolean And. Let's make sure there is two times the same
@@ -125,7 +122,7 @@ def get_sim220(node: ast.BoolOp) -> List[Tuple[int, int, str]]:
125
122
  return errors
126
123
 
127
124
 
128
- def get_sim221(node: ast.BoolOp) -> List[Tuple[int, int, str]]:
125
+ def get_sim221(node: ast.BoolOp) -> list[tuple[int, int, str]]:
129
126
  """
130
127
  Get a list of all calls of the type "a or not a".
131
128
 
@@ -140,7 +137,7 @@ def get_sim221(node: ast.BoolOp) -> List[Tuple[int, int, str]]:
140
137
  ],
141
138
  )
142
139
  """
143
- errors: List[Tuple[int, int, str]] = []
140
+ errors: list[tuple[int, int, str]] = []
144
141
  if not (isinstance(node.op, ast.Or) and len(node.values) >= 2):
145
142
  return errors
146
143
  # We have a boolean OR. Let's make sure there is two times the same
@@ -165,7 +162,7 @@ def get_sim221(node: ast.BoolOp) -> List[Tuple[int, int, str]]:
165
162
  return errors
166
163
 
167
164
 
168
- def get_sim222(node: ast.BoolOp) -> List[Tuple[int, int, str]]:
165
+ def get_sim222(node: ast.BoolOp) -> list[tuple[int, int, str]]:
169
166
  """
170
167
  Get a list of all calls of the type "... or True".
171
168
 
@@ -180,7 +177,7 @@ def get_sim222(node: ast.BoolOp) -> List[Tuple[int, int, str]]:
180
177
  ],
181
178
  )
182
179
  """
183
- errors: List[Tuple[int, int, str]] = []
180
+ errors: list[tuple[int, int, str]] = []
184
181
  if not (isinstance(node.op, ast.Or)):
185
182
  return errors
186
183
 
@@ -192,7 +189,7 @@ def get_sim222(node: ast.BoolOp) -> List[Tuple[int, int, str]]:
192
189
  return errors
193
190
 
194
191
 
195
- def get_sim223(node: ast.BoolOp) -> List[Tuple[int, int, str]]:
192
+ def get_sim223(node: ast.BoolOp) -> list[tuple[int, int, str]]:
196
193
  """
197
194
  Get a list of all calls of the type "... and False".
198
195
 
@@ -207,7 +204,7 @@ def get_sim223(node: ast.BoolOp) -> List[Tuple[int, int, str]]:
207
204
  ],
208
205
  )
209
206
  """
210
- errors: List[Tuple[int, int, str]] = []
207
+ errors: list[tuple[int, int, str]] = []
211
208
  if not (isinstance(node.op, ast.And)):
212
209
  return errors
213
210
 
@@ -1,17 +1,14 @@
1
- # Core Library
2
1
  import ast
3
2
  import json
4
3
  import logging
5
- from typing import List, Tuple
6
4
 
7
- # First party
8
5
  from flake8_simplify.constants import BOOL_CONST_TYPES
9
6
  from flake8_simplify.utils import Call, to_source
10
7
 
11
8
  logger = logging.getLogger(__name__)
12
9
 
13
10
 
14
- def get_sim115(node: Call) -> List[Tuple[int, int, str]]:
11
+ def get_sim115(node: Call) -> list[tuple[int, int, str]]:
15
12
  """
16
13
  Find places where open() is called without a context handler.
17
14
 
@@ -40,7 +37,7 @@ def get_sim115(node: Call) -> List[Tuple[int, int, str]]:
40
37
  ),
41
38
  """
42
39
  RULE = "SIM115 Use context handler for opening files"
43
- errors: List[Tuple[int, int, str]] = []
40
+ errors: list[tuple[int, int, str]] = []
44
41
  if not (
45
42
  isinstance(node.func, ast.Name)
46
43
  and node.func.id == "open"
@@ -54,7 +51,7 @@ def get_sim115(node: Call) -> List[Tuple[int, int, str]]:
54
51
  # Experimental rules
55
52
 
56
53
 
57
- def get_sim901(node: ast.Call) -> List[Tuple[int, int, str]]:
54
+ def get_sim901(node: ast.Call) -> list[tuple[int, int, str]]:
58
55
  """
59
56
  Get a list of all calls of the type "bool(comparison)".
60
57
 
@@ -71,7 +68,7 @@ def get_sim901(node: ast.Call) -> List[Tuple[int, int, str]]:
71
68
  )
72
69
  """
73
70
  RULE = "SIM901 Use '{expected}' instead of '{actual}'"
74
- errors: List[Tuple[int, int, str]] = []
71
+ errors: list[tuple[int, int, str]] = []
75
72
  if not (
76
73
  isinstance(node.func, ast.Name)
77
74
  and node.func.id == "bool"
@@ -93,13 +90,14 @@ def get_sim901(node: ast.Call) -> List[Tuple[int, int, str]]:
93
90
  return errors
94
91
 
95
92
 
96
- def get_sim905(node: ast.Call) -> List[Tuple[int, int, str]]:
93
+ def get_sim905(node: ast.Call) -> list[tuple[int, int, str]]:
97
94
  RULE = "SIM905 Use '{expected}' instead of '{actual}'"
98
- errors: List[Tuple[int, int, str]] = []
95
+ errors: list[tuple[int, int, str]] = []
99
96
  if not (
100
97
  isinstance(node.func, ast.Attribute)
101
98
  and node.func.attr == "split"
102
- and isinstance(node.func.value, ast.Constant) and isinstance(node.func.value.value, str)
99
+ and isinstance(node.func.value, ast.Constant)
100
+ and isinstance(node.func.value.value, str)
103
101
  ):
104
102
  return errors
105
103
 
@@ -120,9 +118,9 @@ def get_sim905(node: ast.Call) -> List[Tuple[int, int, str]]:
120
118
  return errors
121
119
 
122
120
 
123
- def get_sim906(node: ast.Call) -> List[Tuple[int, int, str]]:
121
+ def get_sim906(node: ast.Call) -> list[tuple[int, int, str]]:
124
122
  RULE = "SIM906 Use '{expected}' instead of '{actual}'"
125
- errors: List[Tuple[int, int, str]] = []
123
+ errors: list[tuple[int, int, str]] = []
126
124
  if not (
127
125
  isinstance(node.func, ast.Attribute)
128
126
  and isinstance(node.func.value, ast.Attribute)
@@ -146,8 +144,8 @@ def get_sim906(node: ast.Call) -> List[Tuple[int, int, str]]:
146
144
  ):
147
145
  return errors
148
146
 
149
- def get_os_path_join_args(node: ast.Call) -> List[str]:
150
- names: List[str] = []
147
+ def get_os_path_join_args(node: ast.Call) -> list[str]:
148
+ names: list[str] = []
151
149
  for arg in node.args:
152
150
  if (
153
151
  isinstance(arg, ast.Call)
@@ -183,7 +181,7 @@ def get_sim906(node: ast.Call) -> List[Tuple[int, int, str]]:
183
181
  return errors
184
182
 
185
183
 
186
- def get_sim910(node: Call) -> List[Tuple[int, int, str]]:
184
+ def get_sim910(node: Call) -> list[tuple[int, int, str]]:
187
185
  """
188
186
  Get a list of all usages of "dict.get(key, None)"
189
187
 
@@ -205,7 +203,7 @@ def get_sim910(node: Call) -> List[Tuple[int, int, str]]:
205
203
  ),
206
204
  """
207
205
  RULE = "SIM910 Use '{expected}' instead of '{actual}'"
208
- errors: List[Tuple[int, int, str]] = []
206
+ errors: list[tuple[int, int, str]] = []
209
207
  if not (
210
208
  isinstance(node.func, ast.Attribute)
211
209
  and node.func.attr == "get"
@@ -235,7 +233,7 @@ def get_sim910(node: Call) -> List[Tuple[int, int, str]]:
235
233
  return errors
236
234
 
237
235
 
238
- def get_sim911(node: ast.AST) -> List[Tuple[int, int, str]]:
236
+ def get_sim911(node: ast.AST) -> list[tuple[int, int, str]]:
239
237
  """
240
238
  Find nodes representing the expression "zip(_.keys(), _.values())".
241
239
 
@@ -272,7 +270,7 @@ def get_sim911(node: ast.AST) -> List[Tuple[int, int, str]]:
272
270
  "SIM911 Use '{name}.items()' instead of "
273
271
  "'zip({name}.keys(), {name}.values())'"
274
272
  )
275
- errors: List[Tuple[int, int, str]] = []
273
+ errors: list[tuple[int, int, str]] = []
276
274
 
277
275
  if isinstance(node, ast.Call) and (
278
276
  isinstance(node.func, ast.Name)
@@ -1,9 +1,7 @@
1
- # Core Library
2
1
  import ast
3
- from typing import List, Tuple
4
2
 
5
3
 
6
- def get_sim120(node: ast.ClassDef) -> List[Tuple[int, int, str]]:
4
+ def get_sim120(node: ast.ClassDef) -> list[tuple[int, int, str]]:
7
5
  """
8
6
  Get a list of all classes that inherit from object.
9
7
  """
@@ -11,7 +9,7 @@ def get_sim120(node: ast.ClassDef) -> List[Tuple[int, int, str]]:
11
9
  "SIM120 Use 'class {classname}:' "
12
10
  "instead of 'class {classname}(object):'"
13
11
  )
14
- errors: List[Tuple[int, int, str]] = []
12
+ errors: list[tuple[int, int, str]] = []
15
13
  if not (
16
14
  len(node.bases) == 1
17
15
  and isinstance(node.bases[0], ast.Name)
@@ -1,13 +1,10 @@
1
- # Core Library
2
1
  import ast
3
- from typing import List, Tuple
4
2
 
5
- # First party
6
3
  from flake8_simplify.constants import AST_CONST_TYPES
7
4
  from flake8_simplify.utils import to_source
8
5
 
9
6
 
10
- def get_sim118(node: ast.Compare) -> List[Tuple[int, int, str]]:
7
+ def get_sim118(node: ast.Compare) -> list[tuple[int, int, str]]:
11
8
  """
12
9
  Get a list of all usages of "key in dict.keys()"
13
10
 
@@ -27,7 +24,7 @@ def get_sim118(node: ast.Compare) -> List[Tuple[int, int, str]]:
27
24
  )
28
25
  """
29
26
  RULE = "SIM118 Use '{el} in {dict}' instead of '{el} in {dict}.keys()'"
30
- errors: List[Tuple[int, int, str]] = []
27
+ errors: list[tuple[int, int, str]] = []
31
28
  if not (
32
29
  len(node.ops) == 1
33
30
  and isinstance(node.ops[0], ast.In)
@@ -59,7 +56,7 @@ def get_sim118(node: ast.Compare) -> List[Tuple[int, int, str]]:
59
56
  return errors
60
57
 
61
58
 
62
- def get_sim300(node: ast.Compare) -> List[Tuple[int, int, str]]:
59
+ def get_sim300(node: ast.Compare) -> list[tuple[int, int, str]]:
63
60
  """
64
61
  Get a list of all Yoda conditions.
65
62
 
@@ -74,7 +71,7 @@ def get_sim300(node: ast.Compare) -> List[Tuple[int, int, str]]:
74
71
  "SIM300 Use '{right} == {left}' instead of "
75
72
  "'{left} == {right}' (Yoda-conditions)"
76
73
  )
77
- errors: List[Tuple[int, int, str]] = []
74
+ errors: list[tuple[int, int, str]] = []
78
75
  if not (
79
76
  isinstance(node.left, AST_CONST_TYPES)
80
77
  and len(node.ops) == 1
@@ -1,13 +1,10 @@
1
- # Core Library
2
1
  import ast
3
- from typing import List, Tuple
4
2
 
5
- # First party
6
3
  from flake8_simplify.constants import STR_TYPES
7
4
  from flake8_simplify.utils import to_source
8
5
 
9
6
 
10
- def get_sim112(node: ast.Expr) -> List[Tuple[int, int, str]]:
7
+ def get_sim112(node: ast.Expr) -> list[tuple[int, int, str]]:
11
8
  """
12
9
  Find non-capitalized calls to environment variables.
13
10
 
@@ -27,7 +24,7 @@ def get_sim112(node: ast.Expr) -> List[Tuple[int, int, str]]:
27
24
  ),
28
25
  """
29
26
  RULE = "SIM112 Use '{expected}' instead of '{original}'"
30
- errors: List[Tuple[int, int, str]] = []
27
+ errors: list[tuple[int, int, str]] = []
31
28
 
32
29
  is_index_call = (
33
30
  isinstance(node.value, ast.Subscript)
@@ -1,8 +1,5 @@
1
- # Core Library
2
1
  import ast
3
- from typing import List, Tuple
4
2
 
5
- # First party
6
3
  from flake8_simplify.constants import BOOL_CONST_TYPES
7
4
  from flake8_simplify.utils import (
8
5
  For,
@@ -12,7 +9,7 @@ from flake8_simplify.utils import (
12
9
  )
13
10
 
14
11
 
15
- def get_sim104(node: ast.For) -> List[Tuple[int, int, str]]:
12
+ def get_sim104(node: ast.For) -> list[tuple[int, int, str]]:
16
13
  """
17
14
  Get a list of all "iterate and yield" patterns.
18
15
 
@@ -37,7 +34,7 @@ def get_sim104(node: ast.For) -> List[Tuple[int, int, str]]:
37
34
 
38
35
  """
39
36
  RULE = "SIM104 Use 'yield from {iterable}'"
40
- errors: List[Tuple[int, int, str]] = []
37
+ errors: list[tuple[int, int, str]] = []
41
38
  if (
42
39
  len(node.body) != 1
43
40
  or not isinstance(node.body[0], ast.Expr)
@@ -67,7 +64,7 @@ def get_sim104(node: ast.For) -> List[Tuple[int, int, str]]:
67
64
  return errors
68
65
 
69
66
 
70
- def get_sim110_sim111(node: ast.For) -> List[Tuple[int, int, str]]:
67
+ def get_sim110_sim111(node: ast.For) -> list[tuple[int, int, str]]:
71
68
  """
72
69
  Check if any / all could be used.
73
70
 
@@ -96,7 +93,7 @@ def get_sim110_sim111(node: ast.For) -> List[Tuple[int, int, str]]:
96
93
  """
97
94
  SIM110 = "SIM110 Use 'return any({check} for {target} in {iterable})'"
98
95
  SIM111 = "SIM111 Use 'return all({check} for {target} in {iterable})'"
99
- errors: List[Tuple[int, int, str]] = []
96
+ errors: list[tuple[int, int, str]] = []
100
97
  if not (
101
98
  len(node.body) == 1
102
99
  and isinstance(node.body[0], ast.If)
@@ -140,7 +137,7 @@ def get_sim110_sim111(node: ast.For) -> List[Tuple[int, int, str]]:
140
137
  return errors
141
138
 
142
139
 
143
- def get_sim113(node: For) -> List[Tuple[int, int, str]]:
140
+ def get_sim113(node: For) -> list[tuple[int, int, str]]:
144
141
  """
145
142
  Find loops in which "enumerate" should be used.
146
143
 
@@ -161,7 +158,7 @@ def get_sim113(node: For) -> List[Tuple[int, int, str]]:
161
158
  type_comment=None,
162
159
  ),
163
160
  """
164
- errors: List[Tuple[int, int, str]] = []
161
+ errors: list[tuple[int, int, str]] = []
165
162
  variable_candidates = []
166
163
  if body_contains_continue(node.body):
167
164
  return errors