|
1 | 1 | import contextlib |
| 2 | +import itertools |
2 | 3 | import sys |
3 | 4 | import textwrap |
4 | 5 | import unittest |
@@ -1511,6 +1512,49 @@ def test_jit_error_pops(self): |
1511 | 1512 | with self.assertRaises(TypeError): |
1512 | 1513 | {item for item in items} |
1513 | 1514 |
|
| 1515 | + def test_power_type_depends_on_input_values(self): |
| 1516 | + template = textwrap.dedent(""" |
| 1517 | + import _testinternalcapi |
| 1518 | +
|
| 1519 | + L, R, X, Y = {l}, {r}, {x}, {y} |
| 1520 | +
|
| 1521 | + def check(actual: complex, expected: complex) -> None: |
| 1522 | + assert actual == expected, (actual, expected) |
| 1523 | + assert type(actual) is type(expected), (actual, expected) |
| 1524 | +
|
| 1525 | + def f(l: complex, r: complex) -> None: |
| 1526 | + expected_local_local = pow(l, r) + pow(l, r) |
| 1527 | + expected_const_local = pow(L, r) + pow(L, r) |
| 1528 | + expected_local_const = pow(l, R) + pow(l, R) |
| 1529 | + expected_const_const = pow(L, R) + pow(L, R) |
| 1530 | + for _ in range(_testinternalcapi.TIER2_THRESHOLD): |
| 1531 | + # Narrow types: |
| 1532 | + l + l, r + r |
| 1533 | + # The powers produce results, and the addition is unguarded: |
| 1534 | + check(l ** r + l ** r, expected_local_local) |
| 1535 | + check(L ** r + L ** r, expected_const_local) |
| 1536 | + check(l ** R + l ** R, expected_local_const) |
| 1537 | + check(L ** R + L ** R, expected_const_const) |
| 1538 | +
|
| 1539 | + # JIT for one pair of values... |
| 1540 | + f(L, R) |
| 1541 | + # ...then run with another: |
| 1542 | + f(X, Y) |
| 1543 | + """) |
| 1544 | + interesting = [ |
| 1545 | + (1, 1), # int ** int -> int |
| 1546 | + (1, -1), # int ** int -> float |
| 1547 | + (1, 1.0), # int ** float -> float |
| 1548 | + (-1, 0.1), # int ** float -> complex |
| 1549 | + (1.0, 1), # float ** int -> float |
| 1550 | + (1.0, 1.0), # float ** float -> float |
| 1551 | + (-1.0, 0.1), # float ** float -> complex |
| 1552 | + ] |
| 1553 | + for (l, r), (x, y) in itertools.product(interesting, repeat=2): |
| 1554 | + s = template.format(l=l, r=r, x=x, y=y) |
| 1555 | + with self.subTest(l=l, r=r, x=x, y=y): |
| 1556 | + script_helper.assert_python_ok("-c", s) |
| 1557 | + |
1514 | 1558 |
|
1515 | 1559 | def global_identity(x): |
1516 | 1560 | return x |
|
0 commit comments