##// END OF EJS Templates
Fix embedding terminal IPython with new namespace model.
Thomas Kluyver -
Show More
@@ -72,13 +72,13 b' class InteractiveShellEmbed(TerminalInteractiveShell):'
72 display_banner = CBool(True)
72 display_banner = CBool(True)
73
73
74 def __init__(self, config=None, ipython_dir=None, user_ns=None,
74 def __init__(self, config=None, ipython_dir=None, user_ns=None,
75 user_global_ns=None, custom_exceptions=((),None),
75 user_module=None, custom_exceptions=((),None),
76 usage=None, banner1=None, banner2=None,
76 usage=None, banner1=None, banner2=None,
77 display_banner=None, exit_msg=u''):
77 display_banner=None, exit_msg=u''):
78
78
79 super(InteractiveShellEmbed,self).__init__(
79 super(InteractiveShellEmbed,self).__init__(
80 config=config, ipython_dir=ipython_dir, user_ns=user_ns,
80 config=config, ipython_dir=ipython_dir, user_ns=user_ns,
81 user_global_ns=user_global_ns, custom_exceptions=custom_exceptions,
81 user_module=user_module, custom_exceptions=custom_exceptions,
82 usage=usage, banner1=banner1, banner2=banner2,
82 usage=usage, banner1=banner1, banner2=banner2,
83 display_banner=display_banner
83 display_banner=display_banner
84 )
84 )
@@ -95,7 +95,7 b' class InteractiveShellEmbed(TerminalInteractiveShell):'
95 def init_sys_modules(self):
95 def init_sys_modules(self):
96 pass
96 pass
97
97
98 def __call__(self, header='', local_ns=None, global_ns=None, dummy=None,
98 def __call__(self, header='', local_ns=None, module=None, dummy=None,
99 stack_depth=1):
99 stack_depth=1):
100 """Activate the interactive interpreter.
100 """Activate the interactive interpreter.
101
101
@@ -140,14 +140,14 b' class InteractiveShellEmbed(TerminalInteractiveShell):'
140
140
141 # Call the embedding code with a stack depth of 1 so it can skip over
141 # Call the embedding code with a stack depth of 1 so it can skip over
142 # our call and get the original caller's namespaces.
142 # our call and get the original caller's namespaces.
143 self.mainloop(local_ns, global_ns, stack_depth=stack_depth)
143 self.mainloop(local_ns, module, stack_depth=stack_depth)
144
144
145 self.banner2 = self.old_banner2
145 self.banner2 = self.old_banner2
146
146
147 if self.exit_msg is not None:
147 if self.exit_msg is not None:
148 print self.exit_msg
148 print self.exit_msg
149
149
150 def mainloop(self, local_ns=None, global_ns=None, stack_depth=0,
150 def mainloop(self, local_ns=None, module=None, stack_depth=0,
151 display_banner=None):
151 display_banner=None):
152 """Embeds IPython into a running python program.
152 """Embeds IPython into a running python program.
153
153
@@ -172,32 +172,37 b' class InteractiveShellEmbed(TerminalInteractiveShell):'
172 there is no fundamental reason why it can't work perfectly."""
172 there is no fundamental reason why it can't work perfectly."""
173
173
174 # Get locals and globals from caller
174 # Get locals and globals from caller
175 if local_ns is None or global_ns is None:
175 if local_ns is None or module is None:
176 call_frame = sys._getframe(stack_depth).f_back
176 call_frame = sys._getframe(stack_depth).f_back
177
177
178 if local_ns is None:
178 if local_ns is None:
179 local_ns = call_frame.f_locals
179 local_ns = call_frame.f_locals
180 if global_ns is None:
180 if module is None:
181 global_ns = call_frame.f_globals
181 global_ns = call_frame.f_globals
182
182 module = sys.modules[global_ns['__name__']]
183
184 # Save original namespace and module so we can restore them after
185 # embedding; otherwise the shell doesn't shut down correctly.
186 orig_user_module = self.user_module
187 orig_user_ns = self.user_ns
188
183 # Update namespaces and fire up interpreter
189 # Update namespaces and fire up interpreter
184
190
185 # The global one is easy, we can just throw it in
191 # The global one is easy, we can just throw it in
186 self.user_global_ns = global_ns
192 self.user_module = module
187
193
188 # but the user/local one is tricky: ipython needs it to store internal
194 # But the user/local one is tricky: ipython needs it to store internal
189 # data, but we also need the locals. We'll copy locals in the user
195 # data, but we also need the locals. We'll throw our hidden variables
190 # one, but will track what got copied so we can delete them at exit.
196 # like _ih and get_ipython() into the local namespace, but delete them
191 # This is so that a later embedded call doesn't see locals from a
197 # later.
192 # previous call (which most likely existed in a separate scope).
198 self.user_ns = local_ns
193 local_varnames = local_ns.keys()
199 self.init_user_ns()
194 self.user_ns.update(local_ns)
195 #self.user_ns['local_ns'] = local_ns # dbg
196
200
197 # Patch for global embedding to make sure that things don't overwrite
201 # Patch for global embedding to make sure that things don't overwrite
198 # user globals accidentally. Thanks to Richard <rxe@renre-europe.com>
202 # user globals accidentally. Thanks to Richard <rxe@renre-europe.com>
199 # FIXME. Test this a bit more carefully (the if.. is new)
203 # FIXME. Test this a bit more carefully (the if.. is new)
200 if local_ns is None and global_ns is None:
204 # N.B. This can't now ever be called. Not sure what it was for.
205 if local_ns is None and module is None:
201 self.user_global_ns.update(__main__.__dict__)
206 self.user_global_ns.update(__main__.__dict__)
202
207
203 # make sure the tab-completer has the correct frame information, so it
208 # make sure the tab-completer has the correct frame information, so it
@@ -206,13 +211,14 b' class InteractiveShellEmbed(TerminalInteractiveShell):'
206
211
207 with nested(self.builtin_trap, self.display_trap):
212 with nested(self.builtin_trap, self.display_trap):
208 self.interact(display_banner=display_banner)
213 self.interact(display_banner=display_banner)
209
214
210 # now, purge out the user namespace from anything we might have added
215 # now, purge out the local namespace of IPython's hidden variables.
211 # from the caller's local namespace
216 for name in self.user_ns_hidden:
212 delvar = self.user_ns.pop
217 local_ns.pop(name, None)
213 for var in local_varnames:
218
214 delvar(var,None)
219 # Restore original namespace so shell can shut down when we exit.
215
220 self.user_module = orig_user_module
221 self.user_ns = orig_user_ns
216
222
217 _embedded_shell = None
223 _embedded_shell = None
218
224
General Comments 0
You need to be logged in to leave comments. Login now