Skip to content

Commit f9cb12c

Browse files
author
Release Manager
committed
gh-35820: `sage.features`: Declare features as "standard" explicitly <!-- Please provide a concise, informative and self-explanatory title. --> <!-- Don't put issue numbers in the title. Put it in the Description below. --> <!-- For example, instead of "Fixes #12345", use "Add a new method to multiply two integers" --> ### 📚 Description <!-- Describe your changes here in detail. --> <!-- Why is this change required? What problem does it solve? --> As discussed in #35668 (comment) <!-- If this PR resolves an open issue, please link to it here. For example "Fixes #12345". --> <!-- If your change requires a documentation PR, please link it appropriately. --> ### 📝 Checklist <!-- Put an `x` in all the boxes that apply. It should be `[x]` not `[x ]`. --> - [x] The title is concise, informative, and self-explanatory. - [ ] The description explains in detail what this PR is about. - [x] I have linked a relevant issue or discussion. - [ ] I have created tests covering the changes. - [ ] I have updated the documentation accordingly. ### ⌛ Dependencies <!-- List all open PRs that this PR logically depends on - #12345: short description why this is a dependency - #34567: ... --> - Depends on #35668 (merged here) <!-- If you're unsure about any of these, don't hesitate to ask. We're here to help! --> URL: #35820 Reported by: Matthias Köppe Reviewer(s): Sebastian Oehms
2 parents 9efdddb + 4eddb7c commit f9cb12c

File tree

18 files changed

+99
-64
lines changed

18 files changed

+99
-64
lines changed

src/sage/features/__init__.py

Lines changed: 22 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -124,6 +124,8 @@ class Feature(TrivialUniqueRepresentation):
124124
125125
- ``url`` -- a URL for the upstream package providing the feature
126126
127+
- ``type`` -- (string) one of ``'standard'``, ``'optional'`` (default), ``'experimental'``
128+
127129
Overwrite :meth:`_is_present` to add feature checks.
128130
129131
EXAMPLES::
@@ -137,7 +139,7 @@ class Feature(TrivialUniqueRepresentation):
137139
sage: GapPackage("grape") is GapPackage("grape")
138140
True
139141
"""
140-
def __init__(self, name, spkg=None, url=None, description=None):
142+
def __init__(self, name, spkg=None, url=None, description=None, type='optional'):
141143
r"""
142144
TESTS::
143145
@@ -154,6 +156,19 @@ def __init__(self, name, spkg=None, url=None, description=None):
154156
self._cache_is_present = None
155157
self._cache_resolution = None
156158
self._hidden = False
159+
self._type = type
160+
161+
try:
162+
from sage.misc.package import spkg_type
163+
except ImportError: # may have been surgically removed in a downstream distribution
164+
pass
165+
else:
166+
if spkg and (t := spkg_type(spkg)) not in (type, None):
167+
from warnings import warn
168+
warn(f'Feature {name} is declared {type}, '
169+
f'but it is provided by {spkg}, '
170+
f'which is declared {t} in SAGE_ROOT/build/pkgs',
171+
stacklevel=3)
157172

158173
def is_present(self):
159174
r"""
@@ -246,7 +261,10 @@ def __repr__(self):
246261

247262
def _spkg_type(self):
248263
r"""
249-
Return the type of the SPKG corresponding to this feature.
264+
Return the type of this feature.
265+
266+
For features provided by an SPKG in the Sage distribution,
267+
this should match the SPKG type, or a warning will be issued.
250268
251269
EXAMPLES::
252270
@@ -257,13 +275,8 @@ def _spkg_type(self):
257275
OUTPUT:
258276
259277
The type as a string in ``('base', 'standard', 'optional', 'experimental')``.
260-
If no SPKG corresponds to this feature ``None`` is returned.
261278
"""
262-
from sage.misc.package import _spkg_type
263-
spkg = self.spkg
264-
if not spkg:
265-
spkg = self.name
266-
return _spkg_type(spkg)
279+
return self._type
267280

268281
def resolution(self):
269282
r"""
@@ -857,7 +870,7 @@ class CythonFeature(Feature):
857870
....:
858871
....: assert fabs(-1) == 1
859872
....: '''
860-
sage: fabs = CythonFeature("fabs", test_code=fabs_test_code, spkg="gcc", url="https://gnu.org")
873+
sage: fabs = CythonFeature("fabs", test_code=fabs_test_code, spkg="gcc", url="https://gnu.org", type="standard")
861874
sage: fabs.is_present()
862875
FeatureTestResult('fabs', True)
863876

src/sage/features/cddlib.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,4 +34,4 @@ def __init__(self, name='cddexec_gmp'):
3434
True
3535
"""
3636
Executable.__init__(self, name=name, executable=name, spkg="cddlib",
37-
url="https://github.com/cddlib/cddlib")
37+
url="https://github.com/cddlib/cddlib", type="standard")

src/sage/features/databases.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,8 @@ def __init__(self):
5252
filename='conway_polynomials.p',
5353
search_path=search_path,
5454
spkg='conway_polynomials',
55-
description="Frank Luebeck's database of Conway polynomials")
55+
description="Frank Luebeck's database of Conway polynomials",
56+
type='standard')
5657

5758

5859
CREMONA_DATA_DIRS = set([CREMONA_MINI_DATA_DIR, CREMONA_LARGE_DATA_DIR])

src/sage/features/gfan.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ def __init__(self, cmd=None):
3030
name = "gfan"
3131
else:
3232
name = f"gfan_{cmd}"
33-
Executable.__init__(self, name, executable=name, spkg="gfan")
33+
Executable.__init__(self, name, executable=name, spkg="gfan", type='standard')
3434

3535

3636
def all_features():

src/sage/features/join_feature.py

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,8 @@ class JoinFeature(Feature):
4747
FeatureTestResult('xxyyyy', False)
4848
"""
4949

50-
def __init__(self, name, features, spkg=None, url=None, description=None):
50+
def __init__(self, name, features, spkg=None, url=None, description=None, type=None,
51+
**kwds):
5152
"""
5253
TESTS:
5354
@@ -69,7 +70,15 @@ def __init__(self, name, features, spkg=None, url=None, description=None):
6970
raise ValueError('given features have more than one url; provide url argument')
7071
elif len(urls) == 1:
7172
url = next(iter(urls))
72-
super().__init__(name, spkg=spkg, url=url, description=description)
73+
if type is None:
74+
if any(f._spkg_type() == 'experimental' for f in features):
75+
type = 'experimental'
76+
elif any(f._spkg_type() == 'optional' for f in features):
77+
type = 'optional'
78+
else:
79+
type = 'standard'
80+
81+
super().__init__(name, spkg=spkg, url=url, description=description, type=type, **kwds)
7382
self._features = features
7483

7584
def _is_present(self):

src/sage/features/mip_backends.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -102,7 +102,8 @@ def __init__(self):
102102
JoinFeature.__init__(self, 'cvxopt',
103103
[MIPBackend('CVXOPT'),
104104
PythonModule('cvxopt')],
105-
spkg='cvxopt')
105+
spkg='cvxopt',
106+
type='standard')
106107

107108

108109
def all_features():

src/sage/features/nauty.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,8 @@ def __init__(self, name):
3737
"""
3838
Executable.__init__(self, name=f"nauty_{name}",
3939
executable=f"{SAGE_NAUTY_BINS_PREFIX}{name}",
40-
spkg="nauty")
40+
spkg="nauty",
41+
type="standard")
4142

4243

4344
class Nauty(JoinFeature):

src/sage/features/palp.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -36,11 +36,11 @@ def __init__(self, palpprog, suff=None):
3636
if suff:
3737
Executable.__init__(self, f"palp_{palpprog}_{suff}d",
3838
executable=f"{palpprog}-{suff}d.x",
39-
spkg="palp")
39+
spkg="palp", type="standard")
4040
else:
4141
Executable.__init__(self, f"palp_{palpprog}",
4242
executable=f"{palpprog}.x",
43-
spkg="palp")
43+
spkg="palp", type="standard")
4444

4545
class Palp(JoinFeature):
4646
r"""

src/sage/features/sagemath.py

Lines changed: 22 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,8 @@ def __init__(self):
4040
StaticFile.__init__(self, 'sagemath_doc_html',
4141
filename='html',
4242
search_path=(SAGE_DOC,),
43-
spkg='sagemath_doc_html')
43+
spkg='sagemath_doc_html',
44+
type='standard')
4445

4546

4647
class sage__combinat(JoinFeature):
@@ -67,7 +68,7 @@ def __init__(self):
6768
# Hence, we test a Python module within the package.
6869
JoinFeature.__init__(self, 'sage.combinat',
6970
[PythonModule('sage.combinat.tableau')],
70-
spkg='sagemath_combinat')
71+
spkg='sagemath_combinat', type="standard")
7172

7273

7374
class sage__geometry__polyhedron(PythonModule):
@@ -90,7 +91,7 @@ def __init__(self):
9091
True
9192
"""
9293
PythonModule.__init__(self, 'sage.geometry.polyhedron',
93-
spkg='sagemath_polyhedra')
94+
spkg='sagemath_polyhedra', type="standard")
9495

9596

9697
class sage__graphs(JoinFeature):
@@ -113,7 +114,7 @@ def __init__(self):
113114
"""
114115
JoinFeature.__init__(self, 'sage.graphs',
115116
[PythonModule('sage.graphs.graph')],
116-
spkg='sagemath_graphs')
117+
spkg='sagemath_graphs', type="standard")
117118

118119

119120
class sage__modular(JoinFeature):
@@ -136,7 +137,7 @@ def __init__(self):
136137
"""
137138
JoinFeature.__init__(self, 'sage.modular',
138139
[PythonModule('sage.modular.modform.eisenstein_submodule')],
139-
spkg='sagemath_schemes')
140+
spkg='sagemath_schemes', type='standard')
140141

141142

142143
class sage__groups(JoinFeature):
@@ -158,7 +159,8 @@ def __init__(self):
158159
True
159160
"""
160161
JoinFeature.__init__(self, 'sage.groups',
161-
[PythonModule('sage.groups.perm_gps.permgroup')])
162+
[PythonModule('sage.groups.perm_gps.permgroup')],
163+
spkg='sagemath_groups', type='standard')
162164

163165

164166
class sage__libs__flint(JoinFeature):
@@ -183,7 +185,7 @@ def __init__(self):
183185
JoinFeature.__init__(self, 'sage.libs.flint',
184186
[PythonModule('sage.libs.flint.flint'),
185187
PythonModule('sage.libs.arb.arith')],
186-
spkg='sagemath_flint')
188+
spkg='sagemath_flint', type='standard')
187189

188190

189191
class sage__libs__ntl(JoinFeature):
@@ -207,7 +209,7 @@ def __init__(self):
207209
"""
208210
JoinFeature.__init__(self, 'sage.libs.ntl',
209211
[PythonModule('sage.libs.ntl.convert')],
210-
spkg='sagemath_ntl')
212+
spkg='sagemath_ntl', type='standard')
211213

212214

213215
class sage__libs__pari(JoinFeature):
@@ -230,7 +232,7 @@ def __init__(self):
230232
"""
231233
JoinFeature.__init__(self, 'sage.libs.pari',
232234
[PythonModule('sage.libs.pari.convert_sage')],
233-
spkg='sagemath_pari')
235+
spkg='sagemath_pari', type='standard')
234236

235237

236238
class sage__modules(JoinFeature):
@@ -253,7 +255,7 @@ def __init__(self):
253255
"""
254256
JoinFeature.__init__(self, 'sage.modules',
255257
[PythonModule('sage.modules.free_module')],
256-
spkg='sagemath_modules')
258+
spkg='sagemath_modules', type='standard')
257259

258260

259261
class sage__plot(JoinFeature):
@@ -276,7 +278,7 @@ def __init__(self):
276278
"""
277279
JoinFeature.__init__(self, 'sage.plot',
278280
[PythonModule('sage.plot.plot')],
279-
spkg='sagemath_symbolics')
281+
spkg='sagemath_symbolics', type='standard')
280282

281283

282284
class sage__rings__finite_rings(JoinFeature):
@@ -299,7 +301,8 @@ def __init__(self):
299301
True
300302
"""
301303
JoinFeature.__init__(self, 'sage.rings.finite_rings',
302-
[PythonModule('sage.rings.finite_rings.element_pari_ffelt')])
304+
[PythonModule('sage.rings.finite_rings.element_pari_ffelt')],
305+
type='standard')
303306

304307

305308
class sage__rings__function_field(JoinFeature):
@@ -322,7 +325,8 @@ def __init__(self):
322325
"""
323326
JoinFeature.__init__(self, 'sage.rings.function_field',
324327
[PythonModule('sage.rings.function_field.function_field_polymod'),
325-
sage__libs__singular()])
328+
sage__libs__singular()],
329+
type='standard')
326330

327331

328332
class sage__rings__number_field(JoinFeature):
@@ -344,7 +348,8 @@ def __init__(self):
344348
True
345349
"""
346350
JoinFeature.__init__(self, 'sage.rings.number_field',
347-
[PythonModule('sage.rings.number_field.number_field_element')])
351+
[PythonModule('sage.rings.number_field.number_field_element')],
352+
type='standard')
348353

349354

350355
class sage__rings__padics(JoinFeature):
@@ -366,7 +371,8 @@ def __init__(self):
366371
True
367372
"""
368373
JoinFeature.__init__(self, 'sage.rings.padics',
369-
[PythonModule('sage.rings.padics.factory')])
374+
[PythonModule('sage.rings.padics.factory')],
375+
type='standard')
370376

371377

372378
class sage__rings__polynomial__pbori(JoinFeature):
@@ -389,7 +395,7 @@ def __init__(self):
389395
"""
390396
JoinFeature.__init__(self, 'sage.rings.polynomial.pbori',
391397
[PythonModule('sage.rings.polynomial.pbori.pbori')],
392-
spkg='sagemath_brial')
398+
spkg='sagemath_brial', type='standard')
393399

394400

395401
class sage__rings__real_double(PythonModule):

src/sage/features/singular.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ def __init__(self):
3535
True
3636
"""
3737
Executable.__init__(self, "singular", SINGULAR_BIN,
38-
spkg='singular')
38+
spkg='singular', type='standard')
3939

4040

4141
class sage__libs__singular(JoinFeature):

0 commit comments

Comments
 (0)