mirror of
https://github.com/python/cpython.git
synced 2026-04-13 23:31:02 +00:00
[3.14] gh-145633: Fix struct.pack('f') on s390x (GH-146422) (#146460)
gh-145633: Fix struct.pack('f') on s390x (GH-146422)
Use PyFloat_Pack4() to raise OverflowError.
Add more tests on packing/unpacking floats.
(cherry picked from commit 8de70b31c5)
Co-authored-by: Victor Stinner <vstinner@python.org>
Co-authored-by: Sergey B Kirpichev <skirpichev@gmail.com>
This commit is contained in:
parent
7efa72a6e4
commit
8a25840a2a
3 changed files with 37 additions and 3 deletions
|
|
@ -397,6 +397,21 @@ def test_705836(self):
|
|||
big = (1 << 25) - 1
|
||||
big = math.ldexp(big, 127 - 24)
|
||||
self.assertRaises(OverflowError, struct.pack, ">f", big)
|
||||
self.assertRaises(OverflowError, struct.pack, "<f", big)
|
||||
# same for native format, see gh-145633
|
||||
self.assertRaises(OverflowError, struct.pack, "f", big)
|
||||
|
||||
# And for half-floats
|
||||
big = (1 << 11) - 1
|
||||
big = math.ldexp(big, 15 - 10)
|
||||
packed = struct.pack(">e", big)
|
||||
unpacked = struct.unpack(">e", packed)[0]
|
||||
self.assertEqual(big, unpacked)
|
||||
big = (1 << 12) - 1
|
||||
big = math.ldexp(big, 15 - 11)
|
||||
self.assertRaises(OverflowError, struct.pack, ">e", big)
|
||||
self.assertRaises(OverflowError, struct.pack, "<e", big)
|
||||
self.assertRaises(OverflowError, struct.pack, "e", big)
|
||||
|
||||
def test_1530559(self):
|
||||
for code, byteorder in iter_integer_formats():
|
||||
|
|
@ -862,6 +877,24 @@ def test_operations_on_half_initialized_Struct(self):
|
|||
self.assertRaises(RuntimeError, repr, S)
|
||||
self.assertEqual(S.size, -1)
|
||||
|
||||
def test_float_round_trip(self):
|
||||
for format in (
|
||||
"f", "<f", ">f",
|
||||
"d", "<d", ">d",
|
||||
"e", "<e", ">e",
|
||||
):
|
||||
with self.subTest(format=format):
|
||||
f = struct.unpack(format, struct.pack(format, 1.5))[0]
|
||||
self.assertEqual(f, 1.5)
|
||||
f = struct.unpack(format, struct.pack(format, NAN))[0]
|
||||
self.assertTrue(math.isnan(f), f)
|
||||
f = struct.unpack(format, struct.pack(format, INF))[0]
|
||||
self.assertTrue(math.isinf(f), f)
|
||||
self.assertEqual(math.copysign(1.0, f), 1.0)
|
||||
f = struct.unpack(format, struct.pack(format, -INF))[0]
|
||||
self.assertTrue(math.isinf(f), f)
|
||||
self.assertEqual(math.copysign(1.0, f), -1.0)
|
||||
|
||||
|
||||
class UnpackIteratorTest(unittest.TestCase):
|
||||
"""
|
||||
|
|
|
|||
|
|
@ -0,0 +1,2 @@
|
|||
Fix ``struct.pack('f', float)``: use :c:func:`PyFloat_Pack4` to raise
|
||||
:exc:`OverflowError`. Patch by Sergey B Kirpichev and Victor Stinner.
|
||||
|
|
@ -762,14 +762,13 @@ np_halffloat(_structmodulestate *state, char *p, PyObject *v, const formatdef *f
|
|||
static int
|
||||
np_float(_structmodulestate *state, char *p, PyObject *v, const formatdef *f)
|
||||
{
|
||||
float x = (float)PyFloat_AsDouble(v);
|
||||
double x = PyFloat_AsDouble(v);
|
||||
if (x == -1 && PyErr_Occurred()) {
|
||||
PyErr_SetString(state->StructError,
|
||||
"required argument is not a float");
|
||||
return -1;
|
||||
}
|
||||
memcpy(p, &x, sizeof x);
|
||||
return 0;
|
||||
return PyFloat_Pack4(x, p, PY_LITTLE_ENDIAN);
|
||||
}
|
||||
|
||||
static int
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue