1 ### -*- mode: python, coding: utf-8 -*-
3 ### Testing implicit conversions
5 ### (c) 2019 Straylight/Edgeware
8 ###----- Licensing notice ---------------------------------------------------
10 ### This file is part of the Python interface to Catacomb.
12 ### Catacomb/Python is free software: you can redistribute it and/or
13 ### modify it under the terms of the GNU General Public License as
14 ### published by the Free Software Foundation; either version 2 of the
15 ### License, or (at your option) any later version.
17 ### Catacomb/Python is distributed in the hope that it will be useful, but
18 ### WITHOUT ANY WARRANTY; without even the implied warranty of
19 ### MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
20 ### General Public License for more details.
22 ### You should have received a copy of the GNU General Public License
23 ### along with Catacomb/Python. If not, write to the Free Software
24 ### Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
27 ###--------------------------------------------------------------------------
35 ###--------------------------------------------------------------------------
36 class TestConvert (U
.TestCase
):
37 """Test implicit conversions between various mathematical types."""
44 kk
= C
.BinPolyField(0x13)
48 ## `MP' asymmetric operations.
49 me
.assertEqual(pow(C
.MP(5), 2), 25)
50 me
.assertEqual(pow(5, C
.MP(2)), 25)
51 me
.assertEqual(pow(C
.MP(5), 2, 7), 4)
52 me
.assertEqual(pow(5, C
.MP(2), 7), 4)
53 me
.assertEqual(pow(5, 2, C
.MP(7)), 4)
54 for bad
in [lambda x
: [x
]]:
55 me
.assertRaises(TypeError, pow, C
.MP(5), bad(2))
56 me
.assertRaises(TypeError, pow, C
.MP(5), bad(2), 7)
58 ## Debug builds of Python 2 crash here, and it's not our fault. Run
60 ## $ python2.7-dbg -c 'pow(long(5), 2, [7])'
62 ## to confirm. The `[7]' causes coercion to occur. The first and
63 ## second operands are coerced first, and successfully replaced by
64 ## the results: the first operand (in this case) is unchanged, but
65 ## has its refcount bumped, and the second operand is replaced by the
66 ## result of coercion, which now has a refcount of 1. Then the first
67 ## and third operands are coerced, which fails. Python decrements
68 ## the refcounts of the results of the first coercion, so the second
69 ## operand is now freed and, in debug builds, clobbered. Python then
70 ## tries to format an error message, quoting the types of the
71 ## operands, but one of them has been lost.
72 me
.assertRaises(TypeError, pow, C
.MP(5), 2, bad(7))
73 me
.assertRaises(TypeError, T
.lsl
, C
.MP(5), bad(2))
75 ## `GF' asymmetric operations.
76 me
.assertEqual(pow(C
.GF(0x5), 2), C
.GF(0x11))
77 me
.assertEqual(pow(C
.GF(0x5), C
.MP(2)), C
.GF(0x11))
78 me
.assertEqual(pow(C
.GF(5), 2, C
.GF(0x13)), C
.GF(0x2))
79 for bad
in [lambda x
: [x
]]:
80 me
.assertRaises(TypeError, pow, C
.GF(5), bad(2))
81 me
.assertRaises(TypeError, T
.lsl
, C
.GF(5), bad(2))
82 for bad
in [lambda x
: [x
]]:
83 me
.assertRaises(TypeError, pow, bad(5), C
.GF(2))
84 me
.assertRaises(TypeError, pow, bad(5), C
.GF(2), bad(7))
85 me
.assertRaises(TypeError, pow, bad(5), bad(2), C
.GF(7))
86 me
.assertRaises(TypeError, pow, C
.GF(5), bad(2), bad(7))
88 ## Python bug: see above.
89 me
.assertRaises(TypeError, pow, C
.GF(5), 2, bad(7))
92 me
.assertEqual(C
.MP(5), 5)
93 me
.assertEqual(5, C
.MP(5))
95 me
.assertEqual(C
.MP(5) + 3, 8)
96 me
.assertEqual(3 + C
.MP(5), 8)
97 me
.assertRaises(TypeError, T
.add
, C
.MP(5), C
.GF(3))
98 me
.assertRaises(TypeError, T
.add
, C
.GF(3), C
.MP(5))
101 me
.assertEqual(k(3) + 4, 7)
102 me
.assertEqual(4 + k(3), 7)
103 me
.assertEqual(k(3) + C
.MP(4), 7)
104 me
.assertEqual(C
.MP(4) + k(3), 7)
105 me
.assertEqual(k(3) + 4, 7)
106 me
.assertEqual(C
.GF(7) + kk(3), C
.GF(4))
107 me
.assertEqual(kk(3) + C
.GF(7), C
.GF(4))
109 me
.assertRaises(TypeError, T
.add
, k(3), kk(3))
110 me
.assertRaises(TypeError, T
.add
, kk(3), k(3))
112 ###----- That's all, folks --------------------------------------------------
114 if __name__
== "__main__": U
.main()