From 136de8bf0391918ea4ebbb42163b2b11af1e96fc Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Sat, 18 Sep 2021 20:45:48 -0700 Subject: [PATCH 1/9] src/sage/rings/rational.pyx: Move import of mathml into method --- src/sage/rings/rational.pyx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sage/rings/rational.pyx b/src/sage/rings/rational.pyx index e2c09e6d6ce..ccba2a1cd43 100644 --- a/src/sage/rings/rational.pyx +++ b/src/sage/rings/rational.pyx @@ -65,7 +65,6 @@ from cysignals.signals cimport sig_on, sig_off import operator import fractions -from sage.misc.mathml import mathml from sage.arith.long cimport pyobject_to_long, integer_check_long_py from sage.cpython.string cimport char_to_str, str_to_bytes @@ -1093,6 +1092,7 @@ cdef class Rational(sage.structure.element.FieldElement): if self.denom() == 1: return '%s'%(self.numer()) else: + from sage.misc.mathml import mathml t = '' if self < 0: t = t + '-' From a4b7c9daf59d38aee3399b7f2081700356f182ce Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Tue, 28 Sep 2021 17:27:42 -0700 Subject: [PATCH 2/9] src/sage/rings/finite_rings/finite_field_constructor.py: Do not fail if .finite_field_givaro cannot be imported --- .../rings/finite_rings/finite_field_constructor.py | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/src/sage/rings/finite_rings/finite_field_constructor.py b/src/sage/rings/finite_rings/finite_field_constructor.py index d7b4e15985f..e6129689ad5 100644 --- a/src/sage/rings/finite_rings/finite_field_constructor.py +++ b/src/sage/rings/finite_rings/finite_field_constructor.py @@ -176,16 +176,17 @@ from sage.rings.integer import Integer -from sage.rings.polynomial.polynomial_ring_constructor import PolynomialRing - # the import below is just a redirection from sage.rings.finite_rings.finite_field_base import is_FiniteField assert is_FiniteField # just to silent pyflakes -# We don't late import this because this means trouble with the Givaro library -# On a Macbook Pro OSX 10.5.8, this manifests as a Bus Error on exiting Sage. -# TODO: figure out why -from .finite_field_givaro import FiniteField_givaro +try: + # We don't late import this because this means trouble with the Givaro library + # On a Macbook Pro OSX 10.5.8, this manifests as a Bus Error on exiting Sage. + # TODO: figure out why + from .finite_field_givaro import FiniteField_givaro +except ImportError: + FiniteField_givaro = None from sage.structure.factory import UniqueFactory @@ -633,6 +634,7 @@ def create_key_and_extra_args(self, order, name=None, modulus=None, names=None, # optimization which we also need to avoid an infinite loop: # a modulus of None is a shorthand for x-1. if modulus is not None or impl != 'modn': + from sage.rings.polynomial.polynomial_ring_constructor import PolynomialRing R = PolynomialRing(FiniteField(p), 'x') if modulus is None: modulus = R.irreducible_element(n) From 8ba073457d08480484312f6771365ee36ed9a744 Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Wed, 29 Sep 2021 12:58:59 -0700 Subject: [PATCH 3/9] src/sage/rings/quotient_ring*.py: Delay imports from sage.interfaces.singular --- src/sage/rings/quotient_ring.py | 34 +++++++++++++++++-------- src/sage/rings/quotient_ring_element.py | 5 ++-- 2 files changed, 27 insertions(+), 12 deletions(-) diff --git a/src/sage/rings/quotient_ring.py b/src/sage/rings/quotient_ring.py index 807dce92a9b..fa44e6bc1c8 100644 --- a/src/sage/rings/quotient_ring.py +++ b/src/sage/rings/quotient_ring.py @@ -110,11 +110,9 @@ import sage.misc.latex as latex from . import ring, ideal, quotient_ring_element -import sage.rings.polynomial.multi_polynomial_ideal from sage.structure.category_object import normalize_names from sage.structure.richcmp import richcmp_method, richcmp import sage.structure.parent_gens -from sage.interfaces.singular import singular as singular_default, is_SingularElement from sage.misc.cachefunc import cached_method from sage.categories.rings import Rings from sage.categories.commutative_rings import CommutativeRings @@ -953,13 +951,20 @@ def ideal(self, *gens, **kwds): (not hasattr(self.__R, '_has_singular') or not self.__R._has_singular): # pass through return super(QuotientRing_nc, self).ideal(gens, **kwds) - if is_SingularElement(gens): + try: + from sage.interfaces.singular import is_SingularElement + except ImportError: + is_singular_element = False + else: + is_singular_element = is_SingularElement(gens) + if is_singular_element: gens = list(gens) elif not isinstance(gens, (list, tuple)): gens = [gens] if 'coerce' in kwds and kwds['coerce']: gens = [self(x) for x in gens] # this will even coerce from singular ideals correctly! - return sage.rings.polynomial.multi_polynomial_ideal.MPolynomialIdeal(self, gens, **kwds) + from sage.rings.polynomial.multi_polynomial_ideal import MPolynomialIdeal + return MPolynomialIdeal(self, gens, **kwds) def _element_constructor_(self, x, coerce=True): """ @@ -1005,10 +1010,15 @@ def _element_constructor_(self, x, coerce=True): if x.parent() is self: return x x = x.lift() - if is_SingularElement(x): - #self._singular_().set_ring() - x = self.element_class(self, x.sage_poly(self.cover_ring())) - return x + try: + from sage.interfaces.singular import is_SingularElement + except ImportError: + pass + else: + if is_SingularElement(x): + #self._singular_().set_ring() + x = self.element_class(self, x.sage_poly(self.cover_ring())) + return x if coerce: R = self.cover_ring() x = R(x) @@ -1172,7 +1182,7 @@ def gen(self, i=0): return self(self.__R.gen(i)) - def _singular_(self, singular=singular_default): + def _singular_(self, singular=None): """ Returns the Singular quotient ring of ``self`` if the base ring is coercible to Singular. @@ -1203,6 +1213,8 @@ def _singular_(self, singular=singular_default): // quotient ring from ideal _[1]=x2+y2 """ + if singular is None: + from sage.interfaces.singular import singular try: Q = self.__singular if not (Q.parent() is singular): @@ -1212,7 +1224,7 @@ def _singular_(self, singular=singular_default): except (AttributeError, ValueError): return self._singular_init_(singular) - def _singular_init_(self,singular=singular_default): + def _singular_init_(self, singular=None): """ Returns a newly created Singular quotient ring matching ``self`` if the base ring is coercible to Singular. @@ -1229,6 +1241,8 @@ def _singular_init_(self,singular=singular_default): sage: parent(T) Singular """ + if singular is None: + from sage.interfaces.singular import singular self.__R._singular_().set_ring() self.__singular = singular("%s"%self.__I._singular_().name(),"qring") return self.__singular diff --git a/src/sage/rings/quotient_ring_element.py b/src/sage/rings/quotient_ring_element.py index 8d09a28f6ba..867f3beb18c 100644 --- a/src/sage/rings/quotient_ring_element.py +++ b/src/sage/rings/quotient_ring_element.py @@ -18,7 +18,6 @@ from sage.structure.element import RingElement from sage.structure.richcmp import richcmp, rich_to_bool -from sage.interfaces.singular import singular as singular_default class QuotientRingElement(RingElement): @@ -757,7 +756,7 @@ def monomials(self): """ return [self.__class__(self.parent(), m) for m in self.__rep.monomials()] - def _singular_(self, singular=singular_default): + def _singular_(self, singular=None): """ Return Singular representation of self. @@ -797,6 +796,8 @@ def _singular_(self, singular=singular_default): sage: S((a-2/3*b)._singular_()) a - 2/3*b """ + if singular is None: + from sage.interfaces.singular import singular return self.__rep._singular_(singular) def _magma_init_(self, magma): From 48cab996d7f570d9195a7316a494f972839a46c5 Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Wed, 17 Nov 2021 19:32:11 -0800 Subject: [PATCH 4/9] Import Algebra from sage.rings.ring, not sage.algebras.algebra --- src/sage/algebras/free_algebra_quotient.py | 2 +- src/sage/combinat/species/series.py | 2 +- src/sage/rings/polynomial/polynomial_ring.py | 5 ++--- 3 files changed, 4 insertions(+), 5 deletions(-) diff --git a/src/sage/algebras/free_algebra_quotient.py b/src/sage/algebras/free_algebra_quotient.py index 232a5b30f47..c4e44e80faf 100644 --- a/src/sage/algebras/free_algebra_quotient.py +++ b/src/sage/algebras/free_algebra_quotient.py @@ -59,7 +59,7 @@ # **************************************************************************** from sage.modules.free_module import FreeModule -from sage.algebras.algebra import Algebra +from sage.rings.ring import Algebra from sage.algebras.free_algebra import is_FreeAlgebra from sage.algebras.free_algebra_quotient_element import FreeAlgebraQuotientElement from sage.structure.unique_representation import UniqueRepresentation diff --git a/src/sage/combinat/species/series.py b/src/sage/combinat/species/series.py index b312148a2f3..9f9dd3eff8e 100644 --- a/src/sage/combinat/species/series.py +++ b/src/sage/combinat/species/series.py @@ -40,7 +40,7 @@ from sage.misc.repr import repr_lincomb from sage.misc.cachefunc import cached_method -from sage.algebras.algebra import Algebra +from sage.rings.ring import Algebra from sage.structure.parent import Parent from sage.categories.all import Rings from sage.structure.element import Element, parent, AlgebraElement diff --git a/src/sage/rings/polynomial/polynomial_ring.py b/src/sage/rings/polynomial/polynomial_ring.py index e6c8d400c2e..858f552acdd 100644 --- a/src/sage/rings/polynomial/polynomial_ring.py +++ b/src/sage/rings/polynomial/polynomial_ring.py @@ -147,7 +147,6 @@ import sage.categories as categories from sage.categories.morphism import IdentityMorphism -import sage.algebras.algebra import sage.rings.commutative_algebra as commutative_algebra import sage.rings.ring as ring from sage.structure.element import is_RingElement @@ -226,7 +225,7 @@ def is_PolynomialRing(x): ######################################################################################### -class PolynomialRing_general(sage.algebras.algebra.Algebra): +class PolynomialRing_general(ring.Algebra): """ Univariate polynomial ring over a ring. """ @@ -300,7 +299,7 @@ def __init__(self, base_ring, name=None, sparse=False, element_class=None, categ self.Element = self._polynomial_class self.__cyclopoly_cache = {} self._has_singular = False - sage.algebras.algebra.Algebra.__init__(self, base_ring, names=name, normalize=True, category=category) + ring.Algebra.__init__(self, base_ring, names=name, normalize=True, category=category) self._populate_coercion_lists_(convert_method_name='_polynomial_') def __reduce__(self): From 9f5fd79ec6d608d15ca4e6d2f9c96c34b0a7be66 Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Wed, 17 Nov 2021 20:16:02 -0800 Subject: [PATCH 5/9] Import CommutativeAlgebra from sage.rings.ring, not sage.rings.commutative_algebra --- src/sage/modular/hecke/algebra.py | 6 +++--- src/sage/rings/polynomial/polynomial_ring.py | 3 +-- 2 files changed, 4 insertions(+), 5 deletions(-) diff --git a/src/sage/modular/hecke/algebra.py b/src/sage/modular/hecke/algebra.py index ffd6364c8bc..5bf05da9a37 100644 --- a/src/sage/modular/hecke/algebra.py +++ b/src/sage/modular/hecke/algebra.py @@ -27,11 +27,11 @@ # **************************************************************************** import sage.rings.infinity -import sage.rings.commutative_algebra from sage.matrix.constructor import matrix from sage.arith.all import lcm, gcd from sage.misc.latex import latex from sage.matrix.matrix_space import MatrixSpace +from sage.rings.ring import CommutativeAlgebra from sage.rings.integer_ring import ZZ from sage.rings.rational_field import QQ from sage.structure.element import Element @@ -103,7 +103,7 @@ def _heckebasis(M): @richcmp_method -class HeckeAlgebra_base(CachedRepresentation, sage.rings.commutative_algebra.CommutativeAlgebra): +class HeckeAlgebra_base(CachedRepresentation, CommutativeAlgebra): """ Base class for algebras of Hecke operators on a fixed Hecke module. @@ -179,7 +179,7 @@ def __init__(self, M): if not module.is_HeckeModule(M): raise TypeError("M (=%s) must be a HeckeModule" % M) self.__M = M - sage.rings.commutative_algebra.CommutativeAlgebra.__init__(self, M.base_ring()) + CommutativeAlgebra.__init__(self, M.base_ring()) def _an_element_impl(self): r""" diff --git a/src/sage/rings/polynomial/polynomial_ring.py b/src/sage/rings/polynomial/polynomial_ring.py index 858f552acdd..16ec6d10a9f 100644 --- a/src/sage/rings/polynomial/polynomial_ring.py +++ b/src/sage/rings/polynomial/polynomial_ring.py @@ -147,7 +147,6 @@ import sage.categories as categories from sage.categories.morphism import IdentityMorphism -import sage.rings.commutative_algebra as commutative_algebra import sage.rings.ring as ring from sage.structure.element import is_RingElement import sage.rings.polynomial.polynomial_element_generic as polynomial_element_generic @@ -1661,7 +1660,7 @@ def monics( self, of_degree = None, max_degree = None ): raise ValueError("you should pass exactly one of of_degree and max_degree") -class PolynomialRing_commutative(PolynomialRing_general, commutative_algebra.CommutativeAlgebra): +class PolynomialRing_commutative(PolynomialRing_general, rings.CommutativeAlgebra): """ Univariate polynomial ring over a commutative ring. """ From e606d3570b4d816c2257ae2718bdb25cb849c68a Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Wed, 17 Nov 2021 21:11:57 -0800 Subject: [PATCH 6/9] src/sage/rings/polynomial/polynomial_ring.py: fixup --- src/sage/rings/polynomial/polynomial_ring.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sage/rings/polynomial/polynomial_ring.py b/src/sage/rings/polynomial/polynomial_ring.py index 16ec6d10a9f..bfb8b863edb 100644 --- a/src/sage/rings/polynomial/polynomial_ring.py +++ b/src/sage/rings/polynomial/polynomial_ring.py @@ -1660,7 +1660,7 @@ def monics( self, of_degree = None, max_degree = None ): raise ValueError("you should pass exactly one of of_degree and max_degree") -class PolynomialRing_commutative(PolynomialRing_general, rings.CommutativeAlgebra): +class PolynomialRing_commutative(PolynomialRing_general, ring.CommutativeAlgebra): """ Univariate polynomial ring over a commutative ring. """ From fba5f43491403997227ed0daecc7dea3f4f4f2eb Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Mon, 29 Nov 2021 14:13:06 -0800 Subject: [PATCH 7/9] src/sage/rings/commutative_algebra.py: Fix up imports in doctest --- src/sage/rings/commutative_algebra.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/sage/rings/commutative_algebra.py b/src/sage/rings/commutative_algebra.py index 274ba57bc14..26ab115e52b 100644 --- a/src/sage/rings/commutative_algebra.py +++ b/src/sage/rings/commutative_algebra.py @@ -25,7 +25,9 @@ def is_CommutativeAlgebra(x): EXAMPLES:: - sage: sage.rings.commutative_algebra.is_CommutativeAlgebra(sage.rings.ring.CommutativeAlgebra(ZZ)) + sage: from sage.rings.commutative_algebra import is_CommutativeAlgebra + sage: from sage.rings.ring import CommutativeAlgebra + sage: is_CommutativeAlgebra(CommutativeAlgebra(ZZ)) True """ return isinstance(x, CommutativeAlgebra) From 5c61a2b52a786811af25ef1081d8a1b2f5d19cc4 Mon Sep 17 00:00:00 2001 From: Jonathan Kliem Date: Tue, 30 Nov 2021 10:14:00 +0100 Subject: [PATCH 8/9] small optimizations --- src/sage/rings/quotient_ring.py | 41 +++++++++++++------------ src/sage/rings/quotient_ring_element.py | 10 ++++-- 2 files changed, 29 insertions(+), 22 deletions(-) diff --git a/src/sage/rings/quotient_ring.py b/src/sage/rings/quotient_ring.py index fa44e6bc1c8..70c4afdc283 100644 --- a/src/sage/rings/quotient_ring.py +++ b/src/sage/rings/quotient_ring.py @@ -117,6 +117,15 @@ from sage.categories.rings import Rings from sage.categories.commutative_rings import CommutativeRings + +MPolynomialIdeal = None +try: + from sage.interfaces.singular import singular as singular_default, is_SingularElement +except ImportError: + is_singularElement = lambda x : False + singular_default = None + + def QuotientRing(R, I, names=None, **kwds): r""" Creates a quotient ring of the ring `R` by the twosided ideal `I`. @@ -951,19 +960,16 @@ def ideal(self, *gens, **kwds): (not hasattr(self.__R, '_has_singular') or not self.__R._has_singular): # pass through return super(QuotientRing_nc, self).ideal(gens, **kwds) - try: - from sage.interfaces.singular import is_SingularElement - except ImportError: - is_singular_element = False - else: - is_singular_element = is_SingularElement(gens) - if is_singular_element: + if is_SingularElement(gens): gens = list(gens) elif not isinstance(gens, (list, tuple)): gens = [gens] if 'coerce' in kwds and kwds['coerce']: gens = [self(x) for x in gens] # this will even coerce from singular ideals correctly! - from sage.rings.polynomial.multi_polynomial_ideal import MPolynomialIdeal + + global MPolynomialIdeal + if MPolynomialIdeal is None: + from sage.rings.polynomial.multi_polynomial_ideal import MPolynomialIdeal return MPolynomialIdeal(self, gens, **kwds) def _element_constructor_(self, x, coerce=True): @@ -1010,15 +1016,10 @@ def _element_constructor_(self, x, coerce=True): if x.parent() is self: return x x = x.lift() - try: - from sage.interfaces.singular import is_SingularElement - except ImportError: - pass - else: - if is_SingularElement(x): - #self._singular_().set_ring() - x = self.element_class(self, x.sage_poly(self.cover_ring())) - return x + if is_SingularElement(x): + # self._singular_().set_ring() + x = self.element_class(self, x.sage_poly(self.cover_ring())) + return x if coerce: R = self.cover_ring() x = R(x) @@ -1181,8 +1182,7 @@ def gen(self, i=0): """ return self(self.__R.gen(i)) - - def _singular_(self, singular=None): + def _singular_(self, singular=singular_default): """ Returns the Singular quotient ring of ``self`` if the base ring is coercible to Singular. @@ -1214,7 +1214,8 @@ def _singular_(self, singular=None): _[1]=x2+y2 """ if singular is None: - from sage.interfaces.singular import singular + raise ImportError("could not import singular") + try: Q = self.__singular if not (Q.parent() is singular): diff --git a/src/sage/rings/quotient_ring_element.py b/src/sage/rings/quotient_ring_element.py index 867f3beb18c..964f6d40fb0 100644 --- a/src/sage/rings/quotient_ring_element.py +++ b/src/sage/rings/quotient_ring_element.py @@ -20,6 +20,12 @@ from sage.structure.richcmp import richcmp, rich_to_bool +try: + from sage.interfaces.singular import singular as singular_default +except ImportError: + is_singularElement = lambda x : False + + class QuotientRingElement(RingElement): """ An element of a quotient ring `R/I`. @@ -756,7 +762,7 @@ def monomials(self): """ return [self.__class__(self.parent(), m) for m in self.__rep.monomials()] - def _singular_(self, singular=None): + def _singular_(self, singular=singular_default): """ Return Singular representation of self. @@ -797,7 +803,7 @@ def _singular_(self, singular=None): a - 2/3*b """ if singular is None: - from sage.interfaces.singular import singular + raise ImportError("could not import singular") return self.__rep._singular_(singular) def _magma_init_(self, magma): From 92d88c059f0608e19e951e30f1c0afe2d2bb38f6 Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Tue, 30 Nov 2021 15:48:13 -0800 Subject: [PATCH 9/9] src/sage/rings/quotient_ring_element.py: Fixup --- src/sage/rings/quotient_ring_element.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sage/rings/quotient_ring_element.py b/src/sage/rings/quotient_ring_element.py index 964f6d40fb0..337c22c232c 100644 --- a/src/sage/rings/quotient_ring_element.py +++ b/src/sage/rings/quotient_ring_element.py @@ -23,7 +23,7 @@ try: from sage.interfaces.singular import singular as singular_default except ImportError: - is_singularElement = lambda x : False + singular_default = None class QuotientRingElement(RingElement):