This issue tracker has been migrated to GitHub, and is currently read-only.
For more information, see the GitHub FAQs in the Python's Developer Guide.

classification
Title: test_long.test_nan_inf() failed on OpenBSD (powerpc)
Type: behavior Stage:
Components: Tests Versions: Python 3.4, Python 3.5
process
Status: open Resolution:
Dependencies: Superseder:
Assigned To: Nosy List: landry, mark.dickinson, rpointel, vstinner
Priority: normal Keywords:

Created on 2011-07-19 21:40 by rpointel, last changed 2022-04-11 14:57 by admin.

Files
File name Uploaded Description Edit
pyconfig.h landry, 2011-08-07 09:08 openbsd/macppc pyconfig for python 3.2.1
math.h landry, 2011-08-07 09:08 openbsd/macppc math.h
pyconfig.h.wrong landry, 2011-08-07 10:16 broken pyconfig.h
build-macppc.log landry, 2011-08-07 10:17 python 3.2.1 failing build log
Messages (21)
msg140697 - (view) Author: Remi Pointel (rpointel) * Date: 2011-07-19 21:40
Hello,
the test test_nan_inf failed on OpenBSD on powerpc architecture.
It works fine on amd64 and sparc64.

Don't hesitate if you need more informations.
Details:

Re-running test 'test_long' in verbose mode
test__format__ (test.test_long.LongTest) ... ok
test_bit_length (test.test_long.LongTest) ... ok
test_bitop_identities (test.test_long.LongTest) ... ok
test_conversion (test.test_long.LongTest) ... ok
test_correctly_rounded_true_division (test.test_long.LongTest) ... ok
test_division (test.test_long.LongTest) ... ok
test_float_conversion (test.test_long.LongTest) ... ok
test_float_overflow (test.test_long.LongTest) ... ok
test_format (test.test_long.LongTest) ... ok
test_from_bytes (test.test_long.LongTest) ... ok
test_karatsuba (test.test_long.LongTest) ... ok
test_logs (test.test_long.LongTest) ... ok
test_long (test.test_long.LongTest) ... ok
test_mixed_compares (test.test_long.LongTest) ... ok
test_nan_inf (test.test_long.LongTest) ... FAIL
test_round (test.test_long.LongTest) ... ok
test_small_ints (test.test_long.LongTest) ... ok
test_to_bytes (test.test_long.LongTest) ... ok
test_true_division (test.test_long.LongTest) ... /usr/obj/ports/Python-3.2.1/Python-3.Lib/test/regrtest.py:1053: ResourceWarning: unclosed <socket.socket object, fd=11, family=2, type=1, proto=0>
  gc.collect()
/usr/obj/ports/Python-3.2.1/Python-3.Lib/test/regrtest.py:1053: ResourceWarning: unclosed <socket.socket object, fd=12, family=2, type=1, proto=0>
  gc.collect()
/usr/obj/ports/Python-3.2.1/Python-3.Lib/test/regrtest.py:1053: ResourceWarning: unclosed <socket.socket object, fd=13, family=2, type=1, proto=0>
  gc.collect()
test test_long failed
ok

======================================================================
FAIL: test_nan_inf (test.test_long.LongTest)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "/usr/obj/ports/Python-3.2.1/Python-3.Lib/test/test_long.py", line 633, in test_nan_inf
    self.assertRaises(OverflowError, int, float('inf'))
AssertionError: OverflowError not raised by int

----------------------------------------------------------------------
Ran 19 tests in 25.020s

FAILED (failures=1)
msg140698 - (view) Author: STINNER Victor (vstinner) * (Python committer) Date: 2011-07-19 21:50
What is the result of int(float('inf')) ?
msg140758 - (view) Author: Landry Breuil (landry) Date: 2011-07-20 17:58
$python3.2                                            
Python 3.2.1 (default, Jul 18 2011, 10:56:33) 
[GCC 4.2.1 20070719 ] on openbsd4
>>> int(float('inf'))
0
$sysctl hw                                            
hw.machine=macppc
msg140803 - (view) Author: STINNER Victor (vstinner) * (Python committer) Date: 2011-07-21 10:05
Is HAVE_DECL_ISINF defined in pyconfig.h? PyLong_FromDouble() uses Py_IS_INFINITY(x):
--------------------------------------
/* Py_IS_INFINITY(X)
 * Return 1 if float or double arg is an infinity, else 0.
 * Caution:
 *    X is evaluated more than once.
 *    This implementation may set the underflow flag if |X| is very small;
 *    it really can't be implemented correctly (& easily) before C99.
 *    Override in pyconfig.h if you have a better spelling on your platform.
 *  Py_FORCE_DOUBLE is used to avoid getting false negatives from a
 *    non-infinite value v sitting in an 80-bit x87 register such that
 *    v becomes infinite when spilled from the register to 64-bit memory.
 * Note: PC/pyconfig.h defines Py_IS_INFINITY as _isinf
 */
#ifndef Py_IS_INFINITY
#  if defined HAVE_DECL_ISINF && HAVE_DECL_ISINF == 1
#    define Py_IS_INFINITY(X) isinf(X)
#  else
#    define Py_IS_INFINITY(X) ((X) &&                                   \
                               (Py_FORCE_DOUBLE(X)*0.5 == Py_FORCE_DOUBLE(X)))
#  endif
#endif
--------------------------------------

main() in Modules/python.c starts with:
--------------------------------------
    /* 754 requires that FP exceptions run in "no stop" mode by default,
     * and until C vendors implement C99's ways to control FP exceptions,
     * Python requires non-stop mode.  Alas, some platforms enable FP
     * exceptions by default.  Here we disable them.
     */
#ifdef __FreeBSD__
    fp_except_t m;

    m = fpgetmask();
    fpsetmask(m & ~FP_X_OFL);
#endif
--------------------------------------

You may try to enable this code on OpenBSD, replace "#ifdef __FreeBSD__" by "#if 1".

Can you also please try the following code?

$ python
>>> import struct
>>> struct.pack("f", float("inf"))
b'\x00\x00\x80\x7f'
msg140817 - (view) Author: Mark Dickinson (mark.dickinson) * (Python committer) Date: 2011-07-21 12:57
The result of:

struct.pack("d", float("inf"))

would also be interesting.  I'd expect to see:

'\x7f\xf0\x00\x00\x00\x00\x00\x00'
msg140825 - (view) Author: Landry Breuil (landry) Date: 2011-07-21 19:22
>>> import struct
>>> struct.pack("d", float("inf"))
b'\x7f\xf0\x00\x00\x00\x00\x00\x00'
>>> struct.pack("f", float("inf"))
b'\x7f\x80\x00\x00'

And yes, HAVE_DECL_ISINF is defined to 1 in pyconfig.h
msg140836 - (view) Author: STINNER Victor (vstinner) * (Python committer) Date: 2011-07-21 23:29
You may try:

$ ./python
>>> import ctypes
>>> import ctypes.util
>>> libc = ctypes.cdll.LoadLibrary(ctypes.util.find_library('c'))
>>> isinf = libc.isinf
>>> isinf.argtypes = (ctypes.c_double,)
>>> isinf(0.0)
0
>>> isinf(float('inf'))
1

(try ctypes.util.find_library('m') if isinf is not in libc)
msg140863 - (view) Author: Landry Breuil (landry) Date: 2011-07-22 05:23
Python 3.2.1 (default, Jul 18 2011, 10:56:33) 
[GCC 4.2.1 20070719 ] on openbsd4
Type "help", "copyright", "credits" or "license" for more information.
>>> import ctypes
>>> import ctypes.util
>>> libc = ctypes.cdll.LoadLibrary(ctypes.util.find_library('c'))
>>> isinf = libc.isinf
>>> isinf.argtypes = (ctypes.c_double,)
>>> isinf(0.0)
0
>>> isinf(float('inf'))
1
msg140865 - (view) Author: STINNER Victor (vstinner) * (Python committer) Date: 2011-07-22 10:08
The problem is in PyLong_FromDouble(): if (Py_IS_INFINITY(dval)) is evaluated as false, whereas dval *is* infinity. Possible causes:

 - Py_IS_INFINITY is not defined as "# define Py_IS_INFINITY(X) isinf(X)" (issue with the pyconfig.h file?)
 - the compiler replaces isinf(X) by something else (!?)
 - isinf() is not called with the right argument (conversion between 32, 64 and/or 80 floats?)
 - issue with the FPU mode (unlikely because in your ctypes test, isinf(float("inf")) returns 1, and this test runs in the Python process)

Try to run python in gdb. Set a breakpoint on isinf() (or on PyLong_FromDouble() and use step by step) to check that the function is really called, and called with the "right" argument.

You may also try to replace Py_IS_INFINITY(dval) directly by isinf(dval) (or simply if(1) :-)) in PyLong_FromDouble().
msg140884 - (view) Author: Landry Breuil (landry) Date: 2011-07-22 15:01
$grep -r '#define Py_IS_INF' .
PC/pyconfig.h:#define Py_IS_INFINITY(X) (!_finite(X) && !_isnan(X))


>>> isinf(float('inf'))

Breakpoint 2, __isinf (d=1.0604798301039825e-314) at /usr/src/lib/libc/gen/isinf.c:30
30      in /usr/src/lib/libc/gen/isinf.c
(gdb) bt
#0  __isinf (d=1.0604798301039825e-314) at /usr/src/lib/libc/gen/isinf.c:30
#1  0x8fe528d8 in ffi_call_SYSV () from /usr/local/lib/libffi.so.0.0
msg140886 - (view) Author: Mark Dickinson (mark.dickinson) * (Python committer) Date: 2011-07-22 15:14
The '1.06...e-314' number in the gdb output is interesting:  it indicates a byte-ordering issue, though maybe that issue is only pertinent to gdb itself.

On a little-endian machine:

>>> struct.pack('<d', 1.0604798301039825e-314)
'\x00\x00\xf0\x7f\x00\x00\x00\x00'
>>> struct.pack('<d', float('inf'))
'\x00\x00\x00\x00\x00\x00\xf0\x7f'

Same bytes, different order.  This may indicate some kind of float / double mismatch somewhere, or a byte-ordering issue.
msg140887 - (view) Author: Mark Dickinson (mark.dickinson) * (Python committer) Date: 2011-07-22 15:21
Question: does this test also fail after configuring with the --with-pydebug flag?  (Which I *think* should turn compiler optimizations off, amongst other things.)
msg140889 - (view) Author: STINNER Victor (vstinner) * (Python committer) Date: 2011-07-22 15:28
> $grep -r '#define Py_IS_INF' .
> PC/pyconfig.h:#define Py_IS_INFINITY(X) (!_finite(X) && !_isnan(X))

The PC/ directory is specific to Windows. Py_IS_INFINITY should be defined in Include/pymath.h (at least, in the 3.2 branch)

> Breakpoint 2, __isinf (d=1.0604798301039825e-314)
> ...
> #1  0x8fe528d8 in ffi_call_SYSV () from /usr/local/lib/libffi.so.0.0

Ah, you ran gdb on ctypes. I forgot to specify that you should run gdb on "int(float('inf'))" instruction in Python, sorry. I would like to check int(float), not ctypes ;-)

If gdb has an endian issue, you may also try "print /x d" in the gdb shell.

Example on x86_64:
---------------------------------------------
$ gdb ./python 
GNU gdb (GDB) 7.1-ubuntu
...
(gdb) run
<press ^C>
(gdb) b isinf
Breakpoint 1 at 0xb7f94f16: file ../sysdeps/ieee754/dbl-64/s_isinf.c, line 23. (2 locations)
(gdb) cont
>>> int(float('inf'))

Breakpoint 1, *__GI___isinf (x=inf) at ../sysdeps/ieee754/dbl-64/s_isinf.c:23
23	../sysdeps/ieee754/dbl-64/s_isinf.c: Aucun fichier ou dossier de ce type.
	in ../sysdeps/ieee754/dbl-64/s_isinf.c
(gdb) print /x x
$1 = 0x8000000000000000

(gdb) where
#0  *__GI___isinf (x=inf) at ../sysdeps/ieee754/dbl-64/s_isinf.c:23
#1  0x0819b03e in PyLong_FromDouble (dval=inf) at Objects/longobject.c:280
#2  0x0818d660 in float_trunc (v=<float at remote 0x826fb44>) at Objects/floatobject.c:896
#3  0x081619c6 in PyNumber_Long (o=<float at remote 0x826fb44>) at Objects/abstract.c:1348
#4  0x081a4823 in long_new (type=0x824b420, args=(<float at remote 0x826fb44>,), kwds=0x0) at Objects/longobject.c:4130
...
(gdb) frame 1
#1  0x0819b03e in PyLong_FromDouble (dval=inf) at Objects/longobject.c:280
280	    if (Py_IS_INFINITY(dval)) {
(gdb) print /x dval
$2 = 0x8000000000000000
---------------------------------------------
msg140890 - (view) Author: STINNER Victor (vstinner) * (Python committer) Date: 2011-07-22 15:30
> If gdb has an endian issue,
> you may also try "print /x d" in the gdb shell.

Oh, forget me: /x converts the argument to an integer...
msg140891 - (view) Author: Landry Breuil (landry) Date: 2011-07-22 15:47
Py_IS_INFINITY is defined as

#ifndef Py_IS_INFINITY
#  if defined HAVE_DECL_ISINF && HAVE_DECL_ISINF == 1
#    define Py_IS_INFINITY(X) isinf(X)
#  else
#    define Py_IS_INFINITY(X) ((X) &&                                   \
                               (Py_FORCE_DOUBLE(X)*0.5 == Py_FORCE_DOUBLE(X)))
#  endif
#endif


The test still fails when built --with-pydebug.

(gdb)  b isinf 
Function "isinf" not defined.
Make breakpoint pending on future shared library load? (y or [n]) y
Breakpoint 1 (isinf) pending.
(gdb) r
Starting program: /usr/obj/ports/Python-3.2.1/Python-3.2.1/python 
Breakpoint 2 at 0x852786d4: file /usr/src/lib/libc/gen/isinf.c, line 27.
Pending breakpoint "isinf" resolved
Python 3.2.1 (default, Jul 22 2011, 17:34:54) 
[GCC 4.2.1 20070719 ] on openbsd4
Type "help", "copyright", "credits" or "license" for more information.
>>> int(float('inf'))
0
[56408 refs]

isinf is #defined in math.h to

#define isinf(x) \
        ((sizeof (x) == sizeof (float)) ? \
                __isinff(x) \
        : (sizeof (x) == sizeof (double)) ? \
                __isinf(x) \
        :       __isinfl(x))

but setting a bkp on it changes nothing.

Starting program: /usr/obj/ports/Python-3.2.1/Python-3.2.1/python 
Breakpoint 2 at 0x89b4f708: file /usr/src/lib/libc/gen/isinf.c, line 36.
Pending breakpoint "__isinff" resolved
Python 3.2.1 (default, Jul 22 2011, 17:34:54) 
[GCC 4.2.1 20070719 ] on openbsd4
Type "help", "copyright", "credits" or "license" for more information.
>>> int(float('inf'))
0

Setting a bkp on PyLong_FromDouble() shows that it's not called.

Sorry, this doesnt make sense to me...
msg140894 - (view) Author: STINNER Victor (vstinner) * (Python committer) Date: 2011-07-22 16:04
I'm not sure that your version of gdb understands macros. You may have to set a breakpoint on __isinf. Compile Python with "-g -ggdb" helps gdb.

Py_IS_INFINITY is may not defined as "# define Py_IS_INFINITY(X) isinf(X)". To check that, add #error macro in pymath.h for all cases around #ifndef Py_IS_INFINITY. For example:

#ifndef Py_IS_INFINITY
#  if defined HAVE_DECL_ISINF && HAVE_DECL_ISINF == 1
#    error "Py_IS_INFINITY is implemented using isinf()"
#    define Py_IS_INFINITY(X) isinf(X)
#  else
#    error "Py_IS_INFINITY is implemented using *0.5"
#    define Py_IS_INFINITY(X) ((X) &&                                   \
                               (Py_FORCE_DOUBLE(X)*0.5 == Py_FORCE_DOUBLE(X)))
#  endif
#else
#  error "Py_IS_INFINITY already set!?"
#endif

And recompile Python. It may be a typo in pyconfig.h (generated by configure) or an issue with the inclusion paths of gcc (-I options).

Can you please attach your pyconfig.h and /usr/include/math.h files?

Can you also copy-paste the line used to compile Object/floatobject.c (to check the compiler options)? Use touch Object/floatobject.c && make to recompile this file.

FYI, isinf() is also a macro on Linux:

# ifdef __NO_LONG_DOUBLE_MATH
#  define isinf(x) \
     (sizeof (x) == sizeof (float) ? __isinff (x) : __isinf (x))
# else
#  define isinf(x) \
     (sizeof (x) == sizeof (float)					      \
      ? __isinff (x)							      \
      : sizeof (x) == sizeof (double)					      \
      ? __isinf (x) : __isinfl (x))
# endif
msg141741 - (view) Author: Landry Breuil (landry) Date: 2011-08-07 09:07
floatobject.c is compiled with 

cc -pthread -c -fno-strict-aliasing -O2 -pipe  -Wall -DTHREAD_STACK_SIZE=0x20000 -fPIC -O2 -pipe -Wall -I. -IInclude -I./Include   -fPIC -DPy_BUILD_CORE -o Objects/floatobject.o Objects/floatobject.c
msg141742 - (view) Author: Landry Breuil (landry) Date: 2011-08-07 10:16
Interestingly, after an update of the system i can't build python 3.2.1 anymore :

/usr/include/util.h:102: error: conflicting types for 'openpty'
Include/pyport.h:634: error: previous declaration of 'openpty' was here
/usr/include/util.h:105: error: conflicting types for 'forkpty'
Include/pyport.h:635: error: previous declaration of 'forkpty' was here

./Modules/posixmodule.c: In function 'posix_lstat':
./Modules/posixmodule.c:5155: error: 'lstat' undeclared (first use in this function)
./Modules/posixmodule.c:5155: error: (Each undeclared identifier is reported only once
./Modules/posixmodule.c:5155: error: for each function it appears in.)


Relevant lines of configure output (so those seem to come from systemwide config.site) :
checking for lstat... (cached) yes
checking for openpty... (cached) no
checking for openpty in -lutil... (cached) yes
checking for forkpty... yes

I'm attaching the generated pyconfig.h and the build log, but now that seems to be a different issue.. as pyconfig.h clearly contains wrong defs.

Don't count on me too much for that issue, i have honestly no interest in python and lost enough time on that... i trust remi to pick up on it :)
msg142743 - (view) Author: Remi Pointel (rpointel) * Date: 2011-08-22 19:43
Hi,
what information do you need to advance on this bug?
Cheers,
Remi.
msg143186 - (view) Author: STINNER Victor (vstinner) * (Python committer) Date: 2011-08-29 22:03
> what information do you need to advance on this bug?

It would be easier to debug if I had access to OpenBSD on a PowerPC host.
msg221768 - (view) Author: Mark Lawrence (BreamoreBoy) * Date: 2014-06-28 02:13
Can this be reproduced on 3.4/5?
History
Date User Action Args
2022-04-11 14:57:19adminsetgithub: 56798
2019-03-16 00:00:24BreamoreBoysetnosy: - BreamoreBoy
2014-06-28 02:13:08BreamoreBoysetversions: + Python 3.4, Python 3.5, - Python 3.2
nosy: + BreamoreBoy

messages: + msg221768

type: behavior
2011-08-29 22:03:14vstinnersetmessages: + msg143186
2011-08-22 19:43:44rpointelsetmessages: + msg142743
2011-08-07 10:17:24landrysetfiles: + build-macppc.log
2011-08-07 10:16:53landrysetfiles: + pyconfig.h.wrong

messages: + msg141742
2011-08-07 09:08:59landrysetfiles: + math.h
2011-08-07 09:08:39landrysetfiles: + pyconfig.h
2011-08-07 09:07:30landrysetmessages: + msg141741
2011-07-22 16:04:25vstinnersetmessages: + msg140894
2011-07-22 15:47:49landrysetmessages: + msg140891
2011-07-22 15:30:16vstinnersetmessages: + msg140890
2011-07-22 15:28:02vstinnersetmessages: + msg140889
2011-07-22 15:21:36mark.dickinsonsetmessages: + msg140887
2011-07-22 15:14:49mark.dickinsonsetmessages: + msg140886
2011-07-22 15:01:57landrysetmessages: + msg140884
2011-07-22 10:08:11vstinnersetmessages: + msg140865
2011-07-22 05:23:07landrysetmessages: + msg140863
2011-07-21 23:29:11vstinnersetmessages: + msg140836
2011-07-21 19:22:00landrysetmessages: + msg140825
2011-07-21 12:57:29mark.dickinsonsetmessages: + msg140817
2011-07-21 10:05:52vstinnersetmessages: + msg140803
2011-07-21 09:45:12vstinnersetnosy: + mark.dickinson
2011-07-20 17:58:29landrysetnosy: + landry
messages: + msg140758
2011-07-19 21:50:30vstinnersetnosy: + vstinner
messages: + msg140698
2011-07-19 21:40:34rpointelcreate