-
-
Notifications
You must be signed in to change notification settings - Fork 488
/
tox.ini
398 lines (376 loc) · 14.7 KB
/
tox.ini
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
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
## Configuration for tox.
## Needs tox installed in the system python.
##
## doctest: Run the sage doctests. From the SAGE_ROOT/src directory:
##
## $ tox
##
## Arguments are passed on to "sage -t":
##
## $ tox sage/geometry
##
## To pass on options to "sage -t", use -- to separate it from tox options:
##
## $ tox -- --verbose --optional=sage,pynormaliz --long sage/geometry
##
## pycodestyle:
##
## $ tox -e pycodestyle
##
## Note that on the first run, tox automatically installs pycodestyle
## in a virtual environment.
##
[tox]
envlist = doctest, coverage, startuptime, pycodestyle-minimal, relint, codespell, rst, ruff-minimal
# When adding environments above, also update the delegations in SAGE_ROOT/tox.ini
skipsdist = true
requires =
# For the renamed "allowlist_externals" keyword, need >= 3.18
# Because of https://github.com/tox-dev/tox/issues/3238, need <4.14.1
tox>=3.18
tox<4.14.1
[sagedirect]
# Base for tox environments that bypass the virtual environment set up by tox,
# calling sage directly.
passenv =
HOME
setenv =
SAGE={toxinidir}/../sage
envdir={toxworkdir}/sagedirect
allowlist_externals =
{env:SAGE}
[testenv:doctest]
description =
run the Sage doctester (same as "sage -t")
## This toxenv bypasses the virtual environment set up by tox.
passenv = {[sagedirect]passenv}
setenv = {[sagedirect]setenv}
envdir = {[sagedirect]envdir}
allowlist_externals = {[sagedirect]allowlist_externals}
commands =
{env:SAGE} -t -p 0 {posargs:--all}
[testenv:coverage.py]
# https://coverage.readthedocs.io/en/latest/index.html
description =
run the Sage doctester with Coverage.py
## This toxenv bypasses the virtual environment set up by tox.
passenv = {[sagedirect]passenv}
setenv = {[sagedirect]setenv}
envdir = {[sagedirect]envdir}
allowlist_externals = {[sagedirect]allowlist_externals}
commands_pre =
{env:SAGE} -pip install -U coverage
commands =
{env:SAGE} --python -m coverage run "{toxinidir}/../venv/bin/sage-runtests" -p 0 {posargs:--all}
commands_post =
{env:SAGE} --python -m coverage combine
{env:SAGE} --python -m coverage report
[testenv:coverage.py-html]
# https://coverage.readthedocs.io/en/latest/index.html
description =
run the Sage doctester with Coverage.py, generate HTML report
## This toxenv bypasses the virtual environment set up by tox.
passenv = {[sagedirect]passenv}
setenv = {[sagedirect]setenv}
envdir = {[sagedirect]envdir}
allowlist_externals = {[sagedirect]allowlist_externals}
commands_pre =
{env:SAGE} -pip install -U coverage
commands =
{env:SAGE} --python -m coverage run "{toxinidir}/../venv/bin/sage-runtests" -p 0 {posargs:--all}
commands_post =
{env:SAGE} --python -m coverage combine
{env:SAGE} --python -m coverage report
{env:SAGE} --python -m coverage html -d "{envdir}"
[testenv:coverage.py-xml]
# https://coverage.readthedocs.io/en/latest/index.html
description =
run the Sage doctester with Coverage.py, generate XML report
## This toxenv bypasses the virtual environment set up by tox.
passenv = {[sagedirect]passenv}
setenv = {[sagedirect]setenv}
envdir = {[sagedirect]envdir}
allowlist_externals = {[sagedirect]allowlist_externals}
commands_pre =
{env:SAGE} -pip install -U coverage
commands =
{env:SAGE} --python -m coverage run "{toxinidir}/../venv/bin/sage-runtests" -p 0 {posargs:--all}
commands_post =
{env:SAGE} --python -m coverage combine
{env:SAGE} --python -m coverage report
{env:SAGE} --python -m coverage xml -o "{envdir}/coverage.xml"
[testenv:coverage]
description =
give information about doctest coverage of files
(same as "sage --coverage[all]")
## This toxenv bypasses the virtual environment set up by tox.
passenv = {[sagedirect]passenv}
setenv = {[sagedirect]setenv}
envdir = {[sagedirect]envdir}
allowlist_externals = {[sagedirect]allowlist_externals}
commands =
{env:SAGE} --coverage {posargs:--all}
[testenv:startuptime]
description =
display how long each component of Sage takes to start up
(same as "sage --startuptime")
## This toxenv bypasses the virtual environment set up by tox.
passenv = {[sagedirect]passenv}
setenv = {[sagedirect]setenv}
envdir = {[sagedirect]envdir}
allowlist_externals = {[sagedirect]allowlist_externals}
commands =
{env:SAGE} --startuptime {posargs}
[testenv:pyright]
description =
run the static typing checker pyright
deps = pyright
setenv =
{[sagedirect]setenv}
HOME={envdir}
# Fix version, see .github/workflows/build.yml
PYRIGHT_PYTHON_FORCE_VERSION=1.1.232
allowlist_externals = {[sagedirect]allowlist_externals}
## We run pyright from within the sage-env so that SAGE_LOCAL is available.
## pyright is already configured via SAGE_ROOT/pyrightconfig.json to use our venv.
##
## Running pyright on the whole Sage source tree takes very long
## and may run out of memory. When no files/directories are given, just run it
## on the packages that already have typing annotations.
commands =
{env:SAGE} -sh -c 'pyright {posargs:{toxinidir}/sage/combinat {toxinidir}/sage/manifolds}'
[testenv:pycodestyle]
description =
check against the Python style conventions of PEP8
deps = pycodestyle
commands = pycodestyle {posargs:{toxinidir}/sage/}
[testenv:pycodestyle-minimal]
description =
check against Sage's minimal style conventions
# Check for the following issues:
# E111: indentation is not a multiple of four
# E211: whitespace before '('
# E271: multiple spaces after keyword
# E305: expected 2 blank lines after class or function definition, found 1
# E306: expected 1 blank line before a nested definition, found 0
# E401: multiple imports on one line
# E502 the backslash is redundant between brackets
# E701: multiple statements on one line (colon)
# E702: multiple statements on one line (semicolon)
# E703: statement ends with a semicolon
# E711: comparison to None should be ‘if cond is None:’
# E712: comparison to True should be ‘if cond is True:’ or ‘if cond:’
# E713 test for membership should be ’not in’
# E721: do not compare types, use isinstance()
# E722: do not use bare except, specify exception instead
# W291: trailing whitespace
# W293: blank line contains whitespace
# W391: blank line at end of file
# W605: invalid escape sequence ‘x’
# See https://pycodestyle.pycqa.org/en/latest/intro.html#error-codes
deps = pycodestyle
commands = pycodestyle --select E111,E21,E221,E222,E225,E227,E228,E25,E271,E275,E303,E305,E306,E401,E502,E701,E702,E703,E71,E72,W291,W293,W391,W605 {posargs:{toxinidir}/sage/}
pycodestyle --select E111,E271,E301,E302,E303,E305,E306,E401,E502,E703,E712,E713,E714,E72,W29,W391,W605, --filename *.pyx {posargs:{toxinidir}/sage/}
[pycodestyle]
max-line-length = 160
statistics = True
[testenv:relint]
description =
check whether some forbidden patterns appear
# https://github.com/codingjoe/relint
# The patterns are in .relint.yml
deps = relint
allowlist_externals = find
commands = find {posargs:{toxinidir}/sage/} \
-name "*\#*" -prune -o \
-name "*.a" -prune -o \
-name "*.bak" -prune -o \
-name "*.bz2" -prune -o \
-name "*.dia" -prune -o \
-name "*.gz" -prune -o \
-name "*.ico" -prune -o \
-name "*.inv" -prune -o \
-name "*.JPEG" -prune -o \
-name "*.jpeg" -prune -o \
-name "*.JPG" -prune -o \
-name "*.jpg" -prune -o \
-name "*.log" -prune -o \
-name "*.o" -prune -o \
-name "*.orig" -prune -o \
-name "*.PDF" -prune -o \
-name "*.pdf" -prune -o \
-name "*.PNG" -prune -o \
-name "*.png" -prune -o \
-name "*.pyc" -prune -o \
-name "*.so" -prune -o \
-name "*.sobj" -prune -o \
-name "*.sws" -prune -o \
-name "*.tar" -prune -o \
-name "*.tgz" -prune -o \
-name "*.xz" -prune -o \
-name "*.zip" -prune -o \
-name "*~*" -prune -o \
-name ".DS_Store" -prune -o \
-exec relint -c {toxinidir}/.relint.yml \{\} +
[testenv:codespell]
description =
check for misspelled words in source code
# https://pypi.org/project/codespell/
deps = codespell
commands = codespell \
--skip="*\#*,*.a,*.bak,*.bz2,*.dia,*.gz,*.ico,*.inv,*.JPEG,*.jpeg" \
--skip="*.JPG,*.jpg,*.log,*.o,*.orig,*.PDF,*.pdf,*.PNG,*.png,*.pyc" \
--skip="*.so,*.sobj,*.sws,*.tar,*.tgz,*.xz,*.zip,*~*,.DS_Store" \
--skip="doc/ca,doc/de,doc/es,doc/fr,doc/hu,doc/it,doc/ja,doc/pt,doc/ru,doc/tr" \
--skip="src/doc/ca,src/doc/de,src/doc/es,src/doc/fr,src/doc/hu" \
--skip="src/doc/it,src/doc/ja,src/doc/pt,src/doc/ru,src/doc/tr" \
--skip=".git,.tox,autom4te.cache,cythonized,dist,lib.*,local" \
--skip="logs,scripts-3,tmp,upstream,worktree*,*.egg-info" \
--dictionary=- \
--dictionary={toxinidir}/.codespell-dictionary.txt \
--ignore-words={toxinidir}/.codespell-ignore.txt \
{posargs:{toxinidir}/sage/}
[testenv:rst]
description =
validate Python docstrings markup as reStructuredText
deps = flake8-rst-docstrings
commands = flake8 --select=RST {posargs:{toxinidir}/sage/}
[testenv:cython-lint]
description =
check Cython files for code style
deps = cython-lint
commands = cython-lint --no-pycodestyle {posargs:{toxinidir}/sage/}
[testenv:ruff]
description =
check against Python style conventions
deps = ruff
passenv = RUFF_OUTPUT_FORMAT
commands = ruff check {posargs:{toxinidir}/sage/}
[testenv:ruff-minimal]
description =
check against Sage's minimal style conventions
deps = ruff
# https://github.com/ChartBoost/ruff-action/issues/7#issuecomment-1887780308
passenv = RUFF_OUTPUT_FORMAT
# Output of currently failing, from "./sage -tox -e ruff -- --statistics":
#
# 3579 PLR2004 [ ] Magic value used in comparison, consider replacing `- 0.5` with a constant variable
# 3498 I001 [*] Import block is un-sorted or un-formatted
# 2146 F401 [*] `.PyPolyBoRi.Monomial` imported but unused
# 1964 E741 [ ] Ambiguous variable name: `I`
# 1676 F821 [ ] Undefined name `AA`
# 1513 PLR0912 [ ] Too many branches (102 > 12)
# 1159 PLR0913 [ ] Too many arguments in function definition (10 > 5)
# 815 E402 [ ] Module level import not at top of file
# 671 PLR0915 [ ] Too many statements (100 > 50)
# 483 PLW2901 [ ] Outer `for` loop variable `ext` overwritten by inner `for` loop target
# 433 PLR5501 [*] Use `elif` instead of `else` then `if`, to reduce indentation
# 428 PLR0911 [ ] Too many return statements (10 > 6)
# 404 E731 [*] Do not assign a `lambda` expression, use a `def`
# 351 F405 [ ] `ComplexField` may be undefined, or defined from star imports
# 306 PLR1714 [*] Consider merging multiple comparisons. Use a `set` if the elements are hashable.
# 236 F403 [ ] `from .abelian_gps.all import *` used; unable to detect undefined names
# 116 PLR0402 [*] Use `from matplotlib import cm` in lieu of alias
# 111 PLW0603 [ ] Using the global statement to update `AA_0` is discouraged
# 78 F841 [*] Local variable `B` is assigned to but never used
# 48 PLW0602 [ ] Using global for `D` but no assignment is done
# 33 PLR1711 [*] Useless `return` statement at end of function
# 24 E714 [*] Test for object identity should be `is not`
# 20 PLR1701 [*] Merge `isinstance` calls
# 17 PLW3301 [ ] Nested `max` calls can be flattened
# 16 PLW1510 [*] `subprocess.run` without explicit `check` argument
# 14 E721 [ ] Do not compare types, use `isinstance()`
# 14 PLW0120 [*] `else` clause on loop without a `break` statement; remove the `else` and dedent its contents
# 12 F811 [*] Redefinition of unused `CompleteDiscreteValuationRings` from line 49
# 8 PLC0414 [*] Import alias does not rename original package
# 7 E743 [ ] Ambiguous function name: `I`
# 7 PLE0101 [ ] Explicit return in `__init__`
# 7 PLR0124 [ ] Name compared with itself, consider replacing `a == a`
# 5 PLW0127 [ ] Self-assignment of variable `a`
# 4 F541 [*] f-string without any placeholders
# 4 PLW1508 [ ] Invalid type for environment variable default; expected `str` or `None`
# 3 PLC3002 [ ] Lambda expression called directly. Execute the expression inline instead.
# 2 E742 [ ] Ambiguous class name: `I`
# 2 PLE0302 [ ] The special method `__len__` expects 1 parameter, 3 were given
# 2 PLW0129 [ ] Asserting on a non-empty string literal will always pass
# 1 F402 [ ] Import `factor` from line 259 shadowed by loop variable
# 1 PLC0208 [*] Use a sequence type instead of a `set` when iterating over values
#
commands = ruff check --ignore PLR2004,I001,F401,E741,F821,PLR0912,PLR0913,E402,PLR0915,PLW2901,PLR5501,PLR0911,E731,F405,PLR1714,PLR1736,F403,PLR0402,PLW0603,F841,PLW0602,PLW0642,PLR1711,E714,SIM101,PLR1704,PLW3301,PLW1510,E721,PLW0211,PLW0120,F811,PLC2401,PLC0414,E743,PLE0101,PLR0124,PLW0127,F541,PLW1508,PLC3002,E742,PLE0302,PLW0129,F402,PLC0208 {posargs:{toxinidir}/sage/}
[flake8]
rst-roles =
# Sphinx
doc,
file,
ref,
# Sphinx - https://www.sphinx-doc.org/en/master/usage/restructuredtext/domains.html#the-standard-domain (selection)
envvar,
# Sphinx - https://www.sphinx-doc.org/en/master/usage/restructuredtext/domains.html#cross-referencing-python-objects
attr,
class,
const,
data,
exc,
func,
kbd,
meth,
mod,
obj,
# from src/sage/misc/sagedoc.py
arxiv,
doi,
mathscinet,
oeis,
pari,
python,
issue,
wikipedia,
common_lisp,
ecl,
gap,
gap_package,
giac_cascmd,
giac_us,
maxima,
meson,
polymake,
ppl,
qepcad,
scip,
singular,
soplex
rst-directives =
attribute,
automethod,
autofunction,
toctree,
MODULEAUTHOR,
ONLY,
PLOT,
SEEALSO,
TODO
extend-ignore =
# Ignore RST306 Unknown target name -- because of references to the global bibliography
RST306
exclude =
# Avoid errors by exclude files with generated docstring portions such as {PLOT_OPTIONS_TABLE}
sage/combinat/designs/database.py
sage/graphs/graph_plot.py
sage/misc/sagedoc.py
[pytest]
python_files = *_test.py
norecursedirs = local prefix venv build builddir pkgs .git src/doc src/bin tools
addopts = --import-mode importlib
doctest_optionflags = NORMALIZE_WHITESPACE ELLIPSIS
# https://docs.pytest.org/en/stable/reference/reference.html#confval-consider_namespace_packages
consider_namespace_packages = True
[coverage:run]
source = sage
concurrency = multiprocessing,thread
data_file = .coverage/.coverage
disable_warnings =
no-data-collected
module-not-measured
[coverage:report]
ignore_errors = True
skip_empty = True