Ticket #12876: trac_12876_category-fix_abstract_class-nt-rel11521.patch

File trac_12876_category-fix_abstract_class-nt-rel11521.patch, 34.8 KB (added by SimonKing, 8 years ago)

Nicolas' patch rebased rel #11521

  • sage/categories/hecke_modules.py

    # HG changeset patch
    # User Nicolas M. Thiery <nthiery@users.sf.net>
    # Date 1335304627 -7200
    # Node ID 6b56202511e0e1ac53d24fca5aa438ded5af5948
    # Parent  4d6f4c44ce7cf94beedf64a6c9487c472a142a56
    #12876: Fix element and parent classes of Hom categories to be abstract, and simplify the Hom logic
    
    Rebased relative #11521
    This patch fixes the parent and element classes for Hom categories to
    be purely abstract, and simplifies the Hom logic:
    
    - Unified the logic for selecting the class when building a Homset
      (e.g. Homset, RingHomset, HeckeModuleHomspace, ...). This is now
      systematically done through the _Hom_ hook. The logic still has a
      fundamental flaw, but that's for the later #10668.
    - The cache for Hom is handled at a single point in Hom
      In particular, homsets created via the _Hom_ hook are now unique.
    - If category is None, Hom simply calls itself with the meet of the
      categories of the parent, which removes a cache handling duplication.
    - Parent.Hom calls  Hom directly (removes duplicate _Hom_ logic).
    - ParentWithBase.Hom was redundant and is gone.
    - Reduce the footprint of the current trick to delegate
      Hom(F,F)(on_basis=...) to module_morphism, allow for the diagonal
      option too, an make sure the homset category is set properly.
    - Update a doctest in sage.modules.vector_space_homspace to take into
      account that homsets created via _Hom_ are now unique.
    - Scheme is (apparently) an abstract base class; so it should not be
      instantiated. I changed some doctests in
      sage.schemes.generic.SchemeMorphism to use instead the concrete
      Spec(ZZ). Those doctests were breaking because Scheme does not
      implement equality, which is required for Hom caching.
    
    As a byproduct, the HeckeModules category does not import any more
    HeckeModulesHomspace, which was a recurrent source of import loops.
    
    diff --git a/sage/categories/hecke_modules.py b/sage/categories/hecke_modules.py
    a b  
    8484        R = self.base_ring()
    8585        return [ModulesWithBasis(R)]
    8686
     87
     88    class ParentMethods:
     89
     90        def _Hom_(self, Y, category):
     91            r"""
     92            Returns the homset from ``self`` to ``Y`` in the category ``category``
     93
     94            INPUT::
     95
     96            - ``Y`` -- an Hecke module
     97            - ``category`` -- a subcategory of :class:`HeckeModules`() or None
     98
     99            The sole purpose of this method is to construct the homset
     100            as a :class:`~sage.modular.hecke.homspace.HeckeModuleHomspace`. If
     101            ``category`` is specified and is not a subcategory of
     102            :class:`HeckeModules`(), a ``TypeError`` is raised instead
     103
     104            This method is not meant to be called directly. Please use
     105            :func:`sage.categories.homset.Hom` instead.
     106
     107            EXAMPLES::
     108
     109                sage: M = ModularForms(Gamma0(7), 4)
     110                sage: H = M._Hom_(M, category = HeckeModules(QQ)); H
     111                Set of Morphisms from Modular Forms space of dimension 3 for Congruence Subgroup Gamma0(7) of weight 4 over Rational Field to Modular Forms space of dimension 3 for Congruence Subgroup Gamma0(7) of weight 4 over Rational Field in Category of Hecke modules over Rational Field
     112                sage: H.__class__
     113                <class 'sage.modular.hecke.homspace.HeckeModuleHomspace_with_category'>
     114                sage: TestSuite(H).run(skip=["_test_zero", "_test_elements"])
     115
     116            Fixing :meth:'_test_zero' (``__call__`` should accept a
     117            function as input) and :meth:`_test_elements` (modular
     118            form morphisms elements should inherit from categories) is
     119            :trac:'???'.
     120
     121            TESTS::
     122
     123                sage: H = M._Hom_(M, category = HeckeModules(GF(5))); H
     124                Traceback (most recent call last):
     125                ...
     126                TypeError: Category of Hecke modules over Finite Field of size 5 is not a subcategory of Category of Hecke modules over Rational Field
     127
     128            """
     129            # TODO: double check that it's the correct HeckeModules category below:
     130            if category is not None and not category.is_subcategory(HeckeModules(self.base_ring())):
     131                raise TypeError, "%s is not a subcategory of %s"%(category, HeckeModules(self.base_ring()))
     132            from sage.modular.hecke.homspace import HeckeModuleHomspace
     133            return HeckeModuleHomspace(self, Y, category = category)
     134
    87135    class HomCategory(HomCategory):
    88136        def extra_super_categories(self):
    89137            """
     
    94142            """
    95143            return [] # FIXME: what category structure is there on Homsets of hecke modules?
    96144
    97         import sage.modular.hecke.homspace
    98         class ParentMethods(sage.modular.hecke.homspace.HeckeModuleHomspace):
     145
     146        def base_ring(self):
     147            """
     148            EXAMPLES::
     149
     150                sage: HeckeModules(QQ).hom_category().base_ring()
     151                Rational Field
     152            """
     153            return self.base().base_ring()
     154
     155        class ParentMethods:
    99156            pass
  • sage/categories/homset.py

    diff --git a/sage/categories/homset.py b/sage/categories/homset.py
    a b  
    6767from sage.structure.parent import Parent, Set_generic
    6868from sage.misc.lazy_attribute import lazy_attribute
    6969from sage.misc.cachefunc import cached_function
     70from sage.misc.constant_function import ConstantFunction
    7071import types
    7172
    7273###################################
     
    108109        Set of Morphisms from Integer Ring to Rational Field in Category of sets
    109110
    110111        sage: Hom(FreeModule(ZZ,1), FreeModule(QQ,1))
    111         Set of Morphisms from Ambient free module of rank 1 over the principal ideal domain Integer Ring to Vector space of dimension 1 over Rational Field in Category of modules with basis over Integer Ring
     112        Set of Morphisms from Ambient free module of rank 1 over the principal ideal domain Integer Ring to Vector space of dimension 1 over Rational Field in Category of commutative additive groups
    112113        sage: Hom(FreeModule(QQ,1), FreeModule(ZZ,1))
    113         Set of Morphisms from Vector space of dimension 1 over Rational Field to Ambient free module of rank 1 over the principal ideal domain Integer Ring in Category of vector spaces over Rational Field
     114        Set of Morphisms from Vector space of dimension 1 over Rational Field to Ambient free module of rank 1 over the principal ideal domain Integer Ring in Category of commutative additive groups
    114115
    115116    Here, we test against a memory leak that has been fixed at :trac:`11521` by
    116117    using a weak cache::
     
    151152        ...
    152153        TypeError: Integer Ring is not in Category of groups
    153154
     155    A parent may specify how to construct certain homsets by
     156    implementing a method :meth:`_Hom_`(codomain, category). This
     157    method should either construct the requested homset or raise a
     158    ``TypeError``. This hook is currently mostly used to create
     159    homsets in some specific subclass of :class:`Homset`
     160    (e.g. :class:`sage.rings.homset.RingHomset`, ...)::
     161
     162        sage: Hom(QQ,QQ).__class__
     163        <class 'sage.rings.homset.RingHomset_generic_with_category'>
     164
     165    Do not call this hook directly to create homsets, as it does not
     166    handle unique representation::
     167
     168        sage: Hom(QQ,QQ) == QQ._Hom_(QQ, category=QQ.category())
     169        True
     170        sage: Hom(QQ,QQ) is QQ._Hom_(QQ, category=QQ.category())
     171        False
    154172
    155173    TESTS:
    156174
    157175    Some doc tests in :mod:`sage.rings` (need to) break the unique parent assumption.
    158     But if domain or codomain are not unique parents, then the hom set won't fit.
     176    But if domain or codomain are not unique parents, then the homset won't fit.
    159177    That's to say, the hom set found in the cache will have a (co)domain that is
    160178    equal to, but not identic with, the given (co)domain.
    161179
    162     By trac ticket #9138, we abandon the uniqueness of hom sets, if the domain or
     180    By :trac:`9138`, we abandon the uniqueness of hom sets, if the domain or
    163181    codomain break uniqueness::
    164182
    165183        sage: from sage.rings.polynomial.multi_polynomial_ring import MPolynomialRing_polydict_domain
     
    180198        sage: H1 is H2
    181199        False
    182200
    183     It is always the most recently constructed hom set that remains in the cache::
     201    It is always the most recently constructed homset that remains in the cache::
    184202
    185203        sage: H2 is Hom(QQ,Q)
    186204        True
    187205
    188     Since trac ticket #11900, the meet of the categories of the given arguments is
     206    Variation on the theme::
     207
     208        sage: U1 = FreeModule(ZZ,2)
     209        sage: U2 = FreeModule(ZZ,2,inner_product_matrix=matrix([[1,0],[0,-1]]))
     210        sage: U1 == U2, U1 is U2
     211        (True, False)
     212        sage: V = ZZ^3
     213        sage: H1 = Hom(U1, V); H2 = Hom(U2, V)
     214        sage: H1 == H2, H1 is H2
     215        (True, False)
     216        sage: H1 = Hom(V, U1); H2 = Hom(V, U2)
     217        sage: H1 == H2, H1 is H2
     218        (True, False)
     219
     220    Since :trac:`11900`, the meet of the categories of the given arguments is
    189221    used to determine the default category of the homset. This can also be a join
    190222    category, as in the following example::
    191223
     
    204236    Y, or does the difference only lie in the elements (i.e. the
    205237    morphism), and of course how the parent calls their constructors.
    206238
     239    TESTS::
     240
     241        sage: R = sage.structure.parent.Set_PythonType(int)
     242        sage: S = sage.structure.parent.Set_PythonType(float)
     243        sage: Hom(R, S)
     244        Set of Morphisms from Set of Python objects of type 'int' to Set of Python objects of type 'float' in Category of sets
    207245    """
    208246    # This should use cache_function instead
    209247    # However it breaks somehow the coercion (see e.g. sage -t sage.rings.real_mpfr)
     
    220258        if H.domain() is X and H.codomain() is Y:
    221259            return H
    222260
    223     try:
    224         # Apparently X._Hom_ is supposed to be cached
    225         return X._Hom_(Y, category)
    226     except (AttributeError, TypeError):
    227         pass
    228 
    229261    cat_X = X.category()
    230262    cat_Y = Y.category()
    231263    if category is None:
    232         category = cat_X._meet_(cat_Y)
    233     elif isinstance(category, Category):
    234         if not cat_X.is_subcategory(category):
    235             raise TypeError, "%s is not in %s"%(X, category)
    236         if not cat_Y.is_subcategory(category):
    237             raise TypeError, "%s is not in %s"%(Y, category)
    238     else:
     264        return Hom(X,Y,category=cat_X._meet_(cat_Y))
     265    if not isinstance(category, Category):
    239266        raise TypeError, "Argument category (= %s) must be a category."%category
    240     # Now, as the category may have changed, we try to find the hom set in the cache, again:
    241     cat_ref = weakref.ref(category) if category is not None else None
    242     key = (X,Y,cat_ref)
    243     try:
    244         H = _cache[key]()
    245     except KeyError:
    246         H = None
    247     if H:
    248         # Are domain or codomain breaking the unique parent condition?
    249         if H.domain() is X and H.codomain() is Y:
    250             return H
    251 
    252     # coercing would be incredibly annoying, since the domain and codomain
    253     # are totally different objects
    254     #X = category(X); Y = category(Y)
     267    if not cat_X.is_subcategory(category):
     268        raise TypeError, "%s is not in %s"%(X, category)
     269    if not cat_Y.is_subcategory(category):
     270        raise TypeError, "%s is not in %s"%(Y, category)
    255271
    256272    # construct H
    257273    # Design question: should the Homset classes get the category or the homset category?
    258274    # For the moment, this is the category, for compatibility with the current implementations
    259275    # of Homset in rings, schemes, ...
    260     H = category.hom_category().parent_class(X, Y, category = category)
    261            
    262     ##_cache[key] = weakref.ref(H)
     276    try:
     277        H = X._Hom_(Y, category)
     278    except (AttributeError, TypeError):
     279        H = Homset(X, Y, category = category)
    263280    _cache[key] = weakref.ref(H)
    264281    return H
    265282
     
    383400            ...
    384401            AttributeError: 'sage.rings.integer.Integer' object has no attribute 'hom_category'
    385402        """
    386 
    387403        self._domain = X
    388404        self._codomain = Y
    389405        if category is None:
     
    459475        """
    460476        return self.__category
    461477
    462     def __call__(self, x=None, y=None, check=True, on_basis=None):
     478    def __call__(self, x=None, y=None, check=True, **options):
    463479        """
    464480        Construct a morphism in this homset from x if possible.
    465481       
     
    507523            Set of Morphisms from {1, 2, 3} to {1, 2, 3} in Category of sets
    508524            sage: f(1), f(2), f(3) # todo: not implemented
    509525
     526            sage: H = Hom(ZZ, QQ, Sets())
     527            sage: f = H( ConstantFunction(2/3) )
     528            sage: f.parent()
     529            Set of Morphisms from Integer Ring to Rational Field in Category of sets
     530            sage: f(1), f(2), f(3)
     531            (2/3, 2/3, 2/3)
    510532
    511533        - Robert Bradshaw, with changes by Nicolas M. Thiery
    512534        """
    513         # Temporary workaround: currently, HomCategory.ParentMethods's cannot override
    514         # this __call__ method because of the class inheritance order
    515         # This dispatches back the call there
    516         if on_basis is not None:
    517             return self.__call_on_basis__(on_basis = on_basis)
     535        if options:
     536            # TODO: this is specific for ModulesWithBasis; generalize
     537            # this to allow homsets and categories to provide more
     538            # morphism constructors (on_algebra_generators, ...)
     539            if 'on_basis' or 'diagonal' in options:
     540                return self.__call_on_basis__(category = self.homset_category(),
     541                                              **options)
     542            else:
     543                raise NotImplementedError
     544
    518545        assert x is not None
    519 
    520546        if isinstance(x, morphism.Morphism):
    521547            if x.parent() is self:
    522548                return x
     
    536562                    x = mor * x
    537563                return x
    538564
    539         if isinstance(x, types.FunctionType) or isinstance(x, types.MethodType):
     565        if isinstance(x, (types.FunctionType, types.MethodType, ConstantFunction)):
    540566            return self.element_class_set_morphism(self, x)
    541            
     567
    542568        raise TypeError, "Unable to coerce x (=%s) to a morphism in %s"%(x,self)
    543569
    544570    @lazy_attribute
     
    613639            sage: type(H)
    614640            <class 'sage.modules.free_module_homspace.FreeModuleHomspace_with_category'>
    615641            sage: H.reversed()
    616             Set of Morphisms from Ambient free module of rank 3 over the principal ideal domain Integer Ring to Ambient free module of rank 2 over the principal ideal domain Integer Ring in Category of hom sets in Category of modules with basis over Integer Ring
     642            Set of Morphisms from Ambient free module of rank 3 over the principal ideal domain Integer Ring to Ambient free module of rank 2 over the principal ideal domain Integer Ring in Category of modules with basis over Integer Ring
    617643            sage: type(H.reversed())
    618644            <class 'sage.modules.free_module_homspace.FreeModuleHomspace_with_category'>
    619645        """
    620         return Hom(self.codomain(), self.domain(), category = self.category())
     646        return Hom(self.codomain(), self.domain(), category = self.homset_category())
    621647       
    622648    ############### For compatibility with old coercion model #######################
    623649   
  • sage/categories/modules_with_basis.py

    diff --git a/sage/categories/modules_with_basis.py b/sage/categories/modules_with_basis.py
    a b  
    884884        The category of homomorphisms sets Hom(X,Y) for X, Y modules with basis
    885885        """
    886886
    887         class ParentMethods: #(sage.modules.free_module_homspace.FreeModuleHomspace): #    Only works for plain FreeModule's
    888             """
    889             Abstract class for hom sets
    890             """
    891 
    892             def __call__(self, on_basis = None, *args, **options):
     887        class ParentMethods:
     888            def __call_on_basis__(self, **options):
    893889                """
    894                 Construct an element of this homset
     890                Construct a morphism in this homset from a function defined on the basis
    895891
    896892                INPUT:
    897893
    898                  - on_basis (optional) -- a function from the indices
    899                    of the basis of the domain of ``self`` to the
    900                    codomain of ``self``
     894                - ``on_basis`` -- a function from the indices of the
     895                  basis of the domain of ``self`` to the codomain of
     896                  ``self``
     897
     898                This method simply delegates the work to
     899                :meth:`ModulesWithBasis.ParentMethods.module_morphism`. It
     900                is used by :meth:`Homset.__call__` to handle the
     901                ``on_basis`` argument, and will disapear as soon as
     902                the logic will be generalized.
    901903
    902904                EXAMPLES::
    903905
     
    906908                    sage: H = Hom(X, Y)
    907909                    sage: x = X.basis()
    908910
     911                    sage: phi = H(on_basis = lambda i: Y.monomial(i) + 2*Y.monomial(i+1)) # indirect doctest
     912                    sage: phi
     913                    Generic morphism:
     914                    From: X
     915                    To:   Y
     916                    sage: phi(x[1] + x[3])
     917                    B[1] + 2*B[2] + B[3] + 2*B[4]
     918
     919                Diagonal functions can be constructed using the ``diagonal`` option::
     920
     921                    sage: X = CombinatorialFreeModule(QQ, [1,2,3,4]); X.rename("X")
     922                    sage: Y = CombinatorialFreeModule(QQ, [1,2,3,4], key="Y"); Y.rename("Y")
     923                    sage: H = Hom(X, Y)
     924                    sage: x = X.basis()
     925                    sage: phi = H(diagonal = lambda x: x^2)
     926                    sage: phi(x[1] + x[2] + x[3])
     927                    B[1] + 4*B[2] + 9*B[3]
     928
     929                TESTS::
     930
    909931                As for usual homsets, the argument can be a Python function::
    910932
    911933                    sage: phi = H(lambda x: Y.zero())
     
    916938                    sage: phi(x[1] + x[3])
    917939                    0
    918940
    919                 With the on_basis argument, the function can instead
    920                 be constructed by extending by linearity a function on
    921                 the basis::
     941               We check that the homset category is properly set up::
    922942
    923                     sage: phi = H(on_basis = lambda i: Y.monomial(i) + 2*Y.monomial(i+1))
    924                     sage: phi
    925                     Generic morphism:
    926                     From: X
    927                     To:   Y
    928                     sage: phi(x[1] + x[3])
    929                     B[1] + 2*B[2] + B[3] + 2*B[4]
    930 
    931                 This is achieved internaly by using
    932                 :meth:`ModulesWithBasis.ParentMethods.module_morphism`, which see.
     943                    sage: category = FiniteDimensionalModulesWithBasis(QQ)
     944                    sage: X = CombinatorialFreeModule(QQ, [1,2,3], category = category);   X.rename("X")
     945                    sage: Y = CombinatorialFreeModule(QQ, [1,2,3,4], category = category); Y.rename("Y")
     946                    sage: H = Hom(X, Y)
     947                    sage: H.zero().category_for()
     948                    Category of finite dimensional modules with basis over Rational Field
    933949                """
    934                 if on_basis is not None:
    935                     args = (self.domain().module_morphism(on_basis, codomain = self.codomain()),) + args
    936                 h = Homset.__call__(self, *args, **options)
    937                 if on_basis is not None:
    938                     h._on_basis = on_basis
    939                 return h
    940 
    941             # Temporary hack
    942             __call_on_basis__ = __call__
    943 
    944             @lazy_attribute
    945             def element_class_set_morphism(self):
    946                 """
    947                 A base class for elements of this homset which are
    948                 also SetMorphism's, i.e. implemented by mean of a
    949                 Python function.
    950 
    951                 This overrides the default implementation
    952                 :meth:`Homset.element_class_set_morphism`, to also
    953                 inherit from categories.
    954 
    955                 Todo: refactor during the upcoming homset cleanup.
    956 
    957                 EXAMPLES::
    958 
    959                     sage: X = CombinatorialFreeModule(QQ, [1,2,3]);   X.rename("X")
    960                     sage: Y = CombinatorialFreeModule(QQ, [1,2,3,4]); Y.rename("Y")
    961                     sage: H = Hom(X, Y)
    962                     sage: H.element_class_set_morphism
    963                     <class 'sage.categories.morphism.SetMorphism_with_category'>
    964                     sage: H.element_class_set_morphism.mro()
    965                     [<class 'sage.categories.morphism.SetMorphism_with_category'>,
    966                      <type 'sage.categories.morphism.SetMorphism'>,
    967                      <type 'sage.categories.morphism.Morphism'>,
    968                      <type 'sage.categories.map.Map'>,
    969                      <type 'sage.structure.element.Element'>,
    970                      <type 'sage.structure.sage_object.SageObject'>,
    971                      <class 'sage.categories.modules_with_basis.ModulesWithBasis.HomCategory.element_class'>,
    972                      <class 'sage.categories.category.Modules.HomCategory.element_class'>,
    973                      <class 'sage.categories.vector_spaces.VectorSpaces.element_class'>,
    974                      ...]
    975 
    976                 Compare with:
    977 
    978                     sage: H = Hom(ZZ, ZZ)
    979                     sage: H.element_class_set_morphism
    980                     <type 'sage.categories.morphism.SetMorphism'>
    981                 """
    982                 return self.__make_element_class__(SetMorphism, inherit = True)
     950                return self.domain().module_morphism(codomain = self.codomain(),
     951                                                     **options)
    983952
    984953        class ElementMethods:
    985954            """
    986955            Abstract class for morphisms of modules with basis
    987956            """
     957            @cached_method
    988958            def on_basis(self):
    989959                """
    990960                Returns the action of this morphism on basis elements
     
    1011981                    sage: g == f
    1012982                    True
    1013983                """
    1014                 if not hasattr(self, "_on_basis"):
    1015                     monomial = self.domain().monomial
    1016                     self._on_basis = lambda t: self(monomial(t))
    1017                 return self._on_basis
    1018 
     984                monomial = self.domain().monomial
     985                return lambda t: self(monomial(t))
    1019986
    1020987    class CartesianProducts(CartesianProductsCategory):
    1021988        """
     
    12211188            B[2]
    12221189            sage: phi.on_basis() == phi_on_basis
    12231190            True
    1224 
    1225         Note: could probably be inherited from the categories
    12261191        """
    12271192        return self._on_basis
    12281193
  • sage/categories/objects.py

    diff --git a/sage/categories/objects.py b/sage/categories/objects.py
    a b  
    8686            from sets_cat import Sets
    8787            return [Sets()]
    8888
    89         class ParentMethods(Homset):
     89        class ParentMethods:
    9090            pass
  • sage/categories/rings.py

    diff --git a/sage/categories/rings.py b/sage/categories/rings.py
    a b  
    9292            """
    9393            return x*y - y*x
    9494
     95        def _Hom_(self, Y, category):
     96            r"""
     97            Returns the homset from ``self`` to ``Y`` in the category ``category``
     98
     99            INPUT::
     100
     101            - ``Y`` -- a ring
     102            - ``category`` -- a subcategory of :class:`Rings`() or None
     103
     104            The sole purpose of this method is to construct the homset
     105            as a :class:`~sage.rings.homset.RingHomset`. If
     106            ``category`` is specified and is not a subcategory of
     107            :class:`Rings`(), a ``TypeError`` is raised instead
     108
     109            This method is not meant to be called directly. Please use
     110            :func:`sage.categories.homset.Hom` instead.
     111
     112            EXAMPLES::
     113
     114                sage: H = QQ._Hom_(QQ, category = Rings()); H
     115                Set of Homomorphisms from Rational Field to Rational Field
     116                sage: H.__class__
     117                <class 'sage.rings.homset.RingHomset_generic_with_category'>
     118
     119            TESTS::
     120
     121                sage: Hom(QQ, QQ, category = Rings()).__class__
     122                <class 'sage.rings.homset.RingHomset_generic_with_category'>
     123
     124                sage: Hom(CyclotomicField(3), QQ, category = Rings()).__class__
     125                <class 'sage.rings.number_field.morphism.CyclotomicFieldHomset_with_category'>
     126
     127                sage: TestSuite(Hom(QQ, QQ, category = Rings())).run() # indirect doctest
     128
     129            """
     130            if category is not None and not category.is_subcategory(Rings()):
     131                raise TypeError, "%s is not a subcategory of Rings()"%category
     132            if Y not in Rings():
     133                raise TypeError, "%s is not a ring"%Y
     134            from sage.rings.homset import RingHomset
     135            return RingHomset(self, Y, category = category)
     136
    95137        # this is already in sage.rings.ring.Ring,
    96138        # but not all rings descend from that class,
    97139        # e.g., matrix spaces.
     
    514556            """
    515557            raise TypeError, "Use self.quo(I) or self.quotient(I) to construct the quotient ring."
    516558
    517 
    518559    class ElementMethods:
    519560        pass
    520561
     
    566607
    567608            # This should be cleaned up upon the next homset overhaul
    568609
    569             def __new__(cls, X, Y, category):
     610            def __new__bx(cls, X, Y, category):
    570611                """
    571                     sage: Hom(QQ, QQ, category = Rings()).__class__                  # indirect doctest
    572                     <class 'sage.rings.homset.RingHomset_generic_with_category'>
    573 
    574                     sage: Hom(CyclotomicField(3), QQ, category = Rings()).__class__  # indirect doctest
    575                     <class 'sage.rings.number_field.morphism.CyclotomicFieldHomset_with_category'>
    576612                """
    577613                from sage.rings.homset import RingHomset
    578614                return RingHomset(X, Y, category = category)
     
    583619                argument upon unpickling. Maybe it would be preferable to
    584620                have :meth:`.__new__` accept to be called without arguments.
    585621
    586                 TESTS::
    587 
    588                     sage: Hom(QQ, QQ, category = Rings()).__getnewargs__()
    589                     (Rational Field, Rational Field, Category of hom sets in Category of rings)
    590                     sage: TestSuite(Hom(QQ, QQ, category = Rings())).run() # indirect doctest
    591622                """
    592623                return (self.domain(), self.codomain(), self.category())
  • sage/modules/vector_space_homspace.py

    diff --git a/sage/modules/vector_space_homspace.py b/sage/modules/vector_space_homspace.py
    a b  
    329329            [1 0 2]
    330330
    331331        Coercing a vector space morphism into the parent of a second vector
    332         space morphism will unify their parents. ::
     332        space morphism will unify their parents::
    333333
    334             sage: U = QQ^3
    335             sage: V = QQ^4
    336             sage: W = QQ^3
    337             sage: X = QQ^4
     334            sage: U = FreeModule(QQ,3, sparse=True ); V = QQ^4
     335            sage: W = FreeModule(QQ,3, sparse=False); X = QQ^4
    338336            sage: H = Hom(U, V)
    339337            sage: K = Hom(W, X)
     338            sage: H is K, H == K
     339            (False, True)
    340340
    341341            sage: A = matrix(QQ, 3, 4, [0]*12)
    342342            sage: f = H(A)
  • sage/rings/ring.pyx

    diff --git a/sage/rings/ring.pyx b/sage/rings/ring.pyx
    a b  
    401401        # initialisation has finished.
    402402        return self._category or _Rings
    403403
     404    """
     405    This temporary alias is here for those instances of :class:`Ring`
     406    that are not yet properly in the :class:`Rings`() category.
     407
     408    TESTS::
     409
     410        sage: A = Ring(ZZ)
     411        sage: A._Hom_.__module__
     412        'sage.categories.rings'
     413        sage: Hom(A,A).__class__
     414        <class 'sage.rings.homset.RingHomset_generic_with_category'>
     415    """
     416    _Hom_ = Rings.ParentMethods.__dict__['_Hom_']
     417
    404418    def ideal_monoid(self):
    405419        """
    406420        Return the monoid of ideals of this ring.
  • sage/schemes/elliptic_curves/ell_curve_isogeny.py

    diff --git a/sage/schemes/elliptic_curves/ell_curve_isogeny.py b/sage/schemes/elliptic_curves/ell_curve_isogeny.py
    a b  
    33423342
    33433343            sage: E = EllipticCurve(j=GF(7)(0))
    33443344            sage: phi = EllipticCurveIsogeny(E, [E(0), E((0,1)), E((0,-1))])
    3345             sage: phi*phi
    3346             Traceback (most recent call last):
    3347             ...
    3348             NotImplementedError                     
    33493345            sage: phi._composition_(phi, phi.parent())
    33503346            Traceback (most recent call last):
    33513347            ...
    33523348            NotImplementedError                     
    33533349
     3350        The following should test that :meth:`_composition_` is called
     3351        upon a product. However phi is currently improperly
     3352        constructed (see :trac:``), which triggers an assertion
     3353        failure before the actual call ::
     3354
     3355            sage: phi*phi
     3356            Traceback (most recent call last):
     3357            ...
     3358            TypeError: Elliptic Curve defined by y^2 = x^3 + 1 over Finite Field of size 7 is not in Category of hom sets in Category of Schemes
     3359
     3360        Here would be the desired output::
     3361
     3362            sage: phi*phi            # not tested
     3363            Traceback (most recent call last):
     3364            ...
     3365            NotImplementedError
    33543366        """
    33553367        raise NotImplementedError
    33563368
  • sage/schemes/generic/morphism.py

    diff --git a/sage/schemes/generic/morphism.py b/sage/schemes/generic/morphism.py
    a b  
    120120
    121121    EXAMPLES::
    122122
    123         sage: from sage.schemes.generic.scheme import Scheme
    124         sage: X = Scheme(ZZ)
     123        sage: X = Spec(ZZ)
    125124        sage: Hom = X.Hom(X)
    126125        sage: from sage.schemes.generic.morphism import SchemeMorphism
    127126        sage: f = SchemeMorphism(Hom)
     
    134133       
    135134        EXAMPLES::
    136135       
    137             sage: from sage.schemes.generic.scheme import Scheme
    138             sage: X = Scheme(ZZ)
     136            sage: X = Spec(ZZ)
    139137            sage: Hom = X.Hom(X)
    140138            sage: from sage.schemes.generic.morphism import SchemeMorphism
    141139            sage: f = SchemeMorphism(Hom)
     
    158156
    159157        EXAMPLES::
    160158
    161             sage: from sage.schemes.generic.scheme import Scheme
    162             sage: X = Scheme(ZZ)
     159            sage: X = Spec(ZZ)
    163160            sage: Hom = X.Hom(X)
    164161            sage: from sage.schemes.generic.morphism import SchemeMorphism
    165162            sage: f = SchemeMorphism(Hom)
     
    200197
    201198        EXAMPLES::
    202199
    203             sage: from sage.schemes.generic.scheme import Scheme
    204             sage: X = Scheme(ZZ)
     200            sage: X = Spec(ZZ)
    205201            sage: Hom = X.Hom(X)
    206202            sage: from sage.schemes.generic.morphism import SchemeMorphism
    207203            sage: f = SchemeMorphism(Hom)
  • sage/structure/parent.pyx

    diff --git a/sage/structure/parent.pyx b/sage/structure/parent.pyx
    a b  
    14871487       raise NotImplementedError("Verification of correctness of homomorphisms from %s not yet implemented."%self)
    14881488
    14891489    def Hom(self, codomain, category=None):
    1490         r"""       
     1490        r"""
    14911491        Return the homspace ``Hom(self, codomain, cat)`` of all
    14921492        homomorphisms from self to codomain in the category cat.  The
    14931493        default category is :meth:`category``.
    14941494
     1495        .. SEEALSO:: :func:`~sage.categories.homset.Hom`
     1496
    14951497        EXAMPLES::
    14961498       
    14971499            sage: R.<x,y> = PolynomialRing(QQ, 2)
     
    15131515            Set of Morphisms from Rational Field to Integer Ring in Category of sets
    15141516
    15151517        A parent may specify how to construct certain homsets by
    1516         implementing a method :meth:`_Hom_`(codomain, category). This
    1517         method should either construct the requested homset or raise a
    1518         ``TypeError``.
     1518        implementing a method :meth:`_Hom_`(codomain, category).
     1519        See :func:`~sage.categories.homset.Hom` for details.
    15191520        """
    1520         try:
    1521             return self._Hom_(codomain, category)
    1522         except (AttributeError, TypeError):
    1523             pass
    15241521        from sage.categories.homset import Hom
    15251522        return Hom(self, codomain, category)
    15261523
     
    28852882            # probably
    28862883            import sage.rings.infinity
    28872884            return sage.rings.infinity.infinity
    2888            
    2889 #     def _Hom_disabled(self, domain, cat=None):
    2890 #         """
    2891 #         By default, create a homset in the category of sets.
    2892        
    2893 #         EXAMPLES:
    2894 #             sage: R = sage.structure.parent.Set_PythonType(int)
    2895 #             sage: S = sage.structure.parent.Set_PythonType(float)
    2896 #             sage: R._Hom_(S)
    2897 #             Set of Morphisms from Set of Python objects of type 'int' to Set of Python objects of type 'float' in Category of sets
    2898 #         """
    2899 #         from sage.categories.sets_cat import Sets
    2900 #         from sage.categories.homset import Homset
    2901 #         if cat is None:
    2902 #             cat = Sets()
    2903 #         return Homset(self, domain, cat)
    29042885
    29052886# These functions are to guarantee that user defined _lmul_, _rmul_,
    29062887# _act_on_, _acted_upon_ do not in turn call __mul__ on their
  • sage/structure/parent_base.pyx

    diff --git a/sage/structure/parent_base.pyx b/sage/structure/parent_base.pyx
    a b  
    9090        check_old_coerce(self)
    9191        raise CoercionException, "BUG: the base_extend method must be defined for '%s' (class '%s')"%(
    9292            self, type(self))
    93 
    94     ############################################################################
    95     # Homomorphism --
    96     ############################################################################
    97     def Hom(self, codomain, category = None):
    98         r"""
    99         self.Hom(codomain, category = None):
    100        
    101         Returns the homspace \code{Hom(self, codomain, category)} of all
    102         homomorphisms from self to codomain in the category cat.  The
    103         default category is \code{self.category()}.
    104 
    105         EXAMPLES:
    106             sage: R.<x,y> = PolynomialRing(QQ, 2)
    107             sage: R.Hom(QQ)
    108             Set of Homomorphisms from Multivariate Polynomial Ring in x, y over Rational Field to Rational Field
    109 
    110         Homspaces are defined for very general \sage objects, even elements of familiar rings.
    111             sage: n = 5; Hom(n,7)
    112             Set of Morphisms from 5 to 7 in Category of elements of Integer Ring
    113             sage: z=(2/3); Hom(z,8/1)
    114             Set of Morphisms from 2/3 to 8 in Category of elements of Rational Field
    115 
    116         This example illustrates the optional third argument:
    117             sage: QQ.Hom(ZZ, Sets())
    118             Set of Morphisms from Rational Field to Integer Ring in Category of sets
    119         """
    120         # NT 01-2009: what's the difference with parent.Parent.Hom???
    121         if self._element_constructor is None:
    122             return parent.Parent.Hom(self, codomain, category)
    123         try:
    124             return self._Hom_(codomain, category)
    125         except (AttributeError, TypeError):
    126             pass
    127         from sage.categories.all import Hom
    128         return Hom(self, codomain, category)
    129