@@ -557,25 +557,22 @@ cdef class MPolynomialRing_base(CommutativeRing):
557557 else :
558558 return self ._generic_coerce_map(self .base_ring())
559559
560- cdef _coerce_c_impl (self , x ):
560+ cpdef _coerce_map_from_ (self , other ):
561561 """
562- Return the canonical coercion of x to this multivariate
563- polynomial ring, if one is defined, or raise a :exc:`TypeError` .
562+ Return whether there is canonical coercion map
563+ from the ring ``other`` to this multivariate polynomial ring .
564564
565565 The rings that canonically coerce to this polynomial ring are:
566566
567567 - this ring itself
568- - polynomial rings in the same variables over any base ring that
569- canonically coerces to the base ring of this ring
570568 - polynomial rings in a subset of the variables over any base ring that
571569 canonically coerces to the base ring of this ring
572570 - any ring that canonically coerces to the base ring of this polynomial
573571 ring.
574572
575573 TESTS:
576574
577- This fairly complicated code (from Michel Vandenbergh) ends up
578- implicitly calling ``_coerce_c_impl``::
575+ Fairly complicated code (from Michel Vandenbergh)::
579576
580577 sage: # needs sage.rings.number_field
581578 sage: z = polygen(QQ, 'z')
@@ -588,27 +585,39 @@ cdef class MPolynomialRing_base(CommutativeRing):
588585 sage: x + 1/u
589586 x + 1/u
590587 """
591- try :
592- P = x.parent()
593- # polynomial rings in the same variable over the any base
594- # that coerces in:
595- if isinstance (P, MPolynomialRing_base):
596- if P.variable_names() == self .variable_names():
597- if self .has_coerce_map_from(P.base_ring()):
598- return self (x)
599- elif self .base_ring().has_coerce_map_from(P._mpoly_base_ring(self .variable_names())):
600- return self (x)
601-
602- elif isinstance (P, polynomial_ring.PolynomialRing_generic):
603- if P.variable_name() in self .variable_names():
604- if self .has_coerce_map_from(P.base_ring()):
605- return self (x)
606-
607- except AttributeError :
608- pass
609-
610- # any ring that coerces to the base ring of this polynomial ring.
611- return self (self .base_ring().coerce(x))
588+ base_ring = self .base_ring()
589+ if other is base_ring:
590+ # Because this parent class is a Cython class, the method
591+ # UnitalAlgebras.ParentMethods.__init_extra__(), which normally
592+ # registers the coercion map from the base ring, is called only
593+ # when inheriting from this class in Python (cf. Issue #26958).
594+ return self ._coerce_map_from_base_ring()
595+ f = self ._coerce_map_via([base_ring], other)
596+ if f is not None :
597+ return f
598+
599+ # polynomial rings in a subset of variables
600+ # over the any base that coerces in
601+ if isinstance (other, MPolynomialRing_base):
602+ if self is other:
603+ return True
604+ n = other.ngens()
605+ check = (self .ngens() >= n and
606+ self .variable_names()[:n] == other.variable_names())
607+ if other.base_ring is base_ring and check:
608+ return True
609+ elif base_ring.has_coerce_map_from(other._mpoly_base_ring(self .variable_names())):
610+ return True
611+
612+ # polynomial rings in one of the variables
613+ # over the any base that coerces in
614+ elif isinstance (other, polynomial_ring.PolynomialRing_generic):
615+ if other.variable_name() in self .variable_names():
616+ if self .has_coerce_map_from(other.base_ring()):
617+ return True
618+
619+ # any ring that coerces to the base ring of this polynomial ring
620+ return self .base_ring().has_coerce_map_from(other)
612621
613622 def _extract_polydict (self , x ):
614623 """
0 commit comments