Skip to content

Commit abba674

Browse files
committed
Rerun plural and singular/function on failure
1 parent 1f45900 commit abba674

File tree

3 files changed

+39
-7
lines changed

3 files changed

+39
-7
lines changed

.github/workflows/ci-meson.yml

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -168,9 +168,22 @@ jobs:
168168
pytest --doctest-ignore-import-errors --doctest -rfEs -s src || true
169169
else
170170
pytest -rfEs -s src
171-
./sage -t ${{ matrix.tests == 'all' && '--all' || '--new --long' }} -p4 --format github
171+
./sage -t ${{
172+
matrix.tests == 'all' &&
173+
'--all-except="src/sage/libs/singular/function.pyx src/sage/rings/polynomial/plural.pyx"' ||
174+
'--new --long' }} -p4 --format github
172175
fi
173176
177+
- name: Test flaky files
178+
# unknown issues with plural.pyx causes sporadic failure: https://github.com/sagemath/sage/issues/29528
179+
# we rerun a few times, this step succeeds if any of the 5 runs succeed
180+
if: runner.os != 'windows' && matrix.tests == 'all'
181+
shell: bash -l {0}
182+
run: |
183+
for i in {1..5}; do
184+
./sage -t -p4 --format github src/sage/libs/singular/function.pyx src/sage/rings/polynomial/plural.pyx && break
185+
done
186+
174187
- name: Check that all modules can be imported
175188
shell: bash -l {0}
176189
run: |

src/sage/doctest/__main__.py

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import argparse
22
import os
33
import sys
4+
import shlex
45

56
# Note: the DOT_SAGE and SAGE_STARTUP_FILE environment variables have already been set by sage-env
67
DOT_SAGE = os.environ.get('DOT_SAGE', os.path.join(os.environ.get('HOME'),
@@ -53,6 +54,9 @@ def _make_parser():
5354
parser.add_argument("-T", "--timeout", type=int, default=-1, help="timeout (in seconds) for doctesting one file, 0 for no timeout")
5455
what = parser.add_mutually_exclusive_group()
5556
what.add_argument("-a", "--all", action="store_true", default=False, help="test all files in the Sage library")
57+
what.add_argument("--all-except", type=shlex.split, default=None,
58+
help="test all files in the Sage library except the specified space-separated list "
59+
"(backslash or quote are needed to escape spaces or backslashes or quotes)")
5660
what.add_argument("--installed", action="store_true", default=False, help="test all installed modules of the Sage library")
5761
parser.add_argument("--logfile", type=argparse.FileType('a'), metavar="FILE", help="log all output to FILE")
5862

@@ -163,7 +167,7 @@ def main():
163167
in_filenames = False
164168
afterlog = False
165169
for arg in sys.argv[1:]:
166-
if arg in ('-n', '--new', '-a', '--all', '--installed'):
170+
if arg in ('-n', '--new', '-a', '--all', '--installed') or arg.startswith("--all-except"):
167171
need_filenames = False
168172
elif need_filenames and not (afterlog or in_filenames) and os.path.exists(arg):
169173
in_filenames = True
@@ -174,8 +178,8 @@ def main():
174178

175179
args = parser.parse_args(new_arguments)
176180

177-
if not args.filenames and not (args.all or args.new or args.installed):
178-
print('either use --new, --all, --installed, or some filenames')
181+
if not args.filenames and not (args.all or args.new or args.installed) and args.all_except is None:
182+
print('either use --new, --all, --all-except=..., --installed, or some filenames')
179183
return 2
180184

181185
# Limit the number of threads to 2 to save system resources.

src/sage/doctest/control.py

Lines changed: 18 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,11 @@ class DocTestDefaults(SageObject):
6666
"""
6767
This class is used for doctesting the Sage doctest module.
6868
69+
The interface of this object should be compatible with the ``options`` input
70+
to :class:`DocTestController`, that is, the same interface as the
71+
argument object parsed by the :class:`argparse.ArgumentParser` in
72+
:func:`sage.doctest.__main__._make_parser`.
73+
6974
INPUT:
7075
7176
- ``runtest_default`` -- boolean (default: ``False``); if ``True``,
@@ -118,6 +123,7 @@ def __init__(self, runtest_default=False, **kwds):
118123
self.timeout = -1
119124
self.die_timeout = -1
120125
self.all = False
126+
self.all_except = None
121127
self.installed = False
122128
self.logfile = None
123129
self.long = False
@@ -410,7 +416,9 @@ def __init__(self, options, args):
410416
INPUT:
411417
412418
- ``options`` -- either options generated from the command line by sage-runtests
413-
or a DocTestDefaults object (possibly with some entries modified)
419+
or a :class:`DocTestDefaults` object (possibly with some entries modified).
420+
The attributes available in this object are defined by the :class:`argparse.ArgumentParser`
421+
in :func:`sage.doctest.__main__._make_parser`.
414422
- ``args`` -- list of filenames to doctest
415423
416424
EXAMPLES::
@@ -913,7 +921,7 @@ def all_doc_sources():
913921
all_installed_modules()
914922
all_installed_doc()
915923

916-
elif self.options.all or (self.options.new and not have_git):
924+
elif self.options.all or self.options.all_except is not None or (self.options.new and not have_git):
917925
all_files()
918926
all_doc_sources()
919927

@@ -1007,7 +1015,14 @@ def expand():
10071015
if_installed=self.options.if_installed,
10081016
log=self.log): # log when directly specified filenames are skipped
10091017
yield path
1010-
self.sources = [FileDocTestSource(path, self.options) for path in expand()]
1018+
paths = list(expand())
1019+
if self.options.all_except is not None:
1020+
paths_to_remove = set(os.path.abspath(x) for x in self.options.all_except)
1021+
if not paths_to_remove.issubset(paths):
1022+
raise ValueError(f"--all-except includes {paths_to_remove - set(paths)}, "
1023+
f"which are not found in {paths}")
1024+
paths = [path for path in paths if path not in paths_to_remove] # keep duplicates
1025+
self.sources = [FileDocTestSource(path, self.options) for path in paths]
10111026

10121027
def filter_sources(self):
10131028
"""

0 commit comments

Comments
 (0)