Repository: psychopy/psychopy

Issue:
new xml broke BART and mental rotation Builder demos
not sure how / why

533b97482ec27 is OK, and then b2a0916ccb8b6b54 is not OK

Fails at line ~252: NoneType has no attribute method

```
val = paramNode.get('val').replace("&#10;", "\n")
```



Discussion:

Resolving patch:
diff --git a/psychopy/__init__.py b/psychopy/__init__.py
--- a/psychopy/__init__.py
+++ b/psychopy/__init__.py
@@ -20,7 +20,7 @@
 __git_sha__='n/a'
 __build_platform__='n/a'
 
-__all__ = ["gui", "misc", "visual", "core", "event", "data", "filters", "sound"]
+__all__ = ["gui", "misc", "visual", "core", "event", "data", "sound", "microphone"]
 
 #for developers the following allows access to the current git sha from their repository
 if __git_sha__=='n/a':
diff --git a/psychopy/app/builder/experiment.py b/psychopy/app/builder/experiment.py
--- a/psychopy/app/builder/experiment.py
+++ b/psychopy/app/builder/experiment.py
@@ -7,11 +7,12 @@
 import re, os
 import xml.etree.ElementTree as xml
 from xml.dom import minidom
-
 import StringIO, codecs
+import keyword
+
 from .components import getInitVals, getComponents, getAllComponents
 import psychopy
-from psychopy import data, __version__, logging
+from psychopy import data, __version__, logging, constants
 from psychopy.constants import FOREVER
 
 try:
@@ -255,7 +256,9 @@ def _getXMLparam(self,params,paramNode):
         """
         name=paramNode.get('name')
         valType = paramNode.get('valType')
-        val = paramNode.get('val').replace("&#10;", "\n")
+        val = paramNode.get('val')
+        if not name == 'advancedParams':
+            val = val.replace("&#10;", "\n")
         if name=='storeResponseTime':
             return#deprecated in v1.70.00 because it was redundant
         elif name=='startTime':#deprecated in v1.70.00
@@ -1388,32 +1391,9 @@ def __init__(self, exp):
         #deepcopy fails if you pre-compile regular expressions and stash here
 
         self.numpy = _numpyImports + _numpyRandomImports + ['np']
-        self.keywords = ['and', 'del', 'from', 'not', 'while', 'as', 'elif',
-            'with', 'assert', 'else', 'if', 'pass', 'yield', 'break', 'except',
-            'import', 'print', 'class', 'exec', 'in', 'raise', 'continue', 'or',
-            'finally', 'is', 'return', 'def', 'for', 'lambda', 'try', 'global',
-            'abs', 'all', 'any', 'apply', 'basestring', 'bin', 'bool', 'buffer',
-            'bytearray', 'bytes', 'callable', 'chr', 'classmethod', 'cmp',
-            'compile', 'complex', 'copyright', 'credits', 'delattr', 'dict',
-            'divmod', 'enumerate', 'eval', 'execfile', 'exit', 'file', 'filter',
-            'float', 'format', 'frozenset', 'getattr', 'globals', 'hasattr',
-            'help', 'hex', 'id', 'input', 'int', 'intern', 'isinstance', 'hash',
-            'iter', 'len', 'license', 'list', 'locals', 'long', 'map', 'max',
-            'min', 'next', 'object', 'oct', 'open', 'ord', 'pow', 'print', 'dir',
-            'quit', 'range', 'raw_input', 'reduce', 'reload', 'repr', 'reversed',
-            'set', 'setattr', 'slice', 'sorted', 'staticmethod', 'str', 'sum',
-            'super', 'tuple', 'type', 'unichr', 'unicode', 'vars', 'xrange',
-            'clear', 'copy', 'fromkeys', 'get', 'has_key', 'items', 'iteritems',
-            'iterkeys', 'round', 'memoryview', 'issubclass', 'property', 'zip',
-            'itervalues', 'keys', 'pop', 'popitem', 'setdefault', 'update',
-            'values', 'viewitems', 'viewkeys', 'viewvalues', 'coerce',
-            '__builtins__', '__doc__', '__file__', '__name__', '__package__',
-            'None', 'True', 'False']
+        self.keywords = keyword.kwlist + dir(__builtins__)
         # these are based on a partial test, known to be incomplete:
-        self.psychopy = ['psychopy', 'os', 'core', 'data', 'visual', 'event',
-            'gui', 'sound', 'misc', 'logging', 'microphone',
-            'NOT_STARTED', 'STARTED', 'FINISHED', 'PAUSED', 'STOPPED',
-            'PLAYING', 'FOREVER', 'PSYCHOPY_USERAGENT']
+        self.psychopy = psychopy.__all__ + ['psychopy', 'os'] + dir(constants)
         self.builder = ['KeyResponse', 'key_resp', 'buttons', 'continueRoutine',
             'expInfo', 'expName', 'thisExp', 'filename', 'logFile', 'paramName',
             't', 'frameN', 'currentLoop', 'dlg', '_thisDir', 'endExpNow',
diff --git a/psychopy/preferences/preferences.py b/psychopy/preferences/preferences.py
--- a/psychopy/preferences/preferences.py
+++ b/psychopy/preferences/preferences.py
@@ -80,6 +80,20 @@ def getPaths(self):
             self.paths['prefsSpecFile']= join(prefSpecDir,platform.system()+'.spec')
             self.paths['userPrefsDir']= join(os.environ['HOME'],'.psychopy2')
 
+        # avoid silent fail-to-launch-app if bad permissions:
+        if os.path.exists(self.paths['userPrefsDir']):
+            try:
+                if not os.access(self.paths['userPrefsDir'], os.W_OK | os.R_OK):
+                    raise OSError
+                tmp = os.path.join(self.paths['userPrefsDir'], '.tmp')
+                with open(tmp, 'w') as fileh:
+                    fileh.write('')
+                open(tmp).read()
+                os.remove(tmp)
+            except Exception: # OSError, WindowsError, ...?
+                msg = 'PsychoPy2 error: need read-write permissions for `%s`'
+                sys.exit(msg % self.paths['userPrefsDir'])
+
     def loadAll(self):
         """Load the user prefs and the application data
         """


Test patch: