@@ -36,52 +36,98 @@ dependencies = [
3636 " wheel>=0.43.0,<0.44" ,
3737]
3838
39- [dependency-groups ]
39+ [project . optional-dependencies ]
4040dev = [
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" ,
4852]
4953test = [
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" ,
5661]
5762
58- [tool .uv ]
59- default-groups = [
60- " dev " ,
61- " test " ,
63+ [tool .deptry ]
64+ # DEP003: transitive deps
65+ ignore = [
66+ " DEP003 "
6267]
6368
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+ ]
67118
68119[tool .ruff ]
69- # Black (default: 88)
70- line-length = 130
120+ # Fix without reporting on leftover violations
121+ fix-only = true
71122
72- # Assume Python 3.11.
73- target-version = " py311 "
123+ # Enumerate all fixed violations
124+ show-fixes = true
74125
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
81128
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
85131
86132# Exclude a variety of commonly ignored directories.
87133exclude = [
@@ -110,12 +156,53 @@ exclude = [
110156 " venv" ,
111157]
112158
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+
113189# Allow unused variables when underscore-prefixed.
114190dummy-variable-rgx = " ^(_+|(_+[a-zA-Z0-9_]*[a-zA-Z0-9]+?))$"
115191
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