# Buggy code
def _parse_ctx_free(self, input, mode="exec"):
    last_error_line = last_error_col = -1
    parsed = False
    original_error = None
    while not parsed:
        try:
            tree = self.parser.parse(
                input,
                filename=self.filename,
                mode=mode,
                debug_level=(self.debug_level > 1),
            )
            parsed = True
        except IndentationError as e:
            if original_error is None:
                raise e
            else:
                raise original_error
        except SyntaxError as e:
            if original_error is None:
                original_error = e
            if (e.loc is None) or (
                last_error_line == e.loc.lineno
                and last_error_col in (e.loc.column + 1, e.loc.column)
            ):
                raise original_error
            last_error_col = e.loc.column
            last_error_line = e.loc.lineno
            idx = last_error_line - 1
            lines = input.splitlines()
            line = lines[idx]
            if input.endswith("\n"):
                lines.append("")
            if len(line.strip()) == 0:
                # whitespace only lines are not valid syntax in Python's
                # interactive mode='single', who knew?! Just ignore them.
                # this might cause actual sytax errors to have bad line
                # numbers reported, but should only effect interactive mode
                del lines[idx]
                last_error_line = last_error_col = -1
                input = "\n".join(lines)
                continue

            if last_error_line > 1 and lines[idx - 1].rstrip()[-1:] == ":":
                # catch non-indented blocks and raise error.
                prev_indent = len(lines[idx - 1]) - len(lines[idx - 1].lstrip())
                curr_indent = len(lines[idx]) - len(lines[idx].lstrip())
                if prev_indent == curr_indent:
                    raise original_error
            lexer = self.parser.lexer
            maxcol = find_next_break(line, mincol=last_error_col, lexer=lexer)
            sbpline = subproc_toks(line, returnline=True, maxcol=maxcol, lexer=lexer)
            if sbpline is None:
                # subprocess line had no valid tokens,
                if len(line.partition("#")[0].strip()) == 0:
                    # likely because it only contained a comment.
                    del lines[idx]
                    last_error_line = last_error_col = -1
                    input = "\n".join(lines)
                    continue
                else:
                    # or for some other syntax error
                    raise original_error
            elif sbpline[last_error_col:].startswith(
                "![!["
            ) or sbpline.lstrip().startswith("![!["):
                # if we have already wrapped this in subproc tokens
                # and it still doesn't work, adding more won't help
                # anything
                raise original_error
            else:
                if self.debug_level:
                    msg = "{0}:{1}:{2}{3} - {4}\n{0}:{1}:{2}{3} + {5}"
                    mstr = "" if maxcol is None else ":" + str(maxcol)
                    msg = msg.format(
                        self.filename,
                        last_error_line,
                        last_error_col,
                        mstr,
                        line,
                        sbpline,
                    )
                    print(msg, file=sys.stderr)
                lines[idx] = sbpline
            last_error_col += 3
            input = "\n".join(lines)
    return tree, input


# Traceback (ValueError)
xonshmaster=🐚 fdjskflj --arg=$ENVTraceback (most recent call last):
File "/Users/aaronmeurer/anaconda3/bin/xonsh", line 6, in <module>
sys.exit(xonsh.main.main())
File "/Users/aaronmeurer/Documents/xonsh/xonsh/main.py", line 236, in main
shell.cmdloop()
File "/Users/aaronmeurer/Documents/xonsh/xonsh/ptk/shell.py", line 111, in cmdloop
line = self.singleline(auto_suggest=auto_suggest)
File "/Users/aaronmeurer/Documents/xonsh/xonsh/ptk/shell.py", line 80, in singleline
display_completions_in_columns=multicolumn)
File "/Users/aaronmeurer/Documents/xonsh/xonsh/ptk/shortcuts.py", line 104, in prompt
document = cli.run(reset_current_buffer=False)
File "/Users/aaronmeurer/anaconda/lib/python3.5/site-packages/prompt_toolkit-0.57-py3.5.egg/prompt_toolkit/interface.py", line 353, in run
File "/Users/aaronmeurer/anaconda/lib/python3.5/site-packages/prompt_toolkit-0.57-py3.5.egg/prompt_toolkit/eventloop/posix.py", line 150, in run
File "/Users/aaronmeurer/anaconda/lib/python3.5/site-packages/prompt_toolkit-0.57-py3.5.egg/prompt_toolkit/eventloop/posix.py", line 82, in read_from_stdin
File "/Users/aaronmeurer/anaconda/lib/python3.5/site-packages/prompt_toolkit-0.57-py3.5.egg/prompt_toolkit/terminal/vt100_input.py", line 373, in feed
File "/Users/aaronmeurer/anaconda/lib/python3.5/site-packages/prompt_toolkit-0.57-py3.5.egg/prompt_toolkit/terminal/vt100_input.py", line 292, in _input_par
File "/Users/aaronmeurer/anaconda/lib/python3.5/site-packages/prompt_toolkit-0.57-py3.5.egg/prompt_toolkit/terminal/vt100_input.py", line 325, in _call_hanr
File "/Users/aaronmeurer/anaconda/lib/python3.5/site-packages/prompt_toolkit-0.57-py3.5.egg/prompt_toolkit/interface.py", line 830, in feed_key
File "/Users/aaronmeurer/anaconda/lib/python3.5/site-packages/prompt_toolkit-0.57-py3.5.egg/prompt_toolkit/key_binding/input_processor.py", line 172, in fey
File "/Users/aaronmeurer/anaconda/lib/python3.5/site-packages/prompt_toolkit-0.57-py3.5.egg/prompt_toolkit/key_binding/input_processor.py", line 144, in _ps
File "/Users/aaronmeurer/anaconda/lib/python3.5/site-packages/prompt_toolkit-0.57-py3.5.egg/prompt_toolkit/key_binding/input_processor.py", line 187, in _cr
File "/Users/aaronmeurer/anaconda/lib/python3.5/site-packages/prompt_toolkit-0.57-py3.5.egg/prompt_toolkit/key_binding/registry.py", line 32, in call
File "/Users/aaronmeurer/Documents/xonsh/xonsh/ptk/key_bindings.py", line 110, in multiline_carriage_return
carriage_return(b, event.cli)
File "/Users/aaronmeurer/Documents/xonsh/xonsh/ptk/key_bindings.py", line 55, in carriage_return
elif not current_line_blank and not can_compile(b.document.text):
File "/Users/aaronmeurer/Documents/xonsh/xonsh/ptk/key_bindings.py", line 80, in can_compile
locs=builtins.__xonsh_ctx__)
File "/Users/aaronmeurer/Documents/xonsh/xonsh/execer.py", line 95, in compile
code = compile(tree, filename, mode)
ValueError: expression which can't be assigned to in Store context

# Fixed code
def _parse_ctx_free(self, input, mode="exec"):
    last_error_line = last_error_col = -1
    parsed = False
    original_error = None
    while not parsed:
        try:
            tree = self.parser.parse(
                input,
                filename=self.filename,
                mode=mode,
                debug_level=(self.debug_level > 1),
            )
            parsed = True
        except IndentationError as e:
            if original_error is None:
                raise e
            else:
                raise original_error
        except SyntaxError as e:
            if original_error is None:
                original_error = e
            if (e.loc is None) or (
                last_error_line == e.loc.lineno
                and last_error_col in (e.loc.column + 1, e.loc.column)
            ):
                raise original_error from None
            last_error_col = e.loc.column
            last_error_line = e.loc.lineno
            idx = last_error_line - 1
            lines = input.splitlines()
            line = lines[idx]
            if input.endswith("\n"):
                lines.append("")
            if len(line.strip()) == 0:
                # whitespace only lines are not valid syntax in Python's
                # interactive mode='single', who knew?! Just ignore them.
                # this might cause actual sytax errors to have bad line
                # numbers reported, but should only effect interactive mode
                del lines[idx]
                last_error_line = last_error_col = -1
                input = "\n".join(lines)
                continue

            if last_error_line > 1 and lines[idx - 1].rstrip()[-1:] == ":":
                # catch non-indented blocks and raise error.
                prev_indent = len(lines[idx - 1]) - len(lines[idx - 1].lstrip())
                curr_indent = len(lines[idx]) - len(lines[idx].lstrip())
                if prev_indent == curr_indent:
                    raise original_error
            lexer = self.parser.lexer
            maxcol = find_next_break(line, mincol=last_error_col, lexer=lexer)
            sbpline = subproc_toks(line, returnline=True, maxcol=maxcol, lexer=lexer)
            if sbpline is None:
                # subprocess line had no valid tokens,
                if len(line.partition("#")[0].strip()) == 0:
                    # likely because it only contained a comment.
                    del lines[idx]
                    last_error_line = last_error_col = -1
                    input = "\n".join(lines)
                    continue
                else:
                    # or for some other syntax error
                    raise original_error
            elif sbpline[last_error_col:].startswith(
                "![!["
            ) or sbpline.lstrip().startswith("![!["):
                # if we have already wrapped this in subproc tokens
                # and it still doesn't work, adding more won't help
                # anything
                raise original_error
            else:
                if self.debug_level:
                    msg = "{0}:{1}:{2}{3} - {4}\n{0}:{1}:{2}{3} + {5}"
                    mstr = "" if maxcol is None else ":" + str(maxcol)
                    msg = msg.format(
                        self.filename,
                        last_error_line,
                        last_error_col,
                        mstr,
                        line,
                        sbpline,
                    )
                    print(msg, file=sys.stderr)
                lines[idx] = sbpline
            last_error_col += 3
            input = "\n".join(lines)
    return tree, input