summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--numpy/lib/npyio.py5
-rw-r--r--numpy/lib/tests/test_io.py40
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: