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

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

Replacement of trac_12876_category-fix_abstract_class-nt-rel11521-review-nt.patch wrt to the new patch versions at #715, #12313 etc.

  • sage/categories/hecke_modules.py

    # HG changeset patch
    # User Nicolas M. Thiery <nthiery@users.sf.net>
    # Date 1335304627 -7200
    # Node ID 91a709fb65f2fe6885c36f1fe3ce79cfdfb174a7
    # Parent  5203c6ae65b6357e2d278c79acd1d49a0c6c0978
    #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)
     
    219257        if H.domain() is X and H.codomain() is Y:
    220258            return H
    221259
    222     try:
    223         # Apparently X._Hom_ is supposed to be cached
    224         return X._Hom_(Y, category)
    225     except (AttributeError, TypeError):
    226         pass
    227 
    228260    cat_X = X.category()
    229261    cat_Y = Y.category()
    230262    if category is None:
    231         category = cat_X._meet_(cat_Y)
    232     elif isinstance(category, Category):
    233         if not cat_X.is_subcategory(category):
    234             raise TypeError, "%s is not in %s"%(X, category)
    235         if not cat_Y.is_subcategory(category):
    236             raise TypeError, "%s is not in %s"%(Y, category)
    237     else:
     263        return Hom(X,Y,category=cat_X._meet_(cat_Y))
     264    if not isinstance(category, Category):
    238265        raise TypeError, "Argument category (= %s) must be a category."%category
    239     # Now, as the category may have changed, we try to find the hom set in the cache, again:
    240     key = (X,Y,category)
    241     try:
    242         H = _cache[key]()
    243     except KeyError:
    244         H = None
    245     if H is not None:
    246         # Are domain or codomain breaking the unique parent condition?
    247         if H.domain() is X and H.codomain() is Y:
    248             return H
    249 
    250     # coercing would be incredibly annoying, since the domain and codomain
    251     # are totally different objects
    252     #X = category(X); Y = category(Y)
     266    if not cat_X.is_subcategory(category):
     267        raise TypeError, "%s is not in %s"%(X, category)
     268    if not cat_Y.is_subcategory(category):
     269        raise TypeError, "%s is not in %s"%(Y, category)
    253270
    254271    # construct H
    255272    # Design question: should the Homset classes get the category or the homset category?
    256273    # For the moment, this is the category, for compatibility with the current implementations
    257274    # of Homset in rings, schemes, ...
    258     H = category.hom_category().parent_class(X, Y, category = category)
    259            
    260     ##_cache[key] = weakref.ref(H)
     275    try:
     276        H = X._Hom_(Y, category)
     277    except (AttributeError, TypeError):
     278        H = Homset(X, Y, category = category)
    261279    _cache[key] = KeyedRef(H, _cache.eraser, (id(X),id(Y),id(category)))
    262280    return H
    263281
     
    381399            ...
    382400            AttributeError: 'sage.rings.integer.Integer' object has no attribute 'hom_category'
    383401        """
    384 
    385402        self._domain = X
    386403        self._codomain = Y
    387404        if category is None:
     
    457474        """
    458475        return self.__category
    459476
    460     def __call__(self, x=None, y=None, check=True, on_basis=None):
     477    def __call__(self, x=None, y=None, check=True, **options):
    461478        """
    462479        Construct a morphism in this homset from x if possible.
    463480       
     
    505522            Set of Morphisms from {1, 2, 3} to {1, 2, 3} in Category of sets
    506523            sage: f(1), f(2), f(3) # todo: not implemented
    507524
     525            sage: H = Hom(ZZ, QQ, Sets())
     526            sage: f = H( ConstantFunction(2/3) )
     527            sage: f.parent()
     528            Set of Morphisms from Integer Ring to Rational Field in Category of sets
     529            sage: f(1), f(2), f(3)
     530            (2/3, 2/3, 2/3)
    508531
    509532        - Robert Bradshaw, with changes by Nicolas M. Thiery
    510533        """
    511         # Temporary workaround: currently, HomCategory.ParentMethods's cannot override
    512         # this __call__ method because of the class inheritance order
    513         # This dispatches back the call there
    514         if on_basis is not None:
    515             return self.__call_on_basis__(on_basis = on_basis)
     534        if options:
     535            # TODO: this is specific for ModulesWithBasis; generalize
     536            # this to allow homsets and categories to provide more
     537            # morphism constructors (on_algebra_generators, ...)
     538            if 'on_basis' or 'diagonal' in options:
     539                return self.__call_on_basis__(category = self.homset_category(),
     540                                              **options)
     541            else:
     542                raise NotImplementedError
     543
    516544        assert x is not None
    517 
    518545        if isinstance(x, morphism.Morphism):
    519546            if x.parent() is self:
    520547                return x
     
    534561                    x = mor * x
    535562                return x
    536563
    537         if isinstance(x, types.FunctionType) or isinstance(x, types.MethodType):
     564        if isinstance(x, (types.FunctionType, types.MethodType, ConstantFunction)):
    538565            return self.element_class_set_morphism(self, x)
    539            
     566
    540567        raise TypeError, "Unable to coerce x (=%s) to a morphism in %s"%(x,self)
    541568
    542569    @lazy_attribute
     
    611638            sage: type(H)
    612639            <class 'sage.modules.free_module_homspace.FreeModuleHomspace_with_category'>
    613640            sage: H.reversed()
    614             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
     641            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
    615642            sage: type(H.reversed())
    616643            <class 'sage.modules.free_module_homspace.FreeModuleHomspace_with_category'>
    617644        """
    618         return Hom(self.codomain(), self.domain(), category = self.category())
     645        return Hom(self.codomain(), self.domain(), category = self.homset_category())
    619646       
    620647    ############### For compatibility with old coercion model #######################
    621648   
  • sage/categories/modules_with_basis.py

    diff --git a/sage/categories/modules_with_basis.py b/sage/categories/modules_with_basis.py
    a b  
    908908        The category of homomorphisms sets Hom(X,Y) for X, Y modules with basis
    909909        """
    910910
    911         class ParentMethods: #(sage.modules.free_module_homspace.FreeModuleHomspace): #    Only works for plain FreeModule's
    912             """
    913             Abstract class for hom sets
    914             """
    915 
    916             def __call__(self, on_basis = None, *args, **options):
     911        class ParentMethods:
     912            def __call_on_basis__(self, **options):
    917913                """
    918                 Construct an element of this homset
     914                Construct a morphism in this homset from a function defined on the basis
    919915
    920916                INPUT:
    921917
    922                  - on_basis (optional) -- a function from the indices
    923                    of the basis of the domain of ``self`` to the
    924                    codomain of ``self``
     918                - ``on_basis`` -- a function from the indices of the
     919                  basis of the domain of ``self`` to the codomain of
     920                  ``self``
     921
     922                This method simply delegates the work to
     923                :meth:`ModulesWithBasis.ParentMethods.module_morphism`. It
     924                is used by :meth:`Homset.__call__` to handle the
     925                ``on_basis`` argument, and will disapear as soon as
     926                the logic will be generalized.
    925927
    926928                EXAMPLES::
    927929
     
    930932                    sage: H = Hom(X, Y)
    931933                    sage: x = X.basis()
    932934
     935                    sage: phi = H(on_basis = lambda i: Y.monomial(i) + 2*Y.monomial(i+1)) # indirect doctest
     936                    sage: phi
     937                    Generic morphism:
     938                    From: X
     939                    To:   Y
     940                    sage: phi(x[1] + x[3])
     941                    B[1] + 2*B[2] + B[3] + 2*B[4]
     942
     943                Diagonal functions can be constructed using the ``diagonal`` option::
     944
     945                    sage: X = CombinatorialFreeModule(QQ, [1,2,3,4]); X.rename("X")
     946                    sage: Y = CombinatorialFreeModule(QQ, [1,2,3,4], key="Y"); Y.rename("Y")
     947                    sage: H = Hom(X, Y)
     948                    sage: x = X.basis()
     949                    sage: phi = H(diagonal = lambda x: x^2)
     950                    sage: phi(x[1] + x[2] + x[3])
     951                    B[1] + 4*B[2] + 9*B[3]
     952
     953                TESTS::
     954
    933955                As for usual homsets, the argument can be a Python function::
    934956
    935957                    sage: phi = H(lambda x: Y.zero())
     
    940962                    sage: phi(x[1] + x[3])
    941963                    0
    942964
    943                 With the on_basis argument, the function can instead
    944                 be constructed by extending by linearity a function on
    945                 the basis::
     965               We check that the homset category is properly set up::
    946966
    947                     sage: phi = H(on_basis = lambda i: Y.monomial(i) + 2*Y.monomial(i+1))
    948                     sage: phi
    949                     Generic morphism:
    950                     From: X
    951                     To:   Y
    952                     sage: phi(x[1] + x[3])
    953                     B[1] + 2*B[2] + B[3] + 2*B[4]
    954 
    955                 This is achieved internaly by using
    956                 :meth:`ModulesWithBasis.ParentMethods.module_morphism`, which see.
     967                    sage: category = FiniteDimensionalModulesWithBasis(QQ)
     968                    sage: X = CombinatorialFreeModule(QQ, [1,2,3], category = category);   X.rename("X")
     969                    sage: Y = CombinatorialFreeModule(QQ, [1,2,3,4], category = category); Y.rename("Y")
     970                    sage: H = Hom(X, Y)
     971                    sage: H.zero().category_for()
     972                    Category of finite dimensional modules with basis over Rational Field
    957973                """
    958                 if on_basis is not None:
    959                     args = (self.domain().module_morphism(on_basis, codomain = self.codomain()),) + args
    960                 h = Homset.__call__(self, *args, **options)
    961                 if on_basis is not None:
    962                     h._on_basis = on_basis
    963                 return h
    964 
    965             # Temporary hack
    966             __call_on_basis__ = __call__
    967 
    968             @lazy_attribute
    969             def element_class_set_morphism(self):
    970                 """
    971                 A base class for elements of this homset which are
    972                 also SetMorphism's, i.e. implemented by mean of a
    973                 Python function.
    974 
    975                 This overrides the default implementation
    976                 :meth:`Homset.element_class_set_morphism`, to also
    977                 inherit from categories.
    978 
    979                 Todo: refactor during the upcoming homset cleanup.
    980 
    981                 EXAMPLES::
    982 
    983                     sage: X = CombinatorialFreeModule(QQ, [1,2,3]);   X.rename("X")
    984                     sage: Y = CombinatorialFreeModule(QQ, [1,2,3,4]); Y.rename("Y")
    985                     sage: H = Hom(X, Y)
    986                     sage: H.element_class_set_morphism
    987                     <class 'sage.categories.morphism.SetMorphism_with_category'>
    988                     sage: H.element_class_set_morphism.mro()
    989                     [<class 'sage.categories.morphism.SetMorphism_with_category'>,
    990                      <type 'sage.categories.morphism.SetMorphism'>,
    991                      <type 'sage.categories.morphism.Morphism'>,
    992                      <type 'sage.categories.map.Map'>,
    993                      <type 'sage.structure.element.Element'>,
    994                      <type 'sage.structure.sage_object.SageObject'>,
    995                      <class 'sage.categories.modules_with_basis.ModulesWithBasis.HomCategory.element_class'>,
    996                      <class 'sage.categories.category.Modules.HomCategory.element_class'>,
    997                      <class 'sage.categories.vector_spaces.VectorSpaces.element_class'>,
    998                      ...]
    999 
    1000                 Compare with:
    1001 
    1002                     sage: H = Hom(ZZ, ZZ)
    1003                     sage: H.element_class_set_morphism
    1004                     <type 'sage.categories.morphism.SetMorphism'>
    1005                 """
    1006                 return self.__make_element_class__(SetMorphism, inherit = True)
     974                return self.domain().module_morphism(codomain = self.codomain(),
     975                                                     **options)
    1007976
    1008977        class ElementMethods:
    1009978            """
    1010979            Abstract class for morphisms of modules with basis
    1011980            """
     981            @cached_method
    1012982            def on_basis(self):
    1013983                """
    1014984                Returns the action of this morphism on basis elements
     
    10351005                    sage: g == f
    10361006                    True
    10371007                """
    1038                 if not hasattr(self, "_on_basis"):
    1039                     monomial = self.domain().monomial
    1040                     self._on_basis = lambda t: self(monomial(t))
    1041                 return self._on_basis
    1042 
     1008                monomial = self.domain().monomial
     1009                return lambda t: self(monomial(t))
    10431010
    10441011    class CartesianProducts(CartesianProductsCategory):
    10451012        """
     
    13601327            B[2]
    13611328            sage: phi.on_basis() == phi_on_basis
    13621329            True
    1363 
    1364         Note: could probably be inherited from the categories
    13651330        """
    13661331        return self._on_basis
    13671332
  • 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.
     
    555597            """
    556598            raise TypeError, "Use self.quo(I) or self.quotient(I) to construct the quotient ring."
    557599
    558 
    559600    class ElementMethods:
    560601        pass
    561602
     
    607648
    608649            # This should be cleaned up upon the next homset overhaul
    609650
    610             def __new__(cls, X, Y, category):
     651            def __new__bx(cls, X, Y, category):
    611652                """
    612                     sage: Hom(QQ, QQ, category = Rings()).__class__                  # indirect doctest
    613                     <class 'sage.rings.homset.RingHomset_generic_with_category'>
    614 
    615                     sage: Hom(CyclotomicField(3), QQ, category = Rings()).__class__  # indirect doctest
    616                     <class 'sage.rings.number_field.morphism.CyclotomicFieldHomset_with_category'>
    617653                """
    618654                from sage.rings.homset import RingHomset
    619655                return RingHomset(X, Y, category = category)
     
    624660                argument upon unpickling. Maybe it would be preferable to
    625661                have :meth:`.__new__` accept to be called without arguments.
    626662
    627                 TESTS::
    628 
    629                     sage: Hom(QQ, QQ, category = Rings()).__getnewargs__()
    630                     (Rational Field, Rational Field, Category of hom sets in Category of rings)
    631                     sage: TestSuite(Hom(QQ, QQ, category = Rings())).run() # indirect doctest
    632663                """
    633664                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  
    399399        # initialisation has finished.
    400400        return self._category or _Rings
    401401
     402    """
     403    This temporary alias is here for those instances of :class:`Ring`
     404    that are not yet properly in the :class:`Rings`() category.
     405
     406    TESTS::
     407
     408        sage: A = Ring(ZZ)
     409        sage: A._Hom_.__module__
     410        'sage.categories.rings'
     411        sage: Hom(A,A).__class__
     412        <class 'sage.rings.homset.RingHomset_generic_with_category'>
     413    """
     414    _Hom_ = Rings.ParentMethods.__dict__['_Hom_']
     415
    402416    def ideal_monoid(self):
    403417        """
    404418        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  
    12821282       raise NotImplementedError("Verification of correctness of homomorphisms from %s not yet implemented."%self)
    12831283
    12841284    def Hom(self, codomain, category=None):
    1285         r"""       
     1285        r"""
    12861286        Return the homspace ``Hom(self, codomain, cat)`` of all
    12871287        homomorphisms from self to codomain in the category cat.  The
    12881288        default category is :meth:`category``.
    12891289
     1290        .. SEEALSO:: :func:`~sage.categories.homset.Hom`
     1291
    12901292        EXAMPLES::
    12911293       
    12921294            sage: R.<x,y> = PolynomialRing(QQ, 2)
     
    13081310            Set of Morphisms from Rational Field to Integer Ring in Category of sets
    13091311
    13101312        A parent may specify how to construct certain homsets by
    1311         implementing a method :meth:`_Hom_`(codomain, category). This
    1312         method should either construct the requested homset or raise a
    1313         ``TypeError``.
     1313        implementing a method :meth:`_Hom_`(codomain, category).
     1314        See :func:`~sage.categories.homset.Hom` for details.
    13141315        """
    1315         try:
    1316             return self._Hom_(codomain, category)
    1317         except (AttributeError, TypeError):
    1318             pass
    13191316        from sage.categories.homset import Hom
    13201317        return Hom(self, codomain, category)
    13211318
     
    27572754            # probably
    27582755            import sage.rings.infinity
    27592756            return sage.rings.infinity.infinity
    2760            
    2761 #     def _Hom_disabled(self, domain, cat=None):
    2762 #         """
    2763 #         By default, create a homset in the category of sets.
    2764        
    2765 #         EXAMPLES:
    2766 #             sage: R = sage.structure.parent.Set_PythonType(int)
    2767 #             sage: S = sage.structure.parent.Set_PythonType(float)
    2768 #             sage: R._Hom_(S)
    2769 #             Set of Morphisms from Set of Python objects of type 'int' to Set of Python objects of type 'float' in Category of sets
    2770 #         """
    2771 #         from sage.categories.sets_cat import Sets
    2772 #         from sage.categories.homset import Homset
    2773 #         if cat is None:
    2774 #             cat = Sets()
    2775 #         return Homset(self, domain, cat)
    27762757
    27772758# These functions are to guarantee that user defined _lmul_, _rmul_,
    27782759# _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