@@ -571,25 +571,28 @@ cdef class MPolynomialRing_base(CommutativeRing):
571571 else :
572572 return self ._generic_coerce_map(self .base_ring())
573573
574- cdef _coerce_c_impl (self , x ):
574+ cpdef _coerce_map_from_ (self , other ):
575575 """
576- Return the canonical coercion of x to this multivariate
577- polynomial ring, if one is defined, or raise a :exc:`TypeError `.
576+ Return whether there is canonical coercion map
577+ from the ring ``other`` to this multivariate polynomial ring `R `.
578578
579- The rings that canonically coerce to this polynomial ring are:
579+ The rings that canonically coerce to the polynomial ring `R` are:
580580
581- - this ring itself
582- - polynomial rings in the same variables over any base ring that
583- canonically coerces to the base ring of this ring
584- - polynomial rings in a subset of the variables over any base ring that
585- canonically coerces to the base ring of this ring
586- - any ring that canonically coerces to the base ring of this polynomial
587- ring.
581+ - the ring `R` itself,
582+
583+ - the base ring of `R`,
584+
585+ - any ring that canonically coerces to the base ring of `R`.
586+
587+ - polynomial rings in an initial subset of the variables of `R`
588+ over any base ring that canonically coerces to the base ring of `R`,
589+
590+ - polynomial rings in one of the variables of `R`
591+ over any base ring that canonically coerces to the base ring of `R`,
588592
589593 TESTS:
590594
591- This fairly complicated code (from Michel Vandenbergh) ends up
592- implicitly calling ``_coerce_c_impl``::
595+ Fairly complicated code (from Michel Vandenbergh)::
593596
594597 sage: # needs sage.rings.number_field
595598 sage: z = polygen(QQ, 'z')
@@ -602,27 +605,40 @@ cdef class MPolynomialRing_base(CommutativeRing):
602605 sage: x + 1/u
603606 x + 1/u
604607 """
605- try :
606- P = x.parent()
607- # polynomial rings in the same variable over the any base
608- # that coerces in:
609- if isinstance (P, MPolynomialRing_base):
610- if P.variable_names() == self .variable_names():
611- if self .has_coerce_map_from(P.base_ring()):
612- return self (x)
613- elif self .base_ring().has_coerce_map_from(P._mpoly_base_ring(self .variable_names())):
614- return self (x)
615-
616- elif isinstance (P, polynomial_ring.PolynomialRing_generic):
617- if P.variable_name() in self .variable_names():
618- if self .has_coerce_map_from(P.base_ring()):
619- return self (x)
620-
621- except AttributeError :
622- pass
623-
624- # any ring that coerces to the base ring of this polynomial ring.
625- return self (self .base_ring().coerce(x))
608+ base_ring = self .base_ring()
609+ if other is base_ring:
610+ # Because this parent class is a Cython class, the method
611+ # UnitalAlgebras.ParentMethods.__init_extra__(), which normally
612+ # registers the coercion map from the base ring, is called only
613+ # when inheriting from this class in Python (cf. Issue #26958).
614+ return self ._coerce_map_from_base_ring()
615+
616+ f = self ._coerce_map_via([base_ring], other)
617+ if f is not None :
618+ return f
619+
620+ # polynomial rings in an initial subset of variables
621+ # over the any base that coerces in
622+ if isinstance (other, MPolynomialRing_base):
623+ if self is other:
624+ return True
625+ n = other.ngens()
626+ check = (self .ngens() >= n and
627+ self .variable_names()[:n] == other.variable_names())
628+ if other.base_ring is base_ring and check:
629+ return True
630+ elif base_ring.has_coerce_map_from(other._mpoly_base_ring(self .variable_names())):
631+ return True
632+
633+ # polynomial rings in one of the variables
634+ # over the any base that coerces in
635+ elif isinstance (other, polynomial_ring.PolynomialRing_generic):
636+ if other.variable_name() in self .variable_names():
637+ if self .has_coerce_map_from(other.base_ring()):
638+ return True
639+
640+ # any ring that coerces to the base ring of this polynomial ring
641+ return self .base_ring().has_coerce_map_from(other)
626642
627643 def _extract_polydict (self , x ):
628644 """
0 commit comments