prompt: You will be provided with a partial code base and an issue statement explaining a problem to resolve.
  <issue>
  xonsh dies if the prompt raises an exception
  If a function in the prompt raises an exception, it kills xonsh. I would expect the error to be displayed, but not kill the shell. 
  
  
  </issue>
  <code>
  [start of xonsh/base_shell.py]
  1 """The base class for xonsh shell"""
  2 import os
  3 import sys
  4 import builtins
  5 import traceback
  6 
  7 from xonsh.execer import Execer
  8 from xonsh.tools import XonshError, escape_windows_title_string
  9 from xonsh.tools import ON_WINDOWS
  10 from xonsh.completer import Completer
  11 from xonsh.environ import multiline_prompt, format_prompt
  12 
  13 
  14 class BaseShell(object):
  15     """The xonsh shell."""
  16 
  17     def __init__(self, execer, ctx, **kwargs):
  18         super().__init__(**kwargs)
  19         self.execer = execer
  20         self.ctx = ctx
  21         self.completer = Completer()
  22         self.buffer = []
  23         self.need_more_lines = False
  24         self.mlprompt = None
  25 
  26     def emptyline(self):
  27         """Called when an empty line has been entered."""
  28         self.need_more_lines = False
  29         self.default('')
  30 
  31     def precmd(self, line):
  32         """Called just before execution of line."""
  33         return line if self.need_more_lines else line.lstrip()
  34 
  35     def default(self, line):
  36         """Implements code execution."""
  37         line = line if line.endswith('\n') else line + '\n'
  38         code = self.push(line)
  39         if code is None:
  40             return
  41         try:
  42             self.execer.exec(code, mode='single', glbs=self.ctx)  # no locals
  43         except XonshError as e:
  44             print(e.args[0], file=sys.stderr)
  45         except:
  46             _print_exception()
  47         if builtins.__xonsh_exit__:
  48             return True
  49 
  50     def push(self, line):
  51         """Pushes a line onto the buffer and compiles the code in a way that
  52         enables multiline input.
  53         """
  54         code = None
  55         self.buffer.append(line)
  56         if self.need_more_lines:
  57             return code
  58         src = ''.join(self.buffer)
  59         try:
  60             code = self.execer.compile(src,
  61                                        mode='single',
  62                                        glbs=None,
  63                                        locs=self.ctx)
  64             self.reset_buffer()
  65         except SyntaxError:
  66             if line == '\n':
  67                 self.reset_buffer()
  68                 _print_exception()
  69                 return None
  70             self.need_more_lines = True
  71         except:
  72             self.reset_buffer()
  73             _print_exception()
  74             return None
  75         return code
  76 
  77     def reset_buffer(self):
  78         """Resets the line buffer."""
  79         self.buffer.clear()
  80         self.need_more_lines = False
  81         self.mlprompt = None
  82 
  83     def settitle(self):
  84         """Sets terminal title."""
  85         env = builtins.__xonsh_env__
  86         term = env.get('TERM', None)
  87         if term is None or term == 'linux':
  88             return
  89         if 'TITLE' in env:
  90             t = env['TITLE']
  91         else:
  92             return
  93         t = format_prompt(t)
  94         if ON_WINDOWS and 'ANSICON' not in env:
  95             t = escape_windows_title_string(t)
  96             os.system('title {}'.format(t))
  97         else:
  98             sys.stdout.write("\x1b]2;{0}\x07".format(t))
  99 
  100     @property
  101     def prompt(self):
  102         """Obtains the current prompt string."""
  103         if self.need_more_lines:
  104             if self.mlprompt is None:
  105                 self.mlprompt = multiline_prompt()
  106             return self.mlprompt
  107         env = builtins.__xonsh_env__
  108         if 'PROMPT' in env:
  109             p = env['PROMPT']
  110             p = format_prompt(p)
  111         else:
  112             p = "set '$PROMPT = ...' $ "
  113         self.settitle()
  114         return p
  115         
  116 def _print_exception():
  117     """Print exceptions with/without traceback."""
  118     if not 'XONSH_SHOW_TRACEBACK' in builtins.__xonsh_env__:
  119         sys.stderr.write('xonsh: For full traceback set: '
  120                          '$XONSH_SHOW_TRACEBACK=True\n')
  121     if builtins.__xonsh_env__.get('XONSH_SHOW_TRACEBACK', False):
  122         traceback.print_exc()
  123     else:
  124         exc_type, exc_value, exc_traceback = sys.exc_info()
  125         exception_only =  traceback.format_exception_only(exc_type, exc_value)
  126         sys.stderr.write(''.join(exception_only))
  127
  [end of xonsh/base_shell.py]
  </code>
  
  I need you to solve this issue by generating a single patch file that I can apply directly to this repository using git apply. Please respond with a single patch file in the following format.
  <patch>
  diff --git a/file.py b/file.py
  --- a/file.py
  +++ b/file.py
  @@ -1,27 +1,35 @@
   def euclidean(a, b):
  -    while b:
  -        a, b = b, a % b
  -    return a
  +    if b == 0:
  +        return a
  +    return euclidean(b, a % b)
   
   
   def bresenham(x0, y0, x1, y1):
       points = []
       dx = abs(x1 - x0)
       dy = abs(y1 - y0)
  -    sx = 1 if x0 < x1 else -1
  -    sy = 1 if y0 < y1 else -1
  -    err = dx - dy
  +    x, y = x0, y0
  +    sx = -1 if x0 > x1 else 1
  +    sy = -1 if y0 > y1 else 1
   
  -    while True:
  -        points.append((x0, y0))
  -        if x0 == x1 and y0 == y1:
  -            break
  -        e2 = 2 * err
  -        if e2 > -dy:
  -            err -= dy
  -            x0 += sx
  -        if e2 < dx:
  -            err += dx
  -            y0 += sy
  +    if dx > dy:
  +        err = dx / 2.0
  +        while x != x1:
  +            points.append((x, y))
  +            err -= dy
  +            if err < 0:
  +                y += sy
  +                err += dx
  +            x += sx
  +    else:
  +        err = dy / 2.0
  +        while y != y1:
  +            points.append((x, y))
  +            err -= dx
  +            if err < 0:
  +                x += sx
  +                err += dy
  +            y += sy
  +
  +    points.append((x, y))
       return points
  
  </patch>
golden_diff: diff --git a/xonsh/base_shell.py b/xonsh/base_shell.py
  --- a/xonsh/base_shell.py
  +++ b/xonsh/base_shell.py
  @@ -102,12 +102,19 @@
           """Obtains the current prompt string."""
           if self.need_more_lines:
               if self.mlprompt is None:
  -                self.mlprompt = multiline_prompt()
  +                try:
  +                    self.mlprompt = multiline_prompt()
  +                except Exception:
  +                    _print_exception()
  +                    self.mlprompt =  '<multiline prompt error> '
               return self.mlprompt
           env = builtins.__xonsh_env__
           if 'PROMPT' in env:
               p = env['PROMPT']
  -            p = format_prompt(p)
  +            try:
  +                p = format_prompt(p)
  +            except Exception:
  +                _print_exception()
           else:
               p = "set '$PROMPT = ...' $ "
           self.settitle()
  
verification_info: {"golden_diff": "diff --git a/xonsh/base_shell.py b/xonsh/base_shell.py\n--- a/xonsh/base_shell.py\n+++ b/xonsh/base_shell.py\n@@ -102,12 +102,19 @@\n         \"\"\"Obtains the current prompt string.\"\"\"\n         if self.need_more_lines:\n             if self.mlprompt is None:\n-                self.mlprompt = multiline_prompt()\n+                try:\n+                    self.mlprompt = multiline_prompt()\n+                except Exception:\n+                    _print_exception()\n+                    self.mlprompt =  '<multiline prompt error> '\n             return self.mlprompt\n         env = builtins.__xonsh_env__\n         if 'PROMPT' in env:\n             p = env['PROMPT']\n-            p = format_prompt(p)\n+            try:\n+                p = format_prompt(p)\n+            except Exception:\n+                _print_exception()\n         else:\n             p = \"set '$PROMPT = ...' $ \"\n         self.settitle()\n", "issue": "xonsh dies if the prompt raises an exception\nIf a function in the prompt raises an exception, it kills xonsh. I would expect the error to be displayed, but not kill the shell. \n\n", "before_files": [{"content": "\"\"\"The base class for xonsh shell\"\"\"\nimport os\nimport sys\nimport builtins\nimport traceback\n\nfrom xonsh.execer import Execer\nfrom xonsh.tools import XonshError, escape_windows_title_string\nfrom xonsh.tools import ON_WINDOWS\nfrom xonsh.completer import Completer\nfrom xonsh.environ import multiline_prompt, format_prompt\n\n\nclass BaseShell(object):\n    \"\"\"The xonsh shell.\"\"\"\n\n    def __init__(self, execer, ctx, **kwargs):\n        super().__init__(**kwargs)\n        self.execer = execer\n        self.ctx = ctx\n        self.completer = Completer()\n        self.buffer = []\n        self.need_more_lines = False\n        self.mlprompt = None\n\n    def emptyline(self):\n        \"\"\"Called when an empty line has been entered.\"\"\"\n        self.need_more_lines = False\n        self.default('')\n\n    def precmd(self, line):\n        \"\"\"Called just before execution of line.\"\"\"\n        return line if self.need_more_lines else line.lstrip()\n\n    def default(self, line):\n        \"\"\"Implements code execution.\"\"\"\n        line = line if line.endswith('\\n') else line + '\\n'\n        code = self.push(line)\n        if code is None:\n            return\n        try:\n            self.execer.exec(code, mode='single', glbs=self.ctx)  # no locals\n        except XonshError as e:\n            print(e.args[0], file=sys.stderr)\n        except:\n            _print_exception()\n        if builtins.__xonsh_exit__:\n            return True\n\n    def push(self, line):\n        \"\"\"Pushes a line onto the buffer and compiles the code in a way that\n        enables multiline input.\n        \"\"\"\n        code = None\n        self.buffer.append(line)\n        if self.need_more_lines:\n            return code\n        src = ''.join(self.buffer)\n        try:\n            code = self.execer.compile(src,\n                                       mode='single',\n                                       glbs=None,\n                                       locs=self.ctx)\n            self.reset_buffer()\n        except SyntaxError:\n            if line == '\\n':\n                self.reset_buffer()\n                _print_exception()\n                return None\n            self.need_more_lines = True\n        except:\n            self.reset_buffer()\n            _print_exception()\n            return None\n        return code\n\n    def reset_buffer(self):\n        \"\"\"Resets the line buffer.\"\"\"\n        self.buffer.clear()\n        self.need_more_lines = False\n        self.mlprompt = None\n\n    def settitle(self):\n        \"\"\"Sets terminal title.\"\"\"\n        env = builtins.__xonsh_env__\n        term = env.get('TERM', None)\n        if term is None or term == 'linux':\n            return\n        if 'TITLE' in env:\n            t = env['TITLE']\n        else:\n            return\n        t = format_prompt(t)\n        if ON_WINDOWS and 'ANSICON' not in env:\n            t = escape_windows_title_string(t)\n            os.system('title {}'.format(t))\n        else:\n            sys.stdout.write(\"\\x1b]2;{0}\\x07\".format(t))\n\n    @property\n    def prompt(self):\n        \"\"\"Obtains the current prompt string.\"\"\"\n        if self.need_more_lines:\n            if self.mlprompt is None:\n                self.mlprompt = multiline_prompt()\n            return self.mlprompt\n        env = builtins.__xonsh_env__\n        if 'PROMPT' in env:\n            p = env['PROMPT']\n            p = format_prompt(p)\n        else:\n            p = \"set '$PROMPT = ...' $ \"\n        self.settitle()\n        return p\n        \ndef _print_exception():\n    \"\"\"Print exceptions with/without traceback.\"\"\"\n    if not 'XONSH_SHOW_TRACEBACK' in builtins.__xonsh_env__:\n        sys.stderr.write('xonsh: For full traceback set: '\n                         '$XONSH_SHOW_TRACEBACK=True\\n')\n    if builtins.__xonsh_env__.get('XONSH_SHOW_TRACEBACK', False):\n        traceback.print_exc()\n    else:\n        exc_type, exc_value, exc_traceback = sys.exc_info()\n        exception_only =  traceback.format_exception_only(exc_type, exc_value)\n        sys.stderr.write(''.join(exception_only))\n", "path": "xonsh/base_shell.py"}]}