Skip to content

Commit e04c59d

Browse files
committed
Rename comprehension check to for-loop check and update related code
- Rename `comprehension_one_prefix.py` to `for_loop_one_prefix.py` - Update class name from `COP015ComprehensionOnePrefixCheck` to `COP015ForLoopOnePrefixCheck` - Change violation code description from "Comprehension variables" to "For-loop variables" - Add tests for regular for-loop cases - Rename loop variables in several files for clarity - Remove unused import `MIN_NAME_LENGTH`
1 parent a2bd044 commit e04c59d

6 files changed

Lines changed: 48 additions & 39 deletions

File tree

src/community_of_python_flake8_plugin/checks/dataclass_config.py

Lines changed: 15 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -25,9 +25,9 @@ def has_required_dataclass_params(decorator: ast.expr) -> bool:
2525
return False
2626

2727
keywords: typing.Final = {
28-
keyword_item.arg: keyword_item.value
29-
for keyword_item in decorator.keywords
30-
if isinstance(keyword_item.value, ast.Constant)
28+
one_keyword_item.arg: one_keyword_item.value
29+
for one_keyword_item in decorator.keywords
30+
if isinstance(one_keyword_item.value, ast.Constant)
3131
}
3232
kw_only_param: typing.Final = keywords.get("kw_only")
3333
slots_param: typing.Final = keywords.get("slots")
@@ -47,20 +47,20 @@ def has_required_dataclass_params(decorator: ast.expr) -> bool:
4747

4848
def is_pydantic_model(class_node: ast.ClassDef) -> bool:
4949
"""Check if class inherits from Pydantic BaseModel or RootModel."""
50-
for base_class in class_node.bases:
51-
if isinstance(base_class, ast.Name) and base_class.id in {"BaseModel", "RootModel"}:
50+
for one_base_class in class_node.bases:
51+
if isinstance(one_base_class, ast.Name) and one_base_class.id in {"BaseModel", "RootModel"}:
5252
return True
53-
if isinstance(base_class, ast.Attribute) and base_class.attr in {"BaseModel", "RootModel"}:
53+
if isinstance(one_base_class, ast.Attribute) and one_base_class.attr in {"BaseModel", "RootModel"}:
5454
return True
5555
return False
5656

5757

5858
def is_model_factory(class_node: ast.ClassDef) -> bool:
5959
"""Check if class inherits from ModelFactory."""
60-
for base_class in class_node.bases:
61-
if isinstance(base_class, ast.Name) and base_class.id in {"ModelFactory", "SQLAlchemyFactory"}:
60+
for one_base_class in class_node.bases:
61+
if isinstance(one_base_class, ast.Name) and one_base_class.id in {"ModelFactory", "SQLAlchemyFactory"}:
6262
return True
63-
if isinstance(base_class, ast.Attribute) and base_class.attr in {"ModelFactory", "SQLAlchemyFactory"}:
63+
if isinstance(one_base_class, ast.Attribute) and one_base_class.attr in {"ModelFactory", "SQLAlchemyFactory"}:
6464
return True
6565
return False
6666

@@ -82,9 +82,9 @@ def visit_ClassDef(self, ast_node: ast.ClassDef) -> None:
8282
return
8383

8484
# Check for dataclass decorator
85-
for decorator in ast_node.decorator_list:
86-
if is_dataclass_decorator(decorator):
87-
if not has_required_dataclass_params(decorator):
85+
for one_decorator in ast_node.decorator_list:
86+
if is_dataclass_decorator(one_decorator):
87+
if not has_required_dataclass_params(one_decorator):
8888
self.violations.append(
8989
Violation(
9090
line_number=ast_node.lineno,
@@ -98,9 +98,9 @@ def visit_ClassDef(self, ast_node: ast.ClassDef) -> None:
9898

9999
def _inherits_from_exception(self, ast_node: ast.ClassDef) -> bool:
100100
"""Check if class inherits from Exception or its subclasses."""
101-
for base in ast_node.bases:
102-
if isinstance(base, ast.Name) and ("Error" in base.id or "Exception" in base.id):
101+
for one_base in ast_node.bases:
102+
if isinstance(one_base, ast.Name) and ("Error" in one_base.id or "Exception" in one_base.id):
103103
return True
104-
if isinstance(base, ast.Attribute) and ("Error" in base.attr or "Exception" in base.attr):
104+
if isinstance(one_base, ast.Attribute) and ("Error" in one_base.attr or "Exception" in one_base.attr):
105105
return True
106106
return False

src/community_of_python_flake8_plugin/checks/disabled/module_import_many_names.py

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -17,16 +17,16 @@
1717

1818

1919
def check_module_has_all_declaration(module_node: ast.Module) -> bool:
20-
for statement in module_node.body:
21-
if isinstance(statement, ast.Assign) and any(
22-
isinstance(target_element, ast.Name) and target_element.id == "__all__"
23-
for target_element in statement.targets
20+
for one_statement in module_node.body:
21+
if isinstance(one_statement, ast.Assign) and any(
22+
isinstance(one_target_element, ast.Name) and one_target_element.id == "__all__"
23+
for one_target_element in one_statement.targets
2424
):
2525
return True
2626
if (
27-
isinstance(statement, ast.AnnAssign)
28-
and isinstance(statement.target, ast.Name)
29-
and statement.target.id == "__all__"
27+
isinstance(one_statement, ast.AnnAssign)
28+
and isinstance(one_statement.target, ast.Name)
29+
and one_statement.target.id == "__all__"
3030
):
3131
return True
3232
return False
@@ -77,9 +77,9 @@ def validate_import_size(self, ast_node: ast.ImportFrom) -> None:
7777
return
7878

7979
if not any(
80-
check_module_path_exists(f"{module_name}.{alias_element.name}")
81-
for alias_element in ast_node.names
82-
if isinstance(alias_element, ast.alias) and module_name is not None
80+
check_module_path_exists(f"{module_name}.{one_alias_element.name}")
81+
for one_alias_element in ast_node.names
82+
if isinstance(one_alias_element, ast.alias) and module_name is not None
8383
):
8484
self.violations.append(
8585
Violation(

src/community_of_python_flake8_plugin/checks/final_class.py

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,8 @@
77

88

99
def contains_final_decorator(class_node: ast.ClassDef) -> bool:
10-
for decorator in class_node.decorator_list:
11-
target_name = decorator.func if isinstance(decorator, ast.Call) else decorator
10+
for one_decorator in class_node.decorator_list:
11+
target_name = one_decorator.func if isinstance(one_decorator, ast.Call) else one_decorator
1212
if isinstance(target_name, ast.Name) and target_name.id == "final":
1313
return True
1414
if isinstance(target_name, ast.Attribute) and target_name.attr == "final":
@@ -18,12 +18,12 @@ def contains_final_decorator(class_node: ast.ClassDef) -> bool:
1818

1919
def is_protocol_class(class_node: ast.ClassDef) -> bool:
2020
"""Check if the class directly inherits from typing.Protocol."""
21-
for base in class_node.bases:
21+
for one_base in class_node.bases:
2222
# Check for direct Protocol reference: class MyClass(Protocol):
23-
if isinstance(base, ast.Name) and base.id == "Protocol":
23+
if isinstance(one_base, ast.Name) and one_base.id == "Protocol":
2424
return True
2525
# Check for attributed Protocol reference: class MyClass(typing.Protocol):
26-
if isinstance(base, ast.Attribute) and base.attr == "Protocol":
26+
if isinstance(one_base, ast.Attribute) and one_base.attr == "Protocol":
2727
return True
2828
return False
2929

src/community_of_python_flake8_plugin/checks/comprehension_one_prefix.py renamed to src/community_of_python_flake8_plugin/checks/for_loop_one_prefix.py

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@
22
import ast
33
import typing
44

5-
from community_of_python_flake8_plugin.constants import MIN_NAME_LENGTH
65
from community_of_python_flake8_plugin.violation_codes import ViolationCodes
76
from community_of_python_flake8_plugin.violations import Violation
87

@@ -14,8 +13,8 @@ def _is_ignored_target(target_node: ast.expr) -> bool:
1413

1514

1615
@typing.final
17-
class COP015ComprehensionOnePrefixCheck(ast.NodeVisitor):
18-
def __init__(self, syntax_tree: ast.AST) -> None: # noqa: ARG002
16+
class COP015ForLoopOnePrefixCheck(ast.NodeVisitor):
17+
def __init__(self, syntax_tree: ast.AST) -> None:
1918
self.violations: list[Violation] = []
2019
self.syntax_tree: typing.Final[ast.AST] = syntax_tree
2120

@@ -97,7 +96,7 @@ def _validate_comprehension_target(self, target_node: ast.expr) -> None:
9796
Violation(
9897
line_number=target_node.lineno,
9998
column_number=target_node.col_offset,
100-
violation_code=ViolationCodes.COMPREHENSION_VARIABLE_PREFIX,
99+
violation_code=ViolationCodes.FOR_LOOP_VARIABLE_PREFIX,
101100
)
102101
)
103102
# For tuples (unpacking), validate each element
@@ -108,7 +107,7 @@ def _validate_comprehension_target(self, target_node: ast.expr) -> None:
108107
Violation(
109108
line_number=one_element.lineno,
110109
column_number=one_element.col_offset,
111-
violation_code=ViolationCodes.COMPREHENSION_VARIABLE_PREFIX,
110+
violation_code=ViolationCodes.FOR_LOOP_VARIABLE_PREFIX,
112111
)
113112
)
114113

@@ -117,6 +116,6 @@ def _has_valid_one_prefix(self, identifier: str) -> bool:
117116
# Allow underscore variables
118117
if identifier == "_":
119118
return True
120-
119+
121120
# Check for one_ prefix
122121
return identifier.startswith("one_")

src/community_of_python_flake8_plugin/violation_codes.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,7 @@ class ViolationCodes:
4848
code="COP014", description="Use dataclasses with kw_only=True, slots=True, frozen=True"
4949
)
5050

51-
# Comprehension variable prefix violations
52-
COMPREHENSION_VARIABLE_PREFIX = ViolationCodeItem(
53-
code="COP015", description="Comprehension variables must be prefixed with 'one_'"
51+
# For-loop variable prefix violations
52+
FOR_LOOP_VARIABLE_PREFIX = ViolationCodeItem(
53+
code="COP015", description="For-loop variables must be prefixed with 'one_'"
5454
)

tests/test_plugin.py

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -517,6 +517,16 @@ def test_dataclass_validations(input_source: str, expected_output: list[str]) ->
517517
("result_long_name = (v for v in some_list)", ["COP005", "COP015"]),
518518
# COP005: Generator expression with one_ prefix (vars still too short for general rule)
519519
("result_long_name = (one_v for one_v in some_list)", ["COP005"]),
520+
# COP015: Regular for-loop without one_ prefix should be flagged
521+
("for v in some_list: pass", ["COP015"]),
522+
# No violation: Regular for-loop with one_ prefix
523+
("for one_v in some_list: pass", []),
524+
# No violation: Regular for-loop with underscore (ignored)
525+
("for _ in some_list: pass", []),
526+
# No violation: Regular for-loop with tuple unpacking (ignored)
527+
("for x, y in pairs: pass", []),
528+
# No violation: Regular for-loop with one_ prefix
529+
("for one_x in some_list: pass", []),
520530
],
521531
)
522532
def test_module_vs_class_level_assignments(input_source: str, expected_output: list[str]) -> None:

0 commit comments

Comments
 (0)