diff options
Diffstat (limited to 'numpy')
-rw-r--r-- | numpy/core/src/multiarray/scalartypes.c.src | 37 | ||||
-rw-r--r-- | numpy/core/tests/test_scalarprint.py | 17 |
2 files changed, 54 insertions, 0 deletions
diff --git a/numpy/core/src/multiarray/scalartypes.c.src b/numpy/core/src/multiarray/scalartypes.c.src index ee83206de..3e17ec040 100644 --- a/numpy/core/src/multiarray/scalartypes.c.src +++ b/numpy/core/src/multiarray/scalartypes.c.src @@ -4169,6 +4169,37 @@ initialize_casting_tables(void) } } +#ifndef NPY_PY3K +/* + * In python2, the `float` and `complex` types still implement the obsolete + * "tp_print" method, which uses CPython's float-printing routines to print the + * float. Numpy's float_/cfloat inherit from Python float/complex, but + * override its tp_repr and tp_str methods. In order to avoid an inconsistency + * with the inherited tp_print, we need to override it too. + * + * In python3 the tp_print method is reserved/unused. + */ +static int +doubletype_print(PyObject *o, FILE *fp, int flags) +{ + int ret; + PyObject *to_print; + if (flags & Py_PRINT_RAW) { + to_print = PyObject_Str(o); + } + else { + to_print = PyObject_Repr(o); + } + + if (to_print == NULL) { + return -1; + } + + ret = PyObject_Print(to_print, fp, flags); + Py_DECREF(to_print); + return ret; +} +#endif static PyNumberMethods longdoubletype_as_number; static PyNumberMethods clongdoubletype_as_number; @@ -4221,6 +4252,12 @@ initialize_numeric_types(void) /**end repeat**/ +#ifndef NPY_PY3K + PyDoubleArrType_Type.tp_print = &doubletype_print; + PyCDoubleArrType_Type.tp_print = &doubletype_print; +#endif + + PyBoolArrType_Type.tp_as_number->nb_index = (unaryfunc)bool_index; PyStringArrType_Type.tp_alloc = NULL; diff --git a/numpy/core/tests/test_scalarprint.py b/numpy/core/tests/test_scalarprint.py index d57f1a890..47cd2a40a 100644 --- a/numpy/core/tests/test_scalarprint.py +++ b/numpy/core/tests/test_scalarprint.py @@ -6,6 +6,7 @@ from __future__ import division, absolute_import, print_function import numpy as np from numpy.testing import assert_, assert_equal, run_module_suite +import sys, tempfile class TestRealScalars(object): @@ -45,6 +46,22 @@ class TestRealScalars(object): check(1e15) check(1e16) + def test_py2_float_print(self): + # gh-10753 + # In python2, the python float type implements an obsolte method + # tp_print, which overrides tp_repr and tp_str when using "print" to + # output to a "real file" (ie, not a StringIO). Make sure we don't + # inherit it. + x = np.double(0.1999999999999) + with tempfile.TemporaryFile('r+t') as f: + print(x, file=f) + f.seek(0) + output = f.read() + assert_equal(output, str(x) + '\n') + # In python2 the value float('0.1999999999999') prints with reduced + # precision as '0.2', but we want numpy's np.double('0.1999999999999') + # to print the unique value, '0.1999999999999'. + def test_dragon4(self): # these tests are adapted from Ryan Juckett's dragon4 implementation, # see dragon4.c for details. |