4

EDIT I isolated a real minimal example which does not work (it is a part of more complex code); the culprit is the inputhook part after all:

def foo():
    exec 'a=123' in globals()
    from IPython.frontend.terminal.embed import InteractiveShellEmbed
    ipshell=InteractiveShellEmbed()
    ipshell()

# without inputhook, 'a' is found just fine
import IPython.lib.inputhook
IPython.lib.inputhook.enable_gui(gui='qt4')

foo()

Running with 0.12:

In [1]: a
---------------------------------------------------------------------------
NameError                                 Traceback (most recent call last)
/tmp/<ipython-input-1-60b725f10c9c> in <module>()
----> 1 a

NameError: name 'a' is not defined

What would be the way around?

eudoxos
  • 18,545
  • 10
  • 61
  • 110
  • It seems to work in the development version - maybe there was a bug with 0.12 that has been fixed. – Thomas K Mar 26 '12 at 16:54
  • @ThomasK: I had to complicate the example to make it really non-working. It is related to the qt4 inputhook; it used to work fine with 0.11. – eudoxos Mar 26 '12 at 19:12

1 Answers1

2

The problem is due to this call to InteractiveShell.instance() in the qt integration, when called before IPython is initialized. If this is called before your embedded shell is created, then some assumptions are not met. The fix is to create your embedded shell object first, then you shouldn't have any issue. And you can retrieve the same object from anywhere else in your code by simply calling InteractiveShellEmbed.instance().

This version should work just fine, by creating the InteractiveShellEmbed instance first:

from IPython.frontend.terminal.embed import InteractiveShellEmbed
# create ipshell *before* calling enable_gui
# it is important that you use instance(), instead of the class
# constructor, so that it creates the global InteractiveShell singleton
ipshell = InteractiveShellEmbed.instance()

import IPython.lib.inputhook
IPython.lib.inputhook.enable_gui(gui='tk')

def foo():
    # without inputhook, 'a' is found just fine
    exec 'a=123' in globals()
    # all calls to instance() will always return the same object
    ipshell = InteractiveShellEmbed.instance()
    ipshell()

foo()
minrk
  • 37,545
  • 9
  • 92
  • 87
  • Very nice. I discovered one more problem, however. I am importing a larger package with `from yade import *`; doing so (whether before or after creating the shell instance) results in error again (`a` is not defined). It internally calls `PyEval_InitThreads` and bunch of other things. What could be a possible interference there? – eudoxos Mar 27 '12 at 10:44
  • OK, the problem seemed to be related to circular imports or something similar; works now just fine. – eudoxos Mar 27 '12 at 10:53
  • @minrk Could we also use the ``user_ns`` option when initiating the IPython shell? – osolmaz May 18 '14 at 19:52