Skip to content

Commit 055f3cb

Browse files
committed
Enable ruff linting and format and tune for it
1 parent c544b11 commit 055f3cb

13 files changed

Lines changed: 696 additions & 451 deletions

.github/workflows/tests.yaml

Lines changed: 14 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -32,22 +32,22 @@ jobs:
3232
# run: |
3333
# tox -e lint-git
3434

35-
# lint:
36-
# name: "Linting and type checking"
37-
# runs-on: ubuntu-24.04
35+
lint:
36+
name: "Linting and type checking"
37+
runs-on: ubuntu-24.04
3838
# strategy:
3939
# fail-fast: true
40-
# steps:
41-
# - uses: actions/checkout@v4
42-
# - uses: actions/setup-python@v5
43-
# with:
44-
# python-version: "3.13"
45-
# - name: "Install tox"
46-
# run: |
47-
# pip install tox
48-
# - name: "Lint formatting"
49-
# run: |
50-
# tox -e lint-py
40+
steps:
41+
- uses: actions/checkout@v4
42+
- uses: actions/setup-python@v5
43+
with:
44+
python-version: "3.13"
45+
- name: "Install tox"
46+
run: |
47+
pip install tox
48+
- name: "Lint formatting"
49+
run: |
50+
tox -e lint-py
5151
# - name: "Type checking"
5252
# run: |
5353
# tox -e lint-mypy

pyproject.toml

Lines changed: 178 additions & 83 deletions
Original file line numberDiff line numberDiff line change
@@ -29,43 +29,26 @@ homepage = "https://github.com/ivankorobkov/python-inject"
2929
source = "https://github.com/ivankorobkov/python-inject"
3030
issues = "https://github.com/ivankorobkov/python-inject/issues"
3131

32+
3233
[dependency-groups]
34+
dev = [
35+
"ipython",
36+
"ruff",
37+
"mypy",
38+
"yamllint",
39+
{ include-group = "tests" },
40+
]
41+
3342
tests = [
3443
"pytest",
3544
"pytest-cov",
3645
]
3746

38-
dev = [
39-
"ipython",
40-
{ include-group = "tests" },
41-
]
4247

4348
[build-system]
4449
requires = ["hatchling", "hatch-vcs"]
4550
build-backend = "hatchling.build"
4651

47-
[tool.black]
48-
line-length = 120
49-
skip-string-normalization = true
50-
target_version = ["py39", "py310", "py311"]
51-
include = '\.pyi?$'
52-
exclude = '''
53-
/(
54-
\.eggs
55-
| \.git
56-
| \.github
57-
| \.hg
58-
| \.idea
59-
| \.mypy_cache
60-
| \.tox
61-
| \.pyre_configuration
62-
| \.venv
63-
| _build
64-
| build
65-
| dist
66-
| var
67-
)
68-
'''
6952

7053
[tool.hatch.build.hooks.vcs]
7154
version-file = "src/inject/_version.py"
@@ -78,13 +61,15 @@ packages = ["src/inject"]
7861
[tool.hatch.version]
7962
source = "vcs"
8063

64+
8165
[tool.isort]
8266
case_sensitive = true
8367
include_trailing_comma = true
8468
line_length = 120
8569
multi_line_output = 3
8670
profile = "black"
8771

72+
8873
[tool.mypy]
8974
check_untyped_defs = true
9075
disallow_any_generics = true
@@ -103,6 +88,8 @@ warn_unused_ignores = true
10388
#strict = true # TODO(pyctrl): improve typings and enable strict mode
10489
exclude = ["tests", ".venv"]
10590

91+
92+
# TODO(pyctrl): deprecate pyright — stay with mypy
10693
[tool.pyright]
10794
defineConstant = { DEBUG = true }
10895
exclude = []
@@ -114,69 +101,133 @@ pythonVersion = "3.11"
114101
reportMissingImports = true
115102
reportMissingTypeStubs = false
116103

104+
117105
[tool.ruff]
118-
ignore = [
119-
"B027", # Allow non-abstract empty methods in abstract base classes
120-
"FBT003", # Allow boolean positional values in function calls, like `dict.get(... True)`
121-
# Ignore checks for possible passwords
122-
"S105",
123-
"S106",
124-
"S107",
125-
# Ignore complexity
126-
"C901",
127-
"PLR0911",
128-
"PLR0912",
129-
"PLR0913",
130-
"PLR0915",
131-
"PLC1901", # empty string comparisons
132-
"PLW2901", # `for` loop variable overwritten
133-
"SIM114", # Combine `if` branches using logical `or` operator
106+
line-length = 88
107+
extend-exclude = [".git", ".venv", "docs"]
108+
109+
[tool.ruff.lint]
110+
preview = true
111+
extend-select = ["ALL"]
112+
extend-ignore = [
113+
"D10", # missing documentation
114+
"D203", # 1 of conflicting code-styles
115+
"D212", # 1 of conflicting code-styles
116+
"C408", # allow `dict()` instead of literal
117+
"TD003", # don't require issue link
118+
# Completely disable
119+
"FIX",
120+
"CPY",
121+
# formatter conflict rules
122+
"W191",
123+
"E111",
124+
"E114",
125+
"E117",
126+
"EM101",
127+
"EM102",
128+
"ERA001", # commented code
129+
"D206",
130+
"D300",
131+
"DOC201",
132+
"DOC402",
133+
"Q000",
134+
"Q001",
135+
"Q002",
136+
"Q003",
137+
"COM812",
138+
"COM819",
139+
"ISC001",
140+
"ISC002",
141+
"N818", # Exception name should be named with an Error suffix
142+
"TRY003",
143+
"UP006",
144+
"UP007",
145+
"UP035",
146+
"UP045",
147+
"FA100",
134148
]
135-
line-length = 120
136-
select = [
137-
"A",
138-
"B",
139-
"C",
140-
"DTZ",
141-
"E",
142-
"EM",
143-
"F",
144-
"FBT",
145-
"I",
146-
"ICN",
147-
"ISC",
148-
"N",
149-
"PLC",
150-
"PLE",
151-
"PLR",
152-
"PLW",
153-
"Q",
154-
"RUF",
155-
"S",
156-
"SIM",
157-
"T",
158-
"TID",
159-
"UP",
160-
"W",
161-
"YTT",
162-
]
163-
target-version = ["py39", "py310", "py311"]
164-
unfixable = [
165-
"F401", # Don't touch unused imports
149+
150+
[tool.ruff.lint.extend-per-file-ignores]
151+
"**/tests/**/test_*.py" = [
152+
"ANN", # annotations not required in tests
153+
"E731", # Do not assign a `lambda` expression, use a `def`
154+
"PLC2701", # Private name import
155+
"PLR0913", # Too many arguments in function definition
156+
"PLR0917", # Too many positional arguments
157+
"PLR2004", # allow "magic" values in tests
158+
"PLR6301", # Method could be a function, class method, or static method
159+
"PT017", # Found assertion on exception `except` block, use `pytest.raises()` instead
160+
"PT027", # Use `pytest.raises` instead of unittest-style `assertRaisesRegex`
161+
"S101", # allow asserts
162+
"S311", # Standard pseudo-random generators are not suitable for cryptographic purposes
163+
"SLF001", # allow private member access
166164
]
165+
"/**/tests/__init__.py" = ["PLR6301"]
167166

168-
[tool.ruff.flake8-quotes]
169-
inline-quotes = "single"
167+
[tool.ruff.lint.flake8-import-conventions.extend-aliases]
168+
"typing" = "t"
170169

171-
[tool.ruff.flake8-tidy-imports]
172-
ban-relative-imports = "all"
170+
[tool.ruff.lint.flake8-import-conventions]
171+
banned-from = ["dataclasses", "inject", "typing"]
173172

174-
[tool.ruff.isort]
173+
[tool.ruff.lint.isort]
174+
force-single-line = true
175175
known-first-party = ["inject"]
176176

177-
[tool.ruff.per-file-ignores]
178-
# Tests can use magic values, assertions, and relative imports
179-
"/**/test_*.py" = ["PLR2004", "S101", "TID252"]
177+
[tool.ruff.lint.flake8-tidy-imports]
178+
ban-relative-imports = "all"
179+
180+
[tool.ruff.format]
181+
quote-style = "double"
182+
indent-style = "space"
183+
184+
#ignore = [
185+
# "B027", # Allow non-abstract empty methods in abstract base classes
186+
# "FBT003", # Allow boolean positional values in function calls, like `dict.get(... True)`
187+
# # Ignore checks for possible passwords
188+
# "S105",
189+
# "S106",
190+
# "S107",
191+
# # Ignore complexity
192+
# "C901",
193+
# "PLR0911",
194+
# "PLR0912",
195+
# "PLR0913",
196+
# "PLR0915",
197+
# "PLC1901", # empty string comparisons
198+
# "PLW2901", # `for` loop variable overwritten
199+
# "SIM114", # Combine `if` branches using logical `or` operator
200+
#]
201+
#select = [
202+
# "A",
203+
# "B",
204+
# "C",
205+
# "DTZ",
206+
# "E",
207+
# "EM",
208+
# "F",
209+
# "FBT",
210+
# "I",
211+
# "ICN",
212+
# "ISC",
213+
# "N",
214+
# "PLC",
215+
# "PLE",
216+
# "PLR",
217+
# "PLW",
218+
# "Q",
219+
# "RUF",
220+
# "S",
221+
# "SIM",
222+
# "T",
223+
# "TID",
224+
# "UP",
225+
# "W",
226+
# "YTT",
227+
#]
228+
#unfixable = [
229+
# "F401", # Don't touch unused imports
230+
#]
180231

181232

182233
#### Pytest & Coverage ####
@@ -219,20 +270,23 @@ env_list = [
219270
"py311",
220271
"py312",
221272
"py313",
273+
"fmt-py",
222274
"fmt-toml",
275+
"lint-py",
223276
#"lint-mypy", # TODO(pyctrl): make it green & uncomment
224277
"lint-toml",
225278
"lint-yaml",
279+
#"lint-git",
226280
"coverage",
227281
]
228282

229283
[tool.tox.labels]
230284
fmt = [
231-
# "fmt-py",
285+
"fmt-py",
232286
"fmt-toml",
233287
]
234288
lint = [
235-
#"lint-py",
289+
"lint-py",
236290
#"lint-mypy", # TODO(pyctrl): make it green & uncomment
237291
"lint-toml",
238292
"lint-yaml",
@@ -247,6 +301,28 @@ dependency_groups = ["tests"]
247301
commands = [["pytest", { replace = "posargs", extend = true }]]
248302

249303
# tox envs
304+
[tool.tox.env.lint-py]
305+
description = "Lint python files"
306+
deps = ["ruff"]
307+
skip_install = true
308+
commands = [
309+
[
310+
"ruff",
311+
"format",
312+
"--diff",
313+
{ replace = "posargs", default = [
314+
"{tox_root}",
315+
], extend = true },
316+
],
317+
[
318+
"ruff",
319+
"check",
320+
{ replace = "posargs", default = [
321+
"{tox_root}",
322+
], extend = true },
323+
],
324+
]
325+
250326
[tool.tox.env.lint-mypy]
251327
description = "Type checking"
252328
deps = ["mypy"]
@@ -275,6 +351,25 @@ commands = [
275351
],
276352
]
277353

354+
[tool.tox.env.fmt-py]
355+
description = "Format python files"
356+
deps = ["ruff"]
357+
skip_install = true
358+
commands = [
359+
[
360+
"ruff",
361+
"format",
362+
{ replace = "posargs", default = ["{tox_root}"], extend = true },
363+
],
364+
[
365+
"ruff",
366+
"check",
367+
"--fix",
368+
"--show-fixes",
369+
{ replace = "posargs", default = ["{tox_root}"], extend = true },
370+
],
371+
]
372+
278373
[tool.tox.env.fmt-toml]
279374
description = "Format TOML files"
280375
allowlist_externals = ["taplo"]

0 commit comments

Comments
 (0)