@@ -36,52 +36,98 @@ dependencies = [
36
36
" wheel>=0.43.0,<0.44" ,
37
37
]
38
38
39
- [dependency-groups ]
39
+ [project . optional-dependencies ]
40
40
dev = [
41
- " ipython>=8.31.0,<9" ,
42
- " playwright>=1.49.1,<2" ,
43
- " poetry-plugin-export>=1.8.0,<2" ,
44
- " poetry-plugin-up>=0.7.1,<0.8" ,
45
- " pyclean>=3.0.0,<4" ,
46
- " rich>=13.9.4,<14" ,
47
- " ruff>=0.6.5,<0.7" ,
41
+ " argcomplete<4.0.0,>=3.5.0" ,
42
+ " deptry<1.0.0,>=0.23.0" ,
43
+ " icecream<3.0.0,>=2.1.3" ,
44
+ " ipython<9.0.0,>=8.27.0" ,
45
+ " mypy<2.0.0,>=1.14.1" ,
46
+ " pyclean<4.0.0,>=3.0.0" ,
47
+ " pytest-asyncio<1.0.0,>=0.25.2" ,
48
+ " pytest-cov<7.0.0,>=6.0.0" ,
49
+ " pytest<9.0.0,>=8.3.4" ,
50
+ " rich<14.0.0,>=13.8.1" ,
51
+ " ruff>=0.9.5" ,
48
52
]
49
53
test = [
50
- " pytest>=8.3.4,<9" ,
51
- " pytest-asyncio>=0.24.0,<0.25" ,
52
- " pytest-cov>=5.0.0,<6" ,
53
- " pytest-datafiles>=3.0.0,<4" ,
54
- " pytest-xdist>=3.6.1,<4" ,
55
- " requests-mock>=1.12.1,<2" ,
54
+ " coverage<8.0.0,>=7.6.1" ,
55
+ " hypothesis[cli]<7.0.0,>=6.112.1" ,
56
+ " pytest<9.0.0,>=8.3.3" ,
57
+ " pytest-asyncio<1.0.0,>=0.24.0" ,
58
+ " pytest-cov>=6.1.1" ,
59
+ " pytest-datafiles<4.0.0,>=3.0.0" ,
60
+ " pytest-xdist<4.0.0,>=3.6.1" ,
56
61
]
57
62
58
- [tool .uv ]
59
- default-groups = [
60
- " dev " ,
61
- " test " ,
63
+ [tool .deptry ]
64
+ # DEP003: transitive deps
65
+ ignore = [
66
+ " DEP003 "
62
67
]
63
68
64
- [build-system ]
65
- requires = [" hatchling" ]
66
- build-backend = " hatchling.build"
69
+ [tool .deptry .per_rule_ignores ]
70
+ # DEP002: not used in codebase (excluding dev deps)
71
+ DEP002 = [
72
+ " deptry" ,
73
+ " mypy" ,
74
+ " pytest" ,
75
+ " pytest-asyncio" ,
76
+ " pytest-cov" ,
77
+ " ruff" ,
78
+ " uvicorn"
79
+ ]
80
+
81
+ [tool .mypy ]
82
+ python_version = " 3.11"
83
+ warn_return_any = true
84
+ warn_unused_configs = true
85
+ disallow_untyped_defs = true
86
+ check_untyped_defs = true
87
+
88
+ [tool .pytest .ini_options ]
89
+ testpaths = [" tests" ]
90
+ python_files = " test_*.py"
91
+ python_functions = " test_*"
92
+ python_classes = " Test*"
93
+ asyncio_mode = " auto"
94
+ markers = [
95
+ " unit: marks tests as unit tests" ,
96
+ " integration: marks tests as integration tests" ,
97
+ " e2e: marks tests as end-to-end tests" ,
98
+ " benchmark: marks performance benchmark tests"
99
+ ]
100
+
101
+ [tool .coverage .run ]
102
+ source = [" {{ cookiecutter.python_package_import_name }}" ]
103
+ omit = [
104
+ " */tests/*" ,
105
+ " */migrations/*" ,
106
+ " */alembic/*"
107
+ ]
108
+
109
+ [tool .coverage .report ]
110
+ exclude_lines = [
111
+ " pragma: no cover" ,
112
+ " def __repr__" ,
113
+ " raise NotImplementedError" ,
114
+ " if TYPE_CHECKING:" ,
115
+ " pass" ,
116
+ " ..."
117
+ ]
67
118
68
119
[tool .ruff ]
69
- # Black (default: 88)
70
- line-length = 130
120
+ # Fix without reporting on leftover violations
121
+ fix-only = true
71
122
72
- # Assume Python 3.11.
73
- target-version = " py311 "
123
+ # Enumerate all fixed violations
124
+ show-fixes = true
74
125
75
- [tool .ruff .lint ]
76
- # Enable pycodestyle (`E`) and Pyflakes (`F`) codes by default.
77
- select = [" E" , " F" ]
78
- ignore = []
79
- # Skip unused variable rules
80
- extend-ignore = [" D203" , " E203" , " E251" , " E266" , " E401" , " E402" , " E501" , " F401" , " F403" , " F405" ]
126
+ # Indent width (default: 4)
127
+ indent-width = 4
81
128
82
- # Allow autofix for all enabled rules (when `--fix`) is provided.
83
- fixable = [" A" , " B" , " C" , " D" , " E" , " F" , " G" , " I" , " N" , " Q" , " S" , " T" , " W" , " ANN" , " ARG" , " BLE" , " COM" , " DJ" , " DTZ" , " EM" , " ERA" , " EXE" , " FBT" , " ICN" , " INP" , " ISC" , " NPY" , " PD" , " PGH" , " PIE" , " PL" , " PT" , " PTH" , " PYI" , " RET" , " RSE" , " RUF" , " SIM" , " SLF" , " TCH" , " TID" , " TRY" , " UP" , " YTT" ]
84
- unfixable = []
129
+ # Black (default: 88)
130
+ line-length = 130
85
131
86
132
# Exclude a variety of commonly ignored directories.
87
133
exclude = [
@@ -110,12 +156,53 @@ exclude = [
110
156
" venv" ,
111
157
]
112
158
159
+ # Assume Python 3.11
160
+ target-version = " py311"
161
+
162
+ [tool .ruff .format ]
163
+ # Use spaces instead of tabs
164
+ indent-style = " space"
165
+
166
+ # Use `\n` line endings for all files
167
+ line-ending = " lf"
168
+
169
+ # Set quote style for strings
170
+ quote-style = " preserve"
171
+
172
+ [tool .ruff .lint ]
173
+ select = [
174
+ # pycodestyle
175
+ " E" ,
176
+ # Pyflakes
177
+ " F" ,
178
+ # pyupgrade
179
+ " UP" ,
180
+ # flake8-bugbear
181
+ " B" ,
182
+ # flake8-simplify
183
+ " SIM" ,
184
+ # isort
185
+ " I" ,
186
+ ]
187
+ ignore = [" D203" , " E203" , " E251" , " E266" , " E401" , " E402" , " E501" , " F401" , " F403" , " F841" ]
188
+
113
189
# Allow unused variables when underscore-prefixed.
114
190
dummy-variable-rgx = " ^(_+|(_+[a-zA-Z0-9_]*[a-zA-Z0-9]+?))$"
115
191
116
- [tool .pytest .ini_options ]
117
- markers = [
118
- " slow: marks tests as slow (deselect with '-m \" not slow\" ')" ,
119
- " qa: marks tests as qa (deselect with '-m \" not qa\" ')" ,
120
- ]
121
- testpaths = [" tests" ]
192
+ # Allow autofix for all enabled rules (when `--fix`) is provided.
193
+ fixable = [" A" , " B" , " C" , " D" , " E" , " F" , " G" , " I" , " N" , " Q" , " S" , " T" , " W" , " ANN" , " ARG" , " BLE" , " COM" , " DJ" , " DTZ" , " EM" , " ERA" , " EXE" , " FBT" , " ICN" , " INP" , " ISC" , " NPY" , " PD" , " PGH" , " PIE" , " PL" , " PT" , " PTH" , " PYI" , " RET" , " RSE" , " RUF" , " SIM" , " SLF" , " TID" , " TRY" , " UP" , " YTT" ]
194
+
195
+ # unfixable = []
196
+
197
+ [tool .ruff .lint .isort ]
198
+ combine-as-imports = true
199
+ from-first = false
200
+ no-sections = true
201
+ order-by-type = true
202
+
203
+ [tool .ruff .lint .flake8-quotes ]
204
+ docstring-quotes = " double"
205
+
206
+ [tool .ruff .lint .mccabe ]
207
+ # Unlike Flake8, default to a complexity level of 10.
208
+ max-complexity = 10
0 commit comments