test_half_float in test_struct fails on mips
Bug report
Bug description:
test test_struct failed -- Traceback (most recent call last):
File "/usr/lib/python3.14/test/test_struct.py", line 946, in test_half_float
self.assertEqual(packed[1] & 0x7e, expected)
~~~~~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^^^^^^
AssertionError: 124 != 126
The test always asserts the 0x7e-masked higher byte of math.nan against 0x7e for MIPS. Unfortunately, math.nan depends on toolchain settings here, as setting -mnan=legacy and -mnan=2008 result in different __builtin_nan behavior for GCC, so the PA-RISC solution of picking 0x7c is inappropriate for MIPS. I think we can skip the NaN encoding assertions when platform.machine().startswith('mips') is true.
CPython versions tested on:
3.14
Operating systems tested on:
Linux
Linked PRs
- gh-143432
Alternative is to pick up right compiler options on MIPS in configure. I would rather prefer this.
@picnixz ?
Some possibilities:
- Do nothing on the C side but amend the tests by selecting up the correct mask depending on the configure options.
- Export some macro from "configure" to "Python" to know which encoding was picked up, e.g.,
sys.whatever_namespace.nan_encoding(or any other private value). Did we settle on the__STDC_IEC_559__support macro? if not, we can, in the meantime rely on the sysconfig only (hopefully it will be enough). Otherwise, we can just export it to thetestcapito avoid polluting the runtime for now.
Do nothing on the C side but amend the tests by selecting up the correct mask depending on the configure options.
Why this is better than selecting of correct compiler option?
Did we settle on the
__STDC_IEC_559__support macro?
No, https://github.com/python/cpython/issues/138580 is still open. I don't know how to make progress here.
Otherwise, we can just export it to the testcapi to avoid polluting the runtime for now.
I doubt this solves issue right here. @chenx97 could you verify that this macro defined in one case and not in another?
Specification for NaN encoding (the first bit of the significand field is 0 for signaling and 1 for quiet) is newer then the C11 standard. And this is still not a requirement in the IEEE 754-2019.
Compile-time NaN encoding can be detected using the __mips_nan2008 macro.
@chenx97, could you try this patch?
diff --git a/configure.ac b/configure.ac
index 9e63c8f6144..ad143fc80f6 100644
--- a/configure.ac
+++ b/configure.ac
@@ -988,6 +988,12 @@ AS_CASE([$host],
],
)
+AS_CASE([$host],
+ [mips*-*-*], [
+ AS_VAR_APPEND([CFLAGS], [" -mnan=2008"])
+ ],
+)
+
dnl Add the compiler flag for the iOS minimum supported OS version.
AS_CASE([$ac_sys_system],
[iOS], [
FYI, you need to regenerate configure (make regen-configure).
If it works, I think we can live with a such solution (of course, flag should be added only conditionally, if compiler support).
@chenx97, could you try this patch?
diff --git a/configure.ac b/configure.ac index 9e63c8f6144..ad143fc80f6 100644 --- a/configure.ac +++ b/configure.ac @@ -988,6 +988,12 @@ AS_CASE([$host], ], )
+AS_CASE([$host],
- [mips*--], [
- AS_VAR_APPEND([CFLAGS], [" -mnan=2008"])
- ], +)
dnl Add the compiler flag for the iOS minimum supported OS version. AS_CASE([$ac_sys_system], [iOS], [
FYI, you need to regenerate configure (
make regen-configure).If it works, I think we can live with a such solution (of course, flag should be added only conditionally, if compiler support).
configure: error: C compiler cannot create executables
This is because both values of -mnan cannot be used together:
/usr/bin/ld: main.o: linking -mnan=2008 module with previous -mnan=legacy modules
This patch breaks all legacy NaN systems.
I wonder if we can add a nan_encoding value to sys.float_info, with possible values being "regular" and "parisc".
FYI https://github.com/google/double-conversion/blob/50063989fc1bde19cb69302d8005e6fb4f99f64c/double-conversion/ieee.h#L152
/usr/bin/ld: main.o: linking -mnan=2008 module with previous -mnan=legacy modules
Ah, of course. Shared modules will come with -mnan=legacy forever...
I wonder if we can add a nan_encoding value to sys.float_info, with possible values being "regular" and "parisc".
On pure-Python level there is no difference: signaling NaN is same as quiet NaN, no stdlib function will react on this bit.
I think it's better to add some flag in _testcapi to use just in tests.
Thanks for the fix.