Skip to content

Commit c4c729d

Browse files
committed
gh-130317: Fix test_pack_unpack_roundtrip_for_nans() on x86
* Only test 64-bit double on x86. * Fix _testcapi.float_pack(): use memcpy() to preserve the sNaN bit.
1 parent 02cd6d7 commit c4c729d

File tree

3 files changed

+25
-20
lines changed

3 files changed

+25
-20
lines changed

Lib/test/test_capi/test_float.py

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -183,8 +183,14 @@ def test_pack_unpack_roundtrip(self):
183183
def test_pack_unpack_roundtrip_for_nans(self):
184184
pack = _testcapi.float_pack
185185
unpack = _testcapi.float_unpack
186+
arch_32bit = (sys.maxsize == 2147483647)
187+
if (not arch_32bit) or (sys.platform == 'win32'):
188+
sizes = (2, 4, 8)
189+
else:
190+
sizes = (8,)
191+
186192
for _ in range(1000):
187-
for size in (2, 4, 8):
193+
for size in sizes:
188194
sign = random.randint(0, 1)
189195
signaling = random.randint(0, 1)
190196
quiet = int(not signaling)
@@ -202,7 +208,7 @@ def test_pack_unpack_roundtrip_for_nans(self):
202208
with self.subTest(data=data, size=size, endian=endian):
203209
data1 = data if endian == BIG_ENDIAN else data[::-1]
204210
value = unpack(data1, endian)
205-
if signaling and sys.platform == 'win32':
211+
if signaling and arch_32bit:
206212
# On this platform sNaN becomes qNaN when returned
207213
# from function. That's a known bug, e.g.
208214
# https://developercommunity.visualstudio.com/t/155064

Modules/_testcapi/clinic/float.c.h

Lines changed: 6 additions & 15 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Modules/_testcapi/float.c

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -15,17 +15,25 @@ module _testcapi
1515
_testcapi.float_pack
1616
1717
size: int
18-
d: double
18+
obj: object
1919
le: int
2020
/
2121
2222
Test PyFloat_Pack2(), PyFloat_Pack4() and PyFloat_Pack8()
2323
[clinic start generated code]*/
2424

2525
static PyObject *
26-
_testcapi_float_pack_impl(PyObject *module, int size, double d, int le)
27-
/*[clinic end generated code: output=7899bd98f8b6cb04 input=52c9115121999c98]*/
26+
_testcapi_float_pack_impl(PyObject *module, int size, PyObject *obj, int le)
27+
/*[clinic end generated code: output=7eb936d25b14e105 input=78f017f3ca316740]*/
2828
{
29+
if (!PyFloat_Check(obj)) {
30+
PyErr_SetString(PyExc_ValueError, "float-point number expected");
31+
return NULL;
32+
}
33+
double d;
34+
// gh-130317: memcpy() is needed to preserve the sNaN flag on x86 (32-bit).
35+
memcpy(&d, &((PyFloatObject *)obj)->ob_fval, 8);
36+
2937
switch (size)
3038
{
3139
case 2:

0 commit comments

Comments
 (0)