diff options
-rw-r--r-- | numpy/lib/npyio.py | 5 | ||||
-rw-r--r-- | numpy/lib/tests/test_io.py | 40 |
2 files changed, 43 insertions, 2 deletions
diff --git a/numpy/lib/npyio.py b/numpy/lib/npyio.py index 0f338d781..197562818 100644 --- a/numpy/lib/npyio.py +++ b/numpy/lib/npyio.py @@ -758,7 +758,7 @@ def _getconv(dtype): elif issubclass(typ, np.floating): return floatconv elif issubclass(typ, complex): - return lambda x: complex(asstr(x)) + return lambda x: complex(asstr(x).replace('+-', '-')) elif issubclass(typ, np.bytes_): return asbytes elif issubclass(typ, np.unicode_): @@ -1377,7 +1377,8 @@ def savetxt(fname, X, fmt='%.18e', delimiter=' ', newline='\n', header='', for number in row: row2.append(number.real) row2.append(number.imag) - fh.write(format % tuple(row2) + newline) + s = format % tuple(row2) + newline + fh.write(s.replace('+-', '-')) else: for row in X: try: diff --git a/numpy/lib/tests/test_io.py b/numpy/lib/tests/test_io.py index 06c57d49c..7dcefe80d 100644 --- a/numpy/lib/tests/test_io.py +++ b/numpy/lib/tests/test_io.py @@ -468,6 +468,26 @@ class TestSaveTxt(object): [b'(3.142e+00+2.718e+00j) (3.142e+00+2.718e+00j)\n', b'(3.142e+00+2.718e+00j) (3.142e+00+2.718e+00j)\n']) + def test_complex_negative_exponent(self): + # Previous to 1.15, some formats generated x+-yj, gh 7895 + ncols = 2 + nrows = 2 + a = np.zeros((ncols, nrows), dtype=np.complex128) + re = np.pi + im = np.e + a[:] = re - 1.0j * im + c = BytesIO() + np.savetxt(c, a, fmt='%.3e') + c.seek(0) + lines = c.readlines() + assert_equal( + lines, + [b' (3.142e+00-2.718e+00j) (3.142e+00-2.718e+00j)\n', + b' (3.142e+00-2.718e+00j) (3.142e+00-2.718e+00j)\n']) + + + + def test_custom_writer(self): class CustomWriter(list): @@ -916,6 +936,26 @@ class TestLoadTxt(LoadTxtBase): res = np.loadtxt(c, dtype=complex) assert_equal(res, tgt) + def test_complex_misformatted(self): + # test for backward compatability + # some complex formats used to generate x+-yj + a = np.zeros((2, 2), dtype=np.complex128) + re = np.pi + im = np.e + a[:] = re - 1.0j * im + c = BytesIO() + np.savetxt(c, a, fmt='%.16e') + c.seek(0) + txt = c.read() + c.seek(0) + # misformat the sign on the imaginary part, gh 7895 + txt_bad = txt.replace(b'e+00-', b'e00+-') + assert_(txt_bad != txt) + c.write(txt_bad) + c.seek(0) + res = np.loadtxt(c, dtype=complex) + assert_equal(res, a) + def test_universal_newline(self): with temppath() as name: with open(name, 'w') as f: |