Skip to content

Commit

Permalink
Merge branch 'improve_multiprocessing_hide_option' into sagemath_stan…
Browse files Browse the repository at this point in the history
…dard_remove_optional_build
  • Loading branch information
Matthias Koeppe committed May 9, 2024
2 parents cf6e33d + f881e2b commit 6a25b74
Show file tree
Hide file tree
Showing 4 changed files with 63 additions and 39 deletions.
5 changes: 3 additions & 2 deletions src/sage/doctest/control.py
Original file line number Diff line number Diff line change
Expand Up @@ -1580,8 +1580,9 @@ def run(self):
self.log("Features detected for doctesting: "
+ ','.join(available_software.seen()))
if self.options.hidden_features:
features_hidden = [f.name for f in self.options.hidden_features if f.unhide()]
self.log("Features that have been hidden: " + ','.join(features_hidden))
for f in self.options.hidden_features:
f.unhide()
self.log("Features that have been hidden: " + ','.join(available_software.hidden()))
self.cleanup()
return self.reporter.error_status

Expand Down
51 changes: 41 additions & 10 deletions src/sage/doctest/external.py
Original file line number Diff line number Diff line change
Expand Up @@ -429,6 +429,7 @@ def __init__(self):
self._features = sorted(features, key=lambda feature: feature.name)
self._indices = {feature.name: idx for idx, feature in enumerate(self._features)}
self._seen = Array('i', len(self._features)) # initialized to zeroes
self._hidden = Array('i', len(self._features)) # initialized to zeroes

def __contains__(self, item):
"""
Expand All @@ -444,19 +445,26 @@ def __contains__(self, item):
idx = self._indices[item]
except KeyError:
return False
if not self._seen[idx]:
if not self._allow_external and self._features[idx] in self._external_features:
self._seen[idx] = -1 # not available
elif self._features[idx].is_present():
self._seen[idx] = 1 # available
feature = self._features[idx]
if feature.is_hidden():
if not self._hidden[idx]:
self._hidden[idx] = 1
available = False # a hidden feature is considered to be not available
else:
if not self._allow_external and feature in self._external_features:
# an external feature is considered to be not available
# if this is not allowed
available = False
elif feature.is_present():
available = True
else:
self._seen[idx] = -1 # not available
if self._seen[idx] == 1:
available = False
if available:
if not self._seen[idx]:
self._seen[idx] = 1
return True
elif self._seen[idx] == -1:
return False
else:
raise AssertionError("Invalid value for self.seen")
return False

def issuperset(self, other):
"""
Expand Down Expand Up @@ -495,5 +503,28 @@ def seen(self):
for feature, seen in zip(self._features, self._seen)
if seen > 0]

def hidden(self):
"""
Return the list of detected hidden external software.
EXAMPLES::
sage: from sage.doctest.external import available_software
sage: from sage.features.databases import all_features
sage: for f in all_features():
....: f.hide()
....: if f._spkg_type() == 'standard':
....: test = f.name in available_software
....: f.unhide()
sage: sorted(available_software.hidden())
[...'conway_polynomials',...
'database_cremona_mini_ellcurve',...
'database_ellcurves',...
'database_graphs'...]
"""
return [feature.name
for feature, hidden in zip(self._features, self._hidden)
if hidden > 0]


available_software = AvailableSoftware()
37 changes: 17 additions & 20 deletions src/sage/features/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -158,12 +158,6 @@ def __init__(self, name, spkg=None, url=None, description=None, type='optional')
self._hidden = False
self._type = type

# For multiprocessing of doctests, the data self._num_hidings should be
# shared among subprocesses. Thus we use the Value class from the
# multiprocessing module (cf. self._seen of class AvailableSoftware)
from multiprocessing import Value
self._num_hidings = Value('i', 0, lock=False)

try:
from sage.misc.package import spkg_type
except ImportError: # may have been surgically removed in a downstream distribution
Expand Down Expand Up @@ -220,10 +214,6 @@ def is_present(self):
self._cache_is_present = res

if self._hidden:
if self._num_hidings.value > 0:
self._num_hidings.value += 1
elif self._cache_is_present:
self._num_hidings.value = 1
return FeatureTestResult(self, False, reason="Feature `{name}` is hidden.".format(name=self.name))

return self._cache_is_present
Expand Down Expand Up @@ -354,7 +344,6 @@ def is_standard(self):
sage: from sage.features.databases import DatabaseCremona
sage: DatabaseCremona().is_standard()
False
"""
if self.name.startswith('sage.'):
return True
Expand All @@ -369,7 +358,6 @@ def is_optional(self):
sage: from sage.features.databases import DatabaseCremona
sage: DatabaseCremona().is_optional()
True
"""
return self._spkg_type() == 'optional'

Expand All @@ -394,34 +382,43 @@ def hide(self):
Use method `unhide` to make it available again.
sage: Benzene().unhide() # optional - benzene, needs sage.graphs
1
sage: len(list(graphs.fusenes(2))) # optional - benzene, needs sage.graphs
1
"""
self._hidden = True

def unhide(self):
r"""
Revert what :meth:`hide` did.
OUTPUT: The number of events a present feature has been hidden.
EXAMPLES:
sage: from sage.features.sagemath import sage__plot
sage: sage__plot().hide()
sage: sage__plot().is_present()
FeatureTestResult('sage.plot', False)
sage: sage__plot().unhide() # needs sage.plot
1
sage: sage__plot().is_present() # needs sage.plot
FeatureTestResult('sage.plot', True)
"""
num_hidings = self._num_hidings.value
self._num_hidings.value = 0
self._hidden = False
return int(num_hidings)

def is_hidden(self):
r"""
Return whether ``self`` is present but currently hidden.
EXAMPLES:
sage: from sage.features.sagemath import sage__plot
sage: sage__plot().hide()
sage: sage__plot().is_hidden() # needs sage.plot
True
sage: sage__plot().unhide()
sage: sage__plot().is_hidden()
False
"""
if self._hidden and self._is_present():
return True
return False

class FeatureNotPresentError(RuntimeError):
r"""
Expand Down
9 changes: 2 additions & 7 deletions src/sage/features/join_feature.py
Original file line number Diff line number Diff line change
Expand Up @@ -154,8 +154,6 @@ def unhide(self):
r"""
Revert what :meth:`hide` did.
OUTPUT: The number of events a present feature has been hidden.
EXAMPLES::
sage: from sage.features.sagemath import sage__groups
Expand All @@ -167,14 +165,11 @@ def unhide(self):
FeatureTestResult('sage.groups.perm_gps.permgroup', False)
sage: f.unhide()
4
sage: f.is_present() # optional sage.groups
FeatureTestResult('sage.groups', True)
sage: f._features[0].is_present() # optional sage.groups
FeatureTestResult('sage.groups.perm_gps.permgroup', True)
"""
num_hidings = 0
for f in self._features:
num_hidings += f.unhide()
num_hidings += super().unhide()
return num_hidings
f.unhide()
super().unhide()

0 comments on commit 6a25b74

Please sign in to comment.