1# ticket: 561
2# tag: py2
3# This file tests the behavior of special methods under Python 2
4# after #561.  (Only methods whose behavior differs between Python 2 and 3
5# are tested here; see special_methods_T561.pyx for the rest of the tests.)
6
7__doc__ = u"""
8    >>> vs0 = VerySpecial(0)
9    VS __init__ 0
10    >>> vs1 = VerySpecial(1)
11    VS __init__ 1
12    >>> # Python 3 does not use __cmp__.
13    >>> vs0_cmp = vs0.__cmp__
14    >>> vs0_cmp(vs1)
15    VS __cmp__ 0 1
16    0
17    >>> # Python 3 does not use __div__ or __idiv__.
18    >>> vs0_div = vs0.__div__
19    >>> vs0_div(vs1)
20    VS __div__ 0 1
21    >>> vs0_idiv = vs0.__idiv__
22    >>> vs0_idiv(vs1)
23    VS __idiv__ 0 /= 1
24    >>> vs0_rdiv = vs0.__rdiv__
25    >>> vs0_rdiv(vs1)
26    VS __div__ 1 0
27    >>> # Python 3 does not use __oct__ or __hex__.
28    >>> vs0_oct = vs0.__oct__
29    >>> vs0_oct()
30    VS __oct__ 0
31    >>> vs0_hex = vs0.__hex__
32    >>> vs0_hex()
33    VS __hex__ 0
34    >>> # Python 3 does not use __nonzero__; if you define a __nonzero__
35    >>> # method, Cython for Python 3 would give you a __bool__ method
36    >>> # instead.
37    >>> vs0_nonzero = vs0.__nonzero__
38    >>> vs0_nonzero()
39    VS __nonzero__ 0
40    False
41    >>> # If you define __next__, you get both __next__ and next (this behavior
42    >>> # is unchanged by T561, but only happens in Python 2)
43    >>> vs0_next = vs0.__next__
44    >>> vs0_next()
45    VS next/__next__ 0
46    >>> vs0_next2 = vs0.next
47    >>> vs0_next2()
48    VS next/__next__ 0
49    >>> # Cython supports getslice only for Python 2.
50    >>> vs0_getslice = vs0.__getslice__
51    >>> vs0_getslice(13, 42)
52    VS __getslice__ 0 13 42
53    >>> # Cython supports setslice and delslice only for Python 2.
54    >>> # If you define either setslice or delslice, you get wrapper objects
55    >>> # for both methods.  (This behavior is unchanged by #561.)
56    >>> ss_setslice = SetSlice().__setslice__
57    >>> ss_setslice(13, 42, 'foo')
58    SetSlice setslice 13 42 'foo'
59    >>> ss_delslice = SetSlice().__delslice__
60    >>> ss_delslice(13, 42)
61    Traceback (most recent call last):
62    ...
63    NotImplementedError: 2-element slice deletion not supported by special_methods_T561_py2.SetSlice
64    >>> ds_setslice = DelSlice().__setslice__
65    >>> ds_setslice(13, 42, 'foo')
66    Traceback (most recent call last):
67    ...
68    NotImplementedError: 2-element slice assignment not supported by special_methods_T561_py2.DelSlice
69    >>> ds_delslice = DelSlice().__delslice__
70    >>> ds_delslice(13, 42)
71    DelSlice delslice 13 42
72    >>> sds_setslice = SetDelSlice().__setslice__
73    >>> sds_setslice(13, 42, 'foo')
74    SetDelSlice setslice 13 42 'foo'
75    >>> sds_delslice = SetDelSlice().__delslice__
76    >>> sds_delslice(13, 42)
77    SetDelSlice delslice 13 42
78    >>> # Python 3 does not use __long__.
79    >>> Ll = Long().__long__
80    >>> Ll()
81    Long __long__
82"""
83
84cdef class VerySpecial:
85    cdef readonly int value
86
87    def __init__(self, v):
88        self.value = v
89        print "VS __init__ %d" % self.value
90
91    def __getslice__(self, a, b):
92        print "VS __getslice__ %d %d %d" % (self.value, a, b)
93
94    def __next__(self):
95        print "VS next/__next__ %d" % self.value
96
97    def __nonzero__(self):
98        print "VS __nonzero__ %d" % self.value
99
100    def __oct__(self):
101        print "VS __oct__ %d" % self.value
102
103    def __hex__(self):
104        print "VS __hex__ %d" % self.value
105
106    def __cmp__(self, other):
107        print "VS __cmp__ %d %d" % (self.value, other.value)
108
109    def __div__(self, other):
110        print "VS __div__ %d %d" % (self.value, other.value)
111
112    def __idiv__(self, other):
113        print "VS __idiv__ %d /= %d" % (self.value, other.value)
114
115cdef class SetSlice:
116    def __setslice__(self, a, b, value):
117        print "SetSlice setslice %d %d %r" % (a, b, value)
118
119cdef class DelSlice:
120    def __delslice__(self, a, b):
121        print "DelSlice delslice %d %d" % (a, b)
122
123cdef class SetDelSlice:
124    def __setslice__(self, a, b, value):
125        print "SetDelSlice setslice %d %d %r" % (a, b, value)
126
127    def __delslice__(self, a, b):
128        print "SetDelSlice delslice %d %d" % (a, b)
129
130cdef class Long:
131    def __long__(self):
132        print "Long __long__"
133