@@ -75,19 +75,139 @@ style = "pep440"
7575coverage = " ^6.2"
7676requests-cache = " ^1.2.0"
7777
78+ # https://docs.astral.sh/ruff/settings/
7879[tool .ruff ]
80+ extend-exclude = []
81+ force-exclude = true
7982line-length = 120
83+ # Assume Python 3.9
8084target-version = " py39"
8185
8286[tool .ruff .lint ]
87+
8388select = [
84- " F401" ,
85- " UP"
89+ # core
90+ " F" , # Pyflakes
91+ " E" , # pycodestyle errors
92+ " W" , # pycodestyle warnings
93+ " C90" , # mccabe +
94+ " I" , # isort
95+ " N" , # pep8-naming
96+ # "D", # pydocstyle
97+ " UP" , # pyupgrade
98+ # extensions
99+ # "YTT", # flake8-2020
100+ # "ANN", # flake8-annotations
101+ # "ASYNC", # flake8-async
102+ # "S", # flake8-bandit
103+ # "BLE", # flake8-blind-except
104+ # "FBT", # flake8-boolean-trap
105+ # "B", # flake8-bugbear
106+ # "A", # flake8-builtins
107+ # "COM", # flake8-commas
108+ # "CPY", # flake8-copyright
109+ # "C4", # flake8-comprehensions
110+ # "DTZ", # flake8-datetimez
111+ # "T10", # flake8-debugger
112+ # "DJ", # flake8-django
113+ # "EM", # flake8-errmsg
114+ # "EXE", # flake8-executable
115+ # "FA", # flake8-future-annotations
116+ # "ISC", # flake8-implicit-str-concat
117+ # "ICN", # flake8-import-conventions
118+ # "G", # flake8-logging-format
119+ # "INP", # flake8-no-pep420
120+ # "PIE", # flake8-pie
121+ # "T20", # flake8-print
122+ # "PYI", # flake8-pyi
123+ # "PT", # flake8-pytest-style
124+ # "Q", # flake8-quotes
125+ # "RSE", # flake8-raise
126+ # "RET", # flake8-return
127+ # "SLF", # flake8-self
128+ # "SLOT", # flake8-slots
129+ # "SIM", # flake8-simplify
130+ # "TID", # flake8-tidy-imports
131+ # "TCH", # flake8-type-checking
132+ # "INT", # flake8-gettext
133+ # "ARG", # flake8-unused-arguments
134+ # "PTH", # flake8-use-pathlib
135+ # "TD", # flake8-todos
136+ # "FIX", # flake8-fixme
137+ # "ERA", # eradicate
138+ # "PD", # pandas-vet
139+ # "PGH", # pygrep-hooks
140+ # "PL", # Pylint
141+ # "TRY", # tryceratops
142+ # "FLY", # flynt
143+ # "NPY", # NumPy-specific rules
144+ # "AIR", # Airflow
145+ # "PERF", # Perflint
146+ # "FURB", # refurb
147+ # "LOG", # flake8-logging
148+ # "RUF", # Ruff-specific rules
86149]
150+
151+ # Allow autofix for all enabled rules (when `--fix`) is provided.
152+ fixable = [" ALL" ]
153+ unfixable = []
154+
155+ # D203: one-blank-line-before-class (conflicts with D211)
156+ # D212: multi-line-summary-first-line (conflicts with D213)
157+ # E203: whitespace before ',', ';', or ':'
158+ # E501: line length
159+ # ISC001: conflicts with Ruff's formatter
87160ignore = [
88- # Until 3.9 is dropped
89- " UP007" ,
161+ " D203" ,
162+ " D213" ,
163+ " E203" ,
164+ " E501" ,
165+ " ISC001" ,
90166]
91167
92168[tool .ruff .lint .per-file-ignores ]
93- "tests/**/*.py" = [" F401" ] # unused imports
169+ "tests/**/*.py" = [" S101" ] # use of assert
170+
171+ [tool .ruff .lint .mccabe ]
172+ # Flag errors (`C901`) whenever the complexity level exceeds 15.
173+ max-complexity = 15
174+
175+
176+ [tool .tox ]
177+ requires = [" tox>=4" ]
178+ env_list = [" lint" , " py{39,310,311,312,313}" ]
179+
180+ [tool .tox .env .codespell ]
181+ description = " Run spell checkers."
182+ skip_install = true
183+ deps = [
184+ " codespell" ,
185+ " tomli" , # required for getting config from pyproject.toml
186+ ]
187+ commands = [
188+ [" codespell" , " {posargs}" ]
189+ ]
190+
191+ [tool .tox .env .format ]
192+ description = " Run ruff code formatter."
193+ skip_install = true
194+ deps = [" ruff==0.11.13" ]
195+ commands = [
196+ [" ruff" , " format" , " {posargs:.}" ],
197+ ]
198+
199+ [tool .tox .env .format_check ]
200+ description = " Check that code is correctly formatted by ruff."
201+ skip_install = true
202+ deps = [" ruff==0.11.13" ]
203+ commands = [
204+ [" ruff" , " format" , " --check" , " {posargs:.}" ],
205+ ]
206+
207+ [tool .tox .env .lint ]
208+ description = " Run code linter (no fixes)."
209+ skip_install = true
210+ deps = [" ruff==0.11.13" ]
211+ commands = [
212+ [" ruff" , " check" , " {posargs:.}" ],
213+ ]
0 commit comments