Skip to content

Commit

Permalink
Trac #33497: coerce vs _coerce_ vs _coerce_c
Browse files Browse the repository at this point in the history
Even though the `_coerce_` and `_coerce_c` methods are only implemented
in the soon to be deprecated `sage.structure.parent_old.Parent` it is
still used in some places. The current situation prevents to build a
ring that inherits from Parent and use it as a base ring for the
multivariate polynomial ring.

We replace all usage of `_coerce_`/`_coerce_c` by `coerce` and deprecate
the formers.

URL: https://trac.sagemath.org/33497
Reported by: vdelecroix
Ticket author(s): Vincent Delecroix, Travis Scrimshaw
Reviewer(s): Frédéric Chapoton, Travis Scrimshaw, Vincent Delecroix
  • Loading branch information
Release Manager committed May 19, 2022
2 parents 4d136aa + 4ed53f8 commit 9398d92
Show file tree
Hide file tree
Showing 27 changed files with 98 additions and 86 deletions.
2 changes: 1 addition & 1 deletion src/sage/misc/functional.py
Original file line number Diff line number Diff line change
Expand Up @@ -184,7 +184,7 @@ def coerce(P, x):
<class 'sage.rings.rational.Rational'>
"""
try:
return P._coerce_(x)
return P.coerce(x)
except AttributeError:
return P(x)

Expand Down
2 changes: 1 addition & 1 deletion src/sage/quadratic_forms/quadratic_form__evaluate.pyx
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ cdef QFEvaluateVector_cdef(Q, v):
tmp_val += Q[i,j] * v[i] * v[j]

## Return the value (over R)
return Q.base_ring()._coerce_(tmp_val)
return Q.base_ring().coerce(tmp_val)



Expand Down
4 changes: 2 additions & 2 deletions src/sage/rings/complex_double.pyx
Original file line number Diff line number Diff line change
Expand Up @@ -415,9 +415,9 @@ cdef class ComplexDoubleField_class(sage.rings.abc.ComplexDoubleField):
EXAMPLES::
sage: CDF._coerce_(5) # indirect doctest
sage: CDF.coerce(5) # indirect doctest
5.0
sage: CDF._coerce_(RDF(3.4))
sage: CDF.coerce(RDF(3.4))
3.4
Thus the sum of a CDF and a symbolic object is symbolic::
Expand Down
10 changes: 7 additions & 3 deletions src/sage/rings/finite_rings/element_pari_ffelt.pyx
Original file line number Diff line number Diff line change
Expand Up @@ -1272,7 +1272,7 @@ cdef class FiniteFieldElement_pari_ffelt(FinitePolyExtElement):
You can specify the instance of the Gap interpreter that is used::
sage: F = FiniteField(next_prime(200)^2, 'a', impl='pari_ffelt')
sage: a = F.multiplicative_generator ()
sage: a = F.multiplicative_generator()
sage: a._gap_ (gap)
Z(211^2)
sage: (a^20)._gap_(gap)
Expand All @@ -1281,11 +1281,15 @@ cdef class FiniteFieldElement_pari_ffelt(FinitePolyExtElement):
Gap only supports relatively small finite fields::
sage: F = FiniteField(next_prime(1000)^2, 'a', impl='pari_ffelt')
sage: a = F.multiplicative_generator ()
sage: gap._coerce_(a)
sage: a = F.multiplicative_generator()
sage: a._gap_init_()
Traceback (most recent call last):
...
TypeError: order must be at most 65536
sage: gap.coerce(a)
Traceback (most recent call last):
...
TypeError: no canonical coercion from Finite Field in a of size 1009^2 to Gap
"""
F = self._parent
if F.order() > 65536:
Expand Down
14 changes: 7 additions & 7 deletions src/sage/rings/finite_rings/finite_field_base.pyx
Original file line number Diff line number Diff line change
Expand Up @@ -1311,26 +1311,26 @@ cdef class FiniteField(Field):
a + 1
sage: k = GF(4, 'a')
sage: k._coerce_(GF(2)(1))
sage: k.coerce(GF(2)(1))
1
sage: k._coerce_(k.0)
sage: k.coerce(k.0)
a
sage: k._coerce_(3)
sage: k.coerce(3)
1
sage: k._coerce_(2/3)
sage: k.coerce(2/3)
Traceback (most recent call last):
...
TypeError: no canonical coercion from Rational Field to Finite Field in a of size 2^2
sage: FiniteField(16)._coerce_(FiniteField(4).0)
sage: FiniteField(16).coerce(FiniteField(4).0)
z4^2 + z4
sage: FiniteField(8, 'a')._coerce_(FiniteField(4, 'a').0)
sage: FiniteField(8, 'a').coerce(FiniteField(4, 'a').0)
Traceback (most recent call last):
...
TypeError: no canonical coercion from Finite Field in a of size 2^2 to Finite Field in a of size 2^3
sage: FiniteField(8, 'a')._coerce_(FiniteField(7, 'a')(2))
sage: FiniteField(8, 'a').coerce(FiniteField(7, 'a')(2))
Traceback (most recent call last):
...
TypeError: no canonical coercion from Finite Field of size 7 to Finite Field in a of size 2^3
Expand Down
2 changes: 1 addition & 1 deletion src/sage/rings/finite_rings/integer_mod.pyx
Original file line number Diff line number Diff line change
Expand Up @@ -462,7 +462,7 @@ cdef class IntegerMod_abstract(FiniteRingElement):
2
"""
# The generators are irrelevant (Zmod(n) is its own base), so we ignore base_map
return codomain._coerce_(self)
return codomain.coerce(self)

def __mod__(self, modulus):
"""
Expand Down
4 changes: 2 additions & 2 deletions src/sage/rings/finite_rings/integer_mod_ring.py
Original file line number Diff line number Diff line change
Expand Up @@ -1242,7 +1242,7 @@ def _coerce_map_from_(self, S):
sage: R = IntegerModRing(17)
sage: a = R(3)
sage: b = R._coerce_(3)
sage: b = R.coerce(3)
sage: b
3
sage: a==b
Expand All @@ -1258,7 +1258,7 @@ def _coerce_map_from_(self, S):
::
sage: R._coerce_(2/3)
sage: R.coerce(2/3)
Traceback (most recent call last):
...
TypeError: no canonical coercion from Rational Field to Ring of integers modulo 17
Expand Down
2 changes: 1 addition & 1 deletion src/sage/rings/integer.pyx
Original file line number Diff line number Diff line change
Expand Up @@ -776,7 +776,7 @@ cdef class Integer(sage.structure.element.EuclideanDomainElement):
sage: n._im_gens_(R, [R(1)])
7
"""
return codomain._coerce_(self)
return codomain.coerce(self)

cdef _xor(Integer self, Integer other):
cdef Integer x
Expand Down
2 changes: 1 addition & 1 deletion src/sage/rings/polynomial/multi_polynomial_element.py
Original file line number Diff line number Diff line change
Expand Up @@ -213,7 +213,7 @@ def _im_gens_(self, codomain, im_gens, base_map=None):
"""
n = self.parent().ngens()
if n == 0:
return codomain._coerce_(self)
return codomain.coerce(self)
y = codomain(0)
if base_map is None:
# Just use conversion
Expand Down
50 changes: 25 additions & 25 deletions src/sage/rings/polynomial/multi_polynomial_libsingular.pyx
Original file line number Diff line number Diff line change
Expand Up @@ -527,7 +527,7 @@ cdef class MPolynomialRing_libsingular(MPolynomialRing_base):
We can coerce elements of self to self::
sage: P._coerce_(x*y + 1/2)
sage: P.coerce(x*y + 1/2)
x*y + 1/2
We can coerce elements for a ring with the same algebraic properties::
Expand All @@ -540,31 +540,31 @@ cdef class MPolynomialRing_libsingular(MPolynomialRing_base):
sage: P is R
False
sage: P._coerce_(x*y + 1)
sage: P.coerce(x*y + 1)
x*y + 1
We can coerce base ring elements::
sage: P._coerce_(3/2)
sage: P.coerce(3/2)
3/2
and all kinds of integers::
sage: P._coerce_(ZZ(1))
sage: P.coerce(ZZ(1))
1
sage: P._coerce_(int(1))
sage: P.coerce(int(1))
1
sage: k.<a> = GF(2^8)
sage: P.<x,y> = PolynomialRing(k,2)
sage: P._coerce_(a)
sage: P.coerce(a)
a
sage: z = QQ['z'].0
sage: K.<s> = NumberField(z^2 - 2)
sage: P.<x,y> = PolynomialRing(K, 2)
sage: P._coerce_(1/2*s)
sage: P.coerce(1/2*s)
(1/2*s)
TESTS::
Expand Down Expand Up @@ -988,7 +988,7 @@ cdef class MPolynomialRing_libsingular(MPolynomialRing_base):

# we need to do this, to make sure that we actually get an
# element in self.
return self._coerce_c(element)
return self.coerce(element)

if hasattr(element,'_polynomial_'): # symbolic.expression.Expression
return element._polynomial_(self)
Expand Down Expand Up @@ -1598,9 +1598,9 @@ cdef class MPolynomialRing_libsingular(MPolynomialRing_base):
cdef number *denom

if self is not f._parent:
f = self._coerce_c(f)
f = self.coerce(f)
if self is not g._parent:
g = self._coerce_c(g)
g = self.coerce(g)

if not f._poly:
return self._zero_element
Expand Down Expand Up @@ -1653,7 +1653,7 @@ cdef class MPolynomialRing_libsingular(MPolynomialRing_base):
cdef poly *_b
cdef ring *_r
if a._parent is not b._parent:
b = a._parent._coerce_c(b)
b = a._parent.coerce(b)

_a = a._poly
_b = b._poly
Expand Down Expand Up @@ -1702,9 +1702,9 @@ cdef class MPolynomialRing_libsingular(MPolynomialRing_base):
cdef poly *m = p_ISet(1,self._ring)

if self is not f._parent:
f = self._coerce_c(f)
f = self.coerce(f)
if self is not g._parent:
g = self._coerce_c(g)
g = self.coerce(g)

if f._poly == NULL:
if g._poly == NULL:
Expand Down Expand Up @@ -1814,7 +1814,7 @@ cdef class MPolynomialRing_libsingular(MPolynomialRing_base):
cdef poly *q

if h._parent is not g._parent:
g = h._parent._coerce_c(g)
g = h._parent.coerce(g)

r = h._parent_ring
p = g._poly
Expand Down Expand Up @@ -3532,7 +3532,7 @@ cdef class MPolynomial_libsingular(MPolynomial):
p_Delete(&_p, _ring)
raise TypeError("keys do not match self's parent")
try:
v = parent._coerce_c(v)
v = parent.coerce(v)
except TypeError:
try_symbolic = 1
break
Expand Down Expand Up @@ -3568,7 +3568,7 @@ cdef class MPolynomial_libsingular(MPolynomial):
p_Delete(&_p, _ring)
raise TypeError("key does not match")
try:
v = parent._coerce_c(v)
v = parent.coerce(v)
except TypeError:
try_symbolic = 1
break
Expand Down Expand Up @@ -4537,7 +4537,7 @@ cdef class MPolynomial_libsingular(MPolynomial):
if not (isinstance(f,MPolynomial_libsingular) \
and (<MPolynomial_libsingular>f)._parent is parent):
try:
f = parent._coerce_c(f)
f = parent.coerce(f)
except TypeError as msg:
id_Delete(&fI,r)
id_Delete(&_I,r)
Expand Down Expand Up @@ -4664,7 +4664,7 @@ cdef class MPolynomial_libsingular(MPolynomial):
if not (isinstance(f,MPolynomial_libsingular) \
and (<MPolynomial_libsingular>f)._parent is parent):
try:
f = parent._coerce_c(f)
f = parent.coerce(f)
except TypeError as msg:
id_Delete(&_I,r)
raise TypeError(msg)
Expand Down Expand Up @@ -4713,7 +4713,7 @@ cdef class MPolynomial_libsingular(MPolynomial):
if not (isinstance(other,MPolynomial_libsingular) \
and (<MPolynomial_libsingular>other)._parent is parent):
try:
other = parent._coerce_c(other)
other = parent.coerce(other)
except TypeError as msg:
id_Delete(&_I,r)
raise TypeError(msg)
Expand Down Expand Up @@ -4899,7 +4899,7 @@ cdef class MPolynomial_libsingular(MPolynomial):
raise TypeError("LCM over non-integral domains not available.")

if self._parent is not g._parent:
_g = self._parent._coerce_c(g)
_g = self._parent.coerce(g)
else:
_g = <MPolynomial_libsingular>g

Expand Down Expand Up @@ -5052,9 +5052,9 @@ cdef class MPolynomial_libsingular(MPolynomial):
cdef ring *r = self._parent_ring

if not self._parent is m._parent:
m = self._parent._coerce_c(m)
m = self._parent.coerce(m)
if not self._parent is q._parent:
q = self._parent._coerce_c(q)
q = self._parent.coerce(q)

if m._poly and m._poly.next:
raise ArithmeticError("m must be a monomial.")
Expand Down Expand Up @@ -5140,9 +5140,9 @@ cdef class MPolynomial_libsingular(MPolynomial):
cdef ring *r = self._parent_ring

if not self._parent is m._parent:
m = self._parent._coerce_c(m)
m = self._parent.coerce(m)
if not self._parent is q._parent:
q = self._parent._coerce_c(q)
q = self._parent.coerce(q)

if m._poly and m._poly.next:
raise ArithmeticError("m must be a monomial.")
Expand Down Expand Up @@ -5219,7 +5219,7 @@ cdef class MPolynomial_libsingular(MPolynomial):
#TODO: very slow
n = self.parent().ngens()
if n == 0:
return codomain._coerce_(self)
return codomain.coerce(self)
y = codomain(0)
if base_map is None:
# Just use conversion
Expand Down
4 changes: 2 additions & 2 deletions src/sage/rings/polynomial/multi_polynomial_ring.py
Original file line number Diff line number Diff line change
Expand Up @@ -234,7 +234,7 @@ def __call__(self, x=0, check=True):
::
sage: parent(S2._coerce_(S.0)) is S2
sage: parent(S2.coerce(S.0)) is S2
True
Conversion to reduce modulo a prime between rings with different
Expand Down Expand Up @@ -415,7 +415,7 @@ def __call__(self, x=0, check=True):
return self({self._zero_tuple: x})

try:
y = self.base_ring()._coerce_(x)
y = self.base_ring().coerce(x)
return MPolynomial_polydict(self, {self._zero_tuple: y})
except TypeError:
pass
Expand Down
8 changes: 4 additions & 4 deletions src/sage/rings/polynomial/pbori/pbori.pyx
Original file line number Diff line number Diff line change
Expand Up @@ -2731,7 +2731,7 @@ cdef class BooleanMonomial(MonoidElement):
raise TypeError("BooleanMonomial.__add__ called with not supported types %s and %s" % (type(right), type(left)))

res = new_BP_from_PBMonom(monom._ring, monom._pbmonom)
res += monom._ring._coerce_c(other)
res += monom._ring.coerce(other)
return res

def __floordiv__(BooleanMonomial left, right):
Expand Down Expand Up @@ -3858,7 +3858,7 @@ cdef class BooleanPolynomial(MPolynomial):
"""
cdef BooleanPolynomialRing B = <BooleanPolynomialRing>self._parent
k = B._base
mon = B._coerce_c(mon)
mon = B.coerce(mon)
if mon in set(self.set()):
return k._one_element
else:
Expand Down Expand Up @@ -8161,9 +8161,9 @@ cdef class PolynomialFactory:
elif isinstance(arg, BooleSet):
return (<BooleSet>arg)._ring._element_constructor_(arg)
elif isinstance(arg, BooleanMonomial):
return (<BooleanMonomial>arg)._ring._coerce_(arg)
return (<BooleanMonomial>arg)._ring.coerce(arg)
elif isinstance(ring, BooleanPolynomialRing):
return (<BooleanPolynomialRing>ring)._coerce_(arg)
return (<BooleanPolynomialRing>ring).coerce(arg)
else:
if isinstance(arg, int) or isinstance(arg, Integer):
return new_BP_from_PBPoly(self._ring,
Expand Down
Loading

0 comments on commit 9398d92

Please sign in to comment.