Skip to content

Commit ad09d00

Browse files
[3.15] gh-154568: Fix array unpickling of little-endian float16 (GH-154569) (#155557)
Co-authored-by: PhysicistJohn <54456354+PhysicistJohn@users.noreply.github.com>
1 parent d390759 commit ad09d00

3 files changed

Lines changed: 16 additions & 1 deletion

File tree

Lib/test/test_array.py

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -224,6 +224,10 @@ def test_numbers(self):
224224
[-1<<63, (1<<63)-1, 0]),
225225
(['l'], SIGNED_INT64_BE, '>qqq',
226226
[-1<<63, (1<<63)-1, 0]),
227+
(['e'], IEEE_754_FLOAT16_LE, '<eeee',
228+
[1.0, float('inf'), float('-inf'), -0.0]),
229+
(['e'], IEEE_754_FLOAT16_BE, '>eeee',
230+
[1.0, float('inf'), float('-inf'), -0.0]),
227231
(['f'], IEEE_754_FLOAT_LE, '<ffff',
228232
[16711938.0, float('inf'), float('-inf'), -0.0]),
229233
(['f'], IEEE_754_FLOAT_BE, '>ffff',
@@ -254,6 +258,16 @@ def test_numbers(self):
254258
self.assertEqual(a, b,
255259
msg="{0!r} != {1!r}; testcase={2!r}".format(a, b, testcase))
256260

261+
def test_float16_endianness(self):
262+
# gh-154568: array_reconstructor() slow-path decoder for
263+
# IEEE_754_FLOAT16_LE ignored the encoding.
264+
le_bytes = struct.pack('<e', 1.5)
265+
be_bytes = struct.pack('>e', 1.5)
266+
b_le = array_reconstructor(array.array, 'd', IEEE_754_FLOAT16_LE, le_bytes)
267+
b_be = array_reconstructor(array.array, 'd', IEEE_754_FLOAT16_BE, be_bytes)
268+
self.assertEqual(b_le.tolist(), [1.5])
269+
self.assertEqual(b_be.tolist(), [1.5])
270+
257271
def test_unicode(self):
258272
teststr = "Bonne Journ\xe9e \U0002030a\U00020347"
259273
testcases = (
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Fix :mod:`array` unpickling of little-endian float16.

Modules/arraymodule.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2356,7 +2356,7 @@ array__array_reconstructor_impl(PyObject *module, PyTypeObject *arraytype,
23562356
case IEEE_754_FLOAT16_LE:
23572357
case IEEE_754_FLOAT16_BE: {
23582358
Py_ssize_t i;
2359-
int le = (mformat_code == IEEE_754_FLOAT_LE) ? 1 : 0;
2359+
int le = (mformat_code == IEEE_754_FLOAT16_LE) ? 1 : 0;
23602360
Py_ssize_t itemcount = Py_SIZE(items) / 2;
23612361
const char *memstr = PyBytes_AS_STRING(items);
23622362

0 commit comments

Comments
 (0)