Ticket #14519: trac_14519-cynthonize_element_wrapper-ts.patch

File trac_14519-cynthonize_element_wrapper-ts.patch, 88.1 KB (added by tscrim, 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. 
    133133
    134134    sage: from sage.structure.unique_representation import UniqueRepresentation
    135135    sage: class MyFrac(UniqueRepresentation, Field):
    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()
     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()
    146146
    147147.. end ouf output
    148148
    considerations: 
    261261  comparison does not work in the way expected in Python::
    262262
    263263      sage: class Foo(sage.structure.element.Element):
    264       ...    def __init__(self, x, parent=None):
    265       ...        self.x = x
    266       ...    def _repr_(self):
    267       ...        return "<%s>"%self.x
    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)
    270270      sage: cmp(a,b)
    271271      Traceback (most recent call last):
    272272      ...
    considerations: 
    279279This gives rise to the following code::
    280280
    281281    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())
    325323
    326324.. end of output
    327325
    Thanks to the single underscore methods, 
    333331we stay inside a single parent structure::
    334332
    335333    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)
    338336    sage: a+b, a-b, a*b, a/b
    339337    ((10):(8), (2):(8), (3):(8), (6):(4))
    340     sage: a-b == MyElement(1,4,P)
     338    sage: a-b == MyElement(P, 1, 4)
    341339    True
    342340
    343341.. end of output
    category:: 
    504502
    505503    sage: from sage.categories.quotient_fields import QuotientFields
    506504    sage: class MyFrac(MyFrac):
    507     ...       def __init__(self, base, category=None):
    508     ...           if base not in IntegralDomains():
    509     ...               raise ValueError, "%s is no integral domain"%base
    510     ...           Field.__init__(self, base, category=category or QuotientFields())
     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())
    511509
    512510When constructing instances of ``MyFrac``, their class is dynamically changed
    513511into a new class called ``MyFrac_with_category``. It is a common sub\--class of
    monoids\---see 
    535533We have seen above that we can add elements. Nevertheless, the ``sum`` method
    536534does not work, yet::
    537535
    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])
    542540    Traceback (most recent call last):
    543541    ...
    544542    NotImplementedError
    Hence, for providing our fraction fields 
    566564just need to add a single line to our class**::
    567565
    568566    sage: class MyFrac(MyFrac):
    569     ...       Element = MyElement
     567    ....:     Element = MyElement
    570568
    571569
    572570.. end of output
    This little change provides several bene 
    586584
    587585- The ``sum`` method mentioned above suddenly works::
    588586
    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)
    592590      sage: P.sum([a,b,c])
    593591      (36):(16)
    594592
    refactor them! 
    862860::
    863861
    864862    sage: class MyFrac(MyFrac):
    865     ...       def _element_constructor_(self, *args,**kwds):
    866     ...           if len(args)!=1:
    867     ...               return self.element_class(*args,parent=self,**kwds)
    868     ...           x = args[0]
    869     ...           try:
    870     ...               P = x.parent()
    871     ...           except AttributeError:
    872     ...               return self.element_class(x,parent=self,**kwds)
    873     ...           if P in QuotientFields() and P != self.base():
    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)
    876874
    877875
    878876.. end of output
    rational field, since ``QQ.base()`` is n 
    932930::
    933931
    934932    sage: class MyFrac(MyFrac):
    935     ...       def _coerce_map_from_(self, S):
    936     ...           if self.base().has_coerce_map_from(S):
    937     ...               return True
    938     ...           if S in QuotientFields():
    939     ...               if self.base().has_coerce_map_from(S.base()):
    940     ...                   return True
    941     ...               if hasattr(S,'ring_of_integers') and self.base().has_coerce_map_from(S.ring_of_integers()):
    942     ...                   return True
     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
    943941
    944942
    945943.. end of output
    default implementation. Hence: 
    12841282
    12851283    sage: from sage.categories.pushout import ConstructionFunctor
    12861284    sage: class MyFracFunctor(ConstructionFunctor):
    1287     ...       rank = 5
    1288     ...       def __init__(self):
    1289     ...           ConstructionFunctor.__init__(self, IntegralDomains(), Fields())
    1290     ...       def _apply_functor(self, R):
    1291     ...           return MyFrac(R)
    1292     ...       def merge(self, other):
    1293     ...           if isinstance(other, (type(self), sage.categories.pushout.FractionField)):
    1294     ...               return self
     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
    12951293
    12961294
    12971295.. end of output
    There remains to let our new fraction fi 
    13331331::
    13341332
    13351333    sage: class MyFrac(MyFrac):
    1336     ...       def construction(self):
    1337     ...           return MyFracFunctor(), self.base()
     1334    ....:     def construction(self):
     1335    ....:         return MyFracFunctor(), self.base()
    13381336
    13391337
    13401338.. end of output
    For example, if one forgets to implement 
    14511449following error::
    14521450
    14531451    sage: class Foo(Parent):
    1454     ...    Element = sage.structure.element.Element
    1455     ...    def __init__(self):
    1456     ...        Parent.__init__(self, category=QuotientFields())
     1452    ....:  Element = sage.structure.element.Element
     1453    ....:  def __init__(self):
     1454    ....:      Parent.__init__(self, category=QuotientFields())
    14571455    sage: Bar = Foo()
    14581456    sage: bar = Bar.element_class(Bar)
    14591457    sage: bar._test_not_implemented_methods()
    that. We also override the some_elements 
    15531551::
    15541552
    15551553    sage: class MyFrac(MyFrac):
    1556     ...       def _an_element_(self):
    1557     ...           a = self.base().an_element()
    1558     ...           b = self.base_ring().an_element()
    1559     ...           if (a+b)!=0:
    1560     ...               return self(a)**2/(self(a+b)**3)
    1561     ...           if b != 0:
    1562     ...               return self(a)/self(b)**2
    1563     ...           return self(a)**2*self(b)**3
    1564     ...       def some_elements(self):
    1565     ...           return [self.an_element(),self(self.base().an_element()),self(self.base_ring().an_element())]
     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())]
    15661564
    15671565
    15681566.. end of output
    the category, as follows:: 
    16111609
    16121610    sage: from sage.categories.category import Category
    16131611    sage: class QuotientFieldsWithTest(Category): # do *not* inherit from QuotientFields, but ...
    1614     ...       def super_categories(self):
    1615     ...           return [QuotientFields()]       # ... declare QuotientFields as a super category!
    1616     ...       class ParentMethods:
    1617     ...           pass
    1618     ...       class ElementMethods:
    1619     ...           def _test_factorisation(self, **options):
    1620     ...               P = self.parent()
    1621     ...               assert self == P.prod([P(b)**e for b,e in self.factor()])
     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()])
    16221620
    16231621
    16241622.. end of output
    Appendix: The complete code 
    17211719
    17221720    # Fraction field elements
    17231721    class MyElement(FieldElement):
    1724         def __init__(self, n,d=None, parent=None):
     1722        def __init__(self, parent, n, d=None):
    17251723            if parent is None:
    1726                 raise ValueError, "The parent must be provided"
     1724                raise ValueError("The parent must be provided")
    17271725            B = parent.base()
    17281726            if d is None:
    17291727                # The default denominator is one
    17301728                d = B.one_element()
    17311729            # verify that both numerator and denominator belong to the base
    17321730            if n not in B or d not in B:
    1733                 raise ValueError, "Numerator and denominator must be elements of %s"%B
     1731                raise ValueError("Numerator and denominator must be elements of %s"%B)
    17341732            # Numerator and denominator should not just be "in" B,
    17351733            # but should be defined as elements of B
    17361734            d = B(d)
    17371735            n = B(n)
    17381736            # the denominator must not be zero
    17391737            if d==0:
    1740                 raise ZeroDivisionError, "The denominator must not be zero"
     1738                raise ZeroDivisionError("The denominator must not be zero")
    17411739            # normalize the denominator: WLOG, it shall be non-negative.
    17421740            if d<0:
    17431741                self.n = -n
    Appendix: The complete code 
    17701768        def _add_(self, other):
    17711769            C = self.__class__
    17721770            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)
    17741772        def _sub_(self, other):
    17751773            C = self.__class__
    17761774            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)
    17781776        def _mul_(self, other):
    17791777            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())
    17811779        def _div_(self, other):
    17821780            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())
    17841782
    17851783    # Inheritance from UniqueRepresentation implements the unique parent
    17861784    # behaviour. Moreover, it implements pickling (provided that Python
    Appendix: The complete code 
    18091807            return self.base().characteristic()
    18101808
    18111809        # Implement conversions. Do not override __call__!
    1812         def _element_constructor_(self, *args,**kwds):
     1810        def _element_constructor_(self, *args, **kwds):
    18131811            if len(args)!=1:
    1814                return self.element_class(*args,parent=self,**kwds)
     1812               return self.element_class(self, *args, **kwds)
    18151813            x = args[0]
    18161814            try:
    18171815                P = x.parent()
    18181816            except AttributeError:
    1819                 return self.element_class(x,parent=self,**kwds)
     1817                return self.element_class(self, x, **kwds)
    18201818            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)
    18231821
    18241822        # Implement coercion from the base and from fraction fields
    18251823        # 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 = [ 
    18951895              sources = ['sage/structure/element.pyx'],
    18961896              extra_compile_args=["-Os"]),
    18971897
     1898    Extension('sage.structure.element_wrapper',
     1899              sources = ['sage/structure/element_wrapper.pyx']),
     1900
    18981901    Extension('sage.structure.factory',
    18991902              sources = ['sage/structure/factory.pyx']),
    19001903
  • 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 
    140140        return self((a, (ord(a)-96)) for a in self.alphabet)
    141141
    142142    class Element(ElementWrapper):
    143         def __init__(self, iterable, parent):
     143        def __init__(self, parent, iterable):
    144144            """
    145145            EXAMPLES::
    146146
    147147                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)))
    149149                sage: x
    150150                2*a + c + 5*d
    151151                sage: x.value
    class FreeCommutativeAdditiveSemigroup(U 
    164164            d = dict( (a,0) for a in parent.alphabet )
    165165            for (a, c) in iterable:
    166166                d[a] = c
    167             ElementWrapper.__init__(self, parent = parent, value = d)
     167            ElementWrapper.__init__(self, parent, d)
    168168
    169169        def _repr_(self):
    170170            """
  • sage/categories/examples/semigroups.py

    diff --git a/sage/categories/examples/semigroups.py b/sage/categories/examples/semigroups.py
    a b class FreeSemigroup(UniqueRepresentation 
    309309        """
    310310        for a in x:
    311311            assert a in self.alphabet
    312         return self.element_class(x, parent = self)
     312        return self.element_class(self, x)
    313313
    314314    class Element(ElementWrapper):
    315315        r"""
    class QuotientOfLeftZeroSemigroup(Unique 
    540540        if x.value > 42:
    541541            return self.the_answer()
    542542        else:
    543             return self.element_class(x, parent = self)
     543            return self.element_class(self, x)
    544544
    545545    class Element(ElementWrapper):
    546546        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): 
    4848cdef class LeftZeroSemigroupElement(Element):
    4949    cdef object _value
    5050
    51     def __init__(self, value, parent):
     51    def __init__(self, parent, value):
    5252        """
    5353        EXAMPLES::
    5454
    cdef class LeftZeroSemigroupElement(Elem 
    8080            sage: x = S(3)
    8181            sage: x.__reduce__()
    8282            (<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))
    8484        """
    85         return LeftZeroSemigroupElement, (self._value, self._parent)
     85        return LeftZeroSemigroupElement, (self._parent, self._value)
    8686
    8787    def __cmp__(LeftZeroSemigroupElement self, LeftZeroSemigroupElement other):
    8888        """
  • 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 
    400400            sage: P._from_integer_(42)            # Don't do that at home kids!
    401401            42
    402402        """
    403         return self.element_class(p, self)
     403        return self.element_class(self, p)
    404404
    405405    class Element(IntegerWrapper, PrimeNumbers_Abstract.Element):
    406         def __init__(self, p, parent):
     406        def __init__(self, parent, p):
    407407            """
    408408            TESTS::
    409409
    class PrimeNumbers_Inherits(PrimeNumbers 
    417417                sage: x.parent() is P
    418418                True
    419419            """
    420             IntegerWrapper.__init__(self, p, parent=parent)
     420            IntegerWrapper.__init__(self, parent, p)
    421421
    422422
    423423#*************************************************************************#
    class PrimeNumbers_Wrapper(PrimeNumbers_ 
    524524            ...
    525525            ValueError: 14 is not a prime number
    526526        """
    527         return self.element_class(Integer(e), parent=self)
     527        return self.element_class(self, Integer(e))
    528528
    529529    from sage.structure.element_wrapper import ElementWrapper
    530530    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 
    338338
    339339    sage: x = S('a')
    340340
    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
     343extension class (it is in `sage.structure.element_wrapper`)::
    342344
    343345    sage: x._repr_.__module__
    344     'sage.structure.element_wrapper'
     346    <BLANKLINE>
    345347
    346348``__pow__`` is a generic method for all finite semigroups::
    347349
    categories translates into *inheritance* 
    444446    sage: x.__class__.mro()
    445447    [<class 'sage.categories.examples.finite_semigroups.LeftRegularBand_with_category.element_class'>,
    446448     <class 'sage.categories.examples.finite_semigroups.LeftRegularBand.Element'>,
    447      <class 'sage.structure.element_wrapper.ElementWrapper'>,
     449     <type 'sage.structure.element_wrapper.ElementWrapper'>,
    448450     <type 'sage.structure.element.Element'>,
    449451     <type 'sage.structure.sage_object.SageObject'>,
    450452     <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): 
    336336                sage: S._element_constructor_from_element_class(17)
    337337                17
    338338            """
    339             return self.element_class(parent = self, *args, **keywords)
     339            return self.element_class(self, *args, **keywords)
    340340
    341341        def is_parent_of(self, element):
    342342            """
  • sage/combinat/core.py

    diff --git a/sage/combinat/core.py b/sage/combinat/core.py
    a b class Core(CombinatorialObject, Element) 
    8282        l = sum(part.k_boundary(k).row_lengths())
    8383        return Cores(k, l)(part)
    8484
    85     def __init__(self, core, parent):
     85    def __init__(self, parent, core):
    8686        """
    8787        TESTS::
    8888
  • sage/combinat/crystals/affine.py

    diff --git a/sage/combinat/crystals/affine.py b/sage/combinat/crystals/affine.py
    a b class AffineCrystalFromClassical(UniqueR 
    198198            sage: A.retract(t).parent() is A
    199199            True
    200200        """
    201         return self.element_class(classical_elt, parent = self)
     201        return self.element_class(self, classical_elt)
    202202   
    203203    def _element_constructor_(self, *value, **options):
    204204        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 
    334334            self._finite_cartan_type = False
    335335
    336336
    337         self.module_generators = ( self.element_class((), self), )
     337        self.module_generators = ( self.element_class(self, ()), )
    338338
    339339    def _repr_(self):
    340340        """
    class CrystalOfAlcovePaths(UniqueReprese 
    364364            ((alpha[1], 2), (alpha[1] + alpha[2], 4))
    365365        """
    366366        if isinstance(data, tuple):
    367             return self.element_class(data, self)
     367            return self.element_class(self, data)
    368368        elif isinstance(data, list):
    369369            lambda_chain = self._R.lambda_chain()
    370370            #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])))
    372372
    373373    def vertices(self):
    374374        """
  • sage/combinat/perfect_matching.py

    diff --git a/sage/combinat/perfect_matching.py b/sage/combinat/perfect_matching.py
    a b class PerfectMatching(ElementWrapper): 
    777777            []
    778778        """
    779779        from sage.combinat.permutation import Permutation
    780         return Permutation(self.__dict__['value'])
     780        return Permutation(self.value)
    781781
    782782
    783783class 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 
    633633    """
    634634    Class for a Weyl Group elements
    635635    """
    636     def __init__(self, g, parent, check=False):
     636    def __init__(self, parent, g, check=False):
    637637        """
    638638        EXAMPLES::
    639        
     639
    640640            sage: G = WeylGroup(['A',2])
    641641            sage: s1 = G.simple_reflection(1)
    642642            sage: TestSuite(s1).run()
    643643        """
    644         MatrixGroupElement_gap.__init__(self, g, parent, check=check)
     644        MatrixGroupElement_gap.__init__(self, parent, g, check=check)
    645645        self.__matrix = self.matrix()
    646646        self._parent = parent
    647647
  • 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 
    906906        x = [0]*n
    907907        if self._gens_orders[i] != 1:
    908908            x[i] = 1
    909         return self.element_class(x, self)
     909        return self.element_class(self, x)
    910910
    911911    def gens(self):
    912912        """
  • 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 
    259259        x = [0]*n
    260260        if self.gens_orders()[i] != 1:
    261261            x[i] = 1
    262         return self.element_class(x, self)
     262        return self.element_class(self, x)
    263263
    264264    def gens(self):
    265265        """
  • 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 
    5252        True
    5353    """
    5454
    55     def __init__(self, exponents, parent):
     55    def __init__(self, parent, exponents):
    5656        """
    5757        Create an element.
    5858
    class AbelianGroupElementBase(Multiplica 
    233233        exponents = [ (x-y)%order if order!=0 else x-y
    234234                      for x, y, order in
    235235                      zip(left._exponents, right._exponents, G.gens_orders()) ]
    236         return G.element_class(exponents, G)
     236        return G.element_class(G, exponents)
    237237
    238238    def _mul_(left, right):
    239239        """
    class AbelianGroupElementBase(Multiplica 
    252252        exponents = [ (x+y)%order if order!=0 else x+y
    253253                      for x, y, order in
    254254                      zip(left._exponents, right._exponents, G.gens_orders()) ]
    255         return G.element_class(exponents, G)
     255        return G.element_class(G, exponents)
    256256
    257257    def __pow__(self, n):
    258258        """
    class AbelianGroupElementBase(Multiplica 
    270270        G = self.parent()
    271271        exponents = [ (m*e) % order if order!=0 else m*e
    272272                      for e,order in zip(self._exponents, G.gens_orders()) ]
    273         return G.element_class(exponents, G)
     273        return G.element_class(G, exponents)
    274274
    275275    def inverse(self):
    276276        """
    class AbelianGroupElementBase(Multiplica 
    295295        G = self.parent()
    296296        exponents = [ (-e)%order if order!=0 else -e
    297297                      for e,order in zip(self._exponents, G.gens_orders()) ]
    298         return G.element_class(exponents, G)
     298        return G.element_class(G, exponents)
    299299
    300300    __invert__ = inverse
    301301
  • 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 
    236236        sage: TestSuite(a*b).run()
    237237    """
    238238
    239     def __init__(self, exponents, parent, value=None):
     239    def __init__(self, parent, exponents, value=None):
    240240        """
    241241        Create an element
    242242
    class AbelianGroupWithValuesElement(Abel 
    250250            -1
    251251        """
    252252        self._value = value
    253         AbelianGroupElement.__init__(self, exponents, parent)
     253        AbelianGroupElement.__init__(self, parent, exponents)
    254254
    255255    def value(self):
    256256        """
  • 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,  
    371371                  [2 3 0]     [0]
    372372        """
    373373        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)
    375375
    376376    def translation(self, b):
    377377        """
    class AffineGroup(UniqueRepresentation,  
    394394                  [0 0 1]     [3]
    395395        """
    396396        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)
    398398
    399399    def reflection(self, v):
    400400        """
    class AffineGroup(UniqueRepresentation,  
    433433            raise ValueError('v has norm zero')
    434434        from sage.matrix.constructor import identity_matrix
    435435        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)
    437437
    438438    def random_element(self):
    439439        """
    class AffineGroup(UniqueRepresentation,  
    454454        while not A.is_invertible():  # a generic matrix is invertible
    455455            A.randomize()
    456456        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)
    458458   
    459459    @cached_method
    460460    def _an_element_(self):
    class AffineGroup(UniqueRepresentation,  
    471471        while not A.is_invertible():  # a generic matrix is not always invertible
    472472            A.randomize()
    473473        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)
    475475
  • 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 
    8585              [2 0]     [0]
    8686        x |-> [0 2] x + [0]
    8787    """
    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):
    8989        r"""
    9090        Create element of an affine group.
    9191
    class AffineGroupElement(MatrixGroupElem 
    277277        parent = self.parent()
    278278        A = self._A * other._A
    279279        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)
    281281
    282282    def __call__(self, v):
    283283        """
    class AffineGroupElement(MatrixGroupElem 
    386386        parent = self.parent()
    387387        A = parent.matrix_space()(self._A.inverse())
    388388        b = -A*self.b()
    389         return parent.element_class(A, b, parent, check=False)
     389        return parent.element_class(parent, A, b, check=False)
    390390
    391391    __invert__ = inverse
    392392
  • sage/groups/braid.py

    diff --git a/sage/groups/braid.py b/sage/groups/braid.py
    a b class BraidGroup_class(FinitelyPresented 
    673673            sage: B([1, 2, 3]) # indirect doctest
    674674            s0*s1*s2
    675675        """
    676         return Braid(x, parent=self)
     676        return Braid(self, x)
    677677
    678678    def _permutation_braid_Tietze(self, p):
    679679        """
  • sage/groups/finitely_presented.py

    diff --git a/sage/groups/finitely_presented.py b/sage/groups/finitely_presented.py
    a b class FinitelyPresentedGroupElement(Free 
    173173        b*a*b^-1*a^-1
    174174    """
    175175
    176     def __init__(self, x, parent):
     176    def __init__(self, parent, x):
    177177        """
    178178        The Python constructor.
    179179
    class FinitelyPresentedGroupElement(Free 
    200200            free_element = F(x)
    201201            fp_family = parent.one().gap().FamilyObj()
    202202            x = libgap.ElementOfFpGroup(fp_family, free_element.gap())
    203         ElementLibGAP.__init__(self, x, parent)
     203        ElementLibGAP.__init__(self, parent, x)
    204204
    205205    def __reduce__(self):
    206206        """
    class FinitelyPresentedGroup(UniqueRepre 
    684684            a*b*a*b^-1
    685685        """
    686686        if len(args)!=1:
    687             return self.element_class(*args, parent=self, **kwds)
     687            return self.element_class(self, *args, **kwds)
    688688        x = args[0]
    689689        if x==1:
    690690            return self.one()
    691691        try:
    692692            P = x.parent()
    693693        except AttributeError:
    694             return self.element_class(x, parent=self, **kwds)
     694            return self.element_class(self, x, **kwds)
    695695        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)
    698698
    699699    @cached_method
    700700    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): 
    125125        True
    126126    """
    127127
    128     def __init__(self, x, parent):
     128    def __init__(self, parent, x):
    129129        """
    130130        The Python constructor.
    131131
    class FreeGroupElement(ElementLibGAP): 
    165165                    i=i+1
    166166            AbstractWordTietzeWord = libgap.eval('AbstractWordTietzeWord')
    167167            x = AbstractWordTietzeWord(l, parent._gap_gens())
    168         ElementLibGAP.__init__(self, x, parent)
     168        ElementLibGAP.__init__(self, parent, x)
    169169
    170170    def _latex_(self):
    171171        """
    class FreeGroup_class(UniqueRepresentati 
    594594            <class 'sage.groups.free_group.FreeGroup_class_with_category.element_class'>
    595595        """
    596596        if len(args)!=1:
    597             return self.element_class(*args, parent=self, **kwds)
     597            return self.element_class(self, *args, **kwds)
    598598        x = args[0]
    599599        if x==1:
    600600            return self.one()
    601601        try:
    602602            P = x.parent()
    603603        except AttributeError:
    604             return self.element_class(x, parent=self, **kwds)
     604            return self.element_class(self, x, **kwds)
    605605        if hasattr(P, '_freegroup_'):
    606606            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)
    609609
    610610    def abelian_invariants(self):
    611611        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): 
    330330        if not (0 <= i < self.ngens()):
    331331            raise ValueError('i must be in range(ngens)')
    332332        gap = self._gap_gens()[i]
    333         return self.element_class(gap, parent=self)
     333        return self.element_class(self, gap)
    334334
    335335    @cached_method
    336336    def gens(self):
    class ParentLibGAP(SageObject): 
    374374            sage: G.one().Tietze()
    375375            ()
    376376        """
    377         return self.element_class(self.gap().Identity(), parent=self)
     377        return self.element_class(self, self.gap().Identity())
    378378
    379379    def _an_element_(self):
    380380        """
    cdef class ElementLibGAP(MultiplicativeG 
    397397
    398398    INPUT:
    399399
    400     - ``libgap_element`` -- the libgap element that is being wrapped.
     400    - ``parent`` -- the Sage parent
    401401
    402     - ``parent`` -- the Sage parent.
     402    - ``libgap_element`` -- the libgap element that is being wrapped
    403403
    404404    EXAMPLES::
    405405
    cdef class ElementLibGAP(MultiplicativeG 
    419419        (f1,)
    420420    """
    421421
    422     def __init__(self, libgap_element, parent):
     422    def __init__(self, parent, libgap_element):
    423423        """
    424424        The Python constructor
    425425
    cdef class ElementLibGAP(MultiplicativeG 
    554554            True
    555555        """
    556556        P = left.parent()
    557         return P.element_class(left.gap() * right.gap(), parent=P)
     557        return P.element_class(P, left.gap() * right.gap())
    558558
    559559    cdef int _cmp_c_impl(left, Element right):
    560560        """
    cdef class ElementLibGAP(MultiplicativeG 
    623623            False
    624624        """
    625625        P = left.parent()
    626         return P.element_class(left.gap() / right.gap(), parent=P)
     626        return P.element_class(P, left.gap() / right.gap())
    627627
    628628    def __pow__(self, n, dummy):
    629629        """
    cdef class ElementLibGAP(MultiplicativeG 
    644644        if n not in IntegerRing():
    645645            raise TypeError("exponent must be an integer")
    646646        P = self.parent()
    647         return P.element_class(self.gap().__pow__(n), parent=P)
     647        return P.element_class(P, self.gap().__pow__(n))
    648648
    649649    def __invert__(self):
    650650        """
    cdef class ElementLibGAP(MultiplicativeG 
    665665            b*a*b^-1*a^-1
    666666        """
    667667        P = self.parent()
    668         return P.element_class(self.gap().Inverse(), parent=P)
     668        return P.element_class(P, self.gap().Inverse())
    669669
    670670    inverse = __invert__
    671671
  • 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 
    320320            [0 1], [3 4]
    321321            )
    322322        """
    323         return tuple(self.element_class(x, self, check=False, convert=False)
     323        return tuple(self.element_class(self, x, check=False, convert=False)
    324324                     for x in self._gens_matrix)
    325325
    326326    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 
    226226
    227227class MatrixGroupElement_generic(MatrixGroupElement_base):
    228228
    229     def __init__(self, M, parent, check=True, convert=True):
     229    def __init__(self, parent, M, check=True, convert=True):
    230230        r"""
    231231        Element of a matrix group over a generic ring.
    232232
    class MatrixGroupElement_generic(MatrixG 
    310310            [0 1]
    311311        """
    312312        parent = self.parent()
    313         return parent.element_class(self._matrix * other._matrix, parent,
     313        return parent.element_class(parent, self._matrix * other._matrix,
    314314                                    check=False, convert=False)
    315315
    316316    def __invert__(self):
    class MatrixGroupElement_generic(MatrixG 
    335335           [0 1]
    336336        """
    337337        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)
    339339
    340340    inverse = __invert__
    341341
    class MatrixGroupElement_generic(MatrixG 
    369369
    370370class MatrixGroupElement_gap(GroupElementMixinLibGAP, MatrixGroupElement_base, ElementLibGAP):
    371371
    372     def __init__(self, M, parent, check=True, convert=True):
     372    def __init__(self, parent, M, check=True, convert=True):
    373373        r"""
    374374        Element of a matrix group over a generic ring.
    375375
    class MatrixGroupElement_gap(GroupElemen 
    398398            sage: TestSuite(g).run()
    399399        """
    400400        if isinstance(M, GapElement):
    401             ElementLibGAP.__init__(self, M, parent)
     401            ElementLibGAP.__init__(self, parent, M)
    402402            return
    403403        if convert:
    404404            M = parent.matrix_space()(M)
    class MatrixGroupElement_gap(GroupElemen 
    410410            if M.parent() is not parent.matrix_space():
    411411                raise TypeError('M must be a in the matrix space of the group')
    412412            parent._check_matrix(M, M_gap)
    413         ElementLibGAP.__init__(self, M_gap, parent)
     413        ElementLibGAP.__init__(self, parent, M_gap)
    414414
    415415    def __reduce__(self):
    416416        """
  • 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 
    7474        parent = state[0]
    7575        m = state[1]['_MatrixGroupElement__mat']
    7676        m = parent.matrix_space()(m)
    77         self.__init__(m, parent, check=False)
     77        self.__init__(parent, m, check=False)
    7878
    7979
    8080register_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, 
    6565            [[], [1], [2], [1, 2], [2, 1], [1, 2, 1]]
    6666        """
    6767        for x in self._coxgroup:
    68             yield CoxeterGroup.Element(x, self)
     68            yield CoxeterGroup.Element(self, x)
    6969
    7070    def cartan_type(self):
    7171        """
    class CoxeterGroup(UniqueRepresentation, 
    394394    class Element(ElementWrapper):
    395395        wrapped_class = CoxGroupElement
    396396
    397         def __init__(self, x, parent):
     397        def __init__(self, parent, x):
    398398            """
    399399            TESTS::
    400400
    class CoxeterGroup(UniqueRepresentation, 
    404404            """
    405405            if not isinstance(x, CoxGroupElement):
    406406                x = CoxGroupElement(parent._coxgroup, x).reduced()
    407             ElementWrapper.__init__(self, x, parent)
     407            ElementWrapper.__init__(self, parent, x)
    408408
    409409        def _repr_(self):
    410410            """
  • 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): 
    122122        """
    123123        return self.__class__ == other.__class__
    124124
     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
    125135    class Element(ElementWrapper):
    126136        pass
    127137
  • sage/rings/integer.pyx

    diff --git a/sage/rings/integer.pyx b/sage/rings/integer.pyx
    a b cdef class IntegerWrapper(Integer): 
    396396    specifying an alternative parent to ``IntegerRing()``.
    397397    """
    398398
    399     def __init__(self, x=None, unsigned int base=0, parent=None):
     399    def __init__(self, parent=None, x=None, unsigned int base=0):
    400400        """
    401401        We illustrate how to create integers with parents different
    402402        from ``IntegerRing()``::
    403403
    404404            sage: from sage.rings.integer import IntegerWrapper
    405405
    406             sage: n = IntegerWrapper(3, parent=Primes()) # indirect doctest
     406            sage: n = IntegerWrapper(Primes(), 3) # indirect doctest
    407407            sage: n
    408408            3
    409409            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 
    7474            sage: c.gens()
    7575            (2, 1/2*w - 1/2)
    7676    """
    77     def __init__(self, element, parent, ideal=None):
     77    def __init__(self, parent, element, ideal=None):
    7878        """
    7979        Returns the ideal class of this fractional ideal.
    8080
    class FractionalIdealClass(AbelianGroupW 
    8686        """
    8787        if element is None:
    8888            element = parent._ideal_log(ideal)
    89         AbelianGroupWithValuesElement.__init__(self, element, parent, ideal)
     89        AbelianGroupWithValuesElement.__init__(self, parent, element, ideal)
    9090
    9191    def _repr_(self):
    9292        r"""
    class ClassGroup(AbelianGroupWithValues_ 
    426426            [(0,), (2,), (4,)]
    427427        """
    428428        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()))
    430430        else:
    431431            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)
    434435
    435436    def _ideal_log(self, ideal):
    436437        """
    class SClassGroup(ClassGroup): 
    661662            Fractional S-ideal class (3, a + 1)
    662663        """
    663664        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())
    665666        else:
    666667            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)
    669671
    670672    def _repr_(self):
    671673        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 
    283283        m = [ZZ(m[0,i].python()) for i in range(m.ncols())]
    284284        # NB pari puts the torsion at the end!
    285285        m.insert(0,m.pop())
    286         return self.element_class(m, self)
     286        return self.element_class(self, m)
    287287
    288288    def rank(self):
    289289        """
  • 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:: 
    292292#                  http://www.gnu.org/licenses/
    293293#*****************************************************************************
    294294from sage.misc.cachefunc import cached_method
    295 from sage.misc.lazy_import import lazy_import
    296 
    297295from random import randint, randrange, sample, choice
    298296
    299297import sage.structure.parent_base
    300298from sage.structure.unique_representation import UniqueRepresentation
    301 from sage.structure.element import parent, FieldElement, Element
     299from sage.structure.element import FieldElement, Element
    302300from sage.structure.parent import Parent
    303 
    304301from sage.structure.element_wrapper import ElementWrapper
    305302from sage.structure.sage_object import have_same_parent
    306303
    from sage.categories.sets_with_partial_m 
    309306from sage.categories.sets_cat import Sets
    310307from sage.categories.homset import Hom
    311308
    312 from sage.rings.all import ZZ, QQ, CC
     309from sage.rings.all import ZZ, QQ
    313310from sage.rings.ring import Field
    314311from sage.rings.qqbar import QQbar, AA
    315312from sage.rings.number_field.number_field import CyclotomicField
    from sage.rings.integer import GCD_list, 
    318315from sage.rings.real_mpfr import RealField, mpfr_prec_min
    319316from sage.rings.complex_field import ComplexField
    320317from sage.rings.real_lazy import RLF, CLF
    321 
    322318from 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
     319from 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
    325322
    326323class UniversalCyclotomicField(UniqueRepresentation, Field):
    327324    r"""
    class UniversalCyclotomicField(UniqueRep 
    783780        if coerce:
    784781            for X,a in D.iteritems():
    785782                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))
    787784        return elem
    788785
    789786    def from_base_ring(self,coeff):
    class UniversalCyclotomicField(UniqueRep 
    10621059        coeff_list = elem.list()
    10631060        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)
    10641061
    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):
    10661066        r"""
    10671067        An element of the universal cyclotomic field.
    10681068
    class UniversalCyclotomicField(UniqueRep 
    10701070
    10711071            - :class:`UniversalCyclotomicField`
    10721072        """
     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)
    10731110
    10741111        def __lt__(self,other):
    10751112            r"""
    class UniversalCyclotomicField(UniqueRep 
    13781415                -E(3)
    13791416            """
    13801417            F = self.parent()
    1381             elem = F.element_class(self.value.__neg__(), parent = F)
     1418            elem = F.element_class(F, self.value.__neg__())
    13821419            return elem
    13831420
    13841421        def __invert__(self):
    class UniversalCyclotomicField(UniqueRep 
    15481585                    return None
    15491586
    15501587            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))
    15521589            return elem
    15531590
    15541591        # For backward compatibility
    class ZumbroichBasisIndices(UniqueRepres 
    19521989            sage: a = ZumbroichBasisIndices().an_element(); a
    19531990            (12, 4)
    19541991        """
    1955         return self.element_class((12,4),parent=self)
     1992        return self.element_class(self, (12, 4))
    19561993
    19571994    def __contains__(self, x):
    19581995        r"""
    class ZumbroichBasisIndices(UniqueRepres 
    19722009        """
    19732010        if isinstance(x,tuple) and len(x) == 2:
    19742011            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)) )
    19762013        return x in self.indices(x[0])
    19772014
    19782015    def indices(self, n, m=1):
    class ZumbroichBasisIndices(UniqueRepres 
    19972034        if not n%m == 0:
    19982035            raise ValueError('%s does not divide %s.'%(m,n))
    19992036        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])
    20012038
    20022039    class Element(ElementWrapper):
    20032040        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 
    142142        sage: el = it.next(); el
    143143        [2, 1, 3]
    144144        sage: type(el)
    145         <class 'sage.structure.element_wrapper.DisjointUnionEnumeratedSets_with_category.element_class'>
     145        <type 'sage.structure.element_wrapper.ElementWrapper'>
    146146        sage: el.parent() == UNoFacade
    147147        True
    148148        sage: elv = el.value; elv
    class DisjointUnionEnumeratedSets(Unique 
    374374                if self._facade:
    375375                    yield el
    376376                else:
    377                     yield self.element_class(el, parent=self) # Bypass correctness tests
     377                    yield self.element_class(self, el) # Bypass correctness tests
    378378
    379379    def an_element(self):
    380380        """
    class DisjointUnionEnumeratedSets(Unique 
    476476        if isinstance(el, self.element_class):
    477477            el = el.value
    478478        if self._is_a(el):
    479             return self.element_class(el, parent=self)
     479            return self.element_class(self, el)
    480480        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))
    482482
    483483    @lazy_attribute
    484484    def Element(self):
    class DisjointUnionEnumeratedSets(Unique 
    488488            sage: U = DisjointUnionEnumeratedSets(
    489489            ...            Family([1,2,3], Partitions), facade=False)
    490490            sage: U.Element
    491             <class 'sage.structure.element_wrapper.ElementWrapper'>
     491            <type 'sage.structure.element_wrapper.ElementWrapper'>
    492492            sage: U = DisjointUnionEnumeratedSets(
    493493            ...            Family([1,2,3], Partitions), facade=True)
    494494            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  
    11"""
    2 Wrapping Sage or Python objects as Sage elements
     2Element Wrapper
    33
    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
     4Wrapping Sage or Python objects as Sage elements.
     5
     6AUTHORS:
     7
     8- Nicolas Thiery (2008-2010): Initial version
     9- Travis Scrimshaw (2013-05-04): Cythonized version
    710"""
    811#*****************************************************************************
    912#  Copyright (C) 2008-2010 Nicolas M. Thiery <nthiery at users.sf.net>
    http://trac.sagemath.org/sage_trac/ticke 
    1215#                  http://www.gnu.org/licenses/
    1316#******************************************************************************
    1417
    15 from sage.structure.element import Element
     18include "../ext/python.pxi"
     19from cpython cimport bool
     20
     21from sage.structure.parent cimport Parent
     22from sage.structure.element cimport Element
    1623from copy import copy
    1724
    18 class ElementWrapper(Element):
     25cdef class ElementWrapper(Element):
    1926    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.
    2528
    2629    EXAMPLES::
    2730
    2831        sage: from sage.structure.element_wrapper import DummyParent
    2932        sage: parent = DummyParent("A parent")
    30 
    31         sage: o = ElementWrapper("bla", parent = parent); o
     33        sage: o = ElementWrapper(parent, "bla"); o
    3234        'bla'
    3335        sage: isinstance(o, sage.structure.element.Element)
    3436        True
    class ElementWrapper(Element): 
    4244    methods. On the other hand, it is provided with reasonable default
    4345    implementations for equality testing, hashing, etc.
    4446
    45     The typical use case of `ElementWrapper` is for trivially
    46     constructing new element classes from preexisting Sage or Python
     47    The typical use case of ``ElementWrapper`` is for trivially
     48    constructing new element classes from pre-existing Sage or Python
    4749    classes, with a containment relation. Here we construct the
    4850    tropical monoid of integers endowed with ``min`` as
    4951    multiplication. There, it is desirable *not* to inherit the
    50     ``factor`` method from Integer::
     52    ``factor`` method from ``Integer``::
    5153
    5254        sage: class MinMonoid(Parent):
    53         ...       def _repr_(self):
    54         ...           return "The min monoid"
    55         ...
     55        ....:     def _repr_(self):
     56        ....:         return "The min monoid"
     57        ....:
    5658        sage: M = MinMonoid()
    5759        sage: class MinMonoidElement(ElementWrapper):
    58         ...       wrapped_class = Integer
    59         ...
    60         ...       def __mul__(self, other):
    61         ...           return MinMonoidElement(min(self.value, other.value), parent = self.parent())
    62         sage: x = MinMonoidElement(5, parent = M); x
     60        ....:     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
    6365        5
    6466        sage: x.parent()
    6567        The min monoid
    6668        sage: x.value
    6769        5
    68         sage: y = MinMonoidElement(3, parent = M)
     70        sage: y = MinMonoidElement(M, 3)
    6971        sage: x * y
    7072        3
    7173
    class ElementWrapper(Element): 
    7375    examples in the categories (e.g. ``Semigroups().example()``) for
    7476    several full featured applications.
    7577
    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.
    7982    """
     83    cdef public object value
    8084
    81     wrapped_class = object
    82 
    83     def __init__(self, value, parent):
     85    def __init__(self, parent, value):
    8486        """
    8587        EXAMPLES::
    8688
    8789            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)
    8991
    9092        TESTS::
    9193
    9294            sage: TestSuite(a).run(skip = "_test_category")
    9395
    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.
    96104        """
    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)
    99111        self.value = value
    100112
     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
    101192    def _repr_(self):
    102193        """
    103194        EXAMPLES::
    104195
    105196            sage: from sage.structure.element_wrapper import DummyParent
    106             sage: ElementWrapper(1, parent = DummyParent("A parent")) # indirect doctest
     197            sage: ElementWrapper(DummyParent("A parent"), 1)
    107198            1
    108199        """
    109200        return repr(self.value)
    110201
    111202    def _latex_(self):
    112         """
     203        r"""
    113204        EXAMPLES::
    114205
    115206            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_()
    117208            1
    118             sage: ElementWrapper(3/5, parent = DummyParent("A parent"))._latex_()
     209            sage: ElementWrapper(DummyParent("A parent"), 3/5)._latex_()
    119210            \frac{3}{5}
    120211        """
    121212        from sage.misc.latex import latex
    class ElementWrapper(Element): 
    123214
    124215    def __hash__(self):
    125216        """
    126         Returns the same hash as for the wrapped element
     217        Return the same hash as for the wrapped element.
    127218
    128219        EXAMPLES::
    129220
    130221            sage: from sage.structure.element_wrapper import DummyParent
    131222            sage: parent1 = DummyParent("A parent")
    132223            sage: parent2 = DummyParent("Another parent")
    133             sage: hash(ElementWrapper(1, parent = parent1))
     224            sage: hash(ElementWrapper(parent1, 1))
    134225            1
    135             sage: hash(ElementWrapper(1, parent = parent2))
     226            sage: hash(ElementWrapper(parent2, 1))
    136227            1
    137228
    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?
    139232        """
    140233        return hash(self.value)
    141234
    142     def __eq__(self, other):
     235    def __richcmp__(left, right, int op):
    143236        """
    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
    145240        equal if they have the same class, same parent, and same value.
    146241
    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::
    148254
    149255            sage: from sage.structure.element_wrapper import DummyParent
    150256            sage: parent1 = DummyParent("A parent")
    151257            sage: parent2 = DummyParent("Another parent")
    152258            sage: parent1 == parent2
    153259            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)
    158264            sage: l11 == l11
    159265            True
    160266            sage: l11 == l12
    161267            False
    162268            sage: l11 == l21
    163269            False
    164         """
    165         return (self.__class__ is other.__class__ and
    166                 self.parent() == other.parent() and
    167                 self.value == other.value)
    168270
    169     def __ne__(self, other):
    170         """
    171         Default implementation of unequality testing by using
    172         :meth:`.__eq__`.
    173 
    174         EXAMPLES::
     271        Testing inequality::
    175272
    176273            sage: from sage.structure.element_wrapper import DummyParent
    177274            sage: parent1 = DummyParent("A parent")
    178275            sage: parent2 = DummyParent("Another parent")
    179276            sage: parent1 == parent2
    180277            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)
    185282            sage: l11 != l11
    186283            False
    187284            sage: l11 != l12
    188285            True
    189286            sage: l11 != l21
    190287            True
    191         """
    192         return not self.__eq__(other)
    193288
    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::
    204290
    205291            sage: from sage.structure.element_wrapper import DummyParent
    206292            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)
    209295            sage: x.__lt__(x), x.__lt__(y), y.__lt__(x), x.__lt__(1)
    210296            (False, False, False, False)
    211297            sage: x < x, x < y, y < x, x < 1
    class ElementWrapper(Element): 
    215301            sage: sorted([y,x])
    216302            [2, 1]
    217303        """
     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
    218313        return False
    219314
    220     def _lt_by_value(self, other):
     315    cpdef bool _lt_by_value(self, other):
    221316        """
    222         Returns whether ``self`` is strictly smaller than ``other``.
     317        Return whether ``self`` is strictly smaller than ``other``.
    223318
    224319        With this implementation 'by value', they are always
    225320        incomparable unless ``self`` and ``other`` have the same
    226         class, parent, and self.value < other.value.
     321        class, parent, and ``self.value < other.value``.
    227322
    228323        EXAMPLES::
    229324
    230325            sage: from sage.structure.element_wrapper import DummyParent
    231326            sage: class MyElement(ElementWrapper):
    232             ...       __lt__ = ElementWrapper._lt_by_value
    233             ...
     327            ....:     __lt__ = ElementWrapper._lt_by_value
     328            ....:
    234329            sage: parent1 = DummyParent("A parent")
    235330            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)
    240335            sage: l11 < l11
    241336            False
    242337            sage: l11 < l12, l12 < l11   # values differ
    class ElementWrapper(Element): 
    248343            sage: 1 < l11                # random, since it depends on what the Integer 1 decides to do, which may just involve memory locations
    249344            False
    250345        """
    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
    252349
    253     def _cmp_by_value(self, other):
     350    cpdef int _cmp_by_value(self, other):
    254351        """
    255352        Implementation of ``cmp`` by comparing first values, then
    256353        parents, then class. This behavior (which implies a total
    class ElementWrapper(Element): 
    261358        EXAMPLES::
    262359
    263360            sage: class MyElement(ElementWrapper):
    264             ...       __cmp__ = ElementWrapper._cmp_by_value
    265             ...
     361            ....:     __cmp__ = ElementWrapper._cmp_by_value
     362            ....:
    266363            sage: from sage.structure.element_wrapper import DummyParent
    267364            sage: parent1 = DummyParent("A parent")
    268365            sage: parent2 = DummyParent("Another parent")
    269366            sage: parent1 == parent2
    270367            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)
    275372            sage: cmp(l11, l11)
    276373            0
    277374            sage: cmp(l11, l12), cmp(l12, l11)   # values differ
    class ElementWrapper(Element): 
    291388
    292389    def __copy__(self):
    293390        """
    294         Copy self and in particular its ``value`` attribute.
     391        Copy ``self`` and in particular its ``value`` attribute.
    295392
    296393        EXAMPLES::
    297394
    298395            sage: from sage.structure.element_wrapper import DummyParent
    299396            sage: parent = DummyParent("A parent")
    300             sage: o1 = ElementWrapper([1], parent=parent); o1
     397            sage: o1 = ElementWrapper(parent, [1]); o1
    301398            [1]
    302399            sage: o2 = copy(o1); o2
    303400            [1]
    304             sage: o1 is o2, o1.__dict__ is o2.__dict__
     401            sage: o1 is o2, o1.value is o2.value
    305402            (False, False)
    306403            sage: o2.value[0] = 3; o2
    307404            [3]
    308405            sage: o1
    309406            [1]
    310407            sage: class bla(ElementWrapper): pass
    311             sage: o3 = bla([1], parent=parent)
     408            sage: o3 = bla(parent, [1])
    312409            sage: o4 = copy(o3)
    313410            sage: o3.value[0] = 3; o4
    314411            [1]
    class ElementWrapper(Element): 
    322419        res.value = copy(self.value)
    323420        return res
    324421
    325 
    326422from sage.structure.parent import Parent
    327423from sage.structure.unique_representation import UniqueRepresentation
    328424class DummyParent(UniqueRepresentation, Parent):
    class DummyParent(UniqueRepresentation,  
    356452        """
    357453        return self.name
    358454
    359 from sage.categories.sets_cat import Sets
    360455class ElementWrapperTester(ElementWrapper):
    361456    """
    362457    Test class for the default :meth:`.__copy` method of subclasses of
    class ElementWrapperTester(ElementWrappe 
    374469        sage: x.append(21); x.append(7)
    375470        sage: x, y
    376471        ([n=3, value=[2, 21, 7]], [n=2, value=[2, 42]])
     472        sage: x.value, y.value
     473        ([2, 21, 7], [2, 42])
    377474        sage: x.__dict__, y.__dict__
    378         ({'value': [2, 21, 7], 'n': 3}, {'value': [2, 42], 'n': 2})
     475        ({'n': 3}, {'n': 2})
    379476    """
    380477    def __init__(self):
    381478        """
    class ElementWrapperTester(ElementWrappe 
    385482            sage: x = ElementWrapperTester(); x
    386483            [n=0, value=[]]
    387484        """
    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"), [])
    389487        self.n = 0
    390488
    391489    def append(self, x):
    class ElementWrapperTester(ElementWrappe 
    412510            [n=0, value=[2, 32]]
    413511        """
    414512        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:: 
    1010A simple example of registering coercions::
    1111
    1212    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    ....:
    2625    sage: A = A_class("A")
    2726    sage: B = A_class("B")
    2827    sage: C = A_class("C")
    2928
    3029    sage: def f(a):
    31     ...     return B(a.value+1)
    32     ...
     30    ....:   return B(a.value+1)
     31    ....:
    3332    sage: class MyMorphism(Morphism):
    34     ...     def __init__(self, domain, codomain):
    35     ...         Morphism.__init__(self, Hom(domain, codomain))
    36     ...     #
    37     ...     def _call_(self, x):
    38     ...         return self.codomain()(x.value)
    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    ....:
    4039    sage: f = MyMorphism(A,B)
    4140    sage: f
    4241        Generic morphism:
    base ring, and with ``_mul_`` for the ri 
    6463
    6564    sage: from sage.structure.element import RingElement
    6665    sage: class MyElement(RingElement):
    67     ....:      def __init__(self, x,y, parent = None):
     66    ....:      def __init__(self, parent, x, y):
    6867    ....:          RingElement.__init__(self, parent)
    6968    ....:      def _mul_(self, other):
    7069    ....:          return self
    cdef class Parent(category_object.Catego 
    377376            sage: P.category()
    378377            Category of sets
    379378            sage: class MyParent(Parent):
    380             ...       def __init__(self):
    381             ...           self._init_category_(Groups())
     379            ....:     def __init__(self):
     380            ....:         self._init_category_(Groups())
    382381            sage: MyParent().category()
    383382            Category of groups
    384383        """
    cdef class Parent(category_object.Catego 
    524523            sage: P.category()
    525524            Category of sets
    526525            sage: class MyParent(Parent):
    527             ...       def __init__(self): pass
     526            ....:     def __init__(self): pass
    528527            sage: MyParent().category()
    529528            Category of sets
    530529        """
    cdef class Parent(category_object.Catego 
    547546        Let us now write a parent with broken categories:
    548547
    549548            sage: class MyParent(Parent):
    550             ...       def __init__(self):
    551             ...           pass
     549            ....:     def __init__(self):
     550            ....:         pass
    552551            sage: P = MyParent()
    553552            sage: P._test_category()
    554553            Traceback (most recent call last):
    cdef class Parent(category_object.Catego 
    591590        Let us now write a broken class method::
    592591
    593592            sage: class CCls(Parent):
    594             ...       def __eq__(self, other):
    595             ...           return True
     593            ....:     def __eq__(self, other):
     594            ....:         return True
    596595            sage: CCls()._test_eq()
    597596            Traceback (most recent call last):
    598597            ...
    cdef class Parent(category_object.Catego 
    601600        Let us now break inequality::
    602601
    603602            sage: class CCls(Parent):
    604             ...       def __ne__(self, other):
    605             ...           return True
     603            ....:     def __ne__(self, other):
     604            ....:         return True
    606605            sage: CCls()._test_eq()
    607606            Traceback (most recent call last):
    608607            ...
    cdef class Parent(category_object.Catego 
    727726        EXAMPLES::
    728727
    729728            sage: for s in dir(ZZ):
    730             ...       if s[:6] == "_test_": print s
     729            ....:     if s[:6] == "_test_": print s
    731730            _test_additive_associativity
    732731            _test_an_element
    733732            _test_associativity
    cdef class Parent(category_object.Catego 
    913912        is preserved (see :trac:`5979`)::
    914913
    915914            sage: class MyParent(Parent):
    916             ...       def _element_constructor_(self, x):
    917             ...           print self, x
    918             ...           return sage.structure.element.Element(parent = self)
    919             ...       def _repr_(self):
    920             ...           return "my_parent"
    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            ....:
    922921            sage: my_parent = MyParent()
    923922            sage: x = my_parent("bla")
    924923            my_parent bla
    cdef class Parent(category_object.Catego 
    12501249
    12511250            sage: from sage.rings.integer_ring import IntegerRing_class
    12521251            sage: class MyIntegers_class(IntegerRing_class):
    1253             ...        def is_finite(self):
    1254             ...            raise NotImplementedError
     1252            ....:      def is_finite(self):
     1253            ....:          raise NotImplementedError
    12551254            sage: MyIntegers = MyIntegers_class()
    12561255            sage: MyIntegers.is_finite()
    12571256            Traceback (most recent call last):
    cdef class Parent(category_object.Catego 
    12621261        pressing Ctrl-C.  We let it run for 1 second and then interrupt::
    12631262
    12641263            sage: try:
    1265             ...     alarm(1)
    1266             ...     list(MyIntegers)
    1267             ... except KeyboardInterrupt:
    1268             ...     print "Caught KeyboardInterrupt"
    1269             ...     
     1264            ....:   alarm(1)
     1265            ....:   list(MyIntegers)
     1266            ....: except KeyboardInterrupt:
     1267            ....:   print "Caught KeyboardInterrupt"
     1268            ....:   
    12701269            Caught KeyboardInterrupt
    12711270
    12721271        """
    cdef class Parent(category_object.Catego 
    13891388        override this default implementation::
    13901389
    13911390            sage: class As(Category):
    1392             ...       def super_categories(self): return [Sets()]
    1393             ...       class ParentMethods:
    1394             ...           def __getitem__(self, n):
    1395             ...               return 'coucou'
     1391            ....:     def super_categories(self): return [Sets()]
     1392            ....:     class ParentMethods:
     1393            ....:         def __getitem__(self, n):
     1394            ....:             return 'coucou'
    13961395            sage: class A(Parent):
    1397             ...       def __init__(self):
    1398             ...           Parent.__init__(self, category=As())
     1396            ....:     def __init__(self):
     1397            ....:         Parent.__init__(self, category=As())
    13991398            sage: a = A()
    14001399            sage: a[1]
    14011400            'coucou'
    cdef class Parent(category_object.Catego 
    17271726            sage: import operator
    17281727
    17291728            sage: class SymmetricGroupAction(sage.categories.action.Action):
    1730             ...       "Act on a multivariate polynomial ring by permuting the generators."
    1731             ...       def __init__(self, G, M, is_left=True):
    1732             ...           sage.categories.action.Action.__init__(self, G, M, is_left, operator.mul)
    1733             ... 
    1734             ...       def _call_(self, g, a):
    1735             ...           if not self.is_left():
    1736             ...               g, a = a, g
    1737             ...           D = {}
    1738             ...           for k, v in a.dict().items():
    1739             ...               nk = [0]*len(k)
    1740             ...               for i in range(len(k)):
    1741             ...                   nk[g(i+1)-1] = k[i]
    1742             ...               D[tuple(nk)] = v
    1743             ...           return a.parent()(D)
     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)
    17441743
    17451744            sage: R.<x, y, z> = QQ['x, y, z']
    17461745            sage: G = SymmetricGroup(3)
    cdef class Parent(category_object.Catego 
    20942093            sage: _ = gc.collect()
    20952094            sage: K = GF(1<<55,'t')
    20962095            sage: for i in range(50):
    2097             ...     a = K.random_element()
    2098             ...     E = EllipticCurve(j=a)
    2099             ...     b = K.has_coerce_map_from(E)
     2096            ....:   a = K.random_element()
     2097            ....:   E = EllipticCurve(j=a)
     2098            ....:   b = K.has_coerce_map_from(E)
    21002099            sage: _ = gc.collect()
    21012100            sage: len([x for x in gc.get_objects() if isinstance(x,type(E))])
    21022101            1
    cdef class Parent(category_object.Catego 
    22112210        Regression test for :trac:`12919` (probably not 100% robust)::
    22122211
    22132212            sage: class P(Parent):
    2214             ...       def __init__(self):
    2215             ...           Parent.__init__(self, category=Sets())
    2216             ...       Element=ElementWrapper
     2213            ....:     def __init__(self):
     2214            ....:         Parent.__init__(self, category=Sets())
     2215            ....:     Element=ElementWrapper
    22172216            sage: A = P(); a = A('a')
    22182217            sage: B = P(); b = B('b')
    22192218            sage: C = P(); c = C('c')