Repository: xonsh/xonsh

Issue:
.xonshrc: Hang on startup if missing comma in dict declaration
Attempting to scratch out a `.xonshrc` for the first time I ran into some odd behavior after messing up my alias map:

``` python
11 aliases.update({                                                                                        
12     'ls': "ls -FNh --tabsize=0 --color=auto --group-directories-first"
13     'll': "ls -l",
14     'la': "ls -a",
15     'lla': "ls -la",
16     'grep': 'grep -n --color=auto',
17     'less': 'less -R',
18 })
```

You'll notice the first entry is missing the required `,` element delimiter...
This seems to cause `xonsh` to hang at startup indefinitely when I would have expected it to throw a syntax error.

`SIGINT`-ing the process seems to consistently give tracebacks like the following:

``` python
Traceback (most recent call last):
  File "/home/tyler/repos/xonsh/xonsh/execer.py", line 150, in _parse_ctx_free
    debug_level=self.debug_level)
  File "/home/tyler/repos/xonsh/xonsh/parsers/base.py", line 283, in parse
    tree = self.parser.parse(input=s, lexer=self.lexer, debug=debug_level)
  File "/usr/lib/python3.5/site-packages/ply/yacc.py", line 331, in parse
    return self.parseopt_notrack(input, lexer, debug, tracking, tokenfunc)
  File "/usr/lib/python3.5/site-packages/ply/yacc.py", line 1181, in parseopt_notrack
    tok = call_errorfunc(self.errorfunc, errtoken, self)
  File "/usr/lib/python3.5/site-packages/ply/yacc.py", line 193, in call_errorfunc
    r = errorfunc(token)
  File "/home/tyler/repos/xonsh/xonsh/parsers/base.py", line 2285, in p_error
    column=p.lexpos))
  File "/home/tyler/repos/xonsh/xonsh/parsers/base.py", line 378, in _parse_error
    raise err
SyntaxError: /home/tyler/.xonshrc:14:4: ('code: $[',)

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "/usr/bin/xonsh", line 9, in <module>
    load_entry_point('xonsh', 'console_scripts', 'xonsh')()
  File "/home/tyler/repos/xonsh/xonsh/main.py", line 178, in main
    args = premain(argv)
  File "/home/tyler/repos/xonsh/xonsh/main.py", line 165, in premain
    shell = builtins.__xonsh_shell__ = Shell(**shell_kwargs)
  File "/home/tyler/repos/xonsh/xonsh/shell.py", line 76, in __init__
    self._init_environ(ctx, config, rc)
  File "/home/tyler/repos/xonsh/xonsh/shell.py", line 120, in _init_environ
    self.ctx = xonshrc_context(rcfiles=rc, execer=self.execer)
  File "/home/tyler/repos/xonsh/xonsh/environ.py", line 1144, in xonshrc_context
    execer.exec(rc, glbs=env)
  File "/home/tyler/repos/xonsh/xonsh/execer.py", line 123, in exec
    stacklevel=stacklevel)
  File "/home/tyler/repos/xonsh/xonsh/execer.py", line 94, in compile
    tree = self.parse(input, ctx, mode=mode)
  File "/home/tyler/repos/xonsh/xonsh/execer.py", line 69, in parse
    tree = self._parse_ctx_free(input, mode=mode)
  File "/home/tyler/repos/xonsh/xonsh/execer.py", line 196, in _parse_ctx_free
    lexer=self.parser.lexer)
  File "/home/tyler/repos/xonsh/xonsh/tools.py", line 107, in subproc_toks
    for tok in lexer:
  File "/home/tyler/repos/xonsh/xonsh/lexer.py", line 500, in __iter__
    t = self.token()
  File "/home/tyler/repos/xonsh/xonsh/lexer.py", line 493, in token
    self.last = next(self.token_stream, None)
  File "/home/tyler/repos/xonsh/xonsh/lexer.py", line 431, in get_tokens
    token = next(tokstream)
  File "/usr/lib/python3.5/tokenize.py", line 601, in _tokenize
```

The problem only seems to show up when the `dict`'s elements are defined per line. If I instead leave the comma out on a declaration made on a single line in my `.xonshrc`:

``` python
d = {10: 'ten' 'doggy': 'kitty'}
```

I get the appropriate error:

```
/home/tyler/repos/xonsh/xonsh/environ.py:1149: RuntimeWarning: syntax error in xonsh 
run control file '/home/tyler/.xonshrc': /home/tyler/.xonshrc:9:13: ('code: @(',) 
warn(msg.format(rcfile, err), RuntimeWarning)
```



Discussion:
Thanks for the very detailed error message @tgoodlet. I believe that the problem is coming from the AST transformer trying to repeatedly wrap a malformed line.  


Resolving patch:
diff --git a/xonsh/execer.py b/xonsh/execer.py
--- a/xonsh/execer.py
+++ b/xonsh/execer.py
@@ -189,7 +189,7 @@ def _parse_ctx_free(self, input, mode='exec'):
                                        returnline=True,
                                        maxcol=maxcol,
                                        lexer=self.parser.lexer)
-                if sbpline.startswith('$[$['):
+                if sbpline.lstrip().startswith('$[$['):
                     # if we have already wrapped this in subproc tokens
                     # and it still doesn't work, adding more won't help
                     # anything


Test patch: