Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

New feature annotations # optional - sage.schemes sage.modular sage.libs.flint etc. #35728

Merged
merged 15 commits into from
Jun 21, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 6 additions & 6 deletions src/sage/arith/functions.pyx
Original file line number Diff line number Diff line change
Expand Up @@ -72,25 +72,25 @@ def lcm(a, b=None):

Make sure we try `\QQ` and not merely `\ZZ` (:trac:`13014`)::

sage: bool(lcm(2/5, 3/7) == lcm(SR(2/5), SR(3/7)))
sage: bool(lcm(2/5, 3/7) == lcm(SR(2/5), SR(3/7))) # optional - sage.symbolic
True

Make sure that the lcm of Expressions stays symbolic::

sage: parent(lcm(2, 4))
Integer Ring
sage: parent(lcm(SR(2), 4))
sage: parent(lcm(SR(2), 4)) # optional - sage.symbolic
Symbolic Ring
sage: parent(lcm(2, SR(4)))
sage: parent(lcm(2, SR(4))) # optional - sage.symbolic
Symbolic Ring
sage: parent(lcm(SR(2), SR(4)))
sage: parent(lcm(SR(2), SR(4))) # optional - sage.symbolic
Symbolic Ring

Verify that objects without lcm methods but which can't be
coerced to `\ZZ` or `\QQ` raise an error::

sage: F.<x,y> = FreeMonoid(2)
sage: lcm(x,y)
sage: F.<x,y> = FreeMonoid(2) # optional - sage.groups
sage: lcm(x,y) # optional - sage.groups
Traceback (most recent call last):
...
TypeError: unable to find lcm of x and y
Expand Down
1,281 changes: 645 additions & 636 deletions src/sage/arith/misc.py

Large diffs are not rendered by default.

1 change: 1 addition & 0 deletions src/sage/arith/multi_modular.pyx
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
# sage.doctest: optional - primecountpy
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It would be so cool if all files could be like this one with only the declaration of the overall optional dependencies. Of course it's much more complicated than that in practice as some optional tags concern only a few tests in a file and are really iff some optional package (e.g., igraph) has been installed. But for dependencies that are repeated on almost all lines, it could ease our life to force the entire file to depend on these packages.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, and in some cases we can achieve this by splitting out parts of files to a separate file (but probably we should do this only where it seems natural).

"""
Utility classes for multi-modular algorithms
"""
Expand Down
32 changes: 16 additions & 16 deletions src/sage/categories/action.pyx
Original file line number Diff line number Diff line change
Expand Up @@ -432,16 +432,16 @@ cdef class PrecomposedAction(Action):
We demonstrate that an example discussed on :trac:`14711` did not become a
problem::

sage: E = ModularSymbols(11).2
sage: s = E.modular_symbol_rep()
sage: del E,s
sage: import gc
sage: _ = gc.collect()
sage: E = ModularSymbols(11).2
sage: v = E.manin_symbol_rep()
sage: c,x = v[0]
sage: y = x.modular_symbol_rep()
sage: coercion_model.get_action(QQ, parent(y), op=operator.mul)
sage: E = ModularSymbols(11).2 # optional - sage.modular
sage: s = E.modular_symbol_rep() # optional - sage.modular
sage: del E,s # optional - sage.modular
sage: import gc # optional - sage.modular
sage: _ = gc.collect() # optional - sage.modular
sage: E = ModularSymbols(11).2 # optional - sage.modular
sage: v = E.manin_symbol_rep() # optional - sage.modular
sage: c,x = v[0] # optional - sage.modular
sage: y = x.modular_symbol_rep() # optional - sage.modular
sage: coercion_model.get_action(QQ, parent(y), op=operator.mul) # optional - sage.modular
Left scalar multiplication by Rational Field
on Abelian Group of all Formal Finite Sums over Rational Field
with precomposition on right by Coercion map:
Expand Down Expand Up @@ -483,12 +483,12 @@ cdef class PrecomposedAction(Action):

Check that this action can be pickled (:trac:`29031`)::

sage: E = ModularSymbols(11).2
sage: v = E.manin_symbol_rep()
sage: c,x = v[0]
sage: y = x.modular_symbol_rep()
sage: act = coercion_model.get_action(QQ, parent(y), op=operator.mul)
sage: loads(dumps(act)) is not None
sage: E = ModularSymbols(11).2 # optional - sage.modular
sage: v = E.manin_symbol_rep() # optional - sage.modular
sage: c,x = v[0] # optional - sage.modular
sage: y = x.modular_symbol_rep() # optional - sage.modular
sage: act = coercion_model.get_action(QQ, parent(y), op=operator.mul) # optional - sage.modular
sage: loads(dumps(act)) is not None # optional - sage.modular
True
"""
return (type(self), (self._action, self.G_precomposition, self.S_precomposition))
Expand Down
12 changes: 6 additions & 6 deletions src/sage/categories/hecke_modules.py
Original file line number Diff line number Diff line change
Expand Up @@ -103,7 +103,7 @@ class ParentMethods:

def _Hom_(self, Y, category):
r"""
Returns the homset from ``self`` to ``Y`` in the category ``category``
Return the homset from ``self`` to ``Y`` in the category ``category``

INPUT:

Expand All @@ -121,15 +121,15 @@ def _Hom_(self, Y, category):

EXAMPLES::

sage: M = ModularForms(Gamma0(7), 4)
sage: H = M._Hom_(M, category = HeckeModules(QQ)); H
sage: M = ModularForms(Gamma0(7), 4) # optional - sage.modular
sage: H = M._Hom_(M, category=HeckeModules(QQ)); H # optional - sage.modular
Set of Morphisms
from Modular Forms space of dimension 3 for Congruence Subgroup Gamma0(7) of weight 4 over Rational Field
to Modular Forms space of dimension 3 for Congruence Subgroup Gamma0(7) of weight 4 over Rational Field
in Category of Hecke modules over Rational Field
sage: H.__class__
sage: H.__class__ # optional - sage.modular
<class 'sage.modular.hecke.homspace.HeckeModuleHomspace_with_category'>
sage: TestSuite(H).run(skip=["_test_elements", "_test_an_element", "_test_elements_eq",
sage: TestSuite(H).run(skip=["_test_elements", "_test_an_element", "_test_elements_eq", # optional - sage.modular
....: "_test_elements_eq_reflexive", "_test_elements_eq_transitive",
....: "_test_elements_eq_symmetric", "_test_elements_neq", "_test_some_elements",
....: "_test_zero", "_test_additive_associativity",
Expand All @@ -142,7 +142,7 @@ def _Hom_(self, Y, category):

TESTS::

sage: H = M._Hom_(M, category = HeckeModules(GF(5))); H
sage: H = M._Hom_(M, category=HeckeModules(GF(5))); H # optional - sage.modular sage.rings.finite_rings
Traceback (most recent call last):
...
TypeError: Category of Hecke modules over Finite Field of size 5
Expand Down
12 changes: 6 additions & 6 deletions src/sage/categories/homset.py
Original file line number Diff line number Diff line change
Expand Up @@ -592,15 +592,15 @@ class Homset(Set_generic):

Conversely, homsets of non-unique parents are non-unique::

sage: P11 = ProductProjectiveSpaces(QQ, [1, 1])
sage: H = End(P11)
sage: loads(dumps(P11)) is ProductProjectiveSpaces(QQ, [1, 1])
sage: P11 = ProductProjectiveSpaces(QQ, [1, 1]) # optional - sage.schemes
sage: H = End(P11) # optional - sage.schemes
sage: loads(dumps(P11)) is ProductProjectiveSpaces(QQ, [1, 1]) # optional - sage.schemes
False
sage: loads(dumps(P11)) == ProductProjectiveSpaces(QQ, [1, 1])
sage: loads(dumps(P11)) == ProductProjectiveSpaces(QQ, [1, 1]) # optional - sage.schemes
True
sage: loads(dumps(H)) is H
sage: loads(dumps(H)) is H # optional - sage.schemes
False
sage: loads(dumps(H)) == H
sage: loads(dumps(H)) == H # optional - sage.schemes
True
"""
def __init__(self, X, Y, category=None, base=None, check=True):
Expand Down
2 changes: 1 addition & 1 deletion src/sage/categories/modules_with_basis.py
Original file line number Diff line number Diff line change
Expand Up @@ -165,7 +165,7 @@ def _call_(self, x):
If ``x`` itself is not a module with basis, but there is a
canonical one associated to it, the latter is returned::

sage: CQ(AbelianVariety(Gamma0(37))) # indirect doctest # optional - sage.modules
sage: CQ(AbelianVariety(Gamma0(37))) # indirect doctest # optional - sage.modular sage.modules
Vector space of dimension 4 over Rational Field
"""
try:
Expand Down
145 changes: 138 additions & 7 deletions src/sage/features/sagemath.py
Original file line number Diff line number Diff line change
Expand Up @@ -63,9 +63,11 @@ def __init__(self):
"""
# sage.combinat will be a namespace package.
# Testing whether sage.combinat itself can be imported is meaningless.
# Some modules providing basic combinatorics are already included in sagemath-categories.
# Hence, we test a Python module within the package.
JoinFeature.__init__(self, 'sage.combinat',
[PythonModule('sage.combinat.combination')])
[PythonModule('sage.combinat.tableau')],
spkg='sagemath_combinat')


class sage__geometry__polyhedron(PythonModule):
Expand All @@ -87,7 +89,8 @@ def __init__(self):
sage: isinstance(sage__geometry__polyhedron(), sage__geometry__polyhedron)
True
"""
PythonModule.__init__(self, 'sage.geometry.polyhedron')
PythonModule.__init__(self, 'sage.geometry.polyhedron',
spkg='sagemath_polyhedra')


class sage__graphs(JoinFeature):
Expand All @@ -109,7 +112,31 @@ def __init__(self):
True
"""
JoinFeature.__init__(self, 'sage.graphs',
[PythonModule('sage.graphs.graph')])
[PythonModule('sage.graphs.graph')],
spkg='sagemath_graphs')


class sage__modular(JoinFeature):
r"""
A :class:`~sage.features.Feature` describing the presence of :mod:`sage.modular`.

EXAMPLES::

sage: from sage.features.sagemath import sage__modular
sage: sage__modular().is_present() # optional - sage.modular
FeatureTestResult('sage.modular', True)
"""
def __init__(self):
r"""
TESTS::

sage: from sage.features.sagemath import sage__modular
sage: isinstance(sage__modular(), sage__modular)
True
"""
JoinFeature.__init__(self, 'sage.modular',
[PythonModule('sage.modular.modform.eisenstein_submodule')],
spkg='sagemath_schemes')


class sage__groups(JoinFeature):
Expand All @@ -134,6 +161,55 @@ def __init__(self):
[PythonModule('sage.groups.perm_gps.permgroup')])


class sage__libs__flint(JoinFeature):
r"""
A :class:`sage.features.Feature` describing the presence of :mod:`sage.libs.flint`
and other modules depending on FLINT and arb.

EXAMPLES::

sage: from sage.features.sagemath import sage__libs__flint
sage: sage__libs__flint().is_present() # optional - sage.libs.flint
FeatureTestResult('sage.libs.flint', True)
"""
def __init__(self):
r"""
TESTS::

sage: from sage.features.sagemath import sage__libs__flint
sage: isinstance(sage__libs__flint(), sage__libs__flint)
True
"""
JoinFeature.__init__(self, 'sage.libs.flint',
[PythonModule('sage.libs.flint.flint'),
PythonModule('sage.libs.arb.arith')],
spkg='sagemath_flint')


class sage__libs__ntl(JoinFeature):
r"""
A :class:`sage.features.Feature` describing the presence of :mod:`sage.libs.ntl`
and other modules depending on NTL and arb.

EXAMPLES::

sage: from sage.features.sagemath import sage__libs__ntl
sage: sage__libs__ntl().is_present() # optional - sage.libs.ntl
FeatureTestResult('sage.libs.ntl', True)
"""
def __init__(self):
r"""
TESTS::

sage: from sage.features.sagemath import sage__libs__ntl
sage: isinstance(sage__libs__ntl(), sage__libs__ntl)
True
"""
JoinFeature.__init__(self, 'sage.libs.ntl',
[PythonModule('sage.libs.ntl.convert')],
spkg='sagemath_ntl')


class sage__libs__pari(JoinFeature):
r"""
A :class:`sage.features.Feature` describing the presence of :mod:`sage.libs.pari`.
Expand All @@ -153,7 +229,8 @@ def __init__(self):
True
"""
JoinFeature.__init__(self, 'sage.libs.pari',
[PythonModule('sage.libs.pari.convert_sage')])
[PythonModule('sage.libs.pari.convert_sage')],
spkg='sagemath_pari')


class sage__modules(JoinFeature):
Expand All @@ -175,7 +252,8 @@ def __init__(self):
True
"""
JoinFeature.__init__(self, 'sage.modules',
[PythonModule('sage.modules.free_module')])
[PythonModule('sage.modules.free_module')],
spkg='sagemath_modules')


class sage__plot(JoinFeature):
Expand All @@ -197,7 +275,8 @@ def __init__(self):
True
"""
JoinFeature.__init__(self, 'sage.plot',
[PythonModule('sage.plot.plot')])
[PythonModule('sage.plot.plot')],
spkg='sagemath_symbolics')


class sage__rings__finite_rings(JoinFeature):
Expand Down Expand Up @@ -290,6 +369,29 @@ def __init__(self):
[PythonModule('sage.rings.padics.factory')])


class sage__rings__polynomial__pbori(JoinFeature):
r"""
A :class:`sage.features.Feature` describing the presence of :mod:`sage.rings.polynomial.pbori`.

EXAMPLES::

sage: from sage.features.sagemath import sage__rings__polynomial__pbori
sage: sage__rings__polynomial__pbori().is_present() # optional - sage.rings.polynomial.pbori
FeatureTestResult('sage.rings.polynomial.pbori', True)
"""
def __init__(self):
r"""
TESTS::

sage: from sage.features.sagemath import sage__rings__polynomial__pbori
sage: isinstance(sage__rings__polynomial__pbori(), sage__rings__polynomial__pbori)
True
"""
JoinFeature.__init__(self, 'sage.rings.polynomial.pbori',
[PythonModule('sage.rings.polynomial.pbori.pbori')],
spkg='sagemath_brial')


class sage__rings__real_double(PythonModule):
r"""
A :class:`~sage.features.Feature` describing the presence of :mod:`sage.rings.real_double`.
Expand Down Expand Up @@ -329,7 +431,31 @@ def __init__(self):
sage: isinstance(sage__rings__real_mpfr(), sage__rings__real_mpfr)
True
"""
PythonModule.__init__(self, 'sage.rings.real_mpfr')
PythonModule.__init__(self, 'sage.rings.real_mpfr',
spkg='sagemath_modules')


class sage__schemes(JoinFeature):
r"""
A :class:`~sage.features.Feature` describing the presence of :mod:`sage.schemes`.

EXAMPLES::

sage: from sage.features.sagemath import sage__schemes
sage: sage__schemes().is_present() # optional - sage.schemes
FeatureTestResult('sage.schemes', True)
"""
def __init__(self):
r"""
TESTS::

sage: from sage.features.sagemath import sage__schemes
sage: isinstance(sage__schemes(), sage__schemes)
True
"""
JoinFeature.__init__(self, 'sage.schemes',
[PythonModule('sage.schemes.elliptic_curves.ell_generic')],
spkg="sagemath_schemes")


class sage__symbolic(JoinFeature):
Expand Down Expand Up @@ -382,13 +508,18 @@ def all_features():
sage__geometry__polyhedron(),
sage__graphs(),
sage__groups(),
sage__libs__flint(),
sage__libs__ntl(),
sage__libs__pari(),
sage__modular(),
sage__modules(),
sage__plot(),
sage__rings__finite_rings(),
sage__rings__function_field(),
sage__rings__number_field(),
sage__rings__padics(),
sage__rings__polynomial__pbori(),
sage__rings__real_double(),
sage__rings__real_mpfr(),
sage__schemes(),
sage__symbolic()]
5 changes: 3 additions & 2 deletions src/sage/misc/cachefunc.pyx
Original file line number Diff line number Diff line change
Expand Up @@ -3707,8 +3707,9 @@ class disk_cached_function:
sage: dir = tmp_dir()
sage: @disk_cached_function(dir)
....: def foo(x): return ModularSymbols(x)
sage: foo(389)
Modular Symbols space of dimension 65 for Gamma_0(389) of weight 2 with sign 0 over Rational Field
sage: foo(389) # optional - sage.modular
Modular Symbols space of dimension 65 for Gamma_0(389) of weight 2
with sign 0 over Rational Field
"""
return DiskCachedFunction(f, self._dir, memory_cache=self._memory_cache, key=self._key)

Expand Down
Loading