Ticket #3738: 3738-8-old_check.patch

File 3738-8-old_check.patch, 29.2 KB (added by robertwb, 11 years ago)
  • sage/structure/category_object.pyx

    # HG changeset patch
    # User Robert Bradshaw <robertwb@math.washington.edu>
    # Date 1217319881 25200
    # Node ID 3ba63f57189230558dedfc66eff7768b21f9923f
    # Parent  9663e88234e73ec47718ba6706467c718198e190
    Disable all old coercion mechanisms on Parents that have _element_constructor set.
    
    This allows one to use the new coercion model while inheriting from the old Parent
    (useful so, for instance, we don't need to conver the whole Rings hierarchy at once.
    
    diff -r 9663e88234e7 -r 3ba63f571892 sage/structure/category_object.pyx
    a b cdef class CategoryObject(sage_object.Sa 
    391391#        except AttributeError:
    392392#            raise TypeError, "base extension not defined for %s" % self
    393393           
     394    # COERCE TODO: When everything has a category, move let it be an optional arg.
    394395    def base_ring(self):
    395         # COERCE TODO: When everything has a category, move this to the category level.
     396        return self._base
     397       
     398    def base(self):
    396399        return self._base
    397400       
    398401    #################################################################################################
  • sage/structure/parent.pyx

    diff -r 9663e88234e7 -r 3ba63f571892 sage/structure/parent.pyx
    a b cdef class Parent(category_object.Catego 
    312312            if self._list is not None:
    313313                return self._list
    314314        except AttributeError:
    315             try:
    316                 self._list = list(self.__iter__())
    317                 return self._list
    318             except AttributeError:
    319                 return list(self.__iter__())
     315            pass
     316        the_list = list(self.__iter__())
     317        try:
     318            self._list = the_list
     319        except AttributeError:
     320            pass
     321        return the_list
    320322               
    321323    def __nonzero__(self):
    322324        return True
    cdef class Parent(category_object.Catego 
    344346       is raised.
    345347       """
    346348       raise NotImplementedError, "Verification of correctness of homomorphisms from %s not yet implmented."%self
     349
     350    def Hom(self, codomain, cat=None):
     351        r"""
     352        self.Hom(codomain, cat=None):
     353       
     354        Return the homspace \code{Hom(self, codomain, cat)} of all
     355        homomorphisms from self to codomain in the category cat.  The
     356        default category is \code{self.category()}.
     357
     358        EXAMPLES:
     359            sage: R.<x,y> = PolynomialRing(QQ, 2)
     360            sage: R.Hom(QQ)
     361            Set of Homomorphisms from Multivariate Polynomial Ring in x, y over Rational Field to Rational Field
     362
     363        Homspaces are defined for very general \sage objects, even elements of familiar rings.
     364            sage: n = 5; Hom(n,7)
     365            Set of Morphisms from 5 to 7 in Category of elements of Integer Ring
     366            sage: z=(2/3); Hom(z,8/1)
     367            Set of Morphisms from 2/3 to 8 in Category of elements of Rational Field
     368
     369        This example illustrates the optional third argument:
     370            sage: QQ.Hom(ZZ, Sets())
     371            Set of Morphisms from Rational Field to Integer Ring in Category of sets
     372        """
     373        try:
     374            return self._Hom_(codomain, cat)
     375        except (TypeError, AttributeError):
     376            pass
     377        from sage.categories.all import Hom
     378        return Hom(self, codomain, cat)
    347379
    348380    def hom(self, im_gens, codomain=None, check=None):
    349381       r"""
    cdef class Parent(category_object.Catego 
    888920        return None
    889921
    890922    cpdef an_element(self):
     923        r"""
     924        Implementation of a function that returns an element (often non-trivial)
     925        of a parent object.  This is cached. Parent structures that are should
     926        override \code{_an_element_} instead.
     927        """
    891928        if self.__an_element is None:
    892             self.__an_element = self._an_element_impl()
     929            self.__an_element = self._an_element_()
    893930        return self.__an_element
    894931       
    895932    cpdef _an_element_impl(self):
  • sage/structure/parent_base.pyx

    diff -r 9663e88234e7 -r 3ba63f571892 sage/structure/parent_base.pyx
    a b  
    77###############################################################################
    88
    99include "../ext/stdsage.pxi"
     10
     11cimport parent
     12
     13cdef inline check_old_coerce(parent.Parent p):
     14    if p._element_constructor is not None:
     15        raise RuntimeError, "%s still using old coercion framework" % p
     16
    1017
    1118# TODO: Unpickled parents with base sometimes have thier base set to None.
    1219# This causes a segfault in the module arithmetic architecture.
    cdef class ParentWithBase(parent_old.Par 
    4956        self._base = base
    5057       
    5158    def _richcmp(left, right, int op):
     59        check_old_coerce(left)
    5260        return (<parent_old.Parent>left)._richcmp(right, op) # the cdef method
    5361
    5462       
    5563    cdef _coerce_c_impl(self,x):
     64       check_old_coerce(self)
    5665       if not self._base is self:
    5766           return self._coerce_try(x,(self._base))
    5867       else:
    cdef class ParentWithBase(parent_old.Par 
    6877##         else:
    6978##             return (make_parent_with_base_v0, (self.__class__, _dict, self._base, self._has_coerce_map_from))
    7079
    71     def base_ring(self):
    72         return self._base
    73 
    7480    # Derived class *must* define base_extend.
    7581    def base_extend(self, X):
     82        check_old_coerce(self)
    7683        raise TypeError, "BUG: the base_extend method must be defined for '%s' (class '%s')"%(
    7784            self, type(self))
    78 
    79     def base(self):
    80         return self._base
    8185
    8286    # Canonical base extension by X (recursive)
    8387    def base_extend_canonical(self, X):
    cdef class ParentWithBase(parent_old.Par 
    8690        NOTE: this function should not be extended.
    8791        AUTHOR: Gonzalo Tornaria (2007-06-20)
    8892        """
     93        check_old_coerce(self)
    8994        return  self.base_extend_canonical_c(X)
    9095
    9196    # Canonical base extension by X (recursive)
    cdef class ParentWithBase(parent_old.Par 
    238243
    239244
    240245        """
     246        check_old_coerce(self)
    241247        #cdef special(t):
    242248        #    return PY_TYPE_CHECK(self, t) and not PY_TYPE_CHECK(X, t)
    243249        #
    cdef class ParentWithBase(parent_old.Par 
    271277        NOTE: this function should not be extended.
    272278        AUTHOR: Gonzalo Tornaria (2007-06-20)
    273279        """
     280        check_old_coerce(self)
    274281        return  self.base_extend_canonical_sym_c(X)
    275282
    276283    cdef base_extend_canonical_sym_c(self, ParentWithBase X):
     284        check_old_coerce(self)
    277285        from sage.matrix.matrix_space import MatrixSpace_generic
    278286        from sage.modules.free_module import FreeModule_generic
    279287
    cdef class ParentWithBase(parent_old.Par 
    312320        NOTE: this function should not be extended.
    313321        AUTHOR: Gonzalo Tornaria (2007-06-20)
    314322        """
     323        check_old_coerce(self)
    315324        return  self.base_extend_recursive_c(X)
    316325
    317326    # Not sure if this function is ready to use. It should work fine in the non-ambiguous case,
    cdef class ParentWithBase(parent_old.Par 
    320329        """
    321330        AUTHOR: Gonzalo Tornaria (2007-06-20)
    322331        """
     332        check_old_coerce(self)
    323333        if X.has_coerce_map_from(self):
    324334            return X
    325335        B = self._base_extend_canonical_rec(X)
    cdef class ParentWithBase(parent_old.Par 
    332342        """
    333343        AUTHOR: Gonzalo Tornaria (2007-06-20)
    334344        """
     345        check_old_coerce(self)
    335346        cdef ParentWithBase self_b
    336347        self_b = self._base
    337348        if self_b is self or self_b is None:
    cdef class ParentWithBase(parent_old.Par 
    384395            sage: QQ.Hom(ZZ, Sets())
    385396            Set of Morphisms from Rational Field to Integer Ring in Category of sets
    386397        """
     398        if self._element_constructor is None:
     399            return parent.Parent.Hom(self, codomain, cat)
    387400        try:
    388401            return self._Hom_(codomain, cat)
    389402        except (TypeError, AttributeError):
  • sage/structure/parent_gens.pxd

    diff -r 9663e88234e7 -r 3ba63f571892 sage/structure/parent_gens.pxd
    a b cdef class ParentWithGens(parent_base.Pa 
    1515cdef class ParentWithGens(parent_base.ParentWithBase):
    1616    cdef public object _gens
    1717    cdef public object _gens_dict
    18     cdef public object _names
    1918    cdef public object _latex_names
    2019    cdef public object _list
    2120
  • sage/structure/parent_gens.pyx

    diff -r 9663e88234e7 -r 3ba63f571892 sage/structure/parent_gens.pyx
    a b import sage.misc.defaults 
    5959import sage.misc.defaults
    6060from sage.misc.latex import latex_variable_name
    6161import gens_py
    62 import parent
     62cimport parent
    6363
    6464include '../ext/stdsage.pxi'
     65
     66cdef inline check_old_coerce(parent.Parent p):
     67    if p._element_constructor is not None:
     68        raise RuntimeError, "%s still using old coercion framework" % p
    6569
    6670def is_ParentWithGens(x):
    6771    """
    cdef class ParentWithGens(parent_base.Pa 
    197201
    198202    # First n generators, for n <= ngens:
    199203    def _first_ngens(self, n):
     204        check_old_coerce(self)
    200205        v = self.gens()
    201206        return v[:n]
    202207
    203208    # Derived class *must* define ngens method.
    204209    def ngens(self):
     210        check_old_coerce(self)
    205211        raise NotImplementedError, "Number of generators not known."
    206212
    207213    # Derived class *must* define gen method.
    208214    def gen(self, i=0):
     215        check_old_coerce(self)
    209216        raise NotImplementedError, "i-th generator not known."
    210217           
    211     def __getitem__(self, n):
    212         return self.list()[n]
    213 
    214     def __getslice__(self,  Py_ssize_t n,  Py_ssize_t m):
    215         return self.list()[int(n):int(m)]
    216 
    217     def __len__(self):
    218         return len(self.list())
    219 
    220     def list(self):
    221         """
    222         Return a list of all elements in this object, if possible (the
    223         object must define an iterator).
    224         """
    225         if self._list != None:
    226             return list(self._list)
    227         else:
    228             self._list = list(self.__iter__())
    229         return list(self._list)
    230 
    231     def objgens(self):
    232         """
    233         Return self and the generators of self as a tuple.
    234 
    235         INPUT:
    236             names -- tuple or string
    237 
    238         OUTPUT:
    239             self  -- this object
    240             tuple -- self.gens()
    241        
    242         EXAMPLES:
    243             sage: R, vars = PolynomialRing(QQ,3, 'x').objgens()
    244             sage: R
    245             Multivariate Polynomial Ring in x0, x1, x2 over Rational Field
    246             sage: vars
    247             (x0, x1, x2)
    248         """
    249         return self, self.gens()
    250 
    251     def objgen(self):
    252         """
    253         Return self and the generator of self.
    254 
    255         INPUT:
    256             names -- tuple or string
    257 
    258         OUTPUT:
    259             self  -- this object
    260             an object -- self.gen()
    261        
    262         EXAMPLES:
    263             sage: R, x = PolynomialRing(QQ,'x').objgen()
    264             sage: R
    265             Univariate Polynomial Ring in x over Rational Field
    266             sage: x
    267             x
    268         """
    269         return self, self.gen()
    270 
    271218    def gens(self):
    272219       """
    273220       Return a tuple whose entries are the generators for this
    274221       object, in order.
    275222       """
     223       check_old_coerce(self)
    276224       cdef int i, n
    277225       if self._gens != None:
    278226           return self._gens
    cdef class ParentWithGens(parent_base.Pa 
    288236        r"""
    289237        Return a dictionary whose entries are \code{{var_name:variable,...}}.
    290238        """
     239        if self._element_constructor is not None:
     240            return parent.Parent.gens_dict(self)
    291241        if self._gens_dict != None:
    292242            return self._gens_dict
    293243        else:
    cdef class ParentWithGens(parent_base.Pa 
    319269            ...
    320270            ValueError: variable names cannot be changed after object creation.       
    321271        """
     272        if self._element_constructor is not None:
     273            parent.Parent._assign_names(self, names=None, normalize=True)
     274            return
    322275        if names is None: return
    323276        if normalize:
    324277            names = normalize_names(self.ngens(), names)
    cdef class ParentWithGens(parent_base.Pa 
    328281            names = (names, )  # make it a tuple
    329282        elif not PY_TYPE_CHECK(names, tuple):
    330283            raise TypeError, "names must be a tuple of strings"
    331         self._names = names
    332            
    333     def inject_variables(self, scope=None, verbose=True):
    334         """
    335         Inject the generators of self with their names into the
    336         namespace of the Python code from which this function is
    337         called.  Thus, e.g., if the generators of self are labeled
    338         'a', 'b', and 'c', then after calling this method the
    339         variables a, b, and c in the current scope will be set
    340         equal to the generators of self.
    341 
    342         NOTE: If Foo is a constructor for a SAGE object with
    343         generators, and Foo is defined in Pyrex, then it would
    344         typically call inject_variables() on the object it
    345         creates.  E.g., PolyomialRing(QQ, 'y') does this so that the
    346         variable y is the generator of the polynomial ring.
    347         """
    348         v = self.variable_names()
    349         g = self.gens()
    350         if scope is None:
    351             scope = globals()
    352         if verbose:
    353             print "Defining %s"%(', '.join(v))
    354         cdef int i
    355         for i from 0 <= i < len(v):
    356             scope[v[i]] = g[i]
    357 
    358     def injvar(self, scope=None, verbose=True):
    359         """
    360         This is a synonym for self.inject_variables(...)
    361         <<<sage.structure.parent_gens.ParentWithGens.inject_variables>>>
    362         """
    363         return self.inject_variables(scope=scope, verbose=verbose)
    364        
     284        self._names = names       
    365285
    366286    def __temporarily_change_names(self, names, latex_names):
    367287        """
    368288        This is used by the variable names context manager.
    369289        """
     290        check_old_coerce(self)
    370291        old = self._names, self._latex_names
    371292        (self._names, self._latex_names) = names, latex_names
    372293        return old
    373 
    374     def variable_names(self):
    375         if self._names != None:
    376             return self._names
    377         raise ValueError, "variable names have not yet been set using self._assign_names(...)"
    378 
    379     def latex_variable_names(self):
    380         """
    381         Returns the list of variable names suitable for latex output.
    382 
    383         All '_SOMETHING' substrings are replaced by '_{SOMETHING}' recursively
    384         so that subscripts of subscripts work.
    385 
    386         EXAMPLES:
    387             sage: R, x = PolynomialRing(QQ,'x',12).objgens()
    388             sage: x
    389             (x0, x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11)
    390             sage: print R.latex_variable_names ()
    391             ['x_{0}', 'x_{1}', 'x_{2}', 'x_{3}', 'x_{4}', 'x_{5}', 'x_{6}', 'x_{7}', 'x_{8}', 'x_{9}', 'x_{10}', 'x_{11}']
    392             sage: f = x[0]^3 + 15/3 * x[1]^10
    393             sage: print latex(f)
    394             5 x_{1}^{10} + x_{0}^{3}
    395         """
    396         if self._latex_names != None:
    397             return self._latex_names
    398         # Compute the latex versions of the variable names.
    399         self._latex_names = [latex_variable_name(x) for x in self.variable_names()]
    400         return self._latex_names
    401 
    402     def variable_name(self):
    403         return self.variable_names()[0]
    404 
    405     def latex_name(self):
    406         return self.variable_name()
    407294
    408295    #################################################################################
    409296    # Give all objects with generators a dictionary, so that attribute setting
    cdef class ParentWithGens(parent_base.Pa 
    411298    # i.e., just define __dict__ as an attribute and all this code gets generated.
    412299    #################################################################################
    413300    def __getstate__(self):
     301        if self._element_constructor is not None:
     302            return parent.Parent.__getstate__(self)
    414303        d = []
    415304        try:
    416305            d = list(self.__dict__.copy().iteritems()) # so we can add elements
    cdef class ParentWithGens(parent_base.Pa 
    431320        return d
    432321
    433322    def __setstate__(self,d):
     323        if self._element_constructor is not None:
     324            return parent.Parent.__setstate__(self)
    434325        try:
    435326            self.__dict__ = d
    436327            self._generator_orders = d['_generator_orders']
    cdef class ParentWithGens(parent_base.Pa 
    447338    #################################################################################
    448339    # Morphisms of objects with generators
    449340    #################################################################################
    450 
    451     def _is_valid_homomorphism_(self, codomain, im_gens):
    452         r"""
    453         Return True if \code{im_gens} defines a valid homomorphism
    454         from self to codomain; otherwise return False.
    455 
    456         If determining whether or not a homomorphism is valid has not
    457         been implemented for this ring, then a NotImplementedError exception
    458         is raised.
    459         """
    460         raise NotImplementedError, "Verification of correctness of homomorphisms from %s not yet implmented."%self
    461341
    462342    def hom(self, im_gens, codomain=None, check=True):
    463343        r"""
    cdef class ParentWithGens(parent_base.Pa 
    521401            ...
    522402            TypeError: Natural coercion morphism from Rational Field to Integer Ring not defined.
    523403        """
     404        if self._element_constructor is not None:
     405            return parent.Parent.hom(self, im_gens, codomain, check)
    524406        if isinstance(im_gens, parent.Parent):
    525407            return self.Hom(im_gens).natural_map()
    526408        if codomain is None:
    cdef class ParentWithGens(parent_base.Pa 
    532414
    533415cdef class ParentWithMultiplicativeAbelianGens(ParentWithGens):
    534416    def generator_orders(self):
     417        check_old_coerce(self)
    535418        if self._generator_orders != None:
    536419            return self._generator_orders
    537420        else:
    cdef class ParentWithMultiplicativeAbeli 
    551434   
    552435cdef class ParentWithAdditiveAbelianGens(ParentWithGens):
    553436    def generator_orders(self):
     437        check_old_coerce(self)
    554438        if self._generator_orders != None:
    555439            return self._generator_orders
    556440        else:
  • sage/structure/parent_old.pyx

    diff -r 9663e88234e7 -r 3ba63f571892 sage/structure/parent_old.pyx
    a b def is_Parent(x): 
    4545        True   
    4646    """
    4747    return PyBool_FromLong(PyObject_TypeCheck(x, Parent))
     48   
     49cdef inline check_old_coerce(Parent p):
     50    if p._element_constructor is not None:
     51        raise RuntimeError, "%s still using old coercion framework" % p
    4852
    4953
    5054## def make_parent_v0(_class, _dict, has_coerce_map_from):
    cdef class Parent(parent.Parent): 
    9498            self._action_hash = {}
    9599
    96100       
    97     #############################################################################
    98     # Containment testing
    99     #############################################################################
    100     def __contains__(self, x):
    101         r"""
    102         True if there is an element of self that is equal to x under ==.
    103 
    104         For many structures we test this by using \code{__call__} and
    105         then testing equality between x and the result.
    106        
    107         EXAMPLES:
    108             sage: 2 in Integers(7)
    109             True
    110             sage: 2 in ZZ
    111             True
    112             sage: Integers(7)(3) in ZZ
    113             True
    114             sage: 3/1 in ZZ
    115             True
    116             sage: 5 in QQ
    117             True
    118             sage: I in RR
    119             False
    120             sage: SR(2) in ZZ
    121             True
    122         """
    123         try:
    124             x2 = self(x)
    125             return bool(x2 == x)
    126         except TypeError:
    127             return False
    128    
    129 
    130101    #################################################################################
    131102    # New Coercion support functionality
    132103    #################################################################################
    cdef class Parent(parent.Parent): 
    135106#        return self.coerce_map_from_c(S)
    136107   
    137108    cpdef coerce_map_from_c(self, S):
     109        check_old_coerce(self)
    138110        if S is self:
    139111            from sage.categories.homset import Hom
    140112            return Hom(self, self).identity()
    cdef class Parent(parent.Parent): 
    170142        return mor
    171143       
    172144    def coerce_map_from_impl(self, S):
     145        check_old_coerce(self)
    173146        return self.coerce_map_from_c_impl(S)
    174147           
    175148    cdef coerce_map_from_c_impl(self, S):
     149        check_old_coerce(self)
    176150        import sage.categories.morphism
    177151        from sage.categories.map import Map
    178152        from sage.categories.homset import Hom
    cdef class Parent(parent.Parent): 
    205179#        return self.get_action_c(S, op, self_on_left)
    206180       
    207181    cpdef get_action_c(self, S, op, bint self_on_left):
     182        check_old_coerce(self)
    208183        try:
    209184            if self._action_hash is None: # this is because parent.__init__() does not always get called
    210185                self.init_coerce()
    cdef class Parent(parent.Parent): 
    223198        return action
    224199       
    225200    def get_action_impl(self, S, op, self_on_left):
     201        check_old_coerce(self)
    226202        return self.get_action_c_impl(S, op, self_on_left)
    227203           
    228204    cdef get_action_c_impl(self, S, op, bint self_on_left):
     205        check_old_coerce(self)
    229206        # G acts on S, G -> G', R -> S => G' acts on R (?)
    230207        from sage.categories.action import Action, PrecomposedAction
    231208        from sage.categories.homset import Hom
    cdef class Parent(parent.Parent): 
    337314#            print "found nothing"
    338315               
    339316
    340     def construction(self):
    341         """
    342         Returns a pair (functor, parent) such that functor(parent) return self.
    343         If this ring does not have a functorial construction, return None.
    344         """
    345         return None
    346 
    347317    #################################################################################
    348318    # Coercion support functionality
    349319    #################################################################################
    350320   
    351321    def _coerce_(self, x):            # Call this from Python (do not override!)
     322        check_old_coerce(self)
    352323        return self._coerce_c(x)
    353324   
    354325    cpdef _coerce_c(self, x):          # DO NOT OVERRIDE THIS (call it)
     326        check_old_coerce(self)
    355327        try:
    356328            P = x.parent()   # todo -- optimize
    357329            if P is self:
    cdef class Parent(parent.Parent): 
    368340        Canonically coerce x in assuming that the parent of x is not
    369341        equal to self.
    370342        """
     343        check_old_coerce(self)
    371344        raise TypeError       
    372345
    373346    def _coerce_impl(self, x):        # OVERRIDE THIS FOR PYTHON CLASSES
    cdef class Parent(parent.Parent): 
    375348        Canonically coerce x in assuming that the parent of x is not
    376349        equal to self.
    377350        """
     351        check_old_coerce(self)
    378352        return self._coerce_c_impl(x)
    379353
    380354    def _coerce_try(self, x, v):
    cdef class Parent(parent.Parent): 
    388362             x -- Python object
    389363             v -- parent object or list (iterator) of parent objects
    390364        """
     365        check_old_coerce(self)
    391366        if not isinstance(v, list):
    392367            v = [v]
    393368
    cdef class Parent(parent.Parent): 
    400375        raise TypeError, "no canonical coercion of element into self"
    401376
    402377    def _coerce_self(self, x):
     378        check_old_coerce(self)
    403379        return self._coerce_self_c(x)
    404380
    405381    cdef _coerce_self_c(self, x):
    cdef class Parent(parent.Parent): 
    407383        Try to canonically coerce x into self.
    408384        Return result on success or raise TypeError on failure.
    409385        """
     386        check_old_coerce(self)
    410387        # todo -- optimize?
    411388        try:
    412389            P = x.parent()
    cdef class Parent(parent.Parent): 
    426403        Return True if there is a natural map from S to self.
    427404        Otherwise, return False.
    428405        """
     406        check_old_coerce(self)
    429407        if self == S:
    430408            return True
    431409        if self._has_coerce_map_from is None:
    cdef class Parent(parent.Parent): 
    443421        return x
    444422
    445423    def has_coerce_map_from_impl(self, S):
     424        check_old_coerce(self)
    446425        return self.has_coerce_map_from_c_impl(S)
    447426
    448427    cdef has_coerce_map_from_c_impl(self, S):
     428        check_old_coerce(self)
    449429        if not PY_TYPE_CHECK(S, parent.Parent):
    450430            return False
    451431        try:
    cdef class Parent(parent.Parent): 
    457437        return True
    458438
    459439    cpdef _an_element_impl(self):     # override this in Python
    460         r"""
    461         Implementation of a function that returns an element (often non-trivial)
    462         of a parent object.  Every parent object should implement it,
    463         unless the default implementation works.
    464 
    465         NOTE: Parent structures that are implemented in SageX should
    466         implement \code{_an_element_c_impl} instead.
    467         """
     440        check_old_coerce(self)
    468441        return self._an_element_c_impl()
    469442
    470443    cpdef _an_element_c_impl(self):  # override this in SageX
    cdef class Parent(parent.Parent): 
    473446        that poorly-written functions won't work when they're not
    474447        supposed to. This is cached so doesn't have to be super fast.
    475448        """
     449        check_old_coerce(self)
    476450        try:
    477451            return self.gen(0)
    478452        except:
    cdef class Parent(parent.Parent): 
    493467        raise NotImplementedError, "please implement _an_element_c_impl or _an_element_impl for %s"%self
    494468
    495469    def _an_element(self):        # do not override this (call from Python)
     470        check_old_coerce(self)
    496471        return self._an_element_c()
    497472       
    498473    cpdef _an_element_c(self):     # do not override this (call from SageX)
     474        check_old_coerce(self)
    499475        if not self.__an_element is None:
    500476            return self.__an_element
    501477        if HAS_DICTIONARY(self):
    cdef class Parent(parent.Parent): 
    512488        """
    513489        Compare left and right.
    514490        """
     491        check_old_coerce(left)
    515492        cdef int r
    516493
    517494        if not PY_TYPE_CHECK(right, parent.Parent) or not PY_TYPE_CHECK(left, parent.Parent):
    cdef class Parent(parent.Parent): 
    563540##         return (make_parent_v0, (self.__class__, _dict, self._has_coerce_map_from))
    564541
    565542    cdef int _cmp_c_impl(left, parent.Parent right) except -2:
     543        check_old_coerce(left)
    566544        pass
    567545        # this would be nice to do, but we can't since
    568546        # it leads to infinite recurssions -- and is slow -- and this
    cdef class Parent(parent.Parent): 
    583561
    584562
    585563    ############################################################################
    586     # Homomorphism --
    587     ############################################################################
    588     def Hom(self, codomain, cat=None):
    589         r"""
    590         self.Hom(codomain, cat=None):
    591        
    592         Return the homspace \code{Hom(self, codomain, cat)} of all
    593         homomorphisms from self to codomain in the category cat.  The
    594         default category is \code{self.category()}.
    595 
    596         EXAMPLES:
    597             sage: R.<x,y> = PolynomialRing(QQ, 2)
    598             sage: R.Hom(QQ)
    599             Set of Homomorphisms from Multivariate Polynomial Ring in x, y over Rational Field to Rational Field
    600 
    601         Homspaces are defined for very general \sage objects, even elements of familiar rings.
    602             sage: n = 5; Hom(n,7)
    603             Set of Morphisms from 5 to 7 in Category of elements of Integer Ring
    604             sage: z=(2/3); Hom(z,8/1)
    605             Set of Morphisms from 2/3 to 8 in Category of elements of Rational Field
    606 
    607         This example illustrates the optional third argument:
    608             sage: QQ.Hom(ZZ, Sets())
    609             Set of Morphisms from Rational Field to Integer Ring in Category of sets
    610         """
    611         try:
    612             return self._Hom_(codomain, cat)
    613         except (TypeError, AttributeError):
    614             pass
    615         from sage.categories.all import Hom
    616         return Hom(self, codomain, cat)
    617 
    618     ############################################################################
    619564    # Coercion Compatibility Layer
    620565    ############################################################################
    621566
    622567    cpdef _coerce_map_from_(self, S):
    623         return self.coerce_map_from_c(S)
     568        if self._element_constructor is None:
     569            return self.coerce_map_from_c(S)
     570        else:
     571            return None
    624572   
    625573    cpdef _get_action_(self, other, op, bint self_on_left):
    626         return self.get_action_c(other, op, self_on_left)
     574        if self._element_constructor is None:
     575            return self.get_action_c(other, op, self_on_left)
     576        else:
     577            return None
    627578   
    628579    cpdef _an_element_(self):
    629         return self._an_element_c()
     580        if self._element_constructor is None:
     581            return self._an_element_c()
     582        else:
     583            return parent.Parent._an_element_(self)
    630584       
    631585    cpdef _generic_convert_map(self, S):
    632586        if self._element_constructor is None:
    cdef class Parent(parent.Parent): 
    636590        else:
    637591            return parent.Parent._generic_convert_map(self, S)
    638592       
    639 
    640593
    641594############################################################################
    642595# Set baseclass --