Ticket #14519: trac_14519-cynthonize_element_wrapper-ts.patch
File trac_14519-cynthonize_element_wrapper-ts.patch, 88.1 KB (added by , 8 years ago) |
---|
-
doc/en/thematic_tutorials/coercion_and_categories.rst
# HG changeset patch # User Travis Scrimshaw <tscrim@ucdavis.edu> # Date 1367606736 25200 # Node ID 37047f47bdd9f2e5868c7c26c82fa85ff7c08676 # Parent b20b3463f553f8dcb3c9bacb2659882492118249 #14519: Cynthonized ElementWrapper and made parent the first argument. diff --git a/doc/en/thematic_tutorials/coercion_and_categories.rst b/doc/en/thematic_tutorials/coercion_and_categories.rst
a b be complemented later. 133 133 134 134 sage: from sage.structure.unique_representation import UniqueRepresentation 135 135 sage: class MyFrac(UniqueRepresentation, Field): 136 ... 137 ... 138 ... 139 ... 140 ... 141 ... 142 ... 143 ... 144 ... 145 ... 136 ....: def __init__(self, base): 137 ....: if base not in IntegralDomains(): 138 ....: raise ValueError, "%s is no integral domain"%base 139 ....: Field.__init__(self, base) 140 ....: def _repr_(self): 141 ....: return "NewFrac(%s)"%repr(self.base()) 142 ....: def base_ring(self): 143 ....: return self.base().base_ring() 144 ....: def characteristic(self): 145 ....: return self.base().characteristic() 146 146 147 147 .. end ouf output 148 148 … … considerations: 261 261 comparison does not work in the way expected in Python:: 262 262 263 263 sage: class Foo(sage.structure.element.Element): 264 ... def __init__(self, x, parent=None):265 ... 266 ... 267 ... 268 sage: a = Foo( 1,parent=ZZ)269 sage: b = Foo( 2,parent=ZZ)264 ....: def __init__(self, parent, x): 265 ....: self.x = x 266 ....: def _repr_(self): 267 ....: return "<%s>"%self.x 268 sage: a = Foo(ZZ, 1) 269 sage: b = Foo(ZZ, 2) 270 270 sage: cmp(a,b) 271 271 Traceback (most recent call last): 272 272 ... … … considerations: 279 279 This gives rise to the following code:: 280 280 281 281 sage: class MyElement(FieldElement): 282 ... def __init__(self, n,d=None, parent=None): 283 ... if parent is None: 284 ... raise ValueError, "The parent must be provided" 285 ... B = parent.base() 286 ... if d is None: 287 ... d = B.one_element() 288 ... if n not in B or d not in B: 289 ... raise ValueError, "Numerator and denominator must be elements of %s"%B 290 ... # Numerator and denominator should not just be "in" B, 291 ... # but should be defined as elements of B 292 ... d = B(d) 293 ... n = B(n) 294 ... if d==0: 295 ... raise ZeroDivisionError, "The denominator must not be zero" 296 ... if d<0: 297 ... self.n = -n 298 ... self.d = -d 299 ... else: 300 ... self.n = n 301 ... self.d = d 302 ... FieldElement.__init__(self,parent) 303 ... def numerator(self): 304 ... return self.n 305 ... def denominator(self): 306 ... return self.d 307 ... def _repr_(self): 308 ... return "(%s):(%s)"%(self.n,self.d) 309 ... def __cmp__(self, other): 310 ... return cmp(self.n*other.denominator(), other.numerator()*self.d) 311 ... def _add_(self, other): 312 ... C = self.__class__ 313 ... D = self.d*other.denominator() 314 ... return C(self.n*other.denominator()+self.d*other.numerator(),D, self.parent()) 315 ... def _sub_(self, other): 316 ... C = self.__class__ 317 ... D = self.d*other.denominator() 318 ... return C(self.n*other.denominator()-self.d*other.numerator(),D, self.parent()) 319 ... def _mul_(self, other): 320 ... C = self.__class__ 321 ... return C(self.n*other.numerator(), self.d*other.denominator(), self.parent()) 322 ... def _div_(self, other): 323 ... C = self.__class__ 324 ... return C(self.n*other.denominator(), self.d*other.numerator(), self.parent()) 282 ....: def __init__(self, parent,n,d=None): 283 ....: B = parent.base() 284 ....: if d is None: 285 ....: d = B.one_element() 286 ....: if n not in B or d not in B: 287 ....: raise ValueError("Numerator and denominator must be elements of %s"%B) 288 ....: # Numerator and denominator should not just be "in" B, 289 ....: # but should be defined as elements of B 290 ....: d = B(d) 291 ....: n = B(n) 292 ....: if d==0: 293 ....: raise ZeroDivisionError("The denominator must not be zero") 294 ....: if d<0: 295 ....: self.n = -n 296 ....: self.d = -d 297 ....: else: 298 ....: self.n = n 299 ....: self.d = d 300 ....: FieldElement.__init__(self,parent) 301 ....: def numerator(self): 302 ....: return self.n 303 ....: def denominator(self): 304 ....: return self.d 305 ....: def _repr_(self): 306 ....: return "(%s):(%s)"%(self.n,self.d) 307 ....: def __cmp__(self, other): 308 ....: return cmp(self.n*other.denominator(), other.numerator()*self.d) 309 ....: def _add_(self, other): 310 ....: C = self.__class__ 311 ....: D = self.d*other.denominator() 312 ....: return C(self.parent(), self.n*other.denominator()+self.d*other.numerator(), D) 313 ....: def _sub_(self, other): 314 ....: C = self.__class__ 315 ....: D = self.d*other.denominator() 316 ....: return C(self.parent(), self.n*other.denominator()-self.d*other.numerator(),D) 317 ....: def _mul_(self, other): 318 ....: C = self.__class__ 319 ....: return C(self.parent(), self.n*other.numerator(), self.d*other.denominator()) 320 ....: def _div_(self, other): 321 ....: C = self.__class__ 322 ....: return C(self.parent(), self.n*other.denominator(), self.d*other.numerator()) 325 323 326 324 .. end of output 327 325 … … Thanks to the single underscore methods, 333 331 we stay inside a single parent structure:: 334 332 335 333 sage: P = MyFrac(ZZ) 336 sage: a = MyElement( 3,4,P)337 sage: b = MyElement( 1,2,P)334 sage: a = MyElement(P, 3, 4) 335 sage: b = MyElement(P, 1, 2) 338 336 sage: a+b, a-b, a*b, a/b 339 337 ((10):(8), (2):(8), (3):(8), (6):(4)) 340 sage: a-b == MyElement( 1,4,P)338 sage: a-b == MyElement(P, 1, 4) 341 339 True 342 340 343 341 .. end of output … … category:: 504 502 505 503 sage: from sage.categories.quotient_fields import QuotientFields 506 504 sage: class MyFrac(MyFrac): 507 ... 508 ... 509 ... 510 ... 505 ....: def __init__(self, base, category=None): 506 ....: if base not in IntegralDomains(): 507 ....: raise ValueError, "%s is no integral domain"%base 508 ....: Field.__init__(self, base, category=category or QuotientFields()) 511 509 512 510 When constructing instances of ``MyFrac``, their class is dynamically changed 513 511 into a new class called ``MyFrac_with_category``. It is a common sub\--class of … … monoids\---see 535 533 We have seen above that we can add elements. Nevertheless, the ``sum`` method 536 534 does not work, yet:: 537 535 538 sage: a = MyElement( 3,4,P)539 sage: b = MyElement( 1,2,P)540 sage: c = MyElement( -1,2,P)541 sage: P.sum([a, b,c])536 sage: a = MyElement(P, 3, 4) 537 sage: b = MyElement(P, 1, 2) 538 sage: c = MyElement(P, -1, 2) 539 sage: P.sum([a, b, c]) 542 540 Traceback (most recent call last): 543 541 ... 544 542 NotImplementedError … … Hence, for providing our fraction fields 566 564 just need to add a single line to our class**:: 567 565 568 566 sage: class MyFrac(MyFrac): 569 ... 567 ....: Element = MyElement 570 568 571 569 572 570 .. end of output … … This little change provides several bene 586 584 587 585 - The ``sum`` method mentioned above suddenly works:: 588 586 589 sage: a = MyElement( 9,4,P)590 sage: b = MyElement( 1,2,P)591 sage: c = MyElement( -1,2,P)587 sage: a = MyElement(P, 9, 4) 588 sage: b = MyElement(P, 1, 2) 589 sage: c = MyElement(P, -1, 2) 592 590 sage: P.sum([a,b,c]) 593 591 (36):(16) 594 592 … … refactor them! 862 860 :: 863 861 864 862 sage: class MyFrac(MyFrac): 865 ... def _element_constructor_(self, *args,**kwds):866 ... 867 ... return self.element_class(*args,parent=self,**kwds)868 ... 869 ... 870 ... 871 ... 872 ... return self.element_class(x,parent=self,**kwds)873 ... 874 ... return self.element_class(x.numerator(),x.denominator(),parent=self,**kwds)875 ... return self.element_class(x,parent=self,**kwds)863 ....: def _element_constructor_(self, *args, **kwds): 864 ....: if len(args)!=1: 865 ....: return self.element_class(self, *args, **kwds) 866 ....: x = args[0] 867 ....: try: 868 ....: P = x.parent() 869 ....: except AttributeError: 870 ....: return self.element_class(self, x, **kwds) 871 ....: if P in QuotientFields() and P != self.base(): 872 ....: return self.element_class(self, x.numerator(), x.denominator(), **kwds) 873 ....: return self.element_class(self, x, **kwds) 876 874 877 875 878 876 .. end of output … … rational field, since ``QQ.base()`` is n 932 930 :: 933 931 934 932 sage: class MyFrac(MyFrac): 935 ... 936 ... 937 ... 938 ... 939 ... 940 ... 941 ... 942 ... 933 ....: def _coerce_map_from_(self, S): 934 ....: if self.base().has_coerce_map_from(S): 935 ....: return True 936 ....: if S in QuotientFields(): 937 ....: if self.base().has_coerce_map_from(S.base()): 938 ....: return True 939 ....: if hasattr(S,'ring_of_integers') and self.base().has_coerce_map_from(S.ring_of_integers()): 940 ....: return True 943 941 944 942 945 943 .. end of output … … default implementation. Hence: 1284 1282 1285 1283 sage: from sage.categories.pushout import ConstructionFunctor 1286 1284 sage: class MyFracFunctor(ConstructionFunctor): 1287 ... 1288 ... 1289 ... 1290 ... 1291 ... 1292 ... 1293 ... 1294 ... 1285 ....: rank = 5 1286 ....: def __init__(self): 1287 ....: ConstructionFunctor.__init__(self, IntegralDomains(), Fields()) 1288 ....: def _apply_functor(self, R): 1289 ....: return MyFrac(R) 1290 ....: def merge(self, other): 1291 ....: if isinstance(other, (type(self), sage.categories.pushout.FractionField)): 1292 ....: return self 1295 1293 1296 1294 1297 1295 .. end of output … … There remains to let our new fraction fi 1333 1331 :: 1334 1332 1335 1333 sage: class MyFrac(MyFrac): 1336 ... 1337 ... 1334 ....: def construction(self): 1335 ....: return MyFracFunctor(), self.base() 1338 1336 1339 1337 1340 1338 .. end of output … … For example, if one forgets to implement 1451 1449 following error:: 1452 1450 1453 1451 sage: class Foo(Parent): 1454 ... 1455 ... 1456 ... 1452 ....: Element = sage.structure.element.Element 1453 ....: def __init__(self): 1454 ....: Parent.__init__(self, category=QuotientFields()) 1457 1455 sage: Bar = Foo() 1458 1456 sage: bar = Bar.element_class(Bar) 1459 1457 sage: bar._test_not_implemented_methods() … … that. We also override the some_elements 1553 1551 :: 1554 1552 1555 1553 sage: class MyFrac(MyFrac): 1556 ... 1557 ... 1558 ... 1559 ... 1560 ... 1561 ... 1562 ... 1563 ... 1564 ... 1565 ... 1554 ....: def _an_element_(self): 1555 ....: a = self.base().an_element() 1556 ....: b = self.base_ring().an_element() 1557 ....: if (a+b)!=0: 1558 ....: return self(a)**2/(self(a+b)**3) 1559 ....: if b != 0: 1560 ....: return self(a)/self(b)**2 1561 ....: return self(a)**2*self(b)**3 1562 ....: def some_elements(self): 1563 ....: return [self.an_element(),self(self.base().an_element()),self(self.base_ring().an_element())] 1566 1564 1567 1565 1568 1566 .. end of output … … the category, as follows:: 1611 1609 1612 1610 sage: from sage.categories.category import Category 1613 1611 sage: class QuotientFieldsWithTest(Category): # do *not* inherit from QuotientFields, but ... 1614 ... 1615 ... 1616 ... 1617 ... 1618 ... 1619 ... 1620 ... 1621 ... 1612 ....: def super_categories(self): 1613 ....: return [QuotientFields()] # ... declare QuotientFields as a super category! 1614 ....: class ParentMethods: 1615 ....: pass 1616 ....: class ElementMethods: 1617 ....: def _test_factorisation(self, **options): 1618 ....: P = self.parent() 1619 ....: assert self == P.prod([P(b)**e for b,e in self.factor()]) 1622 1620 1623 1621 1624 1622 .. end of output … … Appendix: The complete code 1721 1719 1722 1720 # Fraction field elements 1723 1721 class MyElement(FieldElement): 1724 def __init__(self, n,d=None, parent=None):1722 def __init__(self, parent, n, d=None): 1725 1723 if parent is None: 1726 raise ValueError , "The parent must be provided"1724 raise ValueError("The parent must be provided") 1727 1725 B = parent.base() 1728 1726 if d is None: 1729 1727 # The default denominator is one 1730 1728 d = B.one_element() 1731 1729 # verify that both numerator and denominator belong to the base 1732 1730 if n not in B or d not in B: 1733 raise ValueError , "Numerator and denominator must be elements of %s"%B1731 raise ValueError("Numerator and denominator must be elements of %s"%B) 1734 1732 # Numerator and denominator should not just be "in" B, 1735 1733 # but should be defined as elements of B 1736 1734 d = B(d) 1737 1735 n = B(n) 1738 1736 # the denominator must not be zero 1739 1737 if d==0: 1740 raise ZeroDivisionError , "The denominator must not be zero"1738 raise ZeroDivisionError("The denominator must not be zero") 1741 1739 # normalize the denominator: WLOG, it shall be non-negative. 1742 1740 if d<0: 1743 1741 self.n = -n … … Appendix: The complete code 1770 1768 def _add_(self, other): 1771 1769 C = self.__class__ 1772 1770 D = self.d*other.denominator() 1773 return C(self. n*other.denominator()+self.d*other.numerator(),D, self.parent())1771 return C(self.parent(), self.n*other.denominator()+self.d*other.numerator(),D) 1774 1772 def _sub_(self, other): 1775 1773 C = self.__class__ 1776 1774 D = self.d*other.denominator() 1777 return C(self. n*other.denominator()-self.d*other.numerator(),D, self.parent())1775 return C(self.parent(), self.n*other.denominator()-self.d*other.numerator(),D) 1778 1776 def _mul_(self, other): 1779 1777 C = self.__class__ 1780 return C(self. n*other.numerator(), self.d*other.denominator(), self.parent())1778 return C(self.parent(), self.n*other.numerator(), self.d*other.denominator()) 1781 1779 def _div_(self, other): 1782 1780 C = self.__class__ 1783 return C(self. n*other.denominator(), self.d*other.numerator(), self.parent())1781 return C(self.parent(), self.n*other.denominator(), self.d*other.numerator()) 1784 1782 1785 1783 # Inheritance from UniqueRepresentation implements the unique parent 1786 1784 # behaviour. Moreover, it implements pickling (provided that Python … … Appendix: The complete code 1809 1807 return self.base().characteristic() 1810 1808 1811 1809 # Implement conversions. Do not override __call__! 1812 def _element_constructor_(self, *args, **kwds):1810 def _element_constructor_(self, *args, **kwds): 1813 1811 if len(args)!=1: 1814 return self.element_class( *args,parent=self,**kwds)1812 return self.element_class(self, *args, **kwds) 1815 1813 x = args[0] 1816 1814 try: 1817 1815 P = x.parent() 1818 1816 except AttributeError: 1819 return self.element_class( x,parent=self,**kwds)1817 return self.element_class(self, x, **kwds) 1820 1818 if P in QuotientFields() and P != self.base(): 1821 return self.element_class( x.numerator(),x.denominator(),parent=self,**kwds)1822 return self.element_class( x,parent=self,**kwds)1819 return self.element_class(self, x.numerator(), x.denominator(), **kwds) 1820 return self.element_class(self, x, **kwds) 1823 1821 1824 1822 # Implement coercion from the base and from fraction fields 1825 1823 # over a ring that coerces into the base -
module_list.py
diff --git a/module_list.py b/module_list.py
a b ext_modules = [ 1895 1895 sources = ['sage/structure/element.pyx'], 1896 1896 extra_compile_args=["-Os"]), 1897 1897 1898 Extension('sage.structure.element_wrapper', 1899 sources = ['sage/structure/element_wrapper.pyx']), 1900 1898 1901 Extension('sage.structure.factory', 1899 1902 sources = ['sage/structure/factory.pyx']), 1900 1903 -
sage/categories/examples/commutative_additive_semigroups.py
diff --git a/sage/categories/examples/commutative_additive_semigroups.py b/sage/categories/examples/commutative_additive_semigroups.py
a b class FreeCommutativeAdditiveSemigroup(U 140 140 return self((a, (ord(a)-96)) for a in self.alphabet) 141 141 142 142 class Element(ElementWrapper): 143 def __init__(self, iterable, parent):143 def __init__(self, parent, iterable): 144 144 """ 145 145 EXAMPLES:: 146 146 147 147 sage: F = CommutativeAdditiveSemigroups().example() 148 sage: x = F.element_class( (('a',4), ('b', 0), ('a', 2), ('c', 1), ('d', 5)), F)148 sage: x = F.element_class(F, (('a',4), ('b', 0), ('a', 2), ('c', 1), ('d', 5))) 149 149 sage: x 150 150 2*a + c + 5*d 151 151 sage: x.value … … class FreeCommutativeAdditiveSemigroup(U 164 164 d = dict( (a,0) for a in parent.alphabet ) 165 165 for (a, c) in iterable: 166 166 d[a] = c 167 ElementWrapper.__init__(self, parent = parent, value =d)167 ElementWrapper.__init__(self, parent, d) 168 168 169 169 def _repr_(self): 170 170 """ -
sage/categories/examples/semigroups.py
diff --git a/sage/categories/examples/semigroups.py b/sage/categories/examples/semigroups.py
a b class FreeSemigroup(UniqueRepresentation 309 309 """ 310 310 for a in x: 311 311 assert a in self.alphabet 312 return self.element_class( x, parent = self)312 return self.element_class(self, x) 313 313 314 314 class Element(ElementWrapper): 315 315 r""" … … class QuotientOfLeftZeroSemigroup(Unique 540 540 if x.value > 42: 541 541 return self.the_answer() 542 542 else: 543 return self.element_class( x, parent = self)543 return self.element_class(self, x) 544 544 545 545 class Element(ElementWrapper): 546 546 pass -
sage/categories/examples/semigroups_cython.pyx
diff --git a/sage/categories/examples/semigroups_cython.pyx b/sage/categories/examples/semigroups_cython.pyx
a b class IdempotentSemigroups(Category): 48 48 cdef class LeftZeroSemigroupElement(Element): 49 49 cdef object _value 50 50 51 def __init__(self, value, parent):51 def __init__(self, parent, value): 52 52 """ 53 53 EXAMPLES:: 54 54 … … cdef class LeftZeroSemigroupElement(Elem 80 80 sage: x = S(3) 81 81 sage: x.__reduce__() 82 82 (<type 'sage.categories.examples.semigroups_cython.LeftZeroSemigroupElement'>, 83 ( 3, An example of a semigroup: the left zero semigroup))83 (An example of a semigroup: the left zero semigroup, 3)) 84 84 """ 85 return LeftZeroSemigroupElement, (self._ value, self._parent)85 return LeftZeroSemigroupElement, (self._parent, self._value) 86 86 87 87 def __cmp__(LeftZeroSemigroupElement self, LeftZeroSemigroupElement other): 88 88 """ -
sage/categories/examples/sets_cat.py
diff --git a/sage/categories/examples/sets_cat.py b/sage/categories/examples/sets_cat.py
a b class PrimeNumbers_Inherits(PrimeNumbers 400 400 sage: P._from_integer_(42) # Don't do that at home kids! 401 401 42 402 402 """ 403 return self.element_class( p, self)403 return self.element_class(self, p) 404 404 405 405 class Element(IntegerWrapper, PrimeNumbers_Abstract.Element): 406 def __init__(self, p , parent):406 def __init__(self, parent, p): 407 407 """ 408 408 TESTS:: 409 409 … … class PrimeNumbers_Inherits(PrimeNumbers 417 417 sage: x.parent() is P 418 418 True 419 419 """ 420 IntegerWrapper.__init__(self, p , parent=parent)420 IntegerWrapper.__init__(self, parent, p) 421 421 422 422 423 423 #*************************************************************************# … … class PrimeNumbers_Wrapper(PrimeNumbers_ 524 524 ... 525 525 ValueError: 14 is not a prime number 526 526 """ 527 return self.element_class( Integer(e), parent=self)527 return self.element_class(self, Integer(e)) 528 528 529 529 from sage.structure.element_wrapper import ElementWrapper 530 530 class Element (ElementWrapper, PrimeNumbers_Abstract.Element): -
sage/categories/primer.py
diff --git a/sage/categories/primer.py b/sage/categories/primer.py
a b Where do all the operations on ``S`` and 338 338 339 339 sage: x = S('a') 340 340 341 ``_repr_`` is a technical method which comes with the data structure (ElementWrapper):: 341 ``_repr_`` is a technical method which comes with the data structure 342 (ElementWrapper), however we can't see it in python because it is an 343 extension class (it is in `sage.structure.element_wrapper`):: 342 344 343 345 sage: x._repr_.__module__ 344 'sage.structure.element_wrapper'346 <BLANKLINE> 345 347 346 348 ``__pow__`` is a generic method for all finite semigroups:: 347 349 … … categories translates into *inheritance* 444 446 sage: x.__class__.mro() 445 447 [<class 'sage.categories.examples.finite_semigroups.LeftRegularBand_with_category.element_class'>, 446 448 <class 'sage.categories.examples.finite_semigroups.LeftRegularBand.Element'>, 447 < class'sage.structure.element_wrapper.ElementWrapper'>,449 <type 'sage.structure.element_wrapper.ElementWrapper'>, 448 450 <type 'sage.structure.element.Element'>, 449 451 <type 'sage.structure.sage_object.SageObject'>, 450 452 <class 'sage.categories.category.FiniteSemigroups.element_class'>, -
sage/categories/sets_cat.py
diff --git a/sage/categories/sets_cat.py b/sage/categories/sets_cat.py
a b class Sets(Category_singleton): 336 336 sage: S._element_constructor_from_element_class(17) 337 337 17 338 338 """ 339 return self.element_class( parent =self, *args, **keywords)339 return self.element_class(self, *args, **keywords) 340 340 341 341 def is_parent_of(self, element): 342 342 """ -
sage/combinat/core.py
diff --git a/sage/combinat/core.py b/sage/combinat/core.py
a b class Core(CombinatorialObject, Element) 82 82 l = sum(part.k_boundary(k).row_lengths()) 83 83 return Cores(k, l)(part) 84 84 85 def __init__(self, core, parent):85 def __init__(self, parent, core): 86 86 """ 87 87 TESTS:: 88 88 -
sage/combinat/crystals/affine.py
diff --git a/sage/combinat/crystals/affine.py b/sage/combinat/crystals/affine.py
a b class AffineCrystalFromClassical(UniqueR 198 198 sage: A.retract(t).parent() is A 199 199 True 200 200 """ 201 return self.element_class( classical_elt, parent = self)201 return self.element_class(self, classical_elt) 202 202 203 203 def _element_constructor_(self, *value, **options): 204 204 r""" -
sage/combinat/crystals/alcove_path.py
diff --git a/sage/combinat/crystals/alcove_path.py b/sage/combinat/crystals/alcove_path.py
a b class CrystalOfAlcovePaths(UniqueReprese 334 334 self._finite_cartan_type = False 335 335 336 336 337 self.module_generators = ( self.element_class( (), self), )337 self.module_generators = ( self.element_class(self, ()), ) 338 338 339 339 def _repr_(self): 340 340 """ … … class CrystalOfAlcovePaths(UniqueReprese 364 364 ((alpha[1], 2), (alpha[1] + alpha[2], 4)) 365 365 """ 366 366 if isinstance(data, tuple): 367 return self.element_class( data, self)367 return self.element_class(self, data) 368 368 elif isinstance(data, list): 369 369 lambda_chain = self._R.lambda_chain() 370 370 #data starts indexing at 0 371 return self.element_class( tuple(sorted([lambda_chain[i] for i in data])), self)371 return self.element_class(self, tuple(sorted([lambda_chain[i] for i in data]))) 372 372 373 373 def vertices(self): 374 374 """ -
sage/combinat/perfect_matching.py
diff --git a/sage/combinat/perfect_matching.py b/sage/combinat/perfect_matching.py
a b class PerfectMatching(ElementWrapper): 777 777 [] 778 778 """ 779 779 from sage.combinat.permutation import Permutation 780 return Permutation(self. __dict__['value'])780 return Permutation(self.value) 781 781 782 782 783 783 class PerfectMatchings(UniqueRepresentation, Parent): -
sage/combinat/root_system/weyl_group.py
diff --git a/sage/combinat/root_system/weyl_group.py b/sage/combinat/root_system/weyl_group.py
a b class WeylGroupElement(MatrixGroupElemen 633 633 """ 634 634 Class for a Weyl Group elements 635 635 """ 636 def __init__(self, g, parent, check=False):636 def __init__(self, parent, g, check=False): 637 637 """ 638 638 EXAMPLES:: 639 639 640 640 sage: G = WeylGroup(['A',2]) 641 641 sage: s1 = G.simple_reflection(1) 642 642 sage: TestSuite(s1).run() 643 643 """ 644 MatrixGroupElement_gap.__init__(self, g, parent, check=check)644 MatrixGroupElement_gap.__init__(self, parent, g, check=check) 645 645 self.__matrix = self.matrix() 646 646 self._parent = parent 647 647 -
sage/groups/abelian_gps/abelian_group.py
diff --git a/sage/groups/abelian_gps/abelian_group.py b/sage/groups/abelian_gps/abelian_group.py
a b class AbelianGroup_class(UniqueRepresent 906 906 x = [0]*n 907 907 if self._gens_orders[i] != 1: 908 908 x[i] = 1 909 return self.element_class( x, self)909 return self.element_class(self, x) 910 910 911 911 def gens(self): 912 912 """ -
sage/groups/abelian_gps/dual_abelian_group.py
diff --git a/sage/groups/abelian_gps/dual_abelian_group.py b/sage/groups/abelian_gps/dual_abelian_group.py
a b class DualAbelianGroup_class(UniqueRepre 259 259 x = [0]*n 260 260 if self.gens_orders()[i] != 1: 261 261 x[i] = 1 262 return self.element_class( x, self)262 return self.element_class(self, x) 263 263 264 264 def gens(self): 265 265 """ -
sage/groups/abelian_gps/element_base.py
diff --git a/sage/groups/abelian_gps/element_base.py b/sage/groups/abelian_gps/element_base.py
a b class AbelianGroupElementBase(Multiplica 52 52 True 53 53 """ 54 54 55 def __init__(self, exponents, parent):55 def __init__(self, parent, exponents): 56 56 """ 57 57 Create an element. 58 58 … … class AbelianGroupElementBase(Multiplica 233 233 exponents = [ (x-y)%order if order!=0 else x-y 234 234 for x, y, order in 235 235 zip(left._exponents, right._exponents, G.gens_orders()) ] 236 return G.element_class( exponents, G)236 return G.element_class(G, exponents) 237 237 238 238 def _mul_(left, right): 239 239 """ … … class AbelianGroupElementBase(Multiplica 252 252 exponents = [ (x+y)%order if order!=0 else x+y 253 253 for x, y, order in 254 254 zip(left._exponents, right._exponents, G.gens_orders()) ] 255 return G.element_class( exponents, G)255 return G.element_class(G, exponents) 256 256 257 257 def __pow__(self, n): 258 258 """ … … class AbelianGroupElementBase(Multiplica 270 270 G = self.parent() 271 271 exponents = [ (m*e) % order if order!=0 else m*e 272 272 for e,order in zip(self._exponents, G.gens_orders()) ] 273 return G.element_class( exponents, G)273 return G.element_class(G, exponents) 274 274 275 275 def inverse(self): 276 276 """ … … class AbelianGroupElementBase(Multiplica 295 295 G = self.parent() 296 296 exponents = [ (-e)%order if order!=0 else -e 297 297 for e,order in zip(self._exponents, G.gens_orders()) ] 298 return G.element_class( exponents, G)298 return G.element_class(G, exponents) 299 299 300 300 __invert__ = inverse 301 301 -
sage/groups/abelian_gps/values.py
diff --git a/sage/groups/abelian_gps/values.py b/sage/groups/abelian_gps/values.py
a b class AbelianGroupWithValuesElement(Abel 236 236 sage: TestSuite(a*b).run() 237 237 """ 238 238 239 def __init__(self, exponents, parent, value=None):239 def __init__(self, parent, exponents, value=None): 240 240 """ 241 241 Create an element 242 242 … … class AbelianGroupWithValuesElement(Abel 250 250 -1 251 251 """ 252 252 self._value = value 253 AbelianGroupElement.__init__(self, exponents, parent)253 AbelianGroupElement.__init__(self, parent, exponents) 254 254 255 255 def value(self): 256 256 """ -
sage/groups/affine_gps/affine_group.py
diff --git a/sage/groups/affine_gps/affine_group.py b/sage/groups/affine_gps/affine_group.py
a b class AffineGroup(UniqueRepresentation, 371 371 [2 3 0] [0] 372 372 """ 373 373 A = self.matrix_space()(A) 374 return self.element_class( A, self.vector_space().zero(), self, check=True, convert=False)374 return self.element_class(self, A, self.vector_space().zero(), check=True, convert=False) 375 375 376 376 def translation(self, b): 377 377 """ … … class AffineGroup(UniqueRepresentation, 394 394 [0 0 1] [3] 395 395 """ 396 396 b = self.vector_space()(b) 397 return self.element_class(self .matrix_space().one(), b, self, check=False, convert=False)397 return self.element_class(self, self.matrix_space().one(), b, check=False, convert=False) 398 398 399 399 def reflection(self, v): 400 400 """ … … class AffineGroup(UniqueRepresentation, 433 433 raise ValueError('v has norm zero') 434 434 from sage.matrix.constructor import identity_matrix 435 435 A = self.matrix_space().one() - v.column() * (v.row() * two_norm2inv) 436 return self.element_class( A, self.vector_space().zero(), self, check=True, convert=False)436 return self.element_class(self, A, self.vector_space().zero(), check=True, convert=False) 437 437 438 438 def random_element(self): 439 439 """ … … class AffineGroup(UniqueRepresentation, 454 454 while not A.is_invertible(): # a generic matrix is invertible 455 455 A.randomize() 456 456 b = self.vector_space().random_element() 457 return self.element_class( A, b, self, check=False, convert=False)457 return self.element_class(self, A, b, check=False, convert=False) 458 458 459 459 @cached_method 460 460 def _an_element_(self): … … class AffineGroup(UniqueRepresentation, 471 471 while not A.is_invertible(): # a generic matrix is not always invertible 472 472 A.randomize() 473 473 b = self.vector_space().an_element() 474 return self.element_class( A, b, self, check=False, convert=False)474 return self.element_class(self, A, b, check=False, convert=False) 475 475 -
sage/groups/affine_gps/group_element.py
diff --git a/sage/groups/affine_gps/group_element.py b/sage/groups/affine_gps/group_element.py
a b class AffineGroupElement(MatrixGroupElem 85 85 [2 0] [0] 86 86 x |-> [0 2] x + [0] 87 87 """ 88 def __init__(self, A, b=0, parent=None, convert=True, check=True):88 def __init__(self, parent, A, b=0, convert=True, check=True): 89 89 r""" 90 90 Create element of an affine group. 91 91 … … class AffineGroupElement(MatrixGroupElem 277 277 parent = self.parent() 278 278 A = self._A * other._A 279 279 b = self._b + self._A * other._b 280 return parent.element_class( A, b, parent, check=False)280 return parent.element_class(parent, A, b, check=False) 281 281 282 282 def __call__(self, v): 283 283 """ … … class AffineGroupElement(MatrixGroupElem 386 386 parent = self.parent() 387 387 A = parent.matrix_space()(self._A.inverse()) 388 388 b = -A*self.b() 389 return parent.element_class( A, b, parent, check=False)389 return parent.element_class(parent, A, b, check=False) 390 390 391 391 __invert__ = inverse 392 392 -
sage/groups/braid.py
diff --git a/sage/groups/braid.py b/sage/groups/braid.py
a b class BraidGroup_class(FinitelyPresented 673 673 sage: B([1, 2, 3]) # indirect doctest 674 674 s0*s1*s2 675 675 """ 676 return Braid( x, parent=self)676 return Braid(self, x) 677 677 678 678 def _permutation_braid_Tietze(self, p): 679 679 """ -
sage/groups/finitely_presented.py
diff --git a/sage/groups/finitely_presented.py b/sage/groups/finitely_presented.py
a b class FinitelyPresentedGroupElement(Free 173 173 b*a*b^-1*a^-1 174 174 """ 175 175 176 def __init__(self, x, parent):176 def __init__(self, parent, x): 177 177 """ 178 178 The Python constructor. 179 179 … … class FinitelyPresentedGroupElement(Free 200 200 free_element = F(x) 201 201 fp_family = parent.one().gap().FamilyObj() 202 202 x = libgap.ElementOfFpGroup(fp_family, free_element.gap()) 203 ElementLibGAP.__init__(self, x, parent)203 ElementLibGAP.__init__(self, parent, x) 204 204 205 205 def __reduce__(self): 206 206 """ … … class FinitelyPresentedGroup(UniqueRepre 684 684 a*b*a*b^-1 685 685 """ 686 686 if len(args)!=1: 687 return self.element_class( *args, parent=self, **kwds)687 return self.element_class(self, *args, **kwds) 688 688 x = args[0] 689 689 if x==1: 690 690 return self.one() 691 691 try: 692 692 P = x.parent() 693 693 except AttributeError: 694 return self.element_class( x, parent=self, **kwds)694 return self.element_class(self, x, **kwds) 695 695 if P is self._free_group: 696 return self.element_class( x.Tietze(), parent=self, **kwds)697 return self.element_class( x, parent=self, **kwds)696 return self.element_class(self, x.Tietze(), **kwds) 697 return self.element_class(self, x, **kwds) 698 698 699 699 @cached_method 700 700 def abelian_invariants(self): -
sage/groups/free_group.py
diff --git a/sage/groups/free_group.py b/sage/groups/free_group.py
a b class FreeGroupElement(ElementLibGAP): 125 125 True 126 126 """ 127 127 128 def __init__(self, x, parent):128 def __init__(self, parent, x): 129 129 """ 130 130 The Python constructor. 131 131 … … class FreeGroupElement(ElementLibGAP): 165 165 i=i+1 166 166 AbstractWordTietzeWord = libgap.eval('AbstractWordTietzeWord') 167 167 x = AbstractWordTietzeWord(l, parent._gap_gens()) 168 ElementLibGAP.__init__(self, x, parent)168 ElementLibGAP.__init__(self, parent, x) 169 169 170 170 def _latex_(self): 171 171 """ … … class FreeGroup_class(UniqueRepresentati 594 594 <class 'sage.groups.free_group.FreeGroup_class_with_category.element_class'> 595 595 """ 596 596 if len(args)!=1: 597 return self.element_class( *args, parent=self, **kwds)597 return self.element_class(self, *args, **kwds) 598 598 x = args[0] 599 599 if x==1: 600 600 return self.one() 601 601 try: 602 602 P = x.parent() 603 603 except AttributeError: 604 return self.element_class( x, parent=self, **kwds)604 return self.element_class(self, x, **kwds) 605 605 if hasattr(P, '_freegroup_'): 606 606 if P.FreeGroup() is self: 607 return self.element_class( x.Tietze(), parent=self, **kwds)608 return self.element_class( x, parent=self, **kwds)607 return self.element_class(self, x.Tietze(), **kwds) 608 return self.element_class(self, x, **kwds) 609 609 610 610 def abelian_invariants(self): 611 611 r""" -
sage/groups/libgap_wrapper.pyx
diff --git a/sage/groups/libgap_wrapper.pyx b/sage/groups/libgap_wrapper.pyx
a b class ParentLibGAP(SageObject): 330 330 if not (0 <= i < self.ngens()): 331 331 raise ValueError('i must be in range(ngens)') 332 332 gap = self._gap_gens()[i] 333 return self.element_class( gap, parent=self)333 return self.element_class(self, gap) 334 334 335 335 @cached_method 336 336 def gens(self): … … class ParentLibGAP(SageObject): 374 374 sage: G.one().Tietze() 375 375 () 376 376 """ 377 return self.element_class(self .gap().Identity(), parent=self)377 return self.element_class(self, self.gap().Identity()) 378 378 379 379 def _an_element_(self): 380 380 """ … … cdef class ElementLibGAP(MultiplicativeG 397 397 398 398 INPUT: 399 399 400 - `` libgap_element`` -- the libgap element that is being wrapped.400 - ``parent`` -- the Sage parent 401 401 402 - `` parent`` -- the Sage parent.402 - ``libgap_element`` -- the libgap element that is being wrapped 403 403 404 404 EXAMPLES:: 405 405 … … cdef class ElementLibGAP(MultiplicativeG 419 419 (f1,) 420 420 """ 421 421 422 def __init__(self, libgap_element, parent):422 def __init__(self, parent, libgap_element): 423 423 """ 424 424 The Python constructor 425 425 … … cdef class ElementLibGAP(MultiplicativeG 554 554 True 555 555 """ 556 556 P = left.parent() 557 return P.element_class( left.gap() * right.gap(), parent=P)557 return P.element_class(P, left.gap() * right.gap()) 558 558 559 559 cdef int _cmp_c_impl(left, Element right): 560 560 """ … … cdef class ElementLibGAP(MultiplicativeG 623 623 False 624 624 """ 625 625 P = left.parent() 626 return P.element_class( left.gap() / right.gap(), parent=P)626 return P.element_class(P, left.gap() / right.gap()) 627 627 628 628 def __pow__(self, n, dummy): 629 629 """ … … cdef class ElementLibGAP(MultiplicativeG 644 644 if n not in IntegerRing(): 645 645 raise TypeError("exponent must be an integer") 646 646 P = self.parent() 647 return P.element_class( self.gap().__pow__(n), parent=P)647 return P.element_class(P, self.gap().__pow__(n)) 648 648 649 649 def __invert__(self): 650 650 """ … … cdef class ElementLibGAP(MultiplicativeG 665 665 b*a*b^-1*a^-1 666 666 """ 667 667 P = self.parent() 668 return P.element_class( self.gap().Inverse(), parent=P)668 return P.element_class(P, self.gap().Inverse()) 669 669 670 670 inverse = __invert__ 671 671 -
sage/groups/matrix_gps/finitely_generated.py
diff --git a/sage/groups/matrix_gps/finitely_generated.py b/sage/groups/matrix_gps/finitely_generated.py
a b class FinitelyGeneratedMatrixGroup_gener 320 320 [0 1], [3 4] 321 321 ) 322 322 """ 323 return tuple(self.element_class( x, self, check=False, convert=False)323 return tuple(self.element_class(self, x, check=False, convert=False) 324 324 for x in self._gens_matrix) 325 325 326 326 def gen(self, i): -
sage/groups/matrix_gps/group_element.py
diff --git a/sage/groups/matrix_gps/group_element.py b/sage/groups/matrix_gps/group_element.py
a b class MatrixGroupElement_base(Multiplica 226 226 227 227 class MatrixGroupElement_generic(MatrixGroupElement_base): 228 228 229 def __init__(self, M, parent, check=True, convert=True):229 def __init__(self, parent, M, check=True, convert=True): 230 230 r""" 231 231 Element of a matrix group over a generic ring. 232 232 … … class MatrixGroupElement_generic(MatrixG 310 310 [0 1] 311 311 """ 312 312 parent = self.parent() 313 return parent.element_class( self._matrix * other._matrix, parent,313 return parent.element_class(parent, self._matrix * other._matrix, 314 314 check=False, convert=False) 315 315 316 316 def __invert__(self): … … class MatrixGroupElement_generic(MatrixG 335 335 [0 1] 336 336 """ 337 337 parent = self.parent() 338 return parent.element_class( ~self._matrix, parent, check=False, convert=False)338 return parent.element_class(parent, ~self._matrix, check=False, convert=False) 339 339 340 340 inverse = __invert__ 341 341 … … class MatrixGroupElement_generic(MatrixG 369 369 370 370 class MatrixGroupElement_gap(GroupElementMixinLibGAP, MatrixGroupElement_base, ElementLibGAP): 371 371 372 def __init__(self, M, parent, check=True, convert=True):372 def __init__(self, parent, M, check=True, convert=True): 373 373 r""" 374 374 Element of a matrix group over a generic ring. 375 375 … … class MatrixGroupElement_gap(GroupElemen 398 398 sage: TestSuite(g).run() 399 399 """ 400 400 if isinstance(M, GapElement): 401 ElementLibGAP.__init__(self, M, parent)401 ElementLibGAP.__init__(self, parent, M) 402 402 return 403 403 if convert: 404 404 M = parent.matrix_space()(M) … … class MatrixGroupElement_gap(GroupElemen 410 410 if M.parent() is not parent.matrix_space(): 411 411 raise TypeError('M must be a in the matrix space of the group') 412 412 parent._check_matrix(M, M_gap) 413 ElementLibGAP.__init__(self, M_gap, parent)413 ElementLibGAP.__init__(self, parent, M_gap) 414 414 415 415 def __reduce__(self): 416 416 """ -
sage/groups/matrix_gps/pickling_overrides.py
diff --git a/sage/groups/matrix_gps/pickling_overrides.py b/sage/groups/matrix_gps/pickling_overrides.py
a b class LegacyMatrixGroupElement(MatrixGro 74 74 parent = state[0] 75 75 m = state[1]['_MatrixGroupElement__mat'] 76 76 m = parent.matrix_space()(m) 77 self.__init__( m, parent, check=False)77 self.__init__(parent, m, check=False) 78 78 79 79 80 80 register_unpickle_override( -
sage/libs/coxeter3/coxeter_group.py
diff --git a/sage/libs/coxeter3/coxeter_group.py b/sage/libs/coxeter3/coxeter_group.py
a b class CoxeterGroup(UniqueRepresentation, 65 65 [[], [1], [2], [1, 2], [2, 1], [1, 2, 1]] 66 66 """ 67 67 for x in self._coxgroup: 68 yield CoxeterGroup.Element( x, self)68 yield CoxeterGroup.Element(self, x) 69 69 70 70 def cartan_type(self): 71 71 """ … … class CoxeterGroup(UniqueRepresentation, 394 394 class Element(ElementWrapper): 395 395 wrapped_class = CoxGroupElement 396 396 397 def __init__(self, x, parent):397 def __init__(self, parent, x): 398 398 """ 399 399 TESTS:: 400 400 … … class CoxeterGroup(UniqueRepresentation, 404 404 """ 405 405 if not isinstance(x, CoxGroupElement): 406 406 x = CoxGroupElement(parent._coxgroup, x).reduced() 407 ElementWrapper.__init__(self, x, parent)407 ElementWrapper.__init__(self, parent, x) 408 408 409 409 def _repr_(self): 410 410 """ -
sage/misc/nested_class_test.py
diff --git a/sage/misc/nested_class_test.py b/sage/misc/nested_class_test.py
a b class TestParent4(Parent): 122 122 """ 123 123 return self.__class__ == other.__class__ 124 124 125 def __ne__(self, other): 126 """ 127 EXAMPLES:: 128 129 sage: from sage.misc.nested_class_test import TestParent4 130 sage: TestParent4() != TestParent4() 131 False 132 """ 133 return self.__class__ != other.__class__ 134 125 135 class Element(ElementWrapper): 126 136 pass 127 137 -
sage/rings/integer.pyx
diff --git a/sage/rings/integer.pyx b/sage/rings/integer.pyx
a b cdef class IntegerWrapper(Integer): 396 396 specifying an alternative parent to ``IntegerRing()``. 397 397 """ 398 398 399 def __init__(self, x=None, unsigned int base=0, parent=None):399 def __init__(self, parent=None, x=None, unsigned int base=0): 400 400 """ 401 401 We illustrate how to create integers with parents different 402 402 from ``IntegerRing()``:: 403 403 404 404 sage: from sage.rings.integer import IntegerWrapper 405 405 406 sage: n = IntegerWrapper( 3, parent=Primes()) # indirect doctest406 sage: n = IntegerWrapper(Primes(), 3) # indirect doctest 407 407 sage: n 408 408 3 409 409 sage: n.parent() -
sage/rings/number_field/class_group.py
diff --git a/sage/rings/number_field/class_group.py b/sage/rings/number_field/class_group.py
a b class FractionalIdealClass(AbelianGroupW 74 74 sage: c.gens() 75 75 (2, 1/2*w - 1/2) 76 76 """ 77 def __init__(self, element, parent, ideal=None):77 def __init__(self, parent, element, ideal=None): 78 78 """ 79 79 Returns the ideal class of this fractional ideal. 80 80 … … class FractionalIdealClass(AbelianGroupW 86 86 """ 87 87 if element is None: 88 88 element = parent._ideal_log(ideal) 89 AbelianGroupWithValuesElement.__init__(self, element, parent, ideal)89 AbelianGroupWithValuesElement.__init__(self, parent, element, ideal) 90 90 91 91 def _repr_(self): 92 92 r""" … … class ClassGroup(AbelianGroupWithValues_ 426 426 [(0,), (2,), (4,)] 427 427 """ 428 428 if isinstance(args[0], FractionalIdealClass): 429 return self.element_class( None, self, self._number_field.ideal(args[0].ideal()))429 return self.element_class(self, None, self._number_field.ideal(args[0].ideal())) 430 430 else: 431 431 I = self._number_field.ideal(*args, **kwds) 432 if I.is_zero(): raise TypeError, "The zero ideal is not a fractional ideal" 433 return self.element_class(None, self, I) 432 if I.is_zero(): 433 raise TypeError("The zero ideal is not a fractional ideal") 434 return self.element_class(self, None, I) 434 435 435 436 def _ideal_log(self, ideal): 436 437 """ … … class SClassGroup(ClassGroup): 661 662 Fractional S-ideal class (3, a + 1) 662 663 """ 663 664 if isinstance(args[0], FractionalIdealClass): 664 return self.element_class( None, self, args[0].ideal())665 return self.element_class(self, None, args[0].ideal()) 665 666 else: 666 667 I = self.number_field().ideal(*args, **kwds) 667 if I.is_zero(): raise TypeError, "The zero ideal is not a fractional ideal" 668 return self.element_class(None, self, I) 668 if I.is_zero(): 669 raise TypeError("The zero ideal is not a fractional ideal") 670 return self.element_class(self, None, I) 669 671 670 672 def _repr_(self): 671 673 r""" -
sage/rings/number_field/unit_group.py
diff --git a/sage/rings/number_field/unit_group.py b/sage/rings/number_field/unit_group.py
a b class UnitGroup(AbelianGroupWithValues_c 283 283 m = [ZZ(m[0,i].python()) for i in range(m.ncols())] 284 284 # NB pari puts the torsion at the end! 285 285 m.insert(0,m.pop()) 286 return self.element_class( m, self)286 return self.element_class(self, m) 287 287 288 288 def rank(self): 289 289 """ -
sage/rings/universal_cyclotomic_field/universal_cyclotomic_field.py
diff --git a/sage/rings/universal_cyclotomic_field/universal_cyclotomic_field.py b/sage/rings/universal_cyclotomic_field/universal_cyclotomic_field.py
a b The following didn't work first:: 292 292 # http://www.gnu.org/licenses/ 293 293 #***************************************************************************** 294 294 from sage.misc.cachefunc import cached_method 295 from sage.misc.lazy_import import lazy_import296 297 295 from random import randint, randrange, sample, choice 298 296 299 297 import sage.structure.parent_base 300 298 from sage.structure.unique_representation import UniqueRepresentation 301 from sage.structure.element import parent,FieldElement, Element299 from sage.structure.element import FieldElement, Element 302 300 from sage.structure.parent import Parent 303 304 301 from sage.structure.element_wrapper import ElementWrapper 305 302 from sage.structure.sage_object import have_same_parent 306 303 … … from sage.categories.sets_with_partial_m 309 306 from sage.categories.sets_cat import Sets 310 307 from sage.categories.homset import Hom 311 308 312 from sage.rings.all import ZZ, QQ , CC309 from sage.rings.all import ZZ, QQ 313 310 from sage.rings.ring import Field 314 311 from sage.rings.qqbar import QQbar, AA 315 312 from sage.rings.number_field.number_field import CyclotomicField … … from sage.rings.integer import GCD_list, 318 315 from sage.rings.real_mpfr import RealField, mpfr_prec_min 319 316 from sage.rings.complex_field import ComplexField 320 317 from sage.rings.real_lazy import RLF, CLF 321 322 318 from sage.combinat.dict_addition import dict_linear_combination, dict_addition 323 324 from sage.rings.universal_cyclotomic_field.universal_cyclotomic_field_c import ZumbroichBasisCython,push_down_cython,ZumbroichDecomposition,galois_conjugates_cython,push_to_higher_field,dict_multiplication,dict_vector_multiplication 319 from sage.rings.universal_cyclotomic_field.universal_cyclotomic_field_c import \ 320 ZumbroichBasisCython, push_down_cython, ZumbroichDecomposition, galois_conjugates_cython, \ 321 push_to_higher_field, dict_multiplication, dict_vector_multiplication 325 322 326 323 class UniversalCyclotomicField(UniqueRepresentation, Field): 327 324 r""" … … class UniversalCyclotomicField(UniqueRep 783 780 if coerce: 784 781 for X,a in D.iteritems(): 785 782 D[X] = QQ(a) 786 elem = self.element_class(self ._data._from_dict(D, remove_zeros=remove_zeros), parent=self)783 elem = self.element_class(self, self._data._from_dict(D, remove_zeros=remove_zeros)) 787 784 return elem 788 785 789 786 def from_base_ring(self,coeff): … … class UniversalCyclotomicField(UniqueRep 1062 1059 coeff_list = elem.list() 1063 1060 return self._from_dict(push_down_cython(n,dict_linear_combination((ZumbroichDecomposition(n, k), coeff_list[ k ]) for k in range(len(coeff_list)) if coeff_list[k] != 0)), remove_zeros=False) 1064 1061 1065 class Element(FieldElement, ElementWrapper): 1062 # This cannot inherit from FieldElement and ElementWrapper, this causes the _add_() 1063 # _sub_(), _mul_(), etc. to not call the corresponding functions in this class, 1064 # leading to a segfault. 1065 class Element(FieldElement): 1066 1066 r""" 1067 1067 An element of the universal cyclotomic field. 1068 1068 … … class UniversalCyclotomicField(UniqueRep 1070 1070 1071 1071 - :class:`UniversalCyclotomicField` 1072 1072 """ 1073 def __init__(self, parent, value): 1074 """ 1075 Initialize ``self``. 1076 1077 EXAMPLES:: 1078 1079 sage: UCF.<E> = UniversalCyclotomicField() 1080 sage: elt = E(6) 1081 sage: TestSuite(elt).run() 1082 """ 1083 self.value = value 1084 FieldElement.__init__(self, parent) 1085 1086 def _repr_(self): 1087 """ 1088 Return a string representation of ``self``. 1089 1090 EXAMPLES:: 1091 1092 sage: UCF.<E> = UniversalCyclotomicField() 1093 sage: E(6) 1094 -E(3)^2 1095 """ 1096 return repr(self.value) 1097 1098 def _latex_(self): 1099 r""" 1100 Return a `\LaTeX` representation of ``self``. 1101 1102 EXAMPLES:: 1103 1104 sage: UCF.<E> = UniversalCyclotomicField() 1105 sage: latex(E(6)) 1106 -\zeta_{3}^{2} 1107 """ 1108 from sage.misc.latex import latex 1109 return latex(self.value) 1073 1110 1074 1111 def __lt__(self,other): 1075 1112 r""" … … class UniversalCyclotomicField(UniqueRep 1378 1415 -E(3) 1379 1416 """ 1380 1417 F = self.parent() 1381 elem = F.element_class( self.value.__neg__(), parent = F)1418 elem = F.element_class(F, self.value.__neg__()) 1382 1419 return elem 1383 1420 1384 1421 def __invert__(self): … … class UniversalCyclotomicField(UniqueRep 1548 1585 return None 1549 1586 1550 1587 F = self.parent() 1551 elem = F.element_class( self.value._acted_upon_(scalar, self_on_left = self_on_left), parent = F)1588 elem = F.element_class(F, self.value._acted_upon_(scalar, self_on_left = self_on_left)) 1552 1589 return elem 1553 1590 1554 1591 # For backward compatibility … … class ZumbroichBasisIndices(UniqueRepres 1952 1989 sage: a = ZumbroichBasisIndices().an_element(); a 1953 1990 (12, 4) 1954 1991 """ 1955 return self.element_class( (12,4),parent=self)1992 return self.element_class(self, (12, 4)) 1956 1993 1957 1994 def __contains__(self, x): 1958 1995 r""" … … class ZumbroichBasisIndices(UniqueRepres 1972 2009 """ 1973 2010 if isinstance(x,tuple) and len(x) == 2: 1974 2011 n,i = int(x[0]),int(x[1]) 1975 x = self.element_class( (n,int(i)),parent=self)2012 x = self.element_class( self, (n, int(i)) ) 1976 2013 return x in self.indices(x[0]) 1977 2014 1978 2015 def indices(self, n, m=1): … … class ZumbroichBasisIndices(UniqueRepres 1997 2034 if not n%m == 0: 1998 2035 raise ValueError('%s does not divide %s.'%(m,n)) 1999 2036 B = ZumbroichBasisCython(n, m) 2000 return (set([ self.element_class((n,int(i)),parent=self) for i in B ]))2037 return set([self.element_class( self, (n, int(i)) ) for i in B]) 2001 2038 2002 2039 class Element(ElementWrapper): 2003 2040 def __getitem__(self,i): -
sage/sets/disjoint_union_enumerated_sets.py
diff --git a/sage/sets/disjoint_union_enumerated_sets.py b/sage/sets/disjoint_union_enumerated_sets.py
a b class DisjointUnionEnumeratedSets(Unique 142 142 sage: el = it.next(); el 143 143 [2, 1, 3] 144 144 sage: type(el) 145 < class 'sage.structure.element_wrapper.DisjointUnionEnumeratedSets_with_category.element_class'>145 <type 'sage.structure.element_wrapper.ElementWrapper'> 146 146 sage: el.parent() == UNoFacade 147 147 True 148 148 sage: elv = el.value; elv … … class DisjointUnionEnumeratedSets(Unique 374 374 if self._facade: 375 375 yield el 376 376 else: 377 yield self.element_class( el, parent=self) # Bypass correctness tests377 yield self.element_class(self, el) # Bypass correctness tests 378 378 379 379 def an_element(self): 380 380 """ … … class DisjointUnionEnumeratedSets(Unique 476 476 if isinstance(el, self.element_class): 477 477 el = el.value 478 478 if self._is_a(el): 479 return self.element_class( el, parent=self)479 return self.element_class(self, el) 480 480 else: 481 raise ValueError , "Value %s does not belong to %s"%(el, self)481 raise ValueError("Value %s does not belong to %s"%(el, self)) 482 482 483 483 @lazy_attribute 484 484 def Element(self): … … class DisjointUnionEnumeratedSets(Unique 488 488 sage: U = DisjointUnionEnumeratedSets( 489 489 ... Family([1,2,3], Partitions), facade=False) 490 490 sage: U.Element 491 < class'sage.structure.element_wrapper.ElementWrapper'>491 <type 'sage.structure.element_wrapper.ElementWrapper'> 492 492 sage: U = DisjointUnionEnumeratedSets( 493 493 ... Family([1,2,3], Partitions), facade=True) 494 494 sage: U.Element -
(a) a/sage/structure/element_wrapper.py vs. (b) b/sage/structure/element_wrapper.pyx
diff --git a/sage/structure/element_wrapper.py b/sage/structure/element_wrapper.pyx rename from sage/structure/element_wrapper.py rename to sage/structure/element_wrapper.pyx
a b 1 1 """ 2 Wrapping Sage or Python objects as Sage elements 2 Element Wrapper 3 3 4 WARNING: This class has serious issues that can lead to subtle 5 segfaults. Do not use it unless you read trac 8200 first: 6 http://trac.sagemath.org/sage_trac/ticket/8200 4 Wrapping Sage or Python objects as Sage elements. 5 6 AUTHORS: 7 8 - Nicolas Thiery (2008-2010): Initial version 9 - Travis Scrimshaw (2013-05-04): Cythonized version 7 10 """ 8 11 #***************************************************************************** 9 12 # Copyright (C) 2008-2010 Nicolas M. Thiery <nthiery at users.sf.net> … … http://trac.sagemath.org/sage_trac/ticke 12 15 # http://www.gnu.org/licenses/ 13 16 #****************************************************************************** 14 17 15 from sage.structure.element import Element 18 include "../ext/python.pxi" 19 from cpython cimport bool 20 21 from sage.structure.parent cimport Parent 22 from sage.structure.element cimport Element 16 23 from copy import copy 17 24 18 c lass ElementWrapper(Element):25 cdef class ElementWrapper(Element): 19 26 r""" 20 A class for wrapping Sage or Python objects as Sage elements 21 22 WARNING: This class has serious issues that can lead to subtle 23 segfaults. Do not use it unless you read trac 8200 first: 24 http://trac.sagemath.org/sage_trac/ticket/8200 27 A class for wrapping Sage or Python objects as Sage elements. 25 28 26 29 EXAMPLES:: 27 30 28 31 sage: from sage.structure.element_wrapper import DummyParent 29 32 sage: parent = DummyParent("A parent") 30 31 sage: o = ElementWrapper("bla", parent = parent); o 33 sage: o = ElementWrapper(parent, "bla"); o 32 34 'bla' 33 35 sage: isinstance(o, sage.structure.element.Element) 34 36 True … … class ElementWrapper(Element): 42 44 methods. On the other hand, it is provided with reasonable default 43 45 implementations for equality testing, hashing, etc. 44 46 45 The typical use case of ` ElementWrapper` is for trivially46 constructing new element classes from pre existing Sage or Python47 The typical use case of ``ElementWrapper`` is for trivially 48 constructing new element classes from pre-existing Sage or Python 47 49 classes, with a containment relation. Here we construct the 48 50 tropical monoid of integers endowed with ``min`` as 49 51 multiplication. There, it is desirable *not* to inherit the 50 ``factor`` method from Integer::52 ``factor`` method from ``Integer``:: 51 53 52 54 sage: class MinMonoid(Parent): 53 ... 54 ... 55 ... 55 ....: def _repr_(self): 56 ....: return "The min monoid" 57 ....: 56 58 sage: M = MinMonoid() 57 59 sage: class MinMonoidElement(ElementWrapper): 58 ... 59 ... 60 ... 61 ... return MinMonoidElement(min(self.value, other.value), parent = self.parent())62 sage: x = MinMonoidElement( 5, parent = M); x60 ....: wrapped_class = Integer 61 ....: 62 ....: def __mul__(self, other): 63 ....: return MinMonoidElement(self.parent(), min(self.value, other.value)) 64 sage: x = MinMonoidElement(M, 5); x 63 65 5 64 66 sage: x.parent() 65 67 The min monoid 66 68 sage: x.value 67 69 5 68 sage: y = MinMonoidElement( 3, parent = M)70 sage: y = MinMonoidElement(M, 3) 69 71 sage: x * y 70 72 3 71 73 … … class ElementWrapper(Element): 73 75 examples in the categories (e.g. ``Semigroups().example()``) for 74 76 several full featured applications. 75 77 76 Caveat: the order between the value and the parent argument is 77 likely to change shortly. At this point, all the code using it in 78 the Sage library will be updated. There will be no transition period. 78 .. WARNING:: 79 80 Versions before :trac:`14519` had parent as the second argument and 81 the value as the first. 79 82 """ 83 cdef public object value 80 84 81 wrapped_class = object 82 83 def __init__(self, value, parent): 85 def __init__(self, parent, value): 84 86 """ 85 87 EXAMPLES:: 86 88 87 89 sage: from sage.structure.element_wrapper import DummyParent 88 sage: a = ElementWrapper( 1, parent = DummyParent("A parent"))90 sage: a = ElementWrapper(DummyParent("A parent"), 1) 89 91 90 92 TESTS:: 91 93 92 94 sage: TestSuite(a).run(skip = "_test_category") 93 95 94 Note: ElementWrapper is not intended to be used directly, 95 hence the failing category test. 96 sage: a = ElementWrapper(1, DummyParent("A parent")) 97 doctest:...: DeprecationWarning: the first argument must be a parent 98 See http://trac.sagemath.org/14519 for details. 99 100 .. NOTE:: 101 102 :class:`ElementWrapper` is not intended to be used directly, 103 hence the failing category test. 96 104 """ 97 assert isinstance(value, self.wrapped_class) 98 Element.__init__(self, parent = parent) 105 #assert isinstance(value, self.wrapped_class) 106 if not isinstance(parent, Parent): 107 from sage.misc.superseded import deprecation 108 deprecation(14519, 'the first argument must be a parent') 109 value, parent = parent, value 110 Element.__init__(self, parent=parent) 99 111 self.value = value 100 112 113 # When self is an extension type without a __dict__ attribute, 114 # this prevents self.__dict__ to return whatever crap obtained by 115 # lookup through the categories ... 116 __dict__ = {} 117 118 def __getstate__(self): 119 """ 120 Return a tuple describing the state of your object. 121 122 This emulates :meth:`Element.__getstate__`, playing as if 123 ``self.value`` was in the dictionary of ``self`` as it used to 124 be before :trac:`14519`. 125 126 EXAMPLES:: 127 128 sage: from sage.structure.element_wrapper import DummyParent 129 sage: P = DummyParent("A parent") 130 sage: a = ElementWrapper(P, 1) 131 sage: a.__getstate__() 132 (A parent, {'value': 1}) 133 sage: class A(ElementWrapper): 134 ....: pass 135 sage: a = A(P, 1) 136 sage: a.x = 2 137 sage: a.__getstate__() == (P, {'value': 1, 'x': 2}) 138 True 139 """ 140 d = self.__dict__.copy() 141 d['value'] = self.value 142 return (self._parent, d) 143 144 def __setstate__(self, state): 145 r""" 146 Initialize the state of the object from data saved in a pickle. 147 148 This emulates :meth:`Element.__setstate__`, playing as if 149 ``self.value`` was to be put in the dictionary of ``self`` as 150 it used to be before :trac:`14519`. 151 152 EXAMPLES:: 153 154 sage: from sage.structure.element_wrapper import DummyParent 155 sage: class A(ElementWrapper): 156 ....: pass 157 sage: a = A(DummyParent("A parent"), 1) 158 sage: a.__setstate__((DummyParent("Another parent"), {'value':0,'x':3})) 159 sage: a.parent() 160 Another parent 161 sage: a.value 162 0 163 sage: a.x 164 3 165 166 TESTS:: 167 168 sage: a = A(DummyParent("A parent"), 1) 169 sage: import __main__; __main__.A = A # Fake A being defined in a python module 170 sage: a.x = 2 171 sage: a == loads(dumps(a)) 172 True 173 sage: a = ElementWrapper(DummyParent("A parent"), 1) 174 sage: a == loads(dumps(a)) 175 True 176 177 Checking that we can still load pickle from before :trac:`14519`:: 178 179 sage: f = loads('x\x9c\x85\x8d\xbb\n\xc2@\x14D\xf1\x11\x8d\xebO\xd8\xda,\xf8\t\x82\xf6\x12\x08\x96a\x8dC\x08f\xd7\xdc\xbb{\x15\x8b\x80\x16\xd1\xdf6\x10\xad,,\xcf0s\xe6>\xcc\xbd)\xa0}`\xc9\x8304*X\xb8\x90]\xd9\xd45Xm{\xde\x7f\x90\x06\xcb\x07\xfd\x8c\xc4\x95$\xc8\x185\xc3wm\x13\xca\xb3S\xe2\x18G\xc9\xa1h\xf4\xefe#\xd6\xdev\x86\xbbL\xd18\x8d\xd7\x8b\x1e(j\x9b\x17M\x12\x9a6\x14\xa7\xd1\xc5T\x02\x9a\xf56.]\xe1u\xe9\x02\x8a\xce`\xcd\t\xd9\x17H\xa5\x83U\x9b\xd0\xdc?\x0f\xfa\rl4S\xbc') 180 sage: f == ElementWrapper(DummyParent("A Parent"), 1) 181 True 182 """ 183 # Make sure the first part of the state is the parent 184 if not isinstance(state[0], Parent): 185 state[0], state[1] = state[1], state[0] 186 self._set_parent(state[0]) 187 d = state[1].copy() 188 self.value = d.pop('value') 189 if d: 190 self.__dict__ = d 191 101 192 def _repr_(self): 102 193 """ 103 194 EXAMPLES:: 104 195 105 196 sage: from sage.structure.element_wrapper import DummyParent 106 sage: ElementWrapper( 1, parent = DummyParent("A parent")) # indirect doctest197 sage: ElementWrapper(DummyParent("A parent"), 1) 107 198 1 108 199 """ 109 200 return repr(self.value) 110 201 111 202 def _latex_(self): 112 """203 r""" 113 204 EXAMPLES:: 114 205 115 206 sage: from sage.structure.element_wrapper import DummyParent 116 sage: ElementWrapper( 1, parent = DummyParent("A parent"))._latex_()207 sage: ElementWrapper(DummyParent("A parent"), 1)._latex_() 117 208 1 118 sage: ElementWrapper( 3/5, parent = DummyParent("A parent"))._latex_()209 sage: ElementWrapper(DummyParent("A parent"), 3/5)._latex_() 119 210 \frac{3}{5} 120 211 """ 121 212 from sage.misc.latex import latex … … class ElementWrapper(Element): 123 214 124 215 def __hash__(self): 125 216 """ 126 Return s the same hash as for the wrapped element217 Return the same hash as for the wrapped element. 127 218 128 219 EXAMPLES:: 129 220 130 221 sage: from sage.structure.element_wrapper import DummyParent 131 222 sage: parent1 = DummyParent("A parent") 132 223 sage: parent2 = DummyParent("Another parent") 133 sage: hash(ElementWrapper( 1, parent = parent1))224 sage: hash(ElementWrapper(parent1, 1)) 134 225 1 135 sage: hash(ElementWrapper( 1, parent = parent2))226 sage: hash(ElementWrapper(parent2, 1)) 136 227 1 137 228 138 TODO: should this take the parent and/or the class into account? 229 .. TODO:: 230 231 Should this take the parent and/or the class into account? 139 232 """ 140 233 return hash(self.value) 141 234 142 def __ eq__(self, other):235 def __richcmp__(left, right, int op): 143 236 """ 144 Default implementation of equality testing: two elements are 237 Return ``True`` if ``left`` compares with ``right`` based on ``op``. 238 239 Default implementation of ``self == other``: two elements are 145 240 equal if they have the same class, same parent, and same value. 146 241 147 EXAMPLES:: 242 Default implementation of ``self < other``: two elements are 243 always incomparable. 244 245 .. NOTE:: 246 247 Another option would be to not define ``__lt__``, but 248 given the current implementation of SageObject, sorted(...) 249 would break. 250 251 TESTS: 252 253 Testing equality:: 148 254 149 255 sage: from sage.structure.element_wrapper import DummyParent 150 256 sage: parent1 = DummyParent("A parent") 151 257 sage: parent2 = DummyParent("Another parent") 152 258 sage: parent1 == parent2 153 259 False 154 sage: l11 = ElementWrapper( 1, parent = parent1)155 sage: l12 = ElementWrapper( 2, parent = parent1)156 sage: l21 = ElementWrapper( 1, parent = parent2)157 sage: l22 = ElementWrapper( 2, parent = parent2)260 sage: l11 = ElementWrapper(parent1, 1) 261 sage: l12 = ElementWrapper(parent1, 2) 262 sage: l21 = ElementWrapper(parent2, 1) 263 sage: l22 = ElementWrapper(parent2, 2) 158 264 sage: l11 == l11 159 265 True 160 266 sage: l11 == l12 161 267 False 162 268 sage: l11 == l21 163 269 False 164 """165 return (self.__class__ is other.__class__ and166 self.parent() == other.parent() and167 self.value == other.value)168 270 169 def __ne__(self, other): 170 """ 171 Default implementation of unequality testing by using 172 :meth:`.__eq__`. 173 174 EXAMPLES:: 271 Testing inequality:: 175 272 176 273 sage: from sage.structure.element_wrapper import DummyParent 177 274 sage: parent1 = DummyParent("A parent") 178 275 sage: parent2 = DummyParent("Another parent") 179 276 sage: parent1 == parent2 180 277 False 181 sage: l11 = ElementWrapper( 1, parent = parent1)182 sage: l12 = ElementWrapper( 2, parent = parent1)183 sage: l21 = ElementWrapper( 1, parent = parent2)184 sage: l22 = ElementWrapper( 2, parent = parent2)278 sage: l11 = ElementWrapper(parent1, 1) 279 sage: l12 = ElementWrapper(parent1, 2) 280 sage: l21 = ElementWrapper(parent2, 1) 281 sage: l22 = ElementWrapper(parent2, 2) 185 282 sage: l11 != l11 186 283 False 187 284 sage: l11 != l12 188 285 True 189 286 sage: l11 != l21 190 287 True 191 """192 return not self.__eq__(other)193 288 194 def __lt__(self, other): 195 """ 196 Returns whether ``self < other``. With this default 197 implementation, they are always incomparable. 198 199 Note: another option would be to not define ``__lt__``, but 200 given the current implementation of SageObject, sorted(...) 201 would break. 202 203 TESTS:: 289 Testing less than:: 204 290 205 291 sage: from sage.structure.element_wrapper import DummyParent 206 292 sage: parent = DummyParent("A parent") 207 sage: x = ElementWrapper( 1, parent = parent)208 sage: y = ElementWrapper( 2, parent = parent)293 sage: x = ElementWrapper(parent, 1) 294 sage: y = ElementWrapper(parent, 2) 209 295 sage: x.__lt__(x), x.__lt__(y), y.__lt__(x), x.__lt__(1) 210 296 (False, False, False, False) 211 297 sage: x < x, x < y, y < x, x < 1 … … class ElementWrapper(Element): 215 301 sage: sorted([y,x]) 216 302 [2, 1] 217 303 """ 304 cdef ElementWrapper self 305 self = left 306 if self.__class__ != right.__class__ \ 307 or self._parent != (<ElementWrapper>right)._parent: 308 return op == Py_NE 309 if op == Py_EQ or op == Py_LE or op == Py_GE: 310 return self.value == (<ElementWrapper>right).value 311 if op == Py_NE: 312 return self.value != (<ElementWrapper>right).value 218 313 return False 219 314 220 def_lt_by_value(self, other):315 cpdef bool _lt_by_value(self, other): 221 316 """ 222 Return swhether ``self`` is strictly smaller than ``other``.317 Return whether ``self`` is strictly smaller than ``other``. 223 318 224 319 With this implementation 'by value', they are always 225 320 incomparable unless ``self`` and ``other`` have the same 226 class, parent, and self.value < other.value.321 class, parent, and ``self.value < other.value``. 227 322 228 323 EXAMPLES:: 229 324 230 325 sage: from sage.structure.element_wrapper import DummyParent 231 326 sage: class MyElement(ElementWrapper): 232 ... 233 ... 327 ....: __lt__ = ElementWrapper._lt_by_value 328 ....: 234 329 sage: parent1 = DummyParent("A parent") 235 330 sage: parent2 = DummyParent("Another parent") 236 sage: l11 = MyElement( 1, parent = parent1)237 sage: l12 = MyElement( 2, parent = parent1)238 sage: l21 = MyElement( 1, parent = parent2)239 sage: l22 = MyElement( 2, parent = parent2)331 sage: l11 = MyElement(parent1, 1) 332 sage: l12 = MyElement(parent1, 2) 333 sage: l21 = MyElement(parent2, 1) 334 sage: l22 = MyElement(parent2, 2) 240 335 sage: l11 < l11 241 336 False 242 337 sage: l11 < l12, l12 < l11 # values differ … … class ElementWrapper(Element): 248 343 sage: 1 < l11 # random, since it depends on what the Integer 1 decides to do, which may just involve memory locations 249 344 False 250 345 """ 251 return self.__class__ is other.__class__ and self.parent() == other.parent() and self.value < other.value 346 return self.__class__ is other.__class__ \ 347 and self._parent is other.parent() \ 348 and self.value < (<ElementWrapper>other).value 252 349 253 def_cmp_by_value(self, other):350 cpdef int _cmp_by_value(self, other): 254 351 """ 255 352 Implementation of ``cmp`` by comparing first values, then 256 353 parents, then class. This behavior (which implies a total … … class ElementWrapper(Element): 261 358 EXAMPLES:: 262 359 263 360 sage: class MyElement(ElementWrapper): 264 ... 265 ... 361 ....: __cmp__ = ElementWrapper._cmp_by_value 362 ....: 266 363 sage: from sage.structure.element_wrapper import DummyParent 267 364 sage: parent1 = DummyParent("A parent") 268 365 sage: parent2 = DummyParent("Another parent") 269 366 sage: parent1 == parent2 270 367 False 271 sage: l11 = MyElement( 1, parent = parent1)272 sage: l12 = MyElement( 2, parent = parent1)273 sage: l21 = MyElement( 1, parent = parent2)274 sage: l22 = MyElement( 2, parent = parent2)368 sage: l11 = MyElement(parent1, 1) 369 sage: l12 = MyElement(parent1, 2) 370 sage: l21 = MyElement(parent2, 1) 371 sage: l22 = MyElement(parent2, 2) 275 372 sage: cmp(l11, l11) 276 373 0 277 374 sage: cmp(l11, l12), cmp(l12, l11) # values differ … … class ElementWrapper(Element): 291 388 292 389 def __copy__(self): 293 390 """ 294 Copy selfand in particular its ``value`` attribute.391 Copy ``self`` and in particular its ``value`` attribute. 295 392 296 393 EXAMPLES:: 297 394 298 395 sage: from sage.structure.element_wrapper import DummyParent 299 396 sage: parent = DummyParent("A parent") 300 sage: o1 = ElementWrapper( [1], parent=parent); o1397 sage: o1 = ElementWrapper(parent, [1]); o1 301 398 [1] 302 399 sage: o2 = copy(o1); o2 303 400 [1] 304 sage: o1 is o2, o1. __dict__ is o2.__dict__401 sage: o1 is o2, o1.value is o2.value 305 402 (False, False) 306 403 sage: o2.value[0] = 3; o2 307 404 [3] 308 405 sage: o1 309 406 [1] 310 407 sage: class bla(ElementWrapper): pass 311 sage: o3 = bla( [1], parent=parent)408 sage: o3 = bla(parent, [1]) 312 409 sage: o4 = copy(o3) 313 410 sage: o3.value[0] = 3; o4 314 411 [1] … … class ElementWrapper(Element): 322 419 res.value = copy(self.value) 323 420 return res 324 421 325 326 422 from sage.structure.parent import Parent 327 423 from sage.structure.unique_representation import UniqueRepresentation 328 424 class DummyParent(UniqueRepresentation, Parent): … … class DummyParent(UniqueRepresentation, 356 452 """ 357 453 return self.name 358 454 359 from sage.categories.sets_cat import Sets360 455 class ElementWrapperTester(ElementWrapper): 361 456 """ 362 457 Test class for the default :meth:`.__copy` method of subclasses of … … class ElementWrapperTester(ElementWrappe 374 469 sage: x.append(21); x.append(7) 375 470 sage: x, y 376 471 ([n=3, value=[2, 21, 7]], [n=2, value=[2, 42]]) 472 sage: x.value, y.value 473 ([2, 21, 7], [2, 42]) 377 474 sage: x.__dict__, y.__dict__ 378 ({' value': [2, 21, 7], 'n': 3}, {'value': [2, 42],'n': 2})475 ({'n': 3}, {'n': 2}) 379 476 """ 380 477 def __init__(self): 381 478 """ … … class ElementWrapperTester(ElementWrappe 385 482 sage: x = ElementWrapperTester(); x 386 483 [n=0, value=[]] 387 484 """ 388 super(ElementWrapperTester, self).__init__([], parent = Sets().example("facade")) 485 from sage.categories.sets_cat import Sets 486 super(ElementWrapperTester, self).__init__(Sets().example("facade"), []) 389 487 self.n = 0 390 488 391 489 def append(self, x): … … class ElementWrapperTester(ElementWrappe 412 510 [n=0, value=[2, 32]] 413 511 """ 414 512 return "[n=%s, value=%s]"%(self.n, self.value) 513 -
sage/structure/parent.pyx
diff --git a/sage/structure/parent.pyx b/sage/structure/parent.pyx
a b CLASS HIERARCHY:: 10 10 A simple example of registering coercions:: 11 11 12 12 sage: class A_class(Parent): 13 ... def __init__(self, name): 14 ... Parent.__init__(self, name=name) 15 ... self._populate_coercion_lists_() 16 ... self.rename(name) 17 ... # 18 ... def category(self): 19 ... return Sets() 20 ... # 21 ... def _element_constructor_(self, i): 22 ... assert(isinstance(i, (int, Integer))) 23 ... return ElementWrapper(i, parent = self) 24 ... 25 ... 13 ....: def __init__(self, name): 14 ....: Parent.__init__(self, name=name) 15 ....: self._populate_coercion_lists_() 16 ....: self.rename(name) 17 ....: # 18 ....: def category(self): 19 ....: return Sets() 20 ....: # 21 ....: def _element_constructor_(self, i): 22 ....: assert(isinstance(i, (int, Integer))) 23 ....: return ElementWrapper(self, i) 24 ....: 26 25 sage: A = A_class("A") 27 26 sage: B = A_class("B") 28 27 sage: C = A_class("C") 29 28 30 29 sage: def f(a): 31 ... 32 ... 30 ....: return B(a.value+1) 31 ....: 33 32 sage: class MyMorphism(Morphism): 34 ... 35 ... 36 ... 37 ... 38 ... 39 ... 33 ....: def __init__(self, domain, codomain): 34 ....: Morphism.__init__(self, Hom(domain, codomain)) 35 ....: # 36 ....: def _call_(self, x): 37 ....: return self.codomain()(x.value) 38 ....: 40 39 sage: f = MyMorphism(A,B) 41 40 sage: f 42 41 Generic morphism: … … base ring, and with ``_mul_`` for the ri 64 63 65 64 sage: from sage.structure.element import RingElement 66 65 sage: class MyElement(RingElement): 67 ....: def __init__(self, x,y, parent = None):66 ....: def __init__(self, parent, x, y): 68 67 ....: RingElement.__init__(self, parent) 69 68 ....: def _mul_(self, other): 70 69 ....: return self … … cdef class Parent(category_object.Catego 377 376 sage: P.category() 378 377 Category of sets 379 378 sage: class MyParent(Parent): 380 ... 381 ... 379 ....: def __init__(self): 380 ....: self._init_category_(Groups()) 382 381 sage: MyParent().category() 383 382 Category of groups 384 383 """ … … cdef class Parent(category_object.Catego 524 523 sage: P.category() 525 524 Category of sets 526 525 sage: class MyParent(Parent): 527 ... 526 ....: def __init__(self): pass 528 527 sage: MyParent().category() 529 528 Category of sets 530 529 """ … … cdef class Parent(category_object.Catego 547 546 Let us now write a parent with broken categories: 548 547 549 548 sage: class MyParent(Parent): 550 ... 551 ... 549 ....: def __init__(self): 550 ....: pass 552 551 sage: P = MyParent() 553 552 sage: P._test_category() 554 553 Traceback (most recent call last): … … cdef class Parent(category_object.Catego 591 590 Let us now write a broken class method:: 592 591 593 592 sage: class CCls(Parent): 594 ... 595 ... 593 ....: def __eq__(self, other): 594 ....: return True 596 595 sage: CCls()._test_eq() 597 596 Traceback (most recent call last): 598 597 ... … … cdef class Parent(category_object.Catego 601 600 Let us now break inequality:: 602 601 603 602 sage: class CCls(Parent): 604 ... 605 ... 603 ....: def __ne__(self, other): 604 ....: return True 606 605 sage: CCls()._test_eq() 607 606 Traceback (most recent call last): 608 607 ... … … cdef class Parent(category_object.Catego 727 726 EXAMPLES:: 728 727 729 728 sage: for s in dir(ZZ): 730 ... 729 ....: if s[:6] == "_test_": print s 731 730 _test_additive_associativity 732 731 _test_an_element 733 732 _test_associativity … … cdef class Parent(category_object.Catego 913 912 is preserved (see :trac:`5979`):: 914 913 915 914 sage: class MyParent(Parent): 916 ... 917 ... 918 ... 919 ... 920 ... 921 ... 915 ....: def _element_constructor_(self, x): 916 ....: print self, x 917 ....: return sage.structure.element.Element(parent = self) 918 ....: def _repr_(self): 919 ....: return "my_parent" 920 ....: 922 921 sage: my_parent = MyParent() 923 922 sage: x = my_parent("bla") 924 923 my_parent bla … … cdef class Parent(category_object.Catego 1250 1249 1251 1250 sage: from sage.rings.integer_ring import IntegerRing_class 1252 1251 sage: class MyIntegers_class(IntegerRing_class): 1253 ... 1254 ... 1252 ....: def is_finite(self): 1253 ....: raise NotImplementedError 1255 1254 sage: MyIntegers = MyIntegers_class() 1256 1255 sage: MyIntegers.is_finite() 1257 1256 Traceback (most recent call last): … … cdef class Parent(category_object.Catego 1262 1261 pressing Ctrl-C. We let it run for 1 second and then interrupt:: 1263 1262 1264 1263 sage: try: 1265 ... 1266 ... 1267 ... except KeyboardInterrupt:1268 ... 1269 ... 1264 ....: alarm(1) 1265 ....: list(MyIntegers) 1266 ....: except KeyboardInterrupt: 1267 ....: print "Caught KeyboardInterrupt" 1268 ....: 1270 1269 Caught KeyboardInterrupt 1271 1270 1272 1271 """ … … cdef class Parent(category_object.Catego 1389 1388 override this default implementation:: 1390 1389 1391 1390 sage: class As(Category): 1392 ... 1393 ... 1394 ... 1395 ... 1391 ....: def super_categories(self): return [Sets()] 1392 ....: class ParentMethods: 1393 ....: def __getitem__(self, n): 1394 ....: return 'coucou' 1396 1395 sage: class A(Parent): 1397 ... 1398 ... 1396 ....: def __init__(self): 1397 ....: Parent.__init__(self, category=As()) 1399 1398 sage: a = A() 1400 1399 sage: a[1] 1401 1400 'coucou' … … cdef class Parent(category_object.Catego 1727 1726 sage: import operator 1728 1727 1729 1728 sage: class SymmetricGroupAction(sage.categories.action.Action): 1730 ... 1731 ... 1732 ... 1733 ... 1734 ... 1735 ... 1736 ... 1737 ... 1738 ... 1739 ... 1740 ... 1741 ... 1742 ... 1743 ... 1729 ....: "Act on a multivariate polynomial ring by permuting the generators." 1730 ....: def __init__(self, G, M, is_left=True): 1731 ....: sage.categories.action.Action.__init__(self, G, M, is_left, operator.mul) 1732 ....: 1733 ....: def _call_(self, g, a): 1734 ....: if not self.is_left(): 1735 ....: g, a = a, g 1736 ....: D = {} 1737 ....: for k, v in a.dict().items(): 1738 ....: nk = [0]*len(k) 1739 ....: for i in range(len(k)): 1740 ....: nk[g(i+1)-1] = k[i] 1741 ....: D[tuple(nk)] = v 1742 ....: return a.parent()(D) 1744 1743 1745 1744 sage: R.<x, y, z> = QQ['x, y, z'] 1746 1745 sage: G = SymmetricGroup(3) … … cdef class Parent(category_object.Catego 2094 2093 sage: _ = gc.collect() 2095 2094 sage: K = GF(1<<55,'t') 2096 2095 sage: for i in range(50): 2097 ... 2098 ... 2099 ... 2096 ....: a = K.random_element() 2097 ....: E = EllipticCurve(j=a) 2098 ....: b = K.has_coerce_map_from(E) 2100 2099 sage: _ = gc.collect() 2101 2100 sage: len([x for x in gc.get_objects() if isinstance(x,type(E))]) 2102 2101 1 … … cdef class Parent(category_object.Catego 2211 2210 Regression test for :trac:`12919` (probably not 100% robust):: 2212 2211 2213 2212 sage: class P(Parent): 2214 ... 2215 ... 2216 ... 2213 ....: def __init__(self): 2214 ....: Parent.__init__(self, category=Sets()) 2215 ....: Element=ElementWrapper 2217 2216 sage: A = P(); a = A('a') 2218 2217 sage: B = P(); b = B('b') 2219 2218 sage: C = P(); c = C('c')