How to implement ipython 0.12 so that it inherits the namespace of the caller?

EDIT I have isolated a real minimal example that does not work (it is part of more complex code); the culprit is the input 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() 

Starting from 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 will be the way?

+4
source share
1 answer

The problem is this call to InteractiveShell.instance() in qt integration when called before initializing IPython. If this is called before the inline shell is created, some assumptions are not fulfilled. The fix is ​​to first create an inline shell object, then you shouldn't have a problem. And you can get the same object from anywhere in your code simply by calling InteractiveShellEmbed.instance() .

This version should work fine by first creating an InteractiveShellEmbed instance:

 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() 
+2
source

Source: https://habr.com/ru/post/1403461/


All Articles