|
7 | 7 | import math |
8 | 8 | import array |
9 | 9 |
|
10 | | -# Used for lazy formatting of failure messages |
11 | | -class Frm(object): |
12 | | - def __init__(self, format, *args): |
13 | | - self.format = format |
14 | | - self.args = args |
15 | | - |
16 | | - def __str__(self): |
17 | | - return self.format % self.args |
18 | | - |
19 | 10 | # SHIFT should match the value in longintrepr.h for best testing. |
20 | 11 | SHIFT = sys.int_info.bits_per_digit |
21 | 12 | BASE = 2 ** SHIFT |
@@ -163,17 +154,18 @@ def getran2(ndigits): |
163 | 154 |
|
164 | 155 | def check_division(self, x, y): |
165 | 156 | eq = self.assertEqual |
166 | | - q, r = divmod(x, y) |
167 | | - q2, r2 = x//y, x%y |
168 | | - pab, pba = x*y, y*x |
169 | | - eq(pab, pba, Frm("multiplication does not commute for %r and %r", x, y)) |
170 | | - eq(q, q2, Frm("divmod returns different quotient than / for %r and %r", x, y)) |
171 | | - eq(r, r2, Frm("divmod returns different mod than %% for %r and %r", x, y)) |
172 | | - eq(x, q*y + r, Frm("x != q*y + r after divmod on x=%r, y=%r", x, y)) |
173 | | - if y > 0: |
174 | | - self.assertTrue(0 <= r < y, Frm("bad mod from divmod on %r and %r", x, y)) |
175 | | - else: |
176 | | - self.assertTrue(y < r <= 0, Frm("bad mod from divmod on %r and %r", x, y)) |
| 157 | + with self.subTest(x=x, y=y): |
| 158 | + q, r = divmod(x, y) |
| 159 | + q2, r2 = x//y, x%y |
| 160 | + pab, pba = x*y, y*x |
| 161 | + eq(pab, pba, "multiplication does not commute") |
| 162 | + eq(q, q2, "divmod returns different quotient than /") |
| 163 | + eq(r, r2, "divmod returns different mod than %") |
| 164 | + eq(x, q*y + r, "x != q*y + r after divmod") |
| 165 | + if y > 0: |
| 166 | + self.assertTrue(0 <= r < y, "bad mod from divmod") |
| 167 | + else: |
| 168 | + self.assertTrue(y < r <= 0, "bad mod from divmod") |
177 | 169 |
|
178 | 170 | def test_division(self): |
179 | 171 | digits = list(range(1, MAXDIGITS+1)) + list(range(KARATSUBA_CUTOFF, |
@@ -228,72 +220,63 @@ def test_karatsuba(self): |
228 | 220 | for bbits in bits: |
229 | 221 | if bbits < abits: |
230 | 222 | continue |
231 | | - b = (1 << bbits) - 1 |
232 | | - x = a * b |
233 | | - y = ((1 << (abits + bbits)) - |
234 | | - (1 << abits) - |
235 | | - (1 << bbits) + |
236 | | - 1) |
237 | | - self.assertEqual(x, y, |
238 | | - Frm("bad result for a*b: a=%r, b=%r, x=%r, y=%r", a, b, x, y)) |
| 223 | + with self.subTest(abits=abits, bbits=bbits): |
| 224 | + b = (1 << bbits) - 1 |
| 225 | + x = a * b |
| 226 | + y = ((1 << (abits + bbits)) - |
| 227 | + (1 << abits) - |
| 228 | + (1 << bbits) + |
| 229 | + 1) |
| 230 | + self.assertEqual(x, y) |
239 | 231 |
|
240 | 232 | def check_bitop_identities_1(self, x): |
241 | 233 | eq = self.assertEqual |
242 | | - eq(x & 0, 0, Frm("x & 0 != 0 for x=%r", x)) |
243 | | - eq(x | 0, x, Frm("x | 0 != x for x=%r", x)) |
244 | | - eq(x ^ 0, x, Frm("x ^ 0 != x for x=%r", x)) |
245 | | - eq(x & -1, x, Frm("x & -1 != x for x=%r", x)) |
246 | | - eq(x | -1, -1, Frm("x | -1 != -1 for x=%r", x)) |
247 | | - eq(x ^ -1, ~x, Frm("x ^ -1 != ~x for x=%r", x)) |
248 | | - eq(x, ~~x, Frm("x != ~~x for x=%r", x)) |
249 | | - eq(x & x, x, Frm("x & x != x for x=%r", x)) |
250 | | - eq(x | x, x, Frm("x | x != x for x=%r", x)) |
251 | | - eq(x ^ x, 0, Frm("x ^ x != 0 for x=%r", x)) |
252 | | - eq(x & ~x, 0, Frm("x & ~x != 0 for x=%r", x)) |
253 | | - eq(x | ~x, -1, Frm("x | ~x != -1 for x=%r", x)) |
254 | | - eq(x ^ ~x, -1, Frm("x ^ ~x != -1 for x=%r", x)) |
255 | | - eq(-x, 1 + ~x, Frm("not -x == 1 + ~x for x=%r", x)) |
256 | | - eq(-x, ~(x-1), Frm("not -x == ~(x-1) forx =%r", x)) |
| 234 | + with self.subTest(x=x): |
| 235 | + eq(x & 0, 0) |
| 236 | + eq(x | 0, x) |
| 237 | + eq(x ^ 0, x) |
| 238 | + eq(x & -1, x) |
| 239 | + eq(x | -1, -1) |
| 240 | + eq(x ^ -1, ~x) |
| 241 | + eq(x, ~~x) |
| 242 | + eq(x & x, x) |
| 243 | + eq(x | x, x) |
| 244 | + eq(x ^ x, 0) |
| 245 | + eq(x & ~x, 0) |
| 246 | + eq(x | ~x, -1) |
| 247 | + eq(x ^ ~x, -1) |
| 248 | + eq(-x, 1 + ~x) |
| 249 | + eq(-x, ~(x-1)) |
257 | 250 | for n in range(2*SHIFT): |
258 | 251 | p2 = 2 ** n |
259 | | - eq(x << n >> n, x, |
260 | | - Frm("x << n >> n != x for x=%r, n=%r", (x, n))) |
261 | | - eq(x // p2, x >> n, |
262 | | - Frm("x // p2 != x >> n for x=%r n=%r p2=%r", (x, n, p2))) |
263 | | - eq(x * p2, x << n, |
264 | | - Frm("x * p2 != x << n for x=%r n=%r p2=%r", (x, n, p2))) |
265 | | - eq(x & -p2, x >> n << n, |
266 | | - Frm("not x & -p2 == x >> n << n for x=%r n=%r p2=%r", (x, n, p2))) |
267 | | - eq(x & -p2, x & ~(p2 - 1), |
268 | | - Frm("not x & -p2 == x & ~(p2 - 1) for x=%r n=%r p2=%r", (x, n, p2))) |
| 252 | + with self.subTest(x=x, n=n, p2=p2): |
| 253 | + eq(x << n >> n, x) |
| 254 | + eq(x // p2, x >> n) |
| 255 | + eq(x * p2, x << n) |
| 256 | + eq(x & -p2, x >> n << n) |
| 257 | + eq(x & -p2, x & ~(p2 - 1)) |
269 | 258 |
|
270 | 259 | def check_bitop_identities_2(self, x, y): |
271 | 260 | eq = self.assertEqual |
272 | | - eq(x & y, y & x, Frm("x & y != y & x for x=%r, y=%r", (x, y))) |
273 | | - eq(x | y, y | x, Frm("x | y != y | x for x=%r, y=%r", (x, y))) |
274 | | - eq(x ^ y, y ^ x, Frm("x ^ y != y ^ x for x=%r, y=%r", (x, y))) |
275 | | - eq(x ^ y ^ x, y, Frm("x ^ y ^ x != y for x=%r, y=%r", (x, y))) |
276 | | - eq(x & y, ~(~x | ~y), Frm("x & y != ~(~x | ~y) for x=%r, y=%r", (x, y))) |
277 | | - eq(x | y, ~(~x & ~y), Frm("x | y != ~(~x & ~y) for x=%r, y=%r", (x, y))) |
278 | | - eq(x ^ y, (x | y) & ~(x & y), |
279 | | - Frm("x ^ y != (x | y) & ~(x & y) for x=%r, y=%r", (x, y))) |
280 | | - eq(x ^ y, (x & ~y) | (~x & y), |
281 | | - Frm("x ^ y == (x & ~y) | (~x & y) for x=%r, y=%r", (x, y))) |
282 | | - eq(x ^ y, (x | y) & (~x | ~y), |
283 | | - Frm("x ^ y == (x | y) & (~x | ~y) for x=%r, y=%r", (x, y))) |
| 261 | + with self.subTest(x=x, y=y): |
| 262 | + eq(x & y, y & x) |
| 263 | + eq(x | y, y | x) |
| 264 | + eq(x ^ y, y ^ x) |
| 265 | + eq(x ^ y ^ x, y) |
| 266 | + eq(x & y, ~(~x | ~y)) |
| 267 | + eq(x | y, ~(~x & ~y)) |
| 268 | + eq(x ^ y, (x | y) & ~(x & y)) |
| 269 | + eq(x ^ y, (x & ~y) | (~x & y)) |
| 270 | + eq(x ^ y, (x | y) & (~x | ~y)) |
284 | 271 |
|
285 | 272 | def check_bitop_identities_3(self, x, y, z): |
286 | 273 | eq = self.assertEqual |
287 | | - eq((x & y) & z, x & (y & z), |
288 | | - Frm("(x & y) & z != x & (y & z) for x=%r, y=%r, z=%r", (x, y, z))) |
289 | | - eq((x | y) | z, x | (y | z), |
290 | | - Frm("(x | y) | z != x | (y | z) for x=%r, y=%r, z=%r", (x, y, z))) |
291 | | - eq((x ^ y) ^ z, x ^ (y ^ z), |
292 | | - Frm("(x ^ y) ^ z != x ^ (y ^ z) for x=%r, y=%r, z=%r", (x, y, z))) |
293 | | - eq(x & (y | z), (x & y) | (x & z), |
294 | | - Frm("x & (y | z) != (x & y) | (x & z) for x=%r, y=%r, z=%r", (x, y, z))) |
295 | | - eq(x | (y & z), (x | y) & (x | z), |
296 | | - Frm("x | (y & z) != (x | y) & (x | z) for x=%r, y=%r, z=%r", (x, y, z))) |
| 274 | + with self.subTest(x=x, y=y, z=z): |
| 275 | + eq((x & y) & z, x & (y & z)) |
| 276 | + eq((x | y) | z, x | (y | z)) |
| 277 | + eq((x ^ y) ^ z, x ^ (y ^ z)) |
| 278 | + eq(x & (y | z), (x & y) | (x & z)) |
| 279 | + eq(x | (y & z), (x | y) & (x | z)) |
297 | 280 |
|
298 | 281 | def test_bitop_identities(self): |
299 | 282 | for x in special: |
@@ -324,11 +307,11 @@ def slow_format(self, x, base): |
324 | 307 | def check_format_1(self, x): |
325 | 308 | for base, mapper in (2, bin), (8, oct), (10, str), (10, repr), (16, hex): |
326 | 309 | got = mapper(x) |
327 | | - expected = self.slow_format(x, base) |
328 | | - msg = Frm("%s returned %r but expected %r for %r", |
329 | | - mapper.__name__, got, expected, x) |
330 | | - self.assertEqual(got, expected, msg) |
331 | | - self.assertEqual(int(got, 0), x, Frm('int("%s", 0) != %r', got, x)) |
| 310 | + with self.subTest(x=x, mapper=mapper.__name__): |
| 311 | + expected = self.slow_format(x, base) |
| 312 | + self.assertEqual(got, expected) |
| 313 | + with self.subTest(got=got): |
| 314 | + self.assertEqual(int(got, 0), x) |
332 | 315 |
|
333 | 316 | def test_format(self): |
334 | 317 | for x in special: |
@@ -627,14 +610,15 @@ def __lt__(self, other): |
627 | 610 | for y in cases: |
628 | 611 | Ry = Rat(y) |
629 | 612 | Rcmp = (Rx > Ry) - (Rx < Ry) |
630 | | - xycmp = (x > y) - (x < y) |
631 | | - eq(Rcmp, xycmp, Frm("%r %r %d %d", x, y, Rcmp, xycmp)) |
632 | | - eq(x == y, Rcmp == 0, Frm("%r == %r %d", x, y, Rcmp)) |
633 | | - eq(x != y, Rcmp != 0, Frm("%r != %r %d", x, y, Rcmp)) |
634 | | - eq(x < y, Rcmp < 0, Frm("%r < %r %d", x, y, Rcmp)) |
635 | | - eq(x <= y, Rcmp <= 0, Frm("%r <= %r %d", x, y, Rcmp)) |
636 | | - eq(x > y, Rcmp > 0, Frm("%r > %r %d", x, y, Rcmp)) |
637 | | - eq(x >= y, Rcmp >= 0, Frm("%r >= %r %d", x, y, Rcmp)) |
| 613 | + with self.subTest(x=x, y=y, Rcmp=Rcmp): |
| 614 | + xycmp = (x > y) - (x < y) |
| 615 | + eq(Rcmp, xycmp) |
| 616 | + eq(x == y, Rcmp == 0) |
| 617 | + eq(x != y, Rcmp != 0) |
| 618 | + eq(x < y, Rcmp < 0) |
| 619 | + eq(x <= y, Rcmp <= 0) |
| 620 | + eq(x > y, Rcmp > 0) |
| 621 | + eq(x >= y, Rcmp >= 0) |
638 | 622 |
|
639 | 623 | def test__format__(self): |
640 | 624 | self.assertEqual(format(123456789, 'd'), '123456789') |
|
0 commit comments