IPython.embed() from ipython crashes twice on exit #676

juliantaylor opened this Issue Aug 4, 2011 · 9 comments

4 participants


when starting an embeded ipython shell from within ipython it crashes when you quit ipython

   $ ipython
   >> from IPython import embed
   >> embed()
   .. embedded shell
   >>>> exit
   >> exit
   -> crash

it crashes twice
first crash:

usr/lib/python2.7/dist-packages/IPython/frontend/terminal/interactiveshell.pyc in interact(self=<IPython.frontend.terminal.interactiveshell.TerminalInteractiveShell object>, display_banner=False)
    300             except:
    301                 # exceptions here are VERY RARE, but they can be triggered
    302                 # asynchronously by signal handlers, for example.
    303                 self.showtraceback()
    304             else:
    305                 self.input_splitter.push(line)
    306                 more = self.input_splitter.push_accepts_more()
    307                 if (self.SyntaxTB.last_syntax_error and
    308                     self.autoedit_syntax):
    309                     self.edit_syntax_error()
    310                 if not more:
    311                     source_raw = self.input_splitter.source_raw_reset()[1]
    312                     self.run_cell(source_raw)
    314         # We are off again...
--> 315         __builtin__.__dict__['__IPYTHON__active'] -= 1
    317         # Turn off the exit flag, so the mainloop can be restarted if desired
    318         self.exit_now = False
    320     def raw_input(self, prompt=''):
    321         """Write a prompt and read a line.
    323         The returned line does not include the trailing newline.
    324         When the user enters the EOF key sequence, EOFError is raised.
    326         Optional inputs:
    328           - prompt(''): a string to be printed to prompt the user.
    330           - continue_prompt(False): whether this line is the first one or a

KeyError: '__IPYTHON__active'

second crash, follows the first:

/usr/lib/python2.7/dist-packages/IPython/core/displayhook.pyc in flush(self=<IPython.core.displayhook.DisplayHook object>)
    304             self.update_user_ns(result)
    305             self.log_output(format_dict)
    306             self.finish_displayhook()
    308     def flush(self):
    309         if not self.do_full_cache:
    310             raise ValueError,"You shouldn't have reached the cache flush "\
    311                   "if full caching is not enabled!"
    312         # delete auto-generated vars from global namespace
    314         for n in range(1,self.prompt_count + 1):
    315             key = '_'+`n`
    316             try:
    317                 del self.shell.user_ns[key]
    318             except: pass
--> 319         self.shell.user_ns['_oh'].clear()
    321         # Release our own references to objects:
    322         self._, self.__, self.___ = '', '', ''
    324         if '_' not in __builtin__.__dict__:
    325             self.shell.user_ns.update({'_':None,'__':None, '___':None})
    326         import gc
    327         # TODO: Is this really needed?
    328         gc.collect()

KeyError: '_oh'
IPython member

For the time being, running IPython inside IPython is a bad idea. If you run any commands inside the inner IPython, it will also complain about collisions in your history.

IPython member

@takluyver - it's easy to detect that embed is being called from inside IPython. Should we warn (or raise) in that case for now?

IPython member

I don't know what the best route is. It also applies to using InteractiveShell.instance(). Ideally, we would make InteractiveShell not a singleton, so you could have several running in the same interpreter. Until then, it might be a good idea to block (or warn on) attempts to nest shells.

IPython member

Yes, we definitely intend to fix this, but while it doesn't work we should probably have preemptive RuntimeErrors or at least warnings.

How does this affect InteractiveShell.instance()? That will always return the same shell instance. ip = InteractiveShell.instance() is identical to ip = get_ipython() for now at least, while it is a singleton.

IPython member

Sorry, I didn't explain that properly. It (at least, the history problem) applies to getting the instance of InteractiveShell and then running commands inside it. Although there's not much we can do about that, I guess.

IPython member

ah, right. Just like calling ip = get_ipython(); ip.run_cell(code). No, there's nothing much we can do about that. Since that is the most likely cause for the history session error, we could add some explanation to that message.

IPython member

I've been considering whether we should make store_history default to False for run_cell, so it's harder to run into this problem accidentally. It would require tweaks for things like sphinx_directive, though.

IPython member

Not a bad idea.

IPython member

Now that we've cleaned up the __IPYTHON__active stuff, the only remaining crash is the one with history:

Error in sys.exitfunc:
Traceback (most recent call last):
  File "/usr/lib/python2.7/atexit.py", line 24, in _run_exitfuncs
    func(*targs, **kargs)
  File "/home/fperez/usr/lib/python2.7/site-packages/IPython/core/interactiveshell.py", line 2733, in atexit_operations
  File "/home/fperez/usr/lib/python2.7/site-packages/IPython/core/interactiveshell.py", line 1126, in reset
  File "/home/fperez/usr/lib/python2.7/site-packages/IPython/core/displayhook.py", line 255, in flush
KeyError: '_oh'

Not high priority, but definitely a bug we should be able to fix eventually. Moving to 0.13.

@minrk minrk closed this in db762d9 Mar 16, 2012
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment