Skip to content

Commit 3103888

Browse files
author
Matthias Koeppe
committed
Merge branch 'hide_features_34185' into feature_standard_optional_static
2 parents 3230f00 + 97eaac9 commit 3103888

File tree

6 files changed

+356
-14
lines changed

6 files changed

+356
-14
lines changed

src/bin/sage-runtests

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,10 @@ if __name__ == "__main__":
5252
'if set to "all", then all tests will be run; '
5353
'use "!FEATURE" to disable tests marked "# optional - FEATURE". '
5454
'Note that "!" needs to be quoted or escaped in the shell.')
55+
parser.add_argument("--hide", metavar="FEATURES", default="",
56+
help='run tests pretending that the software listed in FEATURES (separated by commas) is not installed; '
57+
'if "all" is listed, will also hide features corresponding to all optional or experimental packages; '
58+
'if "optional" is listed, will also hide features corresponding to optional packages.')
5559
parser.add_argument("--randorder", type=int, metavar="SEED", help="randomize order of tests")
5660
parser.add_argument("--random-seed", dest="random_seed", type=int, metavar="SEED", help="random seed (integer) for fuzzing doctests",
5761
default=os.environ.get("SAGE_DOCTEST_RANDOM_SEED"))

src/sage/doctest/control.py

Lines changed: 118 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,6 @@
5757
except ImportError:
5858
pass
5959

60-
6160
class DocTestDefaults(SageObject):
6261
"""
6362
This class is used for doctesting the Sage doctest module.
@@ -137,6 +136,7 @@ def __init__(self, **kwds):
137136
# displaying user-defined optional tags and we don't want to see
138137
# the auto_optional_tags there.
139138
self.optional = set(['sage']) | auto_optional_tags
139+
self.hide = ''
140140

141141
# > 0: always run GC before every test
142142
# < 0: disable GC
@@ -401,6 +401,27 @@ def __init__(self, options, args):
401401
if options.verbose:
402402
options.show_skipped = True
403403

404+
options.hidden_features = set()
405+
if isinstance(options.hide, str):
406+
if not len(options.hide):
407+
options.hide = set([])
408+
else:
409+
s = options.hide.lower()
410+
options.hide = set(s.split(','))
411+
for h in options.hide:
412+
if not optionaltag_regex.search(h):
413+
raise ValueError('invalid optional tag {!r}'.format(h))
414+
if 'all' in options.hide:
415+
options.hide.discard('all')
416+
from sage.features.all import all_features
417+
feature_names = set([f.name for f in all_features() if not f.is_standard()])
418+
options.hide = options.hide.union(feature_names)
419+
if 'optional' in options.hide:
420+
options.hide.discard('optional')
421+
from sage.features.all import all_features
422+
feature_names = set([f.name for f in all_features() if f.is_optional()])
423+
options.hide = options.hide.union(feature_names)
424+
404425
options.disabled_optional = set()
405426
if isinstance(options.optional, str):
406427
s = options.optional.lower()
@@ -417,6 +438,8 @@ def __init__(self, options, args):
417438
options.optional.discard('optional')
418439
from sage.misc.package import list_packages
419440
for pkg in list_packages('optional', local=True).values():
441+
if pkg.name in options.hide:
442+
continue
420443
if pkg.is_installed() and pkg.installed_version == pkg.remote_version:
421444
options.optional.add(pkg.name)
422445

@@ -1330,6 +1353,49 @@ def run(self):
13301353
Features detected...
13311354
0
13321355
1356+
We test the ``--hide`` option (:trac:`34185`)::
1357+
1358+
sage: from sage.doctest.control import test_hide
1359+
sage: filename = tmp_filename(ext='.py')
1360+
sage: with open(filename, 'w') as f:
1361+
....: f.write(test_hide)
1362+
....: f.close()
1363+
729
1364+
sage: DF = DocTestDefaults(hide='buckygen,all')
1365+
sage: DC = DocTestController(DF, [filename])
1366+
sage: DC.run()
1367+
Running doctests with ID ...
1368+
Using --optional=sage...
1369+
Features to be detected: ...
1370+
Doctesting 1 file.
1371+
sage -t ....py
1372+
[4 tests, ... s]
1373+
----------------------------------------------------------------------
1374+
All tests passed!
1375+
----------------------------------------------------------------------
1376+
Total time for all tests: ... seconds
1377+
cpu time: ... seconds
1378+
cumulative wall time: ... seconds
1379+
Features detected...
1380+
0
1381+
1382+
sage: DF = DocTestDefaults(hide='benzene,optional')
1383+
sage: DC = DocTestController(DF, [filename])
1384+
sage: DC.run()
1385+
Running doctests with ID ...
1386+
Using --optional=sage
1387+
Features to be detected: ...
1388+
Doctesting 1 file.
1389+
sage -t ....py
1390+
[4 tests, ... s]
1391+
----------------------------------------------------------------------
1392+
All tests passed!
1393+
----------------------------------------------------------------------
1394+
Total time for all tests: ... seconds
1395+
cpu time: ... seconds
1396+
cumulative wall time: ... seconds
1397+
Features detected...
1398+
0
13331399
"""
13341400
opt = self.options
13351401
L = (opt.gdb, opt.lldb, opt.valgrind, opt.massif, opt.cachegrind, opt.omega)
@@ -1370,6 +1436,21 @@ def run(self):
13701436

13711437
self.log("Using --optional=" + self._optional_tags_string())
13721438
available_software._allow_external = self.options.optional is True or 'external' in self.options.optional
1439+
1440+
for h in self.options.hide:
1441+
try:
1442+
i = available_software._indices[h]
1443+
except KeyError:
1444+
pass
1445+
else:
1446+
f = available_software._features[i]
1447+
if f.is_present():
1448+
f.hide()
1449+
self.options.hidden_features.add(f)
1450+
for g in f.joined_features():
1451+
if g.name in self.options.optional:
1452+
self.options.optional.discard(g.name)
1453+
13731454
for o in self.options.disabled_optional:
13741455
try:
13751456
i = available_software._indices[o]
@@ -1379,12 +1460,17 @@ def run(self):
13791460
available_software._seen[i] = -1
13801461

13811462
self.log("Features to be detected: " + ','.join(available_software.detectable()))
1463+
if self.options.hidden_features:
1464+
self.log("Hidden features: " + ','.join([f.name for f in self.options.hidden_features]))
13821465
self.add_files()
13831466
self.expand_files_into_sources()
13841467
self.filter_sources()
13851468
self.sort_sources()
13861469
self.run_doctests()
13871470

1471+
for f in self.options.hidden_features:
1472+
f.unhide()
1473+
13881474
self.log("Features detected for doctesting: "
13891475
+ ','.join(available_software.seen()))
13901476
self.cleanup()
@@ -1465,3 +1551,34 @@ def stringify(x):
14651551
if not save_dtmode and IP is not None:
14661552
IP.run_line_magic('colors', old_color)
14671553
IP.config.TerminalInteractiveShell.colors = old_config_color
1554+
1555+
1556+
###############################################################################
1557+
# Declaration of doctest strings
1558+
###############################################################################
1559+
1560+
test_hide=r"""r{quotmark}
1561+
{prompt}: next(graphs.fullerenes(20))
1562+
Traceback (most recent call last):
1563+
...
1564+
FeatureNotPresentError: buckygen is not available.
1565+
...
1566+
{prompt}: next(graphs.fullerenes(20)) # optional buckygen
1567+
Graph on 20 vertices
1568+
1569+
{prompt}: len(list(graphs.fusenes(2)))
1570+
Traceback (most recent call last):
1571+
...
1572+
FeatureNotPresentError: benzene is not available.
1573+
...
1574+
{prompt}: len(list(graphs.fusenes(2))) # optional benzene
1575+
1
1576+
{prompt}: from sage.matrix.matrix_space import get_matrix_class
1577+
{prompt}: get_matrix_class(GF(25,'x'), 4, 4, False, 'meataxe')
1578+
Failed lazy import:
1579+
sage.matrix.matrix_gfpn_dense is not available.
1580+
...
1581+
{prompt}: get_matrix_class(GF(25,'x'), 4, 4, False, 'meataxe') # optional meataxe
1582+
<class 'sage.matrix.matrix_gfpn_dense.Matrix_gfpn_dense'>
1583+
{quotmark}
1584+
""".format(quotmark='"""', prompt='sage') # using prompt to hide these lines from _test_enough_doctests

0 commit comments

Comments
 (0)