Skip to content

Commit f70ae99

Browse files
[3.12] gh-111765: Move old PyFloat_* tests to Lib/test/test_capi/test_float.py (GH-111766) (GH-111818)
(cherry picked from commit a077b2f) Co-authored-by: Sergey B Kirpichev <[email protected]>
1 parent 3514184 commit f70ae99

File tree

2 files changed

+65
-65
lines changed

2 files changed

+65
-65
lines changed

Lib/test/test_capi/test_float.py

+65
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,19 @@
1212

1313
NULL = None
1414

15+
# For PyFloat_Pack/Unpack*
16+
BIG_ENDIAN = 0
17+
LITTLE_ENDIAN = 1
18+
EPSILON = {
19+
2: 2.0 ** -11, # binary16
20+
4: 2.0 ** -24, # binary32
21+
8: 2.0 ** -53, # binary64
22+
}
23+
24+
HAVE_IEEE_754 = float.__getformat__("double").startswith("IEEE")
25+
INF = float("inf")
26+
NAN = float("nan")
27+
1528

1629
class CAPIFloatTest(unittest.TestCase):
1730
def test_check(self):
@@ -112,6 +125,58 @@ def test_getmin(self):
112125

113126
self.assertEqual(getmin(), sys.float_info.min)
114127

128+
def test_pack(self):
129+
# Test PyFloat_Pack2(), PyFloat_Pack4() and PyFloat_Pack8()
130+
pack = _testcapi.float_pack
131+
132+
self.assertEqual(pack(2, 1.5, BIG_ENDIAN), b'>\x00')
133+
self.assertEqual(pack(4, 1.5, BIG_ENDIAN), b'?\xc0\x00\x00')
134+
self.assertEqual(pack(8, 1.5, BIG_ENDIAN),
135+
b'?\xf8\x00\x00\x00\x00\x00\x00')
136+
self.assertEqual(pack(2, 1.5, LITTLE_ENDIAN), b'\x00>')
137+
self.assertEqual(pack(4, 1.5, LITTLE_ENDIAN), b'\x00\x00\xc0?')
138+
self.assertEqual(pack(8, 1.5, LITTLE_ENDIAN),
139+
b'\x00\x00\x00\x00\x00\x00\xf8?')
140+
141+
def test_unpack(self):
142+
# Test PyFloat_Unpack2(), PyFloat_Unpack4() and PyFloat_Unpack8()
143+
unpack = _testcapi.float_unpack
144+
145+
self.assertEqual(unpack(b'>\x00', BIG_ENDIAN), 1.5)
146+
self.assertEqual(unpack(b'?\xc0\x00\x00', BIG_ENDIAN), 1.5)
147+
self.assertEqual(unpack(b'?\xf8\x00\x00\x00\x00\x00\x00', BIG_ENDIAN),
148+
1.5)
149+
self.assertEqual(unpack(b'\x00>', LITTLE_ENDIAN), 1.5)
150+
self.assertEqual(unpack(b'\x00\x00\xc0?', LITTLE_ENDIAN), 1.5)
151+
self.assertEqual(unpack(b'\x00\x00\x00\x00\x00\x00\xf8?', LITTLE_ENDIAN),
152+
1.5)
153+
154+
def test_pack_unpack_roundtrip(self):
155+
pack = _testcapi.float_pack
156+
unpack = _testcapi.float_unpack
157+
158+
large = 2.0 ** 100
159+
values = [1.0, 1.5, large, 1.0/7, math.pi]
160+
if HAVE_IEEE_754:
161+
values.extend((INF, NAN))
162+
for value in values:
163+
for size in (2, 4, 8,):
164+
if size == 2 and value == large:
165+
# too large for 16-bit float
166+
continue
167+
rel_tol = EPSILON[size]
168+
for endian in (BIG_ENDIAN, LITTLE_ENDIAN):
169+
with self.subTest(value=value, size=size, endian=endian):
170+
data = pack(size, value, endian)
171+
value2 = unpack(data, endian)
172+
if math.isnan(value):
173+
self.assertTrue(math.isnan(value2), (value, value2))
174+
elif size < 8:
175+
self.assertTrue(math.isclose(value2, value, rel_tol=rel_tol),
176+
(value, value2))
177+
else:
178+
self.assertEqual(value2, value)
179+
115180

116181
if __name__ == "__main__":
117182
unittest.main()

Lib/test/test_float.py

-65
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,6 @@
1818
except ImportError:
1919
_testcapi = None
2020

21-
HAVE_IEEE_754 = float.__getformat__("double").startswith("IEEE")
2221
INF = float("inf")
2322
NAN = float("nan")
2423

@@ -1504,69 +1503,5 @@ def __init__(self, value):
15041503
self.assertEqual(getattr(f, 'foo', 'none'), 'bar')
15051504

15061505

1507-
# Test PyFloat_Pack2(), PyFloat_Pack4() and PyFloat_Pack8()
1508-
# Test PyFloat_Unpack2(), PyFloat_Unpack4() and PyFloat_Unpack8()
1509-
BIG_ENDIAN = 0
1510-
LITTLE_ENDIAN = 1
1511-
EPSILON = {
1512-
2: 2.0 ** -11, # binary16
1513-
4: 2.0 ** -24, # binary32
1514-
8: 2.0 ** -53, # binary64
1515-
}
1516-
1517-
@unittest.skipIf(_testcapi is None, 'needs _testcapi')
1518-
class PackTests(unittest.TestCase):
1519-
def test_pack(self):
1520-
self.assertEqual(_testcapi.float_pack(2, 1.5, BIG_ENDIAN),
1521-
b'>\x00')
1522-
self.assertEqual(_testcapi.float_pack(4, 1.5, BIG_ENDIAN),
1523-
b'?\xc0\x00\x00')
1524-
self.assertEqual(_testcapi.float_pack(8, 1.5, BIG_ENDIAN),
1525-
b'?\xf8\x00\x00\x00\x00\x00\x00')
1526-
self.assertEqual(_testcapi.float_pack(2, 1.5, LITTLE_ENDIAN),
1527-
b'\x00>')
1528-
self.assertEqual(_testcapi.float_pack(4, 1.5, LITTLE_ENDIAN),
1529-
b'\x00\x00\xc0?')
1530-
self.assertEqual(_testcapi.float_pack(8, 1.5, LITTLE_ENDIAN),
1531-
b'\x00\x00\x00\x00\x00\x00\xf8?')
1532-
1533-
def test_unpack(self):
1534-
self.assertEqual(_testcapi.float_unpack(b'>\x00', BIG_ENDIAN),
1535-
1.5)
1536-
self.assertEqual(_testcapi.float_unpack(b'?\xc0\x00\x00', BIG_ENDIAN),
1537-
1.5)
1538-
self.assertEqual(_testcapi.float_unpack(b'?\xf8\x00\x00\x00\x00\x00\x00', BIG_ENDIAN),
1539-
1.5)
1540-
self.assertEqual(_testcapi.float_unpack(b'\x00>', LITTLE_ENDIAN),
1541-
1.5)
1542-
self.assertEqual(_testcapi.float_unpack(b'\x00\x00\xc0?', LITTLE_ENDIAN),
1543-
1.5)
1544-
self.assertEqual(_testcapi.float_unpack(b'\x00\x00\x00\x00\x00\x00\xf8?', LITTLE_ENDIAN),
1545-
1.5)
1546-
1547-
def test_roundtrip(self):
1548-
large = 2.0 ** 100
1549-
values = [1.0, 1.5, large, 1.0/7, math.pi]
1550-
if HAVE_IEEE_754:
1551-
values.extend((INF, NAN))
1552-
for value in values:
1553-
for size in (2, 4, 8,):
1554-
if size == 2 and value == large:
1555-
# too large for 16-bit float
1556-
continue
1557-
rel_tol = EPSILON[size]
1558-
for endian in (BIG_ENDIAN, LITTLE_ENDIAN):
1559-
with self.subTest(value=value, size=size, endian=endian):
1560-
data = _testcapi.float_pack(size, value, endian)
1561-
value2 = _testcapi.float_unpack(data, endian)
1562-
if isnan(value):
1563-
self.assertTrue(isnan(value2), (value, value2))
1564-
elif size < 8:
1565-
self.assertTrue(math.isclose(value2, value, rel_tol=rel_tol),
1566-
(value, value2))
1567-
else:
1568-
self.assertEqual(value2, value)
1569-
1570-
15711506
if __name__ == '__main__':
15721507
unittest.main()

0 commit comments

Comments
 (0)