Repository: pyqtgraph/pyqtgraph

Issue:
Bug when reading arrays in configfile
Arrays (longer than a few elements) can be written out using configfile.writeConfigFile, but then cannot be read back in using configfile.readConfigFile.

This seems to be because `repr(array)` produces a string with line breaks in it. While `eval(repr(array))` works just fine, configfile chokes while reading it in because it parses each line separately, and we end up with a SyntaxError about unexpected EOF. 

To reproduce:
```
>>> from numpy import *
>>> from pyqtgraph import configfile
>>> arr = arange(20)
>>> arr
array([ 0,  1,  2,  3,  4,  5,  6,  7,  8,  9, 10, 11, 12, 13, 14, 15, 16,
       17, 18, 19])
>>> configfile.writeConfigFile({'arr':arr}, 'arraytest.cfg')
>>> configfile.readConfigFile('arraytest.cfg')
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "pyqtgraph/configfile.py", line 64, in readConfigFile
    data = parseString(s)[1]
  File "pyqtgraph/configfile.py", line 168, in parseString
    raise ParseError("Error evaluating expression '%s': [%s: %s]" % (v, ex.__class__.__name__, str(ex)), (ln+1), l)
pyqtgraph.configfile.ParseError: Error parsing config file '/Users/mbkratz/Code/pyqtgraph/arraytest.cfg' at line 1:
arr: array([ 0,  1,  2,  3,  4,  5,  6,  7,  8,  9, 10, 11, 12, 13, 14, 15, 16,
Error evaluating expression 'array([ 0,  1,  2,  3,  4,  5,  6,  7,  8,  9, 10, 11, 12, 13, 14, 15, 16,': [SyntaxError: unexpected EOF while parsing (<string>, line 1)]
>>> 
```



Discussion:

Resolving patch:
diff --git a/pyqtgraph/configfile.py b/pyqtgraph/configfile.py
--- a/pyqtgraph/configfile.py
+++ b/pyqtgraph/configfile.py
@@ -33,9 +33,8 @@ def __str__(self):
             msg = "Error parsing string at line %d:\n" % self.lineNum
         else:
             msg = "Error parsing config file '%s' at line %d:\n" % (self.fileName, self.lineNum)
-        msg += "%s\n%s" % (self.line, self.message)
+        msg += "%s\n%s" % (self.line, Exception.__str__(self))
         return msg
-        #raise Exception()
         
 
 def writeConfigFile(data, fname):
@@ -93,13 +92,14 @@ def genString(data, indent=''):
             s += indent + sk + ':\n'
             s += genString(data[k], indent + '    ')
         else:
-            s += indent + sk + ': ' + repr(data[k]) + '\n'
+            s += indent + sk + ': ' + repr(data[k]).replace("\n", "\\\n") + '\n'
     return s
     
 def parseString(lines, start=0):
     
     data = OrderedDict()
     if isinstance(lines, basestring):
+        lines = lines.replace("\\\n", "")
         lines = lines.split('\n')
         lines = [l for l in lines if re.search(r'\S', l) and not re.match(r'\s*#', l)]  ## remove empty lines
         


Test patch:
diff --git a/pyqtgraph/tests/test_configparser.py b/pyqtgraph/tests/test_configparser.py
new file mode 100644
--- /dev/null
+++ b/pyqtgraph/tests/test_configparser.py
@@ -0,0 +1,36 @@
+from pyqtgraph import configfile
+import numpy as np
+import tempfile, os
+
+def test_longArrays():
+    """
+    Test config saving and loading of long arrays.
+    """
+    tmp = tempfile.mktemp(".cfg")
+
+    arr = np.arange(20)
+    configfile.writeConfigFile({'arr':arr}, tmp)
+    config = configfile.readConfigFile(tmp)
+    
+    assert all(config['arr'] == arr)
+
+    os.remove(tmp)
+
+def test_multipleParameters():
+    """
+    Test config saving and loading of multiple parameters.
+    """
+    tmp = tempfile.mktemp(".cfg")
+
+    par1 = [1,2,3]
+    par2 = "Test"
+    par3 = {'a':3,'b':'c'}
+
+    configfile.writeConfigFile({'par1':par1, 'par2':par2, 'par3':par3}, tmp)
+    config = configfile.readConfigFile(tmp)
+    
+    assert config['par1'] == par1
+    assert config['par2'] == par2
+    assert config['par3'] == par3
+
+    os.remove(tmp)