fix(lint): auto-fix ruff violations and tune lint rules
- Auto-fixed 4,496 lint issues (import sorting, modern syntax, etc.) - Added ignore rules for patterns intentional in this codebase: E402 (late imports), E712 (SQLAlchemy filters), B904 (raise from), SIM108/SIM105/SIM117 (readability preferences) - Added per-file ignores for tests and scripts - Excluded broken scripts/rename_terminology.py (has curly quotes) Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -191,12 +191,12 @@ class PerformanceValidator(BaseValidator):
|
||||
stripped = line.strip()
|
||||
|
||||
# Track for loops over query results
|
||||
if re.search(r'for\s+\w+\s+in\s+.*\.(all|query)', line):
|
||||
if re.search(r"for\s+\w+\s+in\s+.*\.(all|query)", line):
|
||||
in_for_loop = True
|
||||
for_line_num = i
|
||||
elif in_for_loop and stripped and not stripped.startswith("#"):
|
||||
# Check for relationship access in loop
|
||||
if re.search(r'\.\w+\.\w+', line) and "(" not in line:
|
||||
if re.search(r"\.\w+\.\w+", line) and "(" not in line:
|
||||
# Could be accessing a relationship
|
||||
if any(rel in line for rel in [".customer.", ".store.", ".order.", ".product.", ".user."]):
|
||||
self._add_violation(
|
||||
@@ -218,7 +218,7 @@ class PerformanceValidator(BaseValidator):
|
||||
def _check_query_limiting(self, file_path: Path, content: str, lines: list[str]):
|
||||
"""PERF-003: Check for unbounded query results"""
|
||||
for i, line in enumerate(lines, 1):
|
||||
if re.search(r'\.all\(\)', line):
|
||||
if re.search(r"\.all\(\)", line):
|
||||
# Check if there's a limit or filter before
|
||||
context_start = max(0, i - 5)
|
||||
context_lines = lines[context_start:i]
|
||||
@@ -247,7 +247,7 @@ class PerformanceValidator(BaseValidator):
|
||||
stripped = line.strip()
|
||||
|
||||
# Track for loops
|
||||
if re.search(r'for\s+\w+\s+in\s+', line):
|
||||
if re.search(r"for\s+\w+\s+in\s+", line):
|
||||
in_for_loop = True
|
||||
for_indent = len(line) - len(line.lstrip())
|
||||
elif in_for_loop:
|
||||
@@ -270,9 +270,9 @@ class PerformanceValidator(BaseValidator):
|
||||
def _check_existence_checks(self, file_path: Path, content: str, lines: list[str]):
|
||||
"""PERF-008: Check for inefficient existence checks"""
|
||||
patterns = [
|
||||
(r'\.count\(\)\s*>\s*0', "count() > 0"),
|
||||
(r'\.count\(\)\s*>=\s*1', "count() >= 1"),
|
||||
(r'\.count\(\)\s*!=\s*0', "count() != 0"),
|
||||
(r"\.count\(\)\s*>\s*0", "count() > 0"),
|
||||
(r"\.count\(\)\s*>=\s*1", "count() >= 1"),
|
||||
(r"\.count\(\)\s*!=\s*0", "count() != 0"),
|
||||
]
|
||||
|
||||
for i, line in enumerate(lines, 1):
|
||||
@@ -299,7 +299,7 @@ class PerformanceValidator(BaseValidator):
|
||||
stripped = line.strip()
|
||||
|
||||
# Track for loops
|
||||
match = re.search(r'for\s+(\w+)\s+in\s+', line)
|
||||
match = re.search(r"for\s+(\w+)\s+in\s+", line)
|
||||
if match:
|
||||
in_for_loop = True
|
||||
for_indent = len(line) - len(line.lstrip())
|
||||
@@ -336,16 +336,16 @@ class PerformanceValidator(BaseValidator):
|
||||
|
||||
for i, line in enumerate(lines, 1):
|
||||
# Track router decorators
|
||||
if re.search(r'@router\.(get|post)', line):
|
||||
if re.search(r"@router\.(get|post)", line):
|
||||
in_endpoint = True
|
||||
endpoint_line = i
|
||||
has_pagination = False
|
||||
elif in_endpoint:
|
||||
# Check for pagination parameters
|
||||
if re.search(r'(skip|offset|page|limit)', line):
|
||||
if re.search(r"(skip|offset|page|limit)", line):
|
||||
has_pagination = True
|
||||
# Check for function end
|
||||
if re.search(r'^def\s+\w+', line.lstrip()) and i > endpoint_line + 1:
|
||||
if re.search(r"^def\s+\w+", line.lstrip()) and i > endpoint_line + 1:
|
||||
in_endpoint = False
|
||||
# Check for .all() without pagination
|
||||
if ".all()" in line and not has_pagination:
|
||||
@@ -405,8 +405,8 @@ class PerformanceValidator(BaseValidator):
|
||||
return
|
||||
|
||||
patterns = [
|
||||
r'requests\.(get|post|put|delete|patch)\s*\([^)]+\)',
|
||||
r'httpx\.(get|post|put|delete|patch)\s*\([^)]+\)',
|
||||
r"requests\.(get|post|put|delete|patch)\s*\([^)]+\)",
|
||||
r"httpx\.(get|post|put|delete|patch)\s*\([^)]+\)",
|
||||
]
|
||||
|
||||
for i, line in enumerate(lines, 1):
|
||||
@@ -451,7 +451,7 @@ class PerformanceValidator(BaseValidator):
|
||||
def _check_file_streaming(self, file_path: Path, content: str, lines: list[str]):
|
||||
"""PERF-047: Check for loading entire files into memory"""
|
||||
for i, line in enumerate(lines, 1):
|
||||
if re.search(r'await\s+\w+\.read\(\)', line) and "chunk" not in line:
|
||||
if re.search(r"await\s+\w+\.read\(\)", line) and "chunk" not in line:
|
||||
self._add_violation(
|
||||
rule_id="PERF-047",
|
||||
rule_name="Stream large file uploads",
|
||||
@@ -483,7 +483,7 @@ class PerformanceValidator(BaseValidator):
|
||||
"""PERF-049: Check for file handles without context managers"""
|
||||
for i, line in enumerate(lines, 1):
|
||||
# Check for file open without 'with'
|
||||
if re.search(r'^\s*\w+\s*=\s*open\s*\(', line):
|
||||
if re.search(r"^\s*\w+\s*=\s*open\s*\(", line):
|
||||
if "# noqa" not in line:
|
||||
self._add_violation(
|
||||
rule_id="PERF-049",
|
||||
@@ -504,7 +504,7 @@ class PerformanceValidator(BaseValidator):
|
||||
for i, line in enumerate(lines, 1):
|
||||
stripped = line.strip()
|
||||
|
||||
if re.search(r'for\s+\w+\s+in\s+', line):
|
||||
if re.search(r"for\s+\w+\s+in\s+", line):
|
||||
in_for_loop = True
|
||||
for_indent = len(line) - len(line.lstrip())
|
||||
elif in_for_loop:
|
||||
@@ -548,7 +548,7 @@ class PerformanceValidator(BaseValidator):
|
||||
def _check_polling_intervals(self, file_path: Path, content: str, lines: list[str]):
|
||||
"""PERF-062: Check for too-frequent polling"""
|
||||
for i, line in enumerate(lines, 1):
|
||||
match = re.search(r'setInterval\s*\([^,]+,\s*(\d+)\s*\)', line)
|
||||
match = re.search(r"setInterval\s*\([^,]+,\s*(\d+)\s*\)", line)
|
||||
if match:
|
||||
interval = int(match.group(1))
|
||||
if interval < 10000: # Less than 10 seconds
|
||||
@@ -568,7 +568,7 @@ class PerformanceValidator(BaseValidator):
|
||||
"""PERF-064: Check for layout thrashing patterns"""
|
||||
for i, line in enumerate(lines, 1):
|
||||
# Check for read then write patterns
|
||||
if re.search(r'(offsetHeight|offsetWidth|clientHeight|clientWidth)', line):
|
||||
if re.search(r"(offsetHeight|offsetWidth|clientHeight|clientWidth)", line):
|
||||
if i < len(lines):
|
||||
next_line = lines[i] if i < len(lines) else ""
|
||||
if "style" in next_line:
|
||||
@@ -586,7 +586,7 @@ class PerformanceValidator(BaseValidator):
|
||||
def _check_image_lazy_loading(self, file_path: Path, content: str, lines: list[str]):
|
||||
"""PERF-058: Check for images without lazy loading"""
|
||||
for i, line in enumerate(lines, 1):
|
||||
if re.search(r'<img\s+[^>]*src=', line):
|
||||
if re.search(r"<img\s+[^>]*src=", line):
|
||||
if 'loading="lazy"' not in line and "x-intersect" not in line:
|
||||
if "logo" not in line.lower() and "icon" not in line.lower():
|
||||
self._add_violation(
|
||||
@@ -603,7 +603,7 @@ class PerformanceValidator(BaseValidator):
|
||||
def _check_script_loading(self, file_path: Path, content: str, lines: list[str]):
|
||||
"""PERF-067: Check for script tags without defer/async"""
|
||||
for i, line in enumerate(lines, 1):
|
||||
if re.search(r'<script\s+[^>]*src=', line):
|
||||
if re.search(r"<script\s+[^>]*src=", line):
|
||||
if "defer" not in line and "async" not in line:
|
||||
if "alpine" not in line.lower() and "htmx" not in line.lower():
|
||||
self._add_violation(
|
||||
|
||||
Reference in New Issue
Block a user