]> git.proxmox.com Git - mirror_edk2.git/blame - AppPkg/Applications/Python/Python-2.7.2/Lib/test/test_coercion.py
EmbeddedPkg: Extend NvVarStoreFormattedLib LIBRARY_CLASS
[mirror_edk2.git] / AppPkg / Applications / Python / Python-2.7.2 / Lib / test / test_coercion.py
CommitLineData
4710c53d 1import copy\r
2import unittest\r
3from test.test_support import run_unittest, TestFailed, check_warnings\r
4\r
5\r
6# Fake a number that implements numeric methods through __coerce__\r
7class CoerceNumber:\r
8 def __init__(self, arg):\r
9 self.arg = arg\r
10\r
11 def __repr__(self):\r
12 return '<CoerceNumber %s>' % repr(self.arg)\r
13\r
14 def __coerce__(self, other):\r
15 if isinstance(other, CoerceNumber):\r
16 return self.arg, other.arg\r
17 else:\r
18 return (self.arg, other)\r
19\r
20# New-style class version of CoerceNumber\r
21class CoerceTo(object):\r
22 def __init__(self, arg):\r
23 self.arg = arg\r
24 def __coerce__(self, other):\r
25 if isinstance(other, CoerceTo):\r
26 return self.arg, other.arg\r
27 else:\r
28 return self.arg, other\r
29\r
30\r
31# Fake a number that implements numeric ops through methods.\r
32class MethodNumber:\r
33 def __init__(self,arg):\r
34 self.arg = arg\r
35\r
36 def __repr__(self):\r
37 return '<MethodNumber %s>' % repr(self.arg)\r
38\r
39 def __add__(self,other):\r
40 return self.arg + other\r
41\r
42 def __radd__(self,other):\r
43 return other + self.arg\r
44\r
45 def __sub__(self,other):\r
46 return self.arg - other\r
47\r
48 def __rsub__(self,other):\r
49 return other - self.arg\r
50\r
51 def __mul__(self,other):\r
52 return self.arg * other\r
53\r
54 def __rmul__(self,other):\r
55 return other * self.arg\r
56\r
57 def __div__(self,other):\r
58 return self.arg / other\r
59\r
60 def __rdiv__(self,other):\r
61 return other / self.arg\r
62\r
63 def __truediv__(self,other):\r
64 return self.arg / other\r
65\r
66 def __rtruediv__(self,other):\r
67 return other / self.arg\r
68\r
69 def __floordiv__(self,other):\r
70 return self.arg // other\r
71\r
72 def __rfloordiv__(self,other):\r
73 return other // self.arg\r
74\r
75 def __pow__(self,other):\r
76 return self.arg ** other\r
77\r
78 def __rpow__(self,other):\r
79 return other ** self.arg\r
80\r
81 def __mod__(self,other):\r
82 return self.arg % other\r
83\r
84 def __rmod__(self,other):\r
85 return other % self.arg\r
86\r
87 def __cmp__(self, other):\r
88 return cmp(self.arg, other)\r
89\r
90\r
91candidates = [2, 2L, 4.0, 2+0j, [1], (2,), None,\r
92 MethodNumber(2), CoerceNumber(2)]\r
93\r
94infix_binops = [ '+', '-', '*', '**', '%', '//', '/' ]\r
95\r
96TE = TypeError\r
97# b = both normal and augmented give same result list\r
98# s = single result lists for normal and augmented\r
99# e = equals other results\r
100# result lists: ['+', '-', '*', '**', '%', '//', ('classic /', 'new /')]\r
101# ^^^^^^^^^^^^^^^^^^^^^^\r
102# 2-tuple if results differ\r
103# else only one value\r
104infix_results = {\r
105 # 2\r
106 (0,0): ('b', [4, 0, 4, 4, 0, 1, (1, 1.0)]),\r
107 (0,1): ('e', (0,0)),\r
108 (0,2): ('b', [6.0, -2.0, 8.0, 16.0, 2.0, 0.0, 0.5]),\r
109 (0,3): ('b', [4+0j, 0+0j, 4+0j, 4+0j, 0+0j, 1+0j, 1+0j]),\r
110 (0,4): ('b', [TE, TE, [1, 1], TE, TE, TE, TE]),\r
111 (0,5): ('b', [TE, TE, (2, 2), TE, TE, TE, TE]),\r
112 (0,6): ('b', [TE, TE, TE, TE, TE, TE, TE]),\r
113 (0,7): ('e', (0,0)),\r
114 (0,8): ('e', (0,0)),\r
115\r
116 # 2L\r
117 (1,0): ('e', (0,0)),\r
118 (1,1): ('e', (0,1)),\r
119 (1,2): ('e', (0,2)),\r
120 (1,3): ('e', (0,3)),\r
121 (1,4): ('e', (0,4)),\r
122 (1,5): ('e', (0,5)),\r
123 (1,6): ('e', (0,6)),\r
124 (1,7): ('e', (0,7)),\r
125 (1,8): ('e', (0,8)),\r
126\r
127 # 4.0\r
128 (2,0): ('b', [6.0, 2.0, 8.0, 16.0, 0.0, 2.0, 2.0]),\r
129 (2,1): ('e', (2,0)),\r
130 (2,2): ('b', [8.0, 0.0, 16.0, 256.0, 0.0, 1.0, 1.0]),\r
131 (2,3): ('b', [6+0j, 2+0j, 8+0j, 16+0j, 0+0j, 2+0j, 2+0j]),\r
132 (2,4): ('b', [TE, TE, TE, TE, TE, TE, TE]),\r
133 (2,5): ('e', (2,4)),\r
134 (2,6): ('e', (2,4)),\r
135 (2,7): ('e', (2,0)),\r
136 (2,8): ('e', (2,0)),\r
137\r
138 # (2+0j)\r
139 (3,0): ('b', [4+0j, 0+0j, 4+0j, 4+0j, 0+0j, 1+0j, 1+0j]),\r
140 (3,1): ('e', (3,0)),\r
141 (3,2): ('b', [6+0j, -2+0j, 8+0j, 16+0j, 2+0j, 0+0j, 0.5+0j]),\r
142 (3,3): ('b', [4+0j, 0+0j, 4+0j, 4+0j, 0+0j, 1+0j, 1+0j]),\r
143 (3,4): ('b', [TE, TE, TE, TE, TE, TE, TE]),\r
144 (3,5): ('e', (3,4)),\r
145 (3,6): ('e', (3,4)),\r
146 (3,7): ('e', (3,0)),\r
147 (3,8): ('e', (3,0)),\r
148\r
149 # [1]\r
150 (4,0): ('b', [TE, TE, [1, 1], TE, TE, TE, TE]),\r
151 (4,1): ('e', (4,0)),\r
152 (4,2): ('b', [TE, TE, TE, TE, TE, TE, TE]),\r
153 (4,3): ('b', [TE, TE, TE, TE, TE, TE, TE]),\r
154 (4,4): ('b', [[1, 1], TE, TE, TE, TE, TE, TE]),\r
155 (4,5): ('s', [TE, TE, TE, TE, TE, TE, TE], [[1, 2], TE, TE, TE, TE, TE, TE]),\r
156 (4,6): ('b', [TE, TE, TE, TE, TE, TE, TE]),\r
157 (4,7): ('e', (4,0)),\r
158 (4,8): ('e', (4,0)),\r
159\r
160 # (2,)\r
161 (5,0): ('b', [TE, TE, (2, 2), TE, TE, TE, TE]),\r
162 (5,1): ('e', (5,0)),\r
163 (5,2): ('b', [TE, TE, TE, TE, TE, TE, TE]),\r
164 (5,3): ('e', (5,2)),\r
165 (5,4): ('e', (5,2)),\r
166 (5,5): ('b', [(2, 2), TE, TE, TE, TE, TE, TE]),\r
167 (5,6): ('b', [TE, TE, TE, TE, TE, TE, TE]),\r
168 (5,7): ('e', (5,0)),\r
169 (5,8): ('e', (5,0)),\r
170\r
171 # None\r
172 (6,0): ('b', [TE, TE, TE, TE, TE, TE, TE]),\r
173 (6,1): ('e', (6,0)),\r
174 (6,2): ('e', (6,0)),\r
175 (6,3): ('e', (6,0)),\r
176 (6,4): ('e', (6,0)),\r
177 (6,5): ('e', (6,0)),\r
178 (6,6): ('e', (6,0)),\r
179 (6,7): ('e', (6,0)),\r
180 (6,8): ('e', (6,0)),\r
181\r
182 # MethodNumber(2)\r
183 (7,0): ('e', (0,0)),\r
184 (7,1): ('e', (0,1)),\r
185 (7,2): ('e', (0,2)),\r
186 (7,3): ('e', (0,3)),\r
187 (7,4): ('e', (0,4)),\r
188 (7,5): ('e', (0,5)),\r
189 (7,6): ('e', (0,6)),\r
190 (7,7): ('e', (0,7)),\r
191 (7,8): ('e', (0,8)),\r
192\r
193 # CoerceNumber(2)\r
194 (8,0): ('e', (0,0)),\r
195 (8,1): ('e', (0,1)),\r
196 (8,2): ('e', (0,2)),\r
197 (8,3): ('e', (0,3)),\r
198 (8,4): ('e', (0,4)),\r
199 (8,5): ('e', (0,5)),\r
200 (8,6): ('e', (0,6)),\r
201 (8,7): ('e', (0,7)),\r
202 (8,8): ('e', (0,8)),\r
203}\r
204\r
205def process_infix_results():\r
206 for key in sorted(infix_results):\r
207 val = infix_results[key]\r
208 if val[0] == 'e':\r
209 infix_results[key] = infix_results[val[1]]\r
210 else:\r
211 if val[0] == 's':\r
212 res = (val[1], val[2])\r
213 elif val[0] == 'b':\r
214 res = (val[1], val[1])\r
215 for i in range(1):\r
216 if isinstance(res[i][6], tuple):\r
217 if 1/2 == 0:\r
218 # testing with classic (floor) division\r
219 res[i][6] = res[i][6][0]\r
220 else:\r
221 # testing with -Qnew\r
222 res[i][6] = res[i][6][1]\r
223 infix_results[key] = res\r
224\r
225\r
226with check_warnings(("classic (int|long) division", DeprecationWarning),\r
227 quiet=True):\r
228 process_infix_results()\r
229 # now infix_results has two lists of results for every pairing.\r
230\r
231prefix_binops = [ 'divmod' ]\r
232prefix_results = [\r
233 [(1,0), (1L,0L), (0.0,2.0), ((1+0j),0j), TE, TE, TE, TE, (1,0)],\r
234 [(1L,0L), (1L,0L), (0.0,2.0), ((1+0j),0j), TE, TE, TE, TE, (1L,0L)],\r
235 [(2.0,0.0), (2.0,0.0), (1.0,0.0), ((2+0j),0j), TE, TE, TE, TE, (2.0,0.0)],\r
236 [((1+0j),0j), ((1+0j),0j), (0j,(2+0j)), ((1+0j),0j), TE, TE, TE, TE, ((1+0j),0j)],\r
237 [TE, TE, TE, TE, TE, TE, TE, TE, TE],\r
238 [TE, TE, TE, TE, TE, TE, TE, TE, TE],\r
239 [TE, TE, TE, TE, TE, TE, TE, TE, TE],\r
240 [TE, TE, TE, TE, TE, TE, TE, TE, TE],\r
241 [(1,0), (1L,0L), (0.0,2.0), ((1+0j),0j), TE, TE, TE, TE, (1,0)]\r
242]\r
243\r
244def format_float(value):\r
245 if abs(value) < 0.01:\r
246 return '0.0'\r
247 else:\r
248 return '%.1f' % value\r
249\r
250# avoid testing platform fp quirks\r
251def format_result(value):\r
252 if isinstance(value, complex):\r
253 return '(%s + %sj)' % (format_float(value.real),\r
254 format_float(value.imag))\r
255 elif isinstance(value, float):\r
256 return format_float(value)\r
257 return str(value)\r
258\r
259class CoercionTest(unittest.TestCase):\r
260 def test_infix_binops(self):\r
261 for ia, a in enumerate(candidates):\r
262 for ib, b in enumerate(candidates):\r
263 results = infix_results[(ia, ib)]\r
264 for op, res, ires in zip(infix_binops, results[0], results[1]):\r
265 if res is TE:\r
266 self.assertRaises(TypeError, eval,\r
267 'a %s b' % op, {'a': a, 'b': b})\r
268 else:\r
269 self.assertEqual(format_result(res),\r
270 format_result(eval('a %s b' % op)),\r
271 '%s %s %s == %s failed' % (a, op, b, res))\r
272 try:\r
273 z = copy.copy(a)\r
274 except copy.Error:\r
275 z = a # assume it has no inplace ops\r
276 if ires is TE:\r
277 try:\r
278 exec 'z %s= b' % op\r
279 except TypeError:\r
280 pass\r
281 else:\r
282 self.fail("TypeError not raised")\r
283 else:\r
284 exec('z %s= b' % op)\r
285 self.assertEqual(ires, z)\r
286\r
287 def test_prefix_binops(self):\r
288 for ia, a in enumerate(candidates):\r
289 for ib, b in enumerate(candidates):\r
290 for op in prefix_binops:\r
291 res = prefix_results[ia][ib]\r
292 if res is TE:\r
293 self.assertRaises(TypeError, eval,\r
294 '%s(a, b)' % op, {'a': a, 'b': b})\r
295 else:\r
296 self.assertEqual(format_result(res),\r
297 format_result(eval('%s(a, b)' % op)),\r
298 '%s(%s, %s) == %s failed' % (op, a, b, res))\r
299\r
300 def test_cmptypes(self):\r
301 # Built-in tp_compare slots expect their arguments to have the\r
302 # same type, but a user-defined __coerce__ doesn't have to obey.\r
303 # SF #980352\r
304 evil_coercer = CoerceTo(42)\r
305 # Make sure these don't crash any more\r
306 self.assertNotEqual(cmp(u'fish', evil_coercer), 0)\r
307 self.assertNotEqual(cmp(slice(1), evil_coercer), 0)\r
308 # ...but that this still works\r
309 class WackyComparer(object):\r
310 def __cmp__(slf, other):\r
311 self.assertTrue(other == 42, 'expected evil_coercer, got %r' % other)\r
312 return 0\r
313 __hash__ = None # Invalid cmp makes this unhashable\r
314 self.assertEqual(cmp(WackyComparer(), evil_coercer), 0)\r
315 # ...and classic classes too, since that code path is a little different\r
316 class ClassicWackyComparer:\r
317 def __cmp__(slf, other):\r
318 self.assertTrue(other == 42, 'expected evil_coercer, got %r' % other)\r
319 return 0\r
320 self.assertEqual(cmp(ClassicWackyComparer(), evil_coercer), 0)\r
321\r
322 def test_infinite_rec_classic_classes(self):\r
323 # if __coerce__() returns its arguments reversed it causes an infinite\r
324 # recursion for classic classes.\r
325 class Tester:\r
326 def __coerce__(self, other):\r
327 return other, self\r
328\r
329 exc = TestFailed("__coerce__() returning its arguments reverse "\r
330 "should raise RuntimeError")\r
331 try:\r
332 Tester() + 1\r
333 except (RuntimeError, TypeError):\r
334 return\r
335 except:\r
336 raise exc\r
337 else:\r
338 raise exc\r
339\r
340def test_main():\r
341 with check_warnings(("complex divmod.., // and % are deprecated",\r
342 DeprecationWarning),\r
343 ("classic (int|long) division", DeprecationWarning),\r
344 quiet=True):\r
345 run_unittest(CoercionTest)\r
346\r
347if __name__ == "__main__":\r
348 test_main()\r