# HG changeset patch
# User Travis Scrimshaw <tscrim@ucdavis.edur>
# Date 1368759509 25200
# Node ID 6df423f92134651196ec67a27d80e93744380ed6
# Parent 77c87d9376e6c2eff25ab5aa625ccc14c9f62306
#11935: review patch.
diff --git a/sage/categories/category.py b/sage/categories/category.py
a
|
b
|
class Category(UniqueRepresentation, Sag |
436 | 436 | |
437 | 437 | INPUT: |
438 | 438 | |
439 | | - ``s`` -- A string giving the name of this category. |
440 | | If None, the name is determined from the name of the class. |
| 439 | - ``s`` -- (Default: ``None``) A string giving the name of this |
| 440 | category. If ``None``, the name is determined from the name of |
| 441 | the class. |
441 | 442 | |
442 | 443 | EXAMPLES:: |
443 | 444 | |
… |
… |
class Category(UniqueRepresentation, Sag |
655 | 656 | ``category`` is a subclass of the parent class of ``self``. |
656 | 657 | This is most of the time a complete subcategory test. |
657 | 658 | |
658 | | .. warning:: |
| 659 | .. WARNING:: |
659 | 660 | |
660 | 661 | This test is incomplete for categories in |
661 | 662 | :class:`CategoryWithParameters`, as introduced by |
662 | 663 | :trac:`11935`. This method is therefore overwritten by |
663 | 664 | :meth:`~sage.categories.category.CategoryWithParameters._subcategory_hook_`. |
664 | 665 | |
665 | | EXAMPLE:: |
| 666 | EXAMPLES:: |
666 | 667 | |
667 | 668 | sage: Rings()._subcategory_hook_(Rings()) |
668 | 669 | True |
… |
… |
class Category(UniqueRepresentation, Sag |
1034 | 1035 | |
1035 | 1036 | def _make_named_class(self, name, method_provider, cache=False, picklable=True): |
1036 | 1037 | """ |
1037 | | Construction of the parent/element/... class of self. |
| 1038 | Construction of the parent/element/... class of ``self``. |
1038 | 1039 | |
1039 | 1040 | INPUT: |
1040 | 1041 | |
1041 | | - ``name`` -- a string; the name of the class as an attribute of ``self``. |
1042 | | E.g. "parent_class" |
| 1042 | - ``name`` -- a string; the name of the class as an attribute of |
| 1043 | ``self``. E.g. "parent_class" |
1043 | 1044 | - ``method_provider`` -- a string; the name of an attribute of |
1044 | 1045 | ``self`` that provides methods for the new class (in |
1045 | 1046 | addition to those coming from the super categories). |
1046 | 1047 | E.g. "ParentMethods" |
1047 | | - ``cache`` -- a boolean or ``ignore_reduction`` (default: False) |
| 1048 | - ``cache`` -- a boolean or ``ignore_reduction`` (default: ``False``) |
1048 | 1049 | (passed down to dynamic_class; for internal use only) |
1049 | | - ``picklable`` -- a boolean (default: True) |
| 1050 | - ``picklable`` -- a boolean (default: ``True``) |
1050 | 1051 | |
1051 | 1052 | ASSUMPTION: |
1052 | 1053 | |
1053 | 1054 | It is assumed that this method is only called from a lazy |
1054 | | attribute whose name coincides with the given ``name`` |
| 1055 | attribute whose name coincides with the given ``name``. |
1055 | 1056 | |
1056 | 1057 | OUTPUT: |
1057 | 1058 | |
… |
… |
class Category(UniqueRepresentation, Sag |
1105 | 1106 | |
1106 | 1107 | sage: class A: pass |
1107 | 1108 | sage: class BrokenCategory(Category): |
1108 | | ... def super_categories(self): return [] |
1109 | | ... ParentMethods = 1 |
1110 | | ... class ElementMethods(A): |
1111 | | ... pass |
1112 | | ... class MorphismMethods(object): |
1113 | | ... pass |
| 1109 | ....: def super_categories(self): return [] |
| 1110 | ....: ParentMethods = 1 |
| 1111 | ....: class ElementMethods(A): |
| 1112 | ....: pass |
| 1113 | ....: class MorphismMethods(object): |
| 1114 | ....: pass |
1114 | 1115 | sage: C = BrokenCategory() |
1115 | 1116 | sage: C._make_named_class("parent_class", "ParentMethods") |
1116 | 1117 | Traceback (most recent call last): |
… |
… |
class HomCategory(Category): |
1748 | 1749 | |
1749 | 1750 | class CategoryWithParameters(Category): |
1750 | 1751 | """ |
1751 | | A parametrized category whose parent/element classes depend only on its super categories |
| 1752 | A parametrized category whose parent/element classes depend only on |
| 1753 | its super categories. |
1752 | 1754 | |
1753 | | Many categories in Sage are parametrized, like ``C=Algebras(K)`` |
| 1755 | Many categories in Sage are parametrized, like ``C = Algebras(K)`` |
1754 | 1756 | which takes a base ring as parameter. In many cases, however, the |
1755 | 1757 | operations provided by ``C`` in the parent class and element class |
1756 | 1758 | depend only on the super categories of ``C``. For example, the |
… |
… |
class CategoryWithParameters(Category): |
1777 | 1779 | True |
1778 | 1780 | sage: C1.parent_class is C3.parent_class |
1779 | 1781 | False |
1780 | | |
1781 | 1782 | """ |
1782 | 1783 | def _make_named_class(self, name, method_provider, cache = False, **options): |
1783 | 1784 | """ |
… |
… |
class CategoryWithParameters(Category): |
1785 | 1786 | |
1786 | 1787 | INPUT: |
1787 | 1788 | |
1788 | | - ``name`` -- a string; the name of the class as an attribute of ``self`` |
| 1789 | - ``name`` -- a string; the name of the class as an attribute |
| 1790 | of ``self`` |
1789 | 1791 | - ``method_provider`` -- a string; the name of an attribute of |
1790 | 1792 | ``self`` that provides methods for the new class (in |
1791 | | addition to what comes from the super categories). |
| 1793 | addition to what comes from the super categories) |
1792 | 1794 | |
1793 | 1795 | ASSUMPTION: |
1794 | 1796 | |
1795 | 1797 | It is assumed that this method is only called from a lazy |
1796 | | attribute whose name coincides with the given ``name`` |
| 1798 | attribute whose name coincides with the given ``name``. |
1797 | 1799 | |
1798 | 1800 | OUTPUT: |
1799 | 1801 | |
1800 | 1802 | A dynamic class that has the corresponding named classes of |
1801 | 1803 | the super categories of ``self`` as bases and contains the |
1802 | | methods provided by ``getattr(self,method_provider)``. |
| 1804 | methods provided by ``getattr(self, method_provider)``. |
1803 | 1805 | |
1804 | 1806 | .. NOTE:: |
1805 | 1807 | |
… |
… |
class CategoryWithParameters(Category): |
1810 | 1812 | classes across closely related categories providing the |
1811 | 1813 | same code to their parents, elements and so on. |
1812 | 1814 | |
1813 | | EXAMPLES:: |
| 1815 | EXAMPLES: |
1814 | 1816 | |
1815 | | The categories of bimodules over the fields ``CC`` or ``QQ`` |
| 1817 | The categories of bimodules over the fields ``CC`` or ``RR`` |
1816 | 1818 | provide the same methods to their parents and elements:: |
1817 | 1819 | |
1818 | 1820 | sage: Bimodules(ZZ,RR).parent_class is Bimodules(ZZ,RDF).parent_class #indirect doctest |
… |
… |
class CategoryWithParameters(Category): |
1828 | 1830 | sage: Modules(GF(3)).element_class is Modules(ZZ).element_class |
1829 | 1831 | False |
1830 | 1832 | |
1831 | | One could possibly share those classes, but this is not |
1832 | | currently the case:: |
| 1833 | For a more subtle example, one could possibly share the classes for |
| 1834 | ``GF(3)`` and ``GF(2^3, 'x')``, but this is not currently the case:: |
1833 | 1835 | |
1834 | 1836 | sage: Modules(GF(3)).parent_class is Modules(GF(2^3,'x')).parent_class |
1835 | 1837 | False |
… |
… |
class CategoryWithParameters(Category): |
1841 | 1843 | sage: GF(2^3,'x').category() |
1842 | 1844 | Category of finite fields |
1843 | 1845 | |
| 1846 | Similarly for ``QQ`` and ``RR``:: |
| 1847 | |
| 1848 | sage: QQ.category() |
| 1849 | Category of quotient fields |
| 1850 | sage: RR.category() |
| 1851 | Category of fields |
| 1852 | sage: Modules(QQ).parent_class is Modules(RR).parent_class |
| 1853 | False |
| 1854 | |
1844 | 1855 | Some other cases where one could potentially share those classes:: |
1845 | 1856 | |
1846 | 1857 | sage: Modules(GF(3),dispatch=False).parent_class is Modules(ZZ).parent_class |
… |
… |
class CategoryWithParameters(Category): |
1879 | 1890 | |
1880 | 1891 | INPUT: |
1881 | 1892 | |
1882 | | - ``name`` -- a string; the name of the class as an attribute of ``self`` |
| 1893 | - ``name`` -- a string; the name of the class as an attribute |
| 1894 | of ``self`` |
1883 | 1895 | |
1884 | 1896 | .. SEEALSO:: |
1885 | 1897 | |
… |
… |
class CategoryWithParameters(Category): |
1913 | 1925 | |
1914 | 1926 | def _subcategory_hook_(self, C): |
1915 | 1927 | """ |
1916 | | A quick but partial test whether ``C`` is a subcategory of ``self`` |
| 1928 | A quick but partial test whether ``C`` is a subcategory of ``self``. |
1917 | 1929 | |
1918 | 1930 | INPUT: |
1919 | 1931 | |
… |
… |
class CategoryWithParameters(Category): |
1921 | 1933 | |
1922 | 1934 | OUTPUT: |
1923 | 1935 | |
1924 | | - ``False``, if ``C.parent_class`` is not a subclass of |
1925 | | ``self.parent_class``, and :obj:`~sage.misc.unknown.Unknown` |
1926 | | otherwise. |
| 1936 | ``False``, if ``C.parent_class`` is not a subclass of |
| 1937 | ``self.parent_class``, and :obj:`~sage.misc.unknown.Unknown` |
| 1938 | otherwise. |
1927 | 1939 | |
1928 | 1940 | EXAMPLES:: |
1929 | 1941 | |
… |
… |
class JoinCategory(CategoryWithParameter |
1967 | 1979 | Join of Category of euclidean domains and Category of commutative algebras over Finite Field of size 3 |
1968 | 1980 | sage: type(GF(3)['x']) is type(GF(5)['z']) |
1969 | 1981 | True |
1970 | | |
1971 | 1982 | """ |
1972 | 1983 | |
1973 | 1984 | def __init__(self, super_categories, **kwds): |
… |
… |
class JoinCategory(CategoryWithParameter |
2004 | 2015 | |
2005 | 2016 | Since :trac:`11935`, the element/parent classes of a join |
2006 | 2017 | category over base only depend on the element/parent class of |
2007 | | its super categories |
| 2018 | its super categories. |
2008 | 2019 | |
2009 | 2020 | .. SEEALSO:: |
2010 | 2021 | |
… |
… |
class JoinCategory(CategoryWithParameter |
2059 | 2070 | |
2060 | 2071 | def is_subcategory(self, C): |
2061 | 2072 | """ |
2062 | | Tell whether this join category is subcategory of another category `C`. |
| 2073 | Check whether this join category is subcategory of another |
| 2074 | category ``C``. |
2063 | 2075 | |
2064 | 2076 | EXAMPLES:: |
2065 | 2077 | |
2066 | 2078 | sage: Category.join([Rings(),Modules(QQ)]).is_subcategory(Category.join([Rngs(),Bimodules(QQ,QQ)])) |
2067 | 2079 | True |
2068 | | |
2069 | 2080 | """ |
2070 | 2081 | if C is self: |
2071 | 2082 | return True |
diff --git a/sage/categories/category_types.py b/sage/categories/category_types.py
a
|
b
|
class Category_over_base(CategoryWithPar |
263 | 263 | |
264 | 264 | def _subcategory_hook_(self, C): |
265 | 265 | """ |
266 | | A quick test whether a category `C` may be subcategory of this category. |
| 266 | A quick test whether a category ``C`` may be subcategory of |
| 267 | this category. |
267 | 268 | |
268 | 269 | INPUT: |
269 | 270 | |
270 | | - `C` `` a category (type not tested) |
| 271 | - ``C`` -- a category (type not tested) |
271 | 272 | |
272 | 273 | OUTPUT: |
273 | 274 | |
274 | | a boolean if it is certain that `C` is (or is not) a |
| 275 | A boolean if it is certain that ``C`` is (or is not) a |
275 | 276 | subcategory of self. :obj:`~sage.misc.unknown.Unknown` |
276 | 277 | otherwise. |
277 | 278 | |
diff --git a/sage/structure/dynamic_class.py b/sage/structure/dynamic_class.py
a
|
b
|
def dynamic_class(name, bases, cls = Non |
126 | 126 | |
127 | 127 | - ``name`` -- a string |
128 | 128 | - ``bases`` -- a tuple of classes |
129 | | - ``cls`` -- a class or None |
130 | | - ``reduction`` -- a tuple or None |
131 | | - ``doccls`` -- a class or None |
132 | | - ``prepend_cls_bases`` -- a boolean (default: True) |
133 | | - ``cache`` -- a boolean or "ignore_reduction" (default: True) |
| 129 | - ``cls`` -- a class or ``None`` |
| 130 | - ``reduction`` -- a tuple or ``None`` |
| 131 | - ``doccls`` -- a class or ``None`` |
| 132 | - ``prepend_cls_bases`` -- a boolean (default: ``True``) |
| 133 | - ``cache`` -- a boolean or ``"ignore_reduction"`` (default: ``True``) |
134 | 134 | |
135 | 135 | Constructs dynamically a new class ``C`` with name ``name``, and |
136 | 136 | bases ``bases``. If ``cls`` is provided, then its methods will be |
137 | 137 | inserted into ``C``, and its bases will be prepended to ``bases`` |
138 | | (unless ``prepend_cls_bases`` is False). |
| 138 | (unless ``prepend_cls_bases`` is ``False``). |
139 | 139 | |
140 | 140 | The module, documentation and source instrospection is taken from |
141 | 141 | ``doccls``, or ``cls`` if ``doccls`` is ``None``, or ``bases[0]`` |
… |
… |
def dynamic_class(name, bases, cls = Non |
145 | 145 | The constructed class can safely be pickled (assuming the |
146 | 146 | arguments themselves can). |
147 | 147 | |
148 | | Unless ``cache`` is False, the result is cached, ensuring unique |
| 148 | Unless ``cache`` is ``False``, the result is cached, ensuring unique |
149 | 149 | representation of dynamic classes. |
150 | 150 | |
151 | 151 | See :mod:`sage.structure.dynamic_class` for a discussion of the |
… |
… |
def dynamic_class(name, bases, cls = Non |
154 | 154 | EXAMPLES: |
155 | 155 | |
156 | 156 | To setup the stage, we create a class Foo with some methods, |
157 | | cached methods, and lazy_attributes, and a class Bar:: |
| 157 | cached methods, and lazy attributes, and a class Bar:: |
158 | 158 | |
159 | 159 | sage: from sage.misc.lazy_attribute import lazy_attribute |
160 | 160 | sage: from sage.misc.cachefunc import cached_function |
… |
… |
def dynamic_class(name, bases, cls = Non |
231 | 231 | |
232 | 232 | .. RUBRIC:: Caching |
233 | 233 | |
234 | | By default, the built class is cached: |
| 234 | By default, the built class is cached:: |
235 | 235 | |
236 | 236 | sage: dynamic_class("FooBar", (Bar,), Foo) is FooBar |
237 | 237 | True |
… |
… |
def dynamic_class(name, bases, cls = Non |
263 | 263 | sage: dynamic_class("BarFoo", (Foo,), Bar, reduction = (str, (2,)), cache="ignore_reduction") is BarFoo |
264 | 264 | True |
265 | 265 | |
266 | | In particular, the reduction used is that provided upon creating the first class:: |
| 266 | In particular, the reduction used is that provided upon creating the |
| 267 | first class:: |
267 | 268 | |
268 | 269 | sage: dynamic_class("BarFoo", (Foo,), Bar, reduction = (str, (2,)), cache="ignore_reduction")._reduction |
269 | 270 | (<type 'str'>, (3,)) |