-
Notifications
You must be signed in to change notification settings - Fork 1.2k
Expand file tree
/
Copy pathpyproject.toml
More file actions
241 lines (218 loc) · 9.64 KB
/
Copy pathpyproject.toml
File metadata and controls
241 lines (218 loc) · 9.64 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
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
[tool.codespell]
ignore-multiline-regex = "codespell:ignore-begin.*codespell:ignore-end"
ignore-words-list = "deriver"
skip = [
"*.po",
"./coverage/*",
"./dev/*",
"./docs/dev/_build/*",
"./docs/blog-site/*",
"./docs/dev-site/*",
"./docs/user-site/*",
"./htmlcov/*",
"./node_modules/**",
"./package-lock.json",
"./warehouse/admin/static/dist/*",
"./warehouse/static/dist/*",
]
[tool.coverage.run]
branch = true
dynamic_context = "test_function"
source = ["warehouse", "tests"]
omit = [
# We don't want to get coverage information for our migrations.
"warehouse/migrations/*",
# We don't want to actually cover our __main__.py file because it is hard
# to cover and it really just acts as a tiny shim to a function.
"warehouse/__main__.py",
# Again, tiny shim code that we don't actually need to test and trying to
# do so would just get in the way.
"warehouse/wsgi.py",
# And again, tiny shim code.
"warehouse/celery.py",
]
# We run multiple processes in parallel, so we need to make sure that we don't
# write to the same file at the same time.
parallel = true
[tool.coverage.report]
exclude_also = [
"class \\w+\\(Interface\\):",
"if (typing\\.)?TYPE_CHECKING:",
"if __name__ == .__main__.:",
"pytest.fail\\(", # Use for test branches that should never be reached.
# Remove once resolved: https://github.com/nedbat/coveragepy/issues/1563
"case _:\\n\\s*pytest\\.fail\\(",
]
[tool.djlint]
# https://www.djlint.com/docs/configuration/
indent = 2
profile = "jinja"
use_gitignore = true
# The Simple API templates have structures that are relied upon.
extend_exclude = "warehouse/templates/api/simple/*"
# TODO: Evaluate which `img` tags can get height/width attributes and remove H006.
# H006: <img> tag should have `height` and `width` attributes.
# TODO: Convert single quotes to double quotes and remove T002 from ignore.
# T002: Double quotes should be used in tags. Ex {% extends "this.html" %}
# TODO: Add endblock names everywhere and remove T003 from ignore.
# T003: Endblock should have name. Ex: {% endblock body %}.
# T028: Handled by warehouse config. See: https://github.com/pypi/warehouse/pull/14709
ignore = "H006,T002,T003,T028"
[tool.inline-snapshot]
format-command = "ruff format --stdin-filename {filename}"
[tool.mypy]
python_version = "3.14"
warn_unreachable = true
warn_unused_configs = true
warn_unused_ignores = true
plugins = ["mypy_zope:plugin"]
exclude = ["warehouse/locale/.*", "warehouse/migrations/versions.*"]
cache_dir = ".cache/mypy"
[[tool.mypy.overrides]]
# These modules do not yet have types available.
module = [
"bpython.*", # https://github.com/bpython/bpython/issues/892
"b2sdk.*", # https://github.com/Backblaze/b2-sdk-python/issues/148
"celery.app.backends.*", # https://github.com/celery/celery/issues/7394
"celery.backends.redis.*", # https://github.com/celery/celery/issues/7394
"cgi.*", # legacy stdlib module for webob, installed via `legacy_cgi` package
"google.cloud.storage.*", # https://github.com/googleapis/python-storage/issues/393
"forcediphttpsadapter.*",
"IPython.*", # has types, but only installed in dev
"packaging_legacy.*", # https://github.com/di/packaging_legacy/pull/5
"paginate.*",
"paginate_sqlalchemy.*",
"premailer.*",
"pymacaroons.*", # https://github.com/ecordell/pymacaroons/issues/41
"pyramid.*", # https://github.com/Pylons/pyramid/issues/2638
"pyramid_jinja2.*",
"pyramid_mailer.*",
"pyramid_retry.*",
"pyramid_rpc.*",
"pyqrcode.*",
"rfc3986.*", # https://github.com/python-hyper/rfc3986/issues/122
"transaction.*",
"venusian.*",
"whitenoise.*", # https://github.com/evansd/whitenoise/pull/410
"zope.sqlalchemy.*",
]
ignore_missing_imports = true
[tool.pip-tools.compile]
# TODO: This can be removed once it becomes the default.
# See: https://github.com/jazzband/pip-tools/issues/989
allow-unsafe = true
[tool.pytest]
addopts = [
"--allow-hosts=localhost,::1,stripe,redis",
"--disable-socket",
"--durations=20",
"--numprocesses=auto",
# Disable ddtrace for tests
"-p no:ddtrace",
"-p no:ddtrace.pytest_bdd",
"-p no:ddtrace.pytest_benchmark",
]
cache_dir = ".cache/pytest"
filterwarnings = [
"error",
"ignore::warehouse.utils.exceptions.DevelopmentModeWarning",
# https://github.com/pypi/warehouse/issues/15454#issuecomment-2599321232
"ignore:Accessing argon2.__version__ is deprecated.*:DeprecationWarning:passlib.handlers.argon2",
# https://github.com/zopefoundation/meta/issues/194
'''ignore:Deprecated call to `pkg_resources.declare_namespace\('(paste|repoze)'\).*:DeprecationWarning:pkg_resources''',
# https://github.com/Pylons/webob/issues/387
"ignore:The behavior of .*best_match.*:DeprecationWarning:webob.*",
# https://github.com/Pylons/webob/issues/473
# https://github.com/Pylons/webob/pull/475
'ignore:datetime\.datetime\.utcnow\(\) is deprecated.*:DeprecationWarning:webob.*',
# Noise reduction for warnings that are waiting for an upstream fix.
# https://github.com/Pylons/pyramid/issues/3731
"ignore:pkg_resources is deprecated as an API.*:UserWarning:pyramid.asset",
]
markers = [
"functional: Slower running tests which test the entire system is functioning.",
"unit: Quick running unit tests which test small units of functionality.",
]
strict = true
testpaths = ["tests/"]
[tool.ruff]
cache-dir = ".cache/ruff"
target-version = "py314"
[tool.ruff.lint]
# enable ALL lints by default, then opt out of ones we don't want to use so that we
# pick up new lints by default when we upgrade and if they fail, we can make a decision
# about whether to ignore it or fix it.
select = ["ALL"]
ignore = [
"RUF012", # this lint triggers in cases where it's impossible for us to fix it
"TC", # the circular imports in our db models breaks this
"PIE807", # turns `lambda: dict()` into just `dict`, which changes the signature
"FIX", # we regularly leave TODO comments in the code, which this rejects
"TD", # this wants TODO comments to have author and link, which we don't do
"ERA", # this has a REALLY high false positive rate
"ANN", # requires typing annotations, which has almost 15k errors for us
"S101", # We use assert in the test suite, but more importantly for type narrowing
"FBT", # rejects boolean params that change function behavior, requires api changes
"B019", # we have some uses of this, we should probably fix them
"B904", # rejects raise without from, requires manual review
"A", # rejects shadowing builtins, which we do a bit and would need closer review
"SLF", # rejects using _private items, would need careful review to add
"DTZ", # prevents using naive datetimes, probably useful, but needs manual review
"TRY", # would require reworking some of our exceptions to make this work
"EM", # would require reworking some of our exceptions to make this work
"PLR0911", # too many return statements; I'm suspect on the value of the "too many X" rules
"PLR0912", # too many branches; I'm suspect on the value of the "too many X" rules
"PLR0913", # too many arguments; I'm suspect on the value of the "too many X" rules
"PLR0915", # too many statements; I'm suspect on the value of the "too many X" rules
"PLR2004", # we use a lot of magic values, maybe we shouldn't but for now allow it
"PLW1641", # we don't need every object to implement __hash__
"PTH", # tries to enforce pathlib, but most of our paths are abstract urls/keys
"ARG", # rejects unused arguments, but we have to have them in a lot of places
"C90", # enforces mccabe complexity, adding would require refactoring
"D", # requires doc strings, super high error rate for us and not much value
"COM812", # incompatible with the formatter, no idea why this even exists
"COM819", # redundant with the formatter, also no idea why this even exists
]
[tool.ruff.lint.per-file-ignores]
# N805: zope.interface definitions look like classes, but are not
"interfaces.py" = ["N805"]
# INP001: Our migrations are scripts not files that are part of a package
"warehouse/migrations/**/*.py" = ["INP001"]
# The warehouse cli can use print to give feedback to the user.
# The warehouse cli also defers imports on purpose.
"warehouse/cli/**/*.py" = ["T201", "PLC0415"]
# INP001: These are just scripts as well.
# T201: These scripts/helpers are fine to call print
"bin/*.py" = ["INP001", "T201"]
"dev/*.py" = ["INP001", "T201"]
"docs/**/*.py" = ["INP001"]
".github/codeql/custom-queries/python/**/*.py" = ["INP001"]
# PT009: These files use a lot of custom assertion tools that trip up this detection.
"tests/unit/email/test_init.py" = ["PT009"]
"tests/unit/email/test_services.py" = ["PT009"]
"tests/unit/test_views.py" = ["PT009"]
"tests/**/*.py" = [
"TID252", # pretty much all of our tests use relative imports
"S104", # tests use 0.0.0.0 as a sentinel value sometimes
"S105", # tests aren't used in production and can use hardcoded pws for tests
"S106", # tests aren't used in production and can use hardcoded pws for tests
"S108", # tests use hardcoded tmp paths that get stubbed out
"S303", # strength of the hash functions used in tests doesn't matter
"S311", # tests don't need cryptographically strong randomness
"S324", # strength of the hash functions used in tests doesn't matter
]
[tool.ruff.lint.isort]
combine-as-imports = true
lines-between-types = 1
# Even though `cgi` isn't a stdlib module anymore, treat it as one for now
extra-standard-library = ["cgi"]
[tool.ruff.lint.pep8-naming]
classmethod-decorators = [
# Allow SQLAlchemy's dynamic decorators, like `@field.expression`, to trigger class
# method treatment.
"declared_attr",
"expression",
"comparator",
]
[tool.ruff.lint.flake8-tidy-imports.banned-api]
"urllib.parse.urlparse".msg = "Prefer `urllib3.util.parse_url` over `urllib.parse.urlparse`"