1# Augmented assignment test.
2
3from test.test_support import run_unittest, check_py3k_warnings
4import unittest
5
6
7class AugAssignTest(unittest.TestCase):
8    def testBasic(self):
9        x = 2
10        x += 1
11        x *= 2
12        x **= 2
13        x -= 8
14        x //= 5
15        x %= 3
16        x &= 2
17        x |= 5
18        x ^= 1
19        x /= 2
20        if 1/2 == 0:
21            # classic division
22            self.assertEqual(x, 3)
23        else:
24            # new-style division (with -Qnew)
25            self.assertEqual(x, 3.0)
26
27    def test_with_unpacking(self):
28        self.assertRaises(SyntaxError, compile, "x, b += 3", "<test>", "exec")
29
30    def testInList(self):
31        x = [2]
32        x[0] += 1
33        x[0] *= 2
34        x[0] **= 2
35        x[0] -= 8
36        x[0] //= 5
37        x[0] %= 3
38        x[0] &= 2
39        x[0] |= 5
40        x[0] ^= 1
41        x[0] /= 2
42        if 1/2 == 0:
43            self.assertEqual(x[0], 3)
44        else:
45            self.assertEqual(x[0], 3.0)
46
47    def testInDict(self):
48        x = {0: 2}
49        x[0] += 1
50        x[0] *= 2
51        x[0] **= 2
52        x[0] -= 8
53        x[0] //= 5
54        x[0] %= 3
55        x[0] &= 2
56        x[0] |= 5
57        x[0] ^= 1
58        x[0] /= 2
59        if 1/2 == 0:
60            self.assertEqual(x[0], 3)
61        else:
62            self.assertEqual(x[0], 3.0)
63
64    def testSequences(self):
65        x = [1,2]
66        x += [3,4]
67        x *= 2
68
69        self.assertEqual(x, [1, 2, 3, 4, 1, 2, 3, 4])
70
71        x = [1, 2, 3]
72        y = x
73        x[1:2] *= 2
74        y[1:2] += [1]
75
76        self.assertEqual(x, [1, 2, 1, 2, 3])
77        self.assertTrue(x is y)
78
79    def testCustomMethods1(self):
80
81        class aug_test:
82            def __init__(self, value):
83                self.val = value
84            def __radd__(self, val):
85                return self.val + val
86            def __add__(self, val):
87                return aug_test(self.val + val)
88
89        class aug_test2(aug_test):
90            def __iadd__(self, val):
91                self.val = self.val + val
92                return self
93
94        class aug_test3(aug_test):
95            def __iadd__(self, val):
96                return aug_test3(self.val + val)
97
98        x = aug_test(1)
99        y = x
100        x += 10
101
102        self.assertIsInstance(x, aug_test)
103        self.assertTrue(y is not x)
104        self.assertEqual(x.val, 11)
105
106        x = aug_test2(2)
107        y = x
108        x += 10
109
110        self.assertTrue(y is x)
111        self.assertEqual(x.val, 12)
112
113        x = aug_test3(3)
114        y = x
115        x += 10
116
117        self.assertIsInstance(x, aug_test3)
118        self.assertTrue(y is not x)
119        self.assertEqual(x.val, 13)
120
121
122    def testCustomMethods2(test_self):
123        output = []
124
125        class testall:
126            def __add__(self, val):
127                output.append("__add__ called")
128            def __radd__(self, val):
129                output.append("__radd__ called")
130            def __iadd__(self, val):
131                output.append("__iadd__ called")
132                return self
133
134            def __sub__(self, val):
135                output.append("__sub__ called")
136            def __rsub__(self, val):
137                output.append("__rsub__ called")
138            def __isub__(self, val):
139                output.append("__isub__ called")
140                return self
141
142            def __mul__(self, val):
143                output.append("__mul__ called")
144            def __rmul__(self, val):
145                output.append("__rmul__ called")
146            def __imul__(self, val):
147                output.append("__imul__ called")
148                return self
149
150            def __div__(self, val):
151                output.append("__div__ called")
152            def __rdiv__(self, val):
153                output.append("__rdiv__ called")
154            def __idiv__(self, val):
155                output.append("__idiv__ called")
156                return self
157
158            def __floordiv__(self, val):
159                output.append("__floordiv__ called")
160                return self
161            def __ifloordiv__(self, val):
162                output.append("__ifloordiv__ called")
163                return self
164            def __rfloordiv__(self, val):
165                output.append("__rfloordiv__ called")
166                return self
167
168            def __truediv__(self, val):
169                output.append("__truediv__ called")
170                return self
171            def __itruediv__(self, val):
172                output.append("__itruediv__ called")
173                return self
174
175            def __mod__(self, val):
176                output.append("__mod__ called")
177            def __rmod__(self, val):
178                output.append("__rmod__ called")
179            def __imod__(self, val):
180                output.append("__imod__ called")
181                return self
182
183            def __pow__(self, val):
184                output.append("__pow__ called")
185            def __rpow__(self, val):
186                output.append("__rpow__ called")
187            def __ipow__(self, val):
188                output.append("__ipow__ called")
189                return self
190
191            def __or__(self, val):
192                output.append("__or__ called")
193            def __ror__(self, val):
194                output.append("__ror__ called")
195            def __ior__(self, val):
196                output.append("__ior__ called")
197                return self
198
199            def __and__(self, val):
200                output.append("__and__ called")
201            def __rand__(self, val):
202                output.append("__rand__ called")
203            def __iand__(self, val):
204                output.append("__iand__ called")
205                return self
206
207            def __xor__(self, val):
208                output.append("__xor__ called")
209            def __rxor__(self, val):
210                output.append("__rxor__ called")
211            def __ixor__(self, val):
212                output.append("__ixor__ called")
213                return self
214
215            def __rshift__(self, val):
216                output.append("__rshift__ called")
217            def __rrshift__(self, val):
218                output.append("__rrshift__ called")
219            def __irshift__(self, val):
220                output.append("__irshift__ called")
221                return self
222
223            def __lshift__(self, val):
224                output.append("__lshift__ called")
225            def __rlshift__(self, val):
226                output.append("__rlshift__ called")
227            def __ilshift__(self, val):
228                output.append("__ilshift__ called")
229                return self
230
231        x = testall()
232        x + 1
233        1 + x
234        x += 1
235
236        x - 1
237        1 - x
238        x -= 1
239
240        x * 1
241        1 * x
242        x *= 1
243
244        if 1/2 == 0:
245            x / 1
246            1 / x
247            x /= 1
248        else:
249            # True division is in effect, so "/" doesn't map to __div__ etc;
250            # but the canned expected-output file requires that those get called.
251            x.__div__(1)
252            x.__rdiv__(1)
253            x.__idiv__(1)
254
255        x // 1
256        1 // x
257        x //= 1
258
259        x % 1
260        1 % x
261        x %= 1
262
263        x ** 1
264        1 ** x
265        x **= 1
266
267        x | 1
268        1 | x
269        x |= 1
270
271        x & 1
272        1 & x
273        x &= 1
274
275        x ^ 1
276        1 ^ x
277        x ^= 1
278
279        x >> 1
280        1 >> x
281        x >>= 1
282
283        x << 1
284        1 << x
285        x <<= 1
286
287        test_self.assertEqual(output, '''\
288__add__ called
289__radd__ called
290__iadd__ called
291__sub__ called
292__rsub__ called
293__isub__ called
294__mul__ called
295__rmul__ called
296__imul__ called
297__div__ called
298__rdiv__ called
299__idiv__ called
300__floordiv__ called
301__rfloordiv__ called
302__ifloordiv__ called
303__mod__ called
304__rmod__ called
305__imod__ called
306__pow__ called
307__rpow__ called
308__ipow__ called
309__or__ called
310__ror__ called
311__ior__ called
312__and__ called
313__rand__ called
314__iand__ called
315__xor__ called
316__rxor__ called
317__ixor__ called
318__rshift__ called
319__rrshift__ called
320__irshift__ called
321__lshift__ called
322__rlshift__ called
323__ilshift__ called
324'''.splitlines())
325
326def test_main():
327    with check_py3k_warnings(("classic int division", DeprecationWarning)):
328        run_unittest(AugAssignTest)
329
330if __name__ == '__main__':
331    test_main()
332