[Numpy-svn] r6360 - in trunk: . numpy/core numpy/core/src numpy/core/tests

numpy-svn@scip... numpy-svn@scip...
Sat Feb 14 08:54:41 CST 2009


Author: cdavid
Date: 2009-02-14 08:54:26 -0600 (Sat, 14 Feb 2009)
New Revision: 6360

Added:
   trunk/numpy/core/src/numpyos.c
Modified:
   trunk/
   trunk/numpy/core/SConscript
   trunk/numpy/core/setup.py
   trunk/numpy/core/src/arraytypes.inc.src
   trunk/numpy/core/src/multiarraymodule.c
   trunk/numpy/core/src/scalartypes.inc.src
   trunk/numpy/core/tests/test_multiarray.py
   trunk/numpy/core/tests/test_print.py
Log:
Merge fix_float_format branch into the trunk.


Property changes on: trunk
___________________________________________________________________
Name: svnmerge-integrated
   - /branches/distutils-revamp:1-2752 /branches/dynamic_cpu_configuration:1-6101 /branches/fix_float_format:1-6222,6233-6234,6247-6249 /branches/multicore:1-3687 /branches/numpy-mingw-w64:1-6150 /branches/visualstudio_manifest:1-6077 /trunk:1-2871
   + /branches/distutils-revamp:1-2752 /branches/dynamic_cpu_configuration:1-6101 /branches/fix_float_format:1-6359 /branches/multicore:1-3687 /branches/numpy-mingw-w64:1-6150 /branches/visualstudio_manifest:1-6077 /trunk:1-2871

Modified: trunk/numpy/core/SConscript
===================================================================
--- trunk/numpy/core/SConscript	2009-02-12 05:44:07 UTC (rev 6359)
+++ trunk/numpy/core/SConscript	2009-02-14 14:54:26 UTC (rev 6360)
@@ -211,6 +211,10 @@
         config.Define('DISTUTILS_USE_SDK', distutils_use_sdk,
                       "define to 1 to disable SMP support ")
 
+    if a == "Intel":
+        config.Define('FORCE_NO_LONG_DOUBLE_FORMATTING', 1,
+                      "define to 1 to force long double format string to the" \
+                      " same as double (Lg -> g)")
 #--------------
 # Checking Blas
 #--------------

Modified: trunk/numpy/core/setup.py
===================================================================
--- trunk/numpy/core/setup.py	2009-02-12 05:44:07 UTC (rev 6359)
+++ trunk/numpy/core/setup.py	2009-02-14 14:54:26 UTC (rev 6360)
@@ -187,6 +187,14 @@
                                          headers=['stdlib.h']):
                     moredefs.append(('PyOS_ascii_strtod', 'strtod'))
 
+            if sys.platform == "win32":
+                from numpy.distutils.misc_util import get_build_architecture
+                # On win32, force long double format string to be 'g', not
+                # 'Lg', since the MS runtime does not support long double whose
+                # size is > sizeof(double)
+                if get_build_architecture()=="Intel":
+                    moredefs.append('FORCE_NO_LONG_DOUBLE_FORMATTING')
+
             target_f = open(target,'a')
             for d in moredefs:
                 if isinstance(d,str):
@@ -330,6 +338,7 @@
     deps = [join('src','arrayobject.c'),
             join('src','arraymethods.c'),
             join('src','scalartypes.inc.src'),
+            join('src','numpyos.c'),
             join('src','arraytypes.inc.src'),
             join('src','_signbit.c'),
             join('src','ucsnarrow.c'),

Modified: trunk/numpy/core/src/arraytypes.inc.src
===================================================================
--- trunk/numpy/core/src/arraytypes.inc.src	2009-02-12 05:44:07 UTC (rev 6359)
+++ trunk/numpy/core/src/arraytypes.inc.src	2009-02-14 14:54:26 UTC (rev 6360)
@@ -2,41 +2,17 @@
 #include "config.h"
 
 static double
-_getNAN(void) {
-#ifdef NAN
-    return NAN;
-#else
-    static double nan=0;
-
-    if (nan == 0) {
-        double mul = 1e100;
-        double tmp = 0.0;
-        double pinf=0;
-        pinf = mul;
-        for (;;) {
-            pinf *= mul;
-            if (pinf == tmp) break;
-            tmp = pinf;
-        }
-        nan = pinf / pinf;
-    }
-    return nan;
-#endif
-}
-
-
-static double
 MyPyFloat_AsDouble(PyObject *obj)
 {
     double ret = 0;
     PyObject *num;
 
     if (obj == Py_None) {
-        return _getNAN();
+        return NumPyOS_NAN;
     }
     num = PyNumber_Float(obj);
     if (num == NULL) {
-        return _getNAN();
+        return NumPyOS_NAN;
     }
     ret = PyFloat_AsDouble(num);
     Py_DECREF(num);
@@ -192,7 +168,7 @@
             op2 = op; Py_INCREF(op);
         }
         if (op2 == Py_None) {
-            oop.real = oop.imag = _getNAN();
+            oop.real = oop.imag = NumPyOS_NAN;
         }
         else {
             oop = PyComplex_AsCComplex (op2);
@@ -897,17 +873,30 @@
  */
 
 /**begin repeat
-
-#fname=SHORT,USHORT,INT,UINT,LONG,ULONG,LONGLONG,ULONGLONG,FLOAT,DOUBLE,LONGDOUBLE#
-#type=short,ushort,int,uint,long,ulong,longlong,ulonglong,float,double,longdouble#
-#format="hd","hu","d","u","ld","lu",LONGLONG_FMT,ULONGLONG_FMT,"f","lf","Lf"#
+#fname=SHORT,USHORT,INT,UINT,LONG,ULONG,LONGLONG,ULONGLONG#
+#type=short,ushort,int,uint,long,ulong,longlong,ulonglong#
+#format="hd","hu","d","u","ld","lu",LONGLONG_FMT,ULONGLONG_FMT#
 */
 static int
 @fname@_scan (FILE *fp, @type@ *ip, void *NPY_UNUSED(ignore), PyArray_Descr *NPY_UNUSED(ignored))
 {
     return fscanf(fp, "%"@format@, ip);
 }
+/**end repeat**/
 
+/**begin repeat
+#fname=FLOAT,DOUBLE,LONGDOUBLE#
+#type=float,double,longdouble#
+*/
+static int
+@fname@_scan (FILE *fp, @type@ *ip, void *NPY_UNUSED(ignore), PyArray_Descr *NPY_UNUSED(ignored))
+{
+    double result;
+    int ret;
+    ret = NumPyOS_ascii_ftolf(fp, &result);
+    *ip = (@type@) result;
+    return ret;
+}
 /**end repeat**/
 
 /**begin repeat
@@ -966,19 +955,15 @@
 #fname=FLOAT,DOUBLE,LONGDOUBLE#
 #type=float,double,longdouble#
 */
-#if (PY_VERSION_HEX >= 0x02040000) || defined(PyOS_ascii_strtod)
 static int
 @fname@_fromstr(char *str, @type@ *ip, char **endptr, PyArray_Descr *NPY_UNUSED(ignore))
 {
     double result;
 
-    result = PyOS_ascii_strtod(str, endptr);
+    result = NumPyOS_ascii_strtod(str, endptr);
     *ip = (@type@) result;
     return 0;
 }
-#else
-#define @fname@_fromstr NULL
-#endif
 /**end repeat**/
 
 

Modified: trunk/numpy/core/src/multiarraymodule.c
===================================================================
--- trunk/numpy/core/src/multiarraymodule.c	2009-02-12 05:44:07 UTC (rev 6359)
+++ trunk/numpy/core/src/multiarraymodule.c	2009-02-14 14:54:26 UTC (rev 6360)
@@ -7705,6 +7705,9 @@
     PyObject *m, *d, *s;
     PyObject *c_api;
 
+    /* Initialize constants etc. */
+    NumPyOS_init();
+
     /* Create the module and add the functions */
     m = Py_InitModule("multiarray", array_module_methods);
     if (!m) goto err;

Copied: trunk/numpy/core/src/numpyos.c (from rev 6319, branches/fix_float_format/numpy/core/src/numpyos.c)

Modified: trunk/numpy/core/src/scalartypes.inc.src
===================================================================
--- trunk/numpy/core/src/scalartypes.inc.src	2009-02-12 05:44:07 UTC (rev 6359)
+++ trunk/numpy/core/src/scalartypes.inc.src	2009-02-14 14:54:26 UTC (rev 6360)
@@ -5,6 +5,9 @@
 #endif
 #include "numpy/arrayscalars.h"
 
+#include "config.h"
+#include "numpyos.c"
+
 static PyBoolScalarObject _PyArrayScalar_BoolValues[2] = {
     {PyObject_HEAD_INIT(&PyBoolArrType_Type) 0},
     {PyObject_HEAD_INIT(&PyBoolArrType_Type) 1},
@@ -604,23 +607,36 @@
     return ret;
 }
 
+#ifdef FORCE_NO_LONG_DOUBLE_FORMATTING
+#undef NPY_LONGDOUBLE_FMT
+#define NPY_LONGDOUBLE_FMT NPY_DOUBLE_FMT
+#endif
+
 /**begin repeat
  * #name=float, double, longdouble#
  * #NAME=FLOAT, DOUBLE, LONGDOUBLE#
+ * #type=f, d, l#
  */
 
-#define FMT "%.*" NPY_@NAME@_FMT
-#define CFMT1 "%.*" NPY_@NAME@_FMT "j"
-#define CFMT2 "(%.*" NPY_@NAME@_FMT "%+.*" NPY_@NAME@_FMT "j)"
+#define _FMT1 "%%.%i" NPY_@NAME@_FMT
+#define _FMT2 "%%+.%i" NPY_@NAME@_FMT
 
 static void
 format_@name@(char *buf, size_t buflen, @name@ val, unsigned int prec)
 {
-    int cnt, i;
+    /* XXX: Find a correct size here for format string */
+    char format[64], *res;
+    int i, cnt;
 
-    cnt = PyOS_snprintf(buf, buflen, FMT, prec, val);
+    PyOS_snprintf(format, sizeof(format), _FMT1, prec);
+    res = NumPyOS_ascii_format@type@(buf, buflen, format, val, 0);
+    if (res == NULL) {
+        fprintf(stderr, "Error while formatting\n");
+	return;
+    }
 
     /* If nothing but digits after sign, append ".0" */
+    cnt = strlen(buf);
     for (i = (val < 0) ? 1 : 0; i < cnt; ++i) {
         if (!isdigit(Py_CHARMASK(buf[i]))) {
             break;
@@ -634,17 +650,39 @@
 static void
 format_c@name@(char *buf, size_t buflen, c@name@ val, unsigned int prec)
 {
+    /* XXX: Find a correct size here for format string */
+    char format[64];
+    char *res;
     if (val.real == 0.0) {
-        PyOS_snprintf(buf, buflen, CFMT1, prec, val.imag);
+        PyOS_snprintf(format, sizeof(format), _FMT1, prec);
+        res = NumPyOS_ascii_format@type@(buf, buflen-1, format, val.imag, 0);
+	if (res == NULL) {
+            fprintf(stderr, "Error while formatting\n");
+	    return;
+	}
+	strncat(buf, "j", 1);
     }
     else {
-        PyOS_snprintf(buf, buflen, CFMT2, prec, val.real, prec, val.imag);
+	char re[64], im[64];
+	PyOS_snprintf(format, sizeof(format), _FMT1, prec);
+        res = NumPyOS_ascii_format@type@(re, sizeof(re), format, val.real, 0);
+	if (res == NULL) {
+            fprintf(stderr, "Error while formatting\n");
+	    return;
+	}
+
+	PyOS_snprintf(format, sizeof(format), _FMT2, prec);
+        res = NumPyOS_ascii_format@type@(im, sizeof(im), format, val.imag, 0);
+	if (res == NULL) {
+            fprintf(stderr, "Error while formatting\n");
+	    return;
+	}
+	PyOS_snprintf(buf, buflen, "(%s%sj)", re, im);
     }
 }
 
-#undef FMT
-#undef CFMT1
-#undef CFMT2
+#undef _FMT1
+#undef _FMT2
 
 /**end repeat**/
 
@@ -736,7 +774,47 @@
 /**end repeat1**/
 /**end repeat**/
 
+/*
+ * float type print (control print a, where a is a float type instance)
+ */
+/**begin repeat
+ * #name=float, double, longdouble#
+ * #Name=Float, Double, LongDouble#
+ * #NAME=FLOAT, DOUBLE, LONGDOUBLE#
+ */
 
+static int
+@name@type_print(PyObject *v, FILE *fp, int flags)
+{
+	char buf[100];
+        @name@ val = ((Py@Name@ScalarObject *)v)->obval;
+
+	format_@name@(buf, sizeof(buf), val,
+		      (flags & Py_PRINT_RAW) ? @NAME@PREC_STR : @NAME@PREC_REPR);
+	Py_BEGIN_ALLOW_THREADS
+	fputs(buf, fp);
+	Py_END_ALLOW_THREADS
+	return 0;
+}
+
+static int
+c@name@type_print(PyObject *v, FILE *fp, int flags)
+{
+        /* Size of buf: twice sizeof(real) + 2 (for the parenthesis) */
+	char buf[202];
+        c@name@ val = ((PyC@Name@ScalarObject *)v)->obval;
+
+	format_c@name@(buf, sizeof(buf), val,
+		       (flags & Py_PRINT_RAW) ? @NAME@PREC_STR : @NAME@PREC_REPR);
+	Py_BEGIN_ALLOW_THREADS
+	fputs(buf, fp);
+	Py_END_ALLOW_THREADS
+	return 0;
+}
+
+/**end repeat**/
+
+
 /*
  * Could improve this with a PyLong_FromLongDouble(longdouble ldval)
  * but this would need some more work...
@@ -3077,6 +3155,14 @@
     PyCDoubleArrType_Type.tp_@name@  = cdoubletype_@name@;
     /**end repeat**/
 
+    PyFloatArrType_Type.tp_print = floattype_print;
+    PyDoubleArrType_Type.tp_print = doubletype_print;
+    PyLongDoubleArrType_Type.tp_print = longdoubletype_print;
+
+    PyCFloatArrType_Type.tp_print = cfloattype_print;
+    PyCDoubleArrType_Type.tp_print = cdoubletype_print;
+    PyCLongDoubleArrType_Type.tp_print = clongdoubletype_print;
+
     /* These need to be coded specially because getitem does not
        return a normal Python type
      */

Modified: trunk/numpy/core/tests/test_multiarray.py
===================================================================
--- trunk/numpy/core/tests/test_multiarray.py	2009-02-12 05:44:07 UTC (rev 6359)
+++ trunk/numpy/core/tests/test_multiarray.py	2009-02-14 14:54:26 UTC (rev 6360)
@@ -5,6 +5,8 @@
 from numpy.testing import *
 from numpy.core import *
 
+from test_print import in_foreign_locale
+
 class TestFlags(TestCase):
     def setUp(self):
         self.a = arange(10)
@@ -114,41 +116,6 @@
         d2 = dtype('f8')
         assert_equal(d2, dtype(float64))
 
-
-class TestFromstring(TestCase):
-    def test_binary(self):
-        a = fromstring('\x00\x00\x80?\x00\x00\x00@\x00\x00@@\x00\x00\x80@',dtype='<f4')
-        assert_array_equal(a, array([1,2,3,4]))
-
-    def test_string(self):
-        a = fromstring('1,2,3,4', sep=',')
-        assert_array_equal(a, [1., 2., 3., 4.])
-
-    def test_counted_string(self):
-        a = fromstring('1,2,3,4', count=4, sep=',')
-        assert_array_equal(a, [1., 2., 3., 4.])
-        a = fromstring('1,2,3,4', count=3, sep=',')
-        assert_array_equal(a, [1., 2., 3.])
-
-    def test_string_with_ws(self):
-        a = fromstring('1 2  3     4   ', dtype=int, sep=' ')
-        assert_array_equal(a, [1, 2, 3, 4])
-
-    def test_counted_string_with_ws(self):
-        a = fromstring('1 2  3     4   ', count=3, dtype=int, sep=' ')
-        assert_array_equal(a, [1, 2, 3])
-
-    def test_ascii(self):
-        a = fromstring('1 , 2 , 3 , 4', sep=',')
-        b = fromstring('1,2,3,4', dtype=float, sep=',')
-        assert_array_equal(a, [1.,2.,3.,4.])
-        assert_array_equal(a,b)
-
-    def test_malformed(self):
-        a = fromstring('1.234 1,234', sep=' ')
-        assert_array_equal(a, [1.234, 1.])
-
-
 class TestZeroRank(TestCase):
     def setUp(self):
         self.d = array(0), array('x', object)
@@ -813,46 +780,155 @@
         assert_array_equal(x[1][idx],np.sort(x[1]))
 
 
-class TestFromToFile(TestCase):
+class TestIO(object):
+    """Test tofile, fromfile, tostring, and fromstring"""
+    
     def setUp(self):
-        shape = (4,7)
+        shape = (2,4,3)
         rand = np.random.random
-
         self.x = rand(shape) + rand(shape).astype(np.complex)*1j
+        self.x[0,:,1] = [nan, inf, -inf, nan]
         self.dtype = self.x.dtype
+        self.filename = tempfile.mktemp()
 
-    def test_file(self):
-        # Test disabled on Windows, since the tempfile does not flush
-        # properly.  The test ensures that both filenames and file
-        # objects are accepted in tofile and fromfile, so as long as
-        # it runs on at least one platform, we should be ok.
-        if not sys.platform.startswith('win'):
-            tmp_file = tempfile.NamedTemporaryFile('wb',
-                                                   prefix='numpy_tofromfile')
-            self.x.tofile(tmp_file.file)
-            tmp_file.flush()
-            y = np.fromfile(tmp_file.name,dtype=self.dtype)
-            assert_array_equal(y,self.x.flat)
+    def tearDown(self):
+        if os.path.isfile(self.filename):
+            os.unlink(self.filename)
             tmp_file.close()
 
-    def test_filename(self):
-        filename = tempfile.mktemp()
-        f = open(filename,'wb')
+    def test_roundtrip_file(self):
+        f = open(self.filename, 'wb')
         self.x.tofile(f)
         f.close()
-        y = np.fromfile(filename,dtype=self.dtype)
-        assert_array_equal(y,self.x.flat)
+        # NB. doesn't work with flush+seek, due to use of C stdio
+        f = open(self.filename, 'rb')
+        y = np.fromfile(f, dtype=self.dtype)
+        f.close()
+        assert_array_equal(y, self.x.flat)
         os.unlink(filename)
 
+    def test_roundtrip_filename(self):
+        self.x.tofile(self.filename)
+        y = np.fromfile(self.filename, dtype=self.dtype)
+        assert_array_equal(y, self.x.flat)
+
+    def test_roundtrip_binary_str(self):
+        s = self.x.tostring()
+        y = np.fromstring(s, dtype=self.dtype)
+        assert_array_equal(y, self.x.flat)
+
+        s = self.x.tostring('F')
+        y = np.fromstring(s, dtype=self.dtype)
+        assert_array_equal(y, self.x.flatten('F'))
+
+    def test_roundtrip_str(self):
+        x = self.x.real.ravel()
+        s = "@".join(map(str, x))
+        y = np.fromstring(s, sep="@")
+        # NB. str imbues less precision
+        nan_mask = ~np.isfinite(x)
+        assert_array_equal(x[nan_mask], y[nan_mask])
+        assert_array_almost_equal(x[~nan_mask], y[~nan_mask], decimal=5)
+
+    def test_roundtrip_repr(self):
+        x = self.x.real.ravel()
+        s = "@".join(map(repr, x))
+        y = np.fromstring(s, sep="@")
+        assert_array_equal(x, y)
+
+    def _check_from(self, s, value, **kw):
+        y = np.fromstring(s, **kw)
+        assert_array_equal(y, value)
+
+        f = open(self.filename, 'wb')
+        f.write(s)
+        f.close()
+        y = np.fromfile(self.filename, **kw)
+        assert_array_equal(y, value)
+
+    def test_nan(self):
+        self._check_from("nan +nan -nan NaN nan(foo) +NaN(BAR) -NAN(q_u_u_x_)",
+                         [nan, nan, nan, nan, nan, nan, nan],
+                         sep=' ')
+
+    def test_inf(self):
+        self._check_from("inf +inf -inf infinity -Infinity iNfInItY -inF",
+                         [inf, inf, -inf, inf, -inf, inf, -inf], sep=' ')
+
+    def test_numbers(self):
+        self._check_from("1.234 -1.234 .3 .3e55 -123133.1231e+133",
+                         [1.234, -1.234, .3, .3e55, -123133.1231e+133], sep=' ')
+
+    def test_binary(self):
+        self._check_from('\x00\x00\x80?\x00\x00\x00@\x00\x00@@\x00\x00\x80@',
+                         array([1,2,3,4]),
+                         dtype='<f4')
+
+    def test_string(self):
+        self._check_from('1,2,3,4', [1., 2., 3., 4.], sep=',')
+
+    def test_counted_string(self):
+        self._check_from('1,2,3,4', [1., 2., 3., 4.], count=4, sep=',')
+        self._check_from('1,2,3,4', [1., 2., 3.], count=3, sep=',')
+        self._check_from('1,2,3,4', [1., 2., 3., 4.], count=-1, sep=',')
+
+    def test_string_with_ws(self):
+        self._check_from('1 2  3     4   ', [1, 2, 3, 4], dtype=int, sep=' ')
+
+    def test_counted_string_with_ws(self):
+        self._check_from('1 2  3     4   ', [1,2,3], count=3, dtype=int,
+                         sep=' ')
+
+    def test_ascii(self):
+        self._check_from('1 , 2 , 3 , 4', [1.,2.,3.,4.], sep=',')
+        self._check_from('1,2,3,4', [1.,2.,3.,4.], dtype=float, sep=',')
+
     def test_malformed(self):
-        filename = tempfile.mktemp()
-        f = open(filename,'w')
-        f.write("1.234 1,234")
+        self._check_from('1.234 1,234', [1.234, 1.], sep=' ')
+
+    def test_long_sep(self):
+        self._check_from('1_x_3_x_4_x_5', [1,3,4,5], sep='_x_')
+
+    def test_dtype(self):
+        v = np.array([1,2,3,4], dtype=np.int_)
+        self._check_from('1,2,3,4', v, sep=',', dtype=np.int_)
+
+    def test_tofile_sep(self):
+        x = np.array([1.51, 2, 3.51, 4], dtype=float)
+        f = open(self.filename, 'w')
+        x.tofile(f, sep=',')
         f.close()
-        y = np.fromfile(filename, sep=' ')
-        assert_array_equal(y, [1.234, 1.])
+        f = open(self.filename, 'r')
+        s = f.read()
+        f.close()
+        assert_equal(s, '1.51,2.0,3.51,4.0')
         os.unlink(filename)
 
+    def test_tofile_format(self):
+        x = np.array([1.51, 2, 3.51, 4], dtype=float)
+        f = open(self.filename, 'w')
+        x.tofile(f, sep=',', format='%.2f')
+        f.close()
+        f = open(self.filename, 'r')
+        s = f.read()
+        f.close()
+        assert_equal(s, '1.51,2.00,3.51,4.00')
+
+    @in_foreign_locale
+    def _run_in_foreign_locale(self, func, fail=False):
+        np.testing.dec.knownfailureif(fail)(func)(self)
+
+    def test_locale(self):
+        yield self._run_in_foreign_locale, TestIO.test_numbers
+        yield self._run_in_foreign_locale, TestIO.test_nan
+        yield self._run_in_foreign_locale, TestIO.test_inf
+        yield self._run_in_foreign_locale, TestIO.test_counted_string
+        yield self._run_in_foreign_locale, TestIO.test_ascii
+        yield self._run_in_foreign_locale, TestIO.test_malformed
+        yield self._run_in_foreign_locale, TestIO.test_tofile_sep
+        yield self._run_in_foreign_locale, TestIO.test_tofile_format
+
+
 class TestFromBuffer(TestCase):
     def tst_basic(self,buffer,expected,kwargs):
         assert_array_equal(np.frombuffer(buffer,**kwargs),expected)

Modified: trunk/numpy/core/tests/test_print.py
===================================================================
--- trunk/numpy/core/tests/test_print.py	2009-02-12 05:44:07 UTC (rev 6359)
+++ trunk/numpy/core/tests/test_print.py	2009-02-14 14:54:26 UTC (rev 6360)
@@ -1,5 +1,6 @@
 import numpy as np
 from numpy.testing import *
+import nose
 
 import locale
 import sys
@@ -25,7 +26,7 @@
         assert_equal(str(tp(1e10)), ref,
                      err_msg='Failed str formatting for type %s' % tp)
 
-@dec.knownfailureif(True, "formatting tests are known to fail")
+#@dec.knownfailureif(True, "formatting tests are known to fail")
 def test_float_types():
     """ Check formatting.
 
@@ -42,9 +43,9 @@
         assert_equal(str(tp(x)), _REF[x],
                      err_msg='Failed str formatting for type %s' % tp)
 
-@dec.knownfailureif(True, "formatting tests are known to fail")
+#@dec.knownfailureif(True, "formatting tests are known to fail")
 def test_nan_inf_float():
-    """ Check formatting.
+    """ Check formatting of nan & inf.
 
         This is only for the str function, and only for simple types.
         The precision of np.float and np.longdouble aren't the same as the
@@ -69,15 +70,15 @@
     else:
         if sys.platform == 'win32' and sys.version_info[0] <= 2 and \
            sys.version_info[1] <= 5:
-            ref = '1e+010'
+            ref = '(1e+010+0j)'
         else:
-            ref = '1e+10'
+            ref = '(1e+10+0j)'
         assert_equal(str(tp(1e10)), ref,
                      err_msg='Failed str formatting for type %s' % tp)
 
-@dec.knownfailureif(True, "formatting tests are known to fail")
+#@dec.knownfailureif(True, "formatting tests are known to fail")
 def test_complex_types():
-    """Check formatting.
+    """Check formatting of complex types.
 
         This is only for the str function, and only for simple types.
         The precision of np.float and np.longdouble aren't the same as the
@@ -107,80 +108,90 @@
                  err_msg='print failed for type%s' % tp)
 
 def check_float_type_print(tp):
-    for x in [0, 1,-1, 1e10, 1e20, np.inf, -np.inf, np.nan]:
+    for x in [0, 1,-1, 1e20]:
         _test_redirected_print(float(x), tp)
 
+    for x in [np.inf, -np.inf, np.nan]:
+        _test_redirected_print(float(x), tp, _REF[x])
+
+    if tp(1e10).itemsize > 4:
+        _test_redirected_print(float(1e10), tp)
+    else:
+        if sys.platform == 'win32' and sys.version_info[0] <= 2 and \
+           sys.version_info[1] <= 5:
+            ref = '1e+010'
+        else:
+            ref = '1e+10'
+        _test_redirected_print(float(1e10), tp, ref)
+
+#@dec.knownfailureif(True, "formatting tests are known to fail")
 def check_complex_type_print(tp):
     # We do not create complex with inf/nan directly because the feature is
     # missing in python < 2.6
-    for x in [0, 1, -1, 1e10, 1e20, complex(np.inf, 1),
-              complex(np.nan, 1), complex(-np.inf, 1)] :
+    for x in [0, 1, -1, 1e20]:
         _test_redirected_print(complex(x), tp)
 
-@dec.knownfailureif(True, "formatting tests are known to fail")
+    if tp(1e10).itemsize > 8:
+        _test_redirected_print(complex(1e10), tp)
+    else:
+        if sys.platform == 'win32' and sys.version_info[0] <= 2 and \
+           sys.version_info[1] <= 5:
+            ref = '(1e+010+0j)'
+        else:
+            ref = '(1e+10+0j)'
+        _test_redirected_print(complex(1e10), tp, ref)
+
+    _test_redirected_print(complex(np.inf, 1), tp, '(inf+1j)')
+    _test_redirected_print(complex(-np.inf, 1), tp, '(-inf+1j)')
+    _test_redirected_print(complex(-np.nan, 1), tp, '(nan+1j)')
+
 def test_float_type_print():
     """Check formatting when using print """
     for t in [np.float32, np.double, np.longdouble] :
         yield check_float_type_print, t
 
-@dec.knownfailureif(True, "formatting tests are known to fail")
+#@dec.knownfailureif(True, "formatting tests are known to fail")
 def test_complex_type_print():
     """Check formatting when using print """
     for t in [np.complex64, np.cdouble, np.clongdouble] :
         yield check_complex_type_print, t
 
-# Locale tests: scalar types formatting should be independant of the locale
-def has_french_locale():
-    curloc = locale.getlocale(locale.LC_NUMERIC)
-    try:
-        try:
-            if not sys.platform == 'win32':
-                locale.setlocale(locale.LC_NUMERIC, 'fr_FR')
-            else:
-                locale.setlocale(locale.LC_NUMERIC, 'FRENCH')
-
-            st = True
-        except:
-            st = False
-    finally:
-        locale.setlocale(locale.LC_NUMERIC, locale=curloc)
-
-    return st
-
-def _test_locale_independance(tp):
+# Locale tests: scalar types formatting should be independent of the locale
+def in_foreign_locale(func):
     # XXX: How to query locale on a given system ?
 
     # French is one language where the decimal is ',' not '.', and should be
     # relatively common on many systems
-    curloc = locale.getlocale(locale.LC_NUMERIC)
-    try:
-        if not sys.platform == 'win32':
-            locale.setlocale(locale.LC_NUMERIC, 'fr_FR')
-        else:
-            locale.setlocale(locale.LC_NUMERIC, 'FRENCH')
+    def wrapper(*args, **kwargs):
+        curloc = locale.getlocale(locale.LC_NUMERIC)
+        try:
+            try:
+                if not sys.platform == 'win32':
+                    locale.setlocale(locale.LC_NUMERIC, 'fr_FR')
+                else:
+                    locale.setlocale(locale.LC_NUMERIC, 'FRENCH')
+            except locale.Error:
+                raise nose.SkipTest("Skipping locale test, because "
+                                    "French locale not found")
+            return func(*args, **kwargs)
+        finally:
+            locale.setlocale(locale.LC_NUMERIC, locale=curloc)
+    return nose.tools.make_decorator(func)(wrapper)
 
-        assert_equal(str(tp(1.2)), str(float(1.2)),
-                     err_msg='Failed locale test for type %s' % tp)
-    finally:
-        locale.setlocale(locale.LC_NUMERIC, locale=curloc)
-
-@dec.knownfailureif(True, "formatting tests are known to fail")
-@np.testing.dec.skipif(not has_french_locale(),
-                       "Skipping locale test, French locale not found")
+#@dec.knownfailureif(True, "formatting tests are known to fail")
+@in_foreign_locale
 def test_locale_single():
-    return _test_locale_independance(np.float32)
+    assert_equal(str(np.float32(1.2)), str(float(1.2)))
 
-@dec.knownfailureif(True, "formatting tests are known to fail")
-@np.testing.dec.skipif(not has_french_locale(),
-                       "Skipping locale test, French locale not found")
+#@dec.knownfailureif(True, "formatting tests are known to fail")
+@in_foreign_locale
 def test_locale_double():
-    return _test_locale_independance(np.double)
+    assert_equal(str(np.double(1.2)), str(float(1.2)))
 
-@dec.knownfailureif(True, "formatting tests are known to fail")
-@np.testing.dec.skipif(not has_french_locale(),
-                       "Skipping locale test, French locale not found")
+#@dec.knownfailureif(True, "formatting tests are known to fail")
+@in_foreign_locale
 def test_locale_longdouble():
-    return _test_locale_independance(np.longdouble)
+    assert_equal(str(np.longdouble(1.2)), str(float(1.2)))
 
 if __name__ == "__main__":
     run_module_suite()



More information about the Numpy-svn mailing list