Repository navigation
Expand file tree
/
Copy pathpyproject.toml
More file actions
196 lines (177 loc) · 6.91 KB
/
Copy pathpyproject.toml
File metadata and controls
196 lines (177 loc) · 6.91 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
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
[build-system]
# >=77 is needed for the SPDX license expression and license-files (PEP 639)
requires = ["setuptools>=77", "wheel"]
build-backend = "setuptools.build_meta"
[project]
name = "b4"
version = "0.17-dev"
description = "A tool to work with public-inbox and patch archives"
readme = "README.rst"
keywords = ["git", "public-inbox", "lore.kernel.org", "patch", "email", "workflow"]
license = "GPL-2.0-or-later"
license-files = ["COPYING"]
authors = [
{name = "Konstantin Ryabitsev", email="konstantin@linuxfoundation.org"},
]
requires-python = ">=3.11"
classifiers = [
"Environment :: Console",
"Operating System :: POSIX :: Linux",
"Intended Audience :: Developers",
"Topic :: Communications :: Email",
"Topic :: Software Development",
"Topic :: Utilities",
]
dependencies = [
"requests>=2.24,<3.0",
# 1.14 is the floor: it introduced pygit2.enums (the only newish API b4
# uses) and is what enterprise distros ship (e.g. AlmaLinux/RHEL 10).
"pygit2>=1.14,<2.0",
"dkimpy>=1.0.5,<2.0",
# dkimpy needs it too, but b4 sets up its resolver cache directly.
"dnspython>=2.0,<3.0",
"patatt>=0.7,<2.0",
# 0.10.1 added local_sufficient, which update_series_tracking() relies
# on to stop asking lore.kernel.org about a series the mirror already
# answered for.
"liblore>=0.10.1",
]
[dependency-groups]
dev = [
"mypy",
"pip-tools",
"pyright",
"pytest",
"pytest-asyncio",
"ruff",
"ty",
"types-pymysql>=1.2.0.20260923",
"types-requests",
]
misc = [
"ezpi>=0.7",
"falcon",
"instructor",
"pydantic",
"pymysql",
]
[project.optional-dependencies]
completion = [
"shtab>=1.8",
"argcomplete>=3.0",
]
# Bug tracking (b4 bugs) is an experimental feature built on git-bug. It is
# optional so that packagers can ship b4 without pulling in git-bug, which is
# a Go binary that ezgb drives and that pip cannot install for you.
bugs = [
"ezgb>=0.2.0",
]
tui = [
"textual[syntax]>=1.0",
# textual pulls in rich, but b4 uses it directly (the review and bugs
# TUIs), so declare it explicitly rather than lean on the transitive dep.
"rich>=13.0",
]
[tool.setuptools.packages.find]
where = ['src']
exclude = ['tests*']
[tool.pip-tools]
generate_hashes = true
[project.urls]
Homepage = "https://git.kernel.org/pub/scm/utils/b4/b4.git/"
Repository = "https://git.kernel.org/pub/scm/utils/b4/b4.git"
Documentation = "https://b4.docs.kernel.org/"
[project.scripts]
b4 = "b4.command:cmd"
[tool.pytest.ini_options]
asyncio_mode = "auto"
asyncio_default_fixture_loop_scope = "function"
filterwarnings = "ignore:.*(pyopenssl|invalid escape sequence).*:DeprecationWarning"
norecursedirs = ["tests/helpers", "ezgb", "liblore", "patatt"]
log_file = "pytest.log"
log_file_level = "DEBUG"
log_file_format = "%(asctime)s [%(levelname)8s] %(message)s (%(filename)s:%(lineno)s)"
log_file_date_format = "%Y-%m-%d %H:%M:%S"
[tool.bumpversion]
current_version = "0.17-dev"
files = [
{filename = "src/b4/__init__.py"},
{filename = "src/b4/man/b4.1.rst"},
{filename = "src/b4/man/b4.1"},
]
[tool.ruff]
extend-exclude = ["ezgb", "liblore", "patatt"]
[tool.ruff.lint]
# Explicit select (not extend-select): ruff 0.16 expanded the default rule
# set, and we don't want upstream default changes to alter what we enforce.
select = [
"E4", # https://docs.astral.sh/ruff/rules/#error-e (imports)
"E7", # https://docs.astral.sh/ruff/rules/#error-e (statements)
"E9", # https://docs.astral.sh/ruff/rules/#error-e (runtime)
"F", # https://docs.astral.sh/ruff/rules/#pyflakes-f
"B007", # https://docs.astral.sh/ruff/rules/unused-loop-control-variable/
"B904", # https://docs.astral.sh/ruff/rules/raise-without-from-err/
"DTZ", # https://docs.astral.sh/ruff/rules/#flake8-datetimez-dtz
"G", # https://docs.astral.sh/ruff/rules/#flake8-logging-format-g
"I", # https://docs.astral.sh/ruff/rules/#isort-i
"PERF102", # https://docs.astral.sh/ruff/rules/incorrect-dict-iterator/
"PGH004", # https://docs.astral.sh/ruff/rules/blanket-noqa/
"PIE790", # https://docs.astral.sh/ruff/rules/unnecessary-placeholder/
"PIE810", # https://docs.astral.sh/ruff/rules/multiple-starts-ends-with/
"RET505", # https://docs.astral.sh/ruff/rules/superfluous-else-return/
"RET506", # https://docs.astral.sh/ruff/rules/superfluous-else-raise/
"RET507", # https://docs.astral.sh/ruff/rules/superfluous-else-continue/
"RET508", # https://docs.astral.sh/ruff/rules/superfluous-else-break/
"RUF059", # https://docs.astral.sh/ruff/rules/unused-unpacked-variable/
"RUF100", # https://docs.astral.sh/ruff/rules/unused-noqa/
"SIM103", # https://docs.astral.sh/ruff/rules/needless-bool/
"SIM113", # https://docs.astral.sh/ruff/rules/enumerate-for-loop/
"SIM118", # https://docs.astral.sh/ruff/rules/in-dict-keys/
"SIM201", # https://docs.astral.sh/ruff/rules/negate-equal-op/
]
flake8-quotes.inline-quotes = "single"
[tool.ruff.lint.per-file-ignores]
# Test modules gate optional-dependency imports behind pytest.importorskip(),
# which must run before those imports -- E402 is expected and correct here.
"src/tests/*" = ["E402"]
[tool.ruff.format]
quote-style = "single"
[tool.mypy]
# build/ is regenerated by setuptools and shadows src/b4 as a duplicate
# "b4" module if left in the scan
exclude = ["^build/", "^ezgb/", "^liblore/", "^patatt/"]
strict = true
warn_unreachable = true
[tool.pyright]
# pyright automatically ignores virtual environments and other directories, but
# once we specify `exclude`, we're on our own. See
# https://github.com/microsoft/pyright/issues/9057#issuecomment-2366938099.
exclude = [".venv*", "build", "ezgb", "liblore", "patatt"]
typeCheckingMode = "strict"
# Overly strict rules.
reportConstantRedefinition = false
reportUnknownArgumentType = false
reportUnknownLambdaType = false
reportUnknownMemberType = false
reportUnknownVariableType = false
# False positives caused by underscore-prefixed functions used across files.
# Might be good to clean this up.
reportPrivateUsage = false
reportUnusedFunction = false
[tool.ty.src]
exclude = ["ezgb/", "liblore/", "patatt/"]
[tool.ty.rules]
all = "error"
# New in ty 0.0.52: flags every method that overrides a base-class method
# without @override. Adopting it would require a typing_extensions dependency
# for the 3.11 fallback (typing.override is 3.12+), which is too much weight
# for a style rule. Revisit if/when the supported Python floor moves to 3.12.
missing-override-decorator = "ignore"
# Opt-in strictness rules added in ty 0.0.70-0.0.79. The unsound-* pair flags
# every Any (json, sqlite rows, argparse) flowing into an annotated type, the
# -strict condition rule has known false positives, and disjoint-cast trips
# over pygit2's stubs. Narrowing those Any sources is a separate cleanup.
unsound-return-statement = "ignore"
unsound-assignment = "ignore"
redundant-condition-strict = "ignore"
disjoint-cast = "ignore"