-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathruff.toml
More file actions
109 lines (98 loc) · 3.38 KB
/
ruff.toml
File metadata and controls
109 lines (98 loc) · 3.38 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
# Ruff configuration - Solo Developer Mode
# Focused on catching real bugs, not style nitpicks
target-version = "py313"
line-length = 120
exclude = [
".git",
".mypy_cache",
".pytest_cache",
".ruff_cache",
".venv",
"__pycache__",
"build",
"dist",
"alembic/versions",
"node_modules",
".hypothesis",
"*.pyi",
"src/infrastructure/grpc/generated",
]
src = ["src", "tests"]
respect-gitignore = true
fix = true
show-fixes = true
[lint]
# Essential rules only - catch bugs, not style
select = [
"E", # pycodestyle errors (syntax issues)
"F", # Pyflakes (undefined names, unused imports)
"I", # isort (import sorting)
"B", # flake8-bugbear (common bugs)
"UP", # pyupgrade (Python version upgrades)
"S", # Security (bandit) - keep security checks
"RUF", # Ruff-specific useful rules
]
ignore = [
"E501", # Line too long - let formatter handle
"E402", # Module level import not at top - sometimes needed
"E721", # Type comparison - sometimes needed
"E741", # Ambiguous variable name - context matters
"B008", # Function call in default argument (FastAPI Depends)
"B024", # Abstract class without abstract methods
"B027", # Empty method in abstract class
"B904", # raise without from - not critical
"S101", # Assert usage - fine for dev
"S104", # Binding to all interfaces - fine for dev
"S105", # Hardcoded passwords - fine for dev/tests
"S106", # Hardcoded password argument
"S311", # Random for crypto - usually fine
"S603", # subprocess call - fine for dev
"S607", # partial executable path - fine for dev
"RUF002", # Ambiguous unicode - false positives
"RUF012", # Mutable class attributes (SQLModel)
"RUF100", # Unused noqa - don't care
"RUF059", # Unused unpacked variable
"F811", # Redefinition - sometimes intentional
"F821", # Undefined name - many false positives with forward refs
"F841", # Unused variable - sometimes intentional
"F401", # Unused import - handle manually when needed
"B007", # Unused loop variable
"UP007", # Use X | Y for Union - not always cleaner
"UP038", # Use X | Y in isinstance - not always cleaner
]
fixable = ["ALL"]
unfixable = []
[lint.per-file-ignores]
"tests/**/*.py" = [
"S", # Security rules relaxed in tests
"B", # Bugbear relaxed in tests
]
"scripts/**/*.py" = [
"S", # Security relaxed in scripts
]
"alembic/**/*.py" = [
"ALL", # Migrations are auto-generated
]
# gRPC servicers use PascalCase methods (Check, Watch, GetItem, etc) by protobuf convention
"src/infrastructure/grpc/**/*.py" = ["N802"]
"src/interface/grpc/**/*.py" = ["N802"]
# SQLAlchemy @declared_attr requires cls (not self) as first argument
"src/infrastructure/db/models/*.py" = ["N805"]
[lint.isort]
known-first-party = ["application", "domain", "infrastructure", "interface", "core"]
combine-as-imports = true
section-order = ["future", "standard-library", "third-party", "first-party", "local-folder"]
[lint.mccabe]
# Maximum cyclomatic complexity (CLAUDE.md requirement: max 10)
max-complexity = 10
[lint.pylint]
max-args = 6
max-branches = 12
max-returns = 6
max-statements = 50
[format]
quote-style = "double"
indent-style = "space"
line-ending = "lf"
docstring-code-format = true
docstring-code-line-length = 100