Show More
@@ -0,0 +1,104 b'' | |||
|
1 | #!/usr/bin/env python | |
|
2 | # encoding: utf-8 | |
|
3 | """ | |
|
4 | A context manager for managing things injected into :mod:`__builtin__`. | |
|
5 | ||
|
6 | Authors: | |
|
7 | ||
|
8 | * Brian Granger | |
|
9 | """ | |
|
10 | ||
|
11 | #----------------------------------------------------------------------------- | |
|
12 | # Copyright (C) 2008-2009 The IPython Development Team | |
|
13 | # | |
|
14 | # Distributed under the terms of the BSD License. The full license is in | |
|
15 | # the file COPYING, distributed as part of this software. | |
|
16 | #----------------------------------------------------------------------------- | |
|
17 | ||
|
18 | #----------------------------------------------------------------------------- | |
|
19 | # Imports | |
|
20 | #----------------------------------------------------------------------------- | |
|
21 | ||
|
22 | import __builtin__ | |
|
23 | ||
|
24 | from IPython.core.component import Component | |
|
25 | from IPython.core.quitter import Quitter | |
|
26 | ||
|
27 | #----------------------------------------------------------------------------- | |
|
28 | # Classes and functions | |
|
29 | #----------------------------------------------------------------------------- | |
|
30 | ||
|
31 | ||
|
32 | class BuiltinUndefined(object): pass | |
|
33 | BuiltinUndefined = BuiltinUndefined() | |
|
34 | ||
|
35 | ||
|
36 | class BuiltinTrap(Component): | |
|
37 | ||
|
38 | def __init__(self, parent, name=None, config=None): | |
|
39 | super(BuiltinTrap, self).__init__(parent, name, config) | |
|
40 | # Don't just grab parent!!! | |
|
41 | from IPython.core.iplib import InteractiveShell | |
|
42 | self.shell = InteractiveShell.get_instances(root=self.root)[0] | |
|
43 | self._orig_builtins = {} | |
|
44 | ||
|
45 | def __enter__(self): | |
|
46 | self.set() | |
|
47 | # I return self, so callers can use add_builtin in a with clause. | |
|
48 | return self | |
|
49 | ||
|
50 | def __exit__(self, type, value, traceback): | |
|
51 | self.unset() | |
|
52 | return True | |
|
53 | ||
|
54 | def add_builtin(self, key, value): | |
|
55 | """Add a builtin and save the original.""" | |
|
56 | orig = __builtin__.__dict__.get(key, BuiltinUndefined) | |
|
57 | self._orig_builtins[key] = orig | |
|
58 | __builtin__.__dict__[key] = value | |
|
59 | ||
|
60 | def remove_builtin(self, key): | |
|
61 | """Remove an added builtin and re-set the original.""" | |
|
62 | try: | |
|
63 | orig = self._orig_builtins.pop(key) | |
|
64 | except KeyError: | |
|
65 | pass | |
|
66 | else: | |
|
67 | if orig is BuiltinUndefined: | |
|
68 | del __builtin__.__dict__[key] | |
|
69 | else: | |
|
70 | __builtin__.__dict__[key] = orig | |
|
71 | ||
|
72 | def set(self): | |
|
73 | """Store ipython references in the __builtin__ namespace.""" | |
|
74 | self.add_builtin('exit', Quitter(self.shell, 'exit')) | |
|
75 | self.add_builtin('quit', Quitter(self.shell, 'quit')) | |
|
76 | ||
|
77 | # Recursive reload function | |
|
78 | try: | |
|
79 | from IPython.lib import deepreload | |
|
80 | if self.shell.deep_reload: | |
|
81 | self.add_builtin('reload', deepreload.reload) | |
|
82 | else: | |
|
83 | self.add_builtin('dreload', deepreload.reload) | |
|
84 | del deepreload | |
|
85 | except ImportError: | |
|
86 | pass | |
|
87 | ||
|
88 | # Keep in the builtins a flag for when IPython is active. We set it | |
|
89 | # with setdefault so that multiple nested IPythons don't clobber one | |
|
90 | # another. Each will increase its value by one upon being activated, | |
|
91 | # which also gives us a way to determine the nesting level. | |
|
92 | __builtin__.__dict__.setdefault('__IPYTHON__active',0) | |
|
93 | ||
|
94 | def unset(self): | |
|
95 | """Remove any builtins which might have been added by add_builtins, or | |
|
96 | restore overwritten ones to their previous values.""" | |
|
97 | for key in self._orig_builtins.keys(): | |
|
98 | self.remove_builtin(key) | |
|
99 | self._orig_builtins.clear() | |
|
100 | self._builtins_added = False | |
|
101 | try: | |
|
102 | del __builtin__.__dict__['__IPYTHON__active'] | |
|
103 | except KeyError: | |
|
104 | pass No newline at end of file |
@@ -0,0 +1,38 b'' | |||
|
1 | #!/usr/bin/env python | |
|
2 | # encoding: utf-8 | |
|
3 | """ | |
|
4 | A simple class for quitting IPython. | |
|
5 | ||
|
6 | Authors: | |
|
7 | ||
|
8 | * Brian Granger | |
|
9 | """ | |
|
10 | ||
|
11 | #----------------------------------------------------------------------------- | |
|
12 | # Copyright (C) 2008-2009 The IPython Development Team | |
|
13 | # | |
|
14 | # Distributed under the terms of the BSD License. The full license is in | |
|
15 | # the file COPYING, distributed as part of this software. | |
|
16 | #----------------------------------------------------------------------------- | |
|
17 | ||
|
18 | #----------------------------------------------------------------------------- | |
|
19 | # Imports | |
|
20 | #----------------------------------------------------------------------------- | |
|
21 | ||
|
22 | ||
|
23 | class Quitter(object): | |
|
24 | """Simple class to handle exit, similar to Python 2.5's. | |
|
25 | ||
|
26 | It handles exiting in an ipython-safe manner, which the one in Python 2.5 | |
|
27 | doesn't do (obviously, since it doesn't know about ipython).""" | |
|
28 | ||
|
29 | def __init__(self, shell, name): | |
|
30 | self.shell = shell | |
|
31 | self.name = name | |
|
32 | ||
|
33 | def __repr__(self): | |
|
34 | return 'Type %s() to exit.' % self.name | |
|
35 | __str__ = __repr__ | |
|
36 | ||
|
37 | def __call__(self): | |
|
38 | self.shell.exit() No newline at end of file |
@@ -52,15 +52,19 b' class MetaComponentTracker(type):' | |||
|
52 | 52 | When a Component or subclass is instantiated, this is called and |
|
53 | 53 | the instance is saved in a WeakValueDictionary for tracking. |
|
54 | 54 | """ |
|
55 | ||
|
56 | instance = super(MetaComponentTracker, cls).__call__(*args, **kw) | |
|
55 | instance = cls.__new__(cls, *args, **kw) | |
|
56 | # Do this before __init__ is called so get_instances works inside | |
|
57 | # __init__ methods! | |
|
57 | 58 | for c in cls.__mro__: |
|
58 | 59 | if issubclass(cls, c) and issubclass(c, Component): |
|
59 | 60 | c.__numcreated += 1 |
|
60 | 61 | c.__instance_refs[c.__numcreated] = instance |
|
62 | if isinstance(instance, cls): | |
|
63 | cls.__init__(instance, *args, **kw) | |
|
64 | ||
|
61 | 65 | return instance |
|
62 | 66 | |
|
63 | def get_instances(cls, name=None, root=None): | |
|
67 | def get_instances(cls, name=None, root=None, classname=None): | |
|
64 | 68 | """Get all instances of cls and its subclasses. |
|
65 | 69 | |
|
66 | 70 | Parameters |
@@ -69,21 +73,26 b' class MetaComponentTracker(type):' | |||
|
69 | 73 | Limit to components with this name. |
|
70 | 74 | root : Component or subclass |
|
71 | 75 | Limit to components having this root. |
|
76 | classname : str | |
|
77 | The string name of a class to match exactly. | |
|
72 | 78 | """ |
|
73 | 79 | instances = cls.__instance_refs.values() |
|
74 | 80 | if name is not None: |
|
75 | 81 | instances = [i for i in instances if i.name == name] |
|
82 | if classname is not None: | |
|
83 | instances = [i for i in instances if i.__class__.__name__ == classname] | |
|
76 | 84 | if root is not None: |
|
77 | 85 | instances = [i for i in instances if i.root == root] |
|
78 | 86 | return instances |
|
79 | 87 | |
|
80 |
def get_instances_by_condition(cls, call, name=None, root=None |
|
|
88 | def get_instances_by_condition(cls, call, name=None, root=None, | |
|
89 | classname=None): | |
|
81 | 90 | """Get all instances of cls, i such that call(i)==True. |
|
82 | 91 | |
|
83 |
This also takes the ``name`` and ``root`` a |
|
|
84 | :meth:`get_instance` | |
|
92 | This also takes the ``name`` and ``root`` and ``classname`` | |
|
93 | arguments of :meth:`get_instance` | |
|
85 | 94 | """ |
|
86 | return [i for i in cls.get_instances(name, root) if call(i)] | |
|
95 | return [i for i in cls.get_instances(name, root, classname) if call(i)] | |
|
87 | 96 | |
|
88 | 97 | |
|
89 | 98 | class ComponentNameGenerator(object): |
@@ -23,6 +23,8 b' Notes' | |||
|
23 | 23 | # Imports |
|
24 | 24 | #----------------------------------------------------------------------------- |
|
25 | 25 | |
|
26 | from __future__ import with_statement | |
|
27 | ||
|
26 | 28 | import sys |
|
27 | 29 | |
|
28 | 30 | from IPython.core import ultratb |
@@ -63,7 +65,7 b' class InteractiveShellEmbed(InteractiveShell):' | |||
|
63 | 65 | def __init__(self, parent=None, config=None, ipythondir=None, usage=None, |
|
64 | 66 | user_ns=None, user_global_ns=None, |
|
65 | 67 | banner1=None, banner2=None, |
|
66 |
custom_exceptions=((),None), exit_msg= |
|
|
68 | custom_exceptions=((),None), exit_msg=''): | |
|
67 | 69 | |
|
68 | 70 | # First we need to save the state of sys.displayhook and |
|
69 | 71 | # sys.ipcompleter so we can restore it when we are done. |
@@ -172,7 +174,7 b' class InteractiveShellEmbed(InteractiveShell):' | |||
|
172 | 174 | |
|
173 | 175 | # Call the embedding code with a stack depth of 1 so it can skip over |
|
174 | 176 | # our call and get the original caller's namespaces. |
|
175 |
self. |
|
|
177 | self.mainloop(banner, local_ns, global_ns, | |
|
176 | 178 | stack_depth=stack_depth) |
|
177 | 179 | |
|
178 | 180 | if self.exit_msg is not None: |
@@ -182,6 +184,71 b' class InteractiveShellEmbed(InteractiveShell):' | |||
|
182 | 184 | self.restore_sys_displayhook() |
|
183 | 185 | self.restore_sys_ipcompleter() |
|
184 | 186 | |
|
187 | def mainloop(self,header='',local_ns=None,global_ns=None,stack_depth=0): | |
|
188 | """Embeds IPython into a running python program. | |
|
189 | ||
|
190 | Input: | |
|
191 | ||
|
192 | - header: An optional header message can be specified. | |
|
193 | ||
|
194 | - local_ns, global_ns: working namespaces. If given as None, the | |
|
195 | IPython-initialized one is updated with __main__.__dict__, so that | |
|
196 | program variables become visible but user-specific configuration | |
|
197 | remains possible. | |
|
198 | ||
|
199 | - stack_depth: specifies how many levels in the stack to go to | |
|
200 | looking for namespaces (when local_ns and global_ns are None). This | |
|
201 | allows an intermediate caller to make sure that this function gets | |
|
202 | the namespace from the intended level in the stack. By default (0) | |
|
203 | it will get its locals and globals from the immediate caller. | |
|
204 | ||
|
205 | Warning: it's possible to use this in a program which is being run by | |
|
206 | IPython itself (via %run), but some funny things will happen (a few | |
|
207 | globals get overwritten). In the future this will be cleaned up, as | |
|
208 | there is no fundamental reason why it can't work perfectly.""" | |
|
209 | ||
|
210 | # Get locals and globals from caller | |
|
211 | if local_ns is None or global_ns is None: | |
|
212 | call_frame = sys._getframe(stack_depth).f_back | |
|
213 | ||
|
214 | if local_ns is None: | |
|
215 | local_ns = call_frame.f_locals | |
|
216 | if global_ns is None: | |
|
217 | global_ns = call_frame.f_globals | |
|
218 | ||
|
219 | # Update namespaces and fire up interpreter | |
|
220 | ||
|
221 | # The global one is easy, we can just throw it in | |
|
222 | self.user_global_ns = global_ns | |
|
223 | ||
|
224 | # but the user/local one is tricky: ipython needs it to store internal | |
|
225 | # data, but we also need the locals. We'll copy locals in the user | |
|
226 | # one, but will track what got copied so we can delete them at exit. | |
|
227 | # This is so that a later embedded call doesn't see locals from a | |
|
228 | # previous call (which most likely existed in a separate scope). | |
|
229 | local_varnames = local_ns.keys() | |
|
230 | self.user_ns.update(local_ns) | |
|
231 | #self.user_ns['local_ns'] = local_ns # dbg | |
|
232 | ||
|
233 | # Patch for global embedding to make sure that things don't overwrite | |
|
234 | # user globals accidentally. Thanks to Richard <rxe@renre-europe.com> | |
|
235 | # FIXME. Test this a bit more carefully (the if.. is new) | |
|
236 | if local_ns is None and global_ns is None: | |
|
237 | self.user_global_ns.update(__main__.__dict__) | |
|
238 | ||
|
239 | # make sure the tab-completer has the correct frame information, so it | |
|
240 | # actually completes using the frame's locals/globals | |
|
241 | self.set_completer_frame() | |
|
242 | ||
|
243 | with self.builtin_trap: | |
|
244 | self.interact(header) | |
|
245 | ||
|
246 | # now, purge out the user namespace from anything we might have added | |
|
247 | # from the caller's local namespace | |
|
248 | delvar = self.user_ns.pop | |
|
249 | for var in local_varnames: | |
|
250 | delvar(var,None) | |
|
251 | ||
|
185 | 252 | |
|
186 | 253 | _embedded_shell = None |
|
187 | 254 |
@@ -16,6 +16,8 b' Main IPython Component' | |||
|
16 | 16 | # Imports |
|
17 | 17 | #----------------------------------------------------------------------------- |
|
18 | 18 | |
|
19 | from __future__ import with_statement | |
|
20 | ||
|
19 | 21 | import __main__ |
|
20 | 22 | import __builtin__ |
|
21 | 23 | import StringIO |
@@ -38,6 +40,7 b' from IPython.core import shadowns' | |||
|
38 | 40 | from IPython.core import history as ipcorehist |
|
39 | 41 | from IPython.core import prefilter |
|
40 | 42 | from IPython.core.autocall import IPyAutocall |
|
43 | from IPython.core.builtin_trap import BuiltinTrap | |
|
41 | 44 | from IPython.core.fakemodule import FakeModule, init_fakemod_dict |
|
42 | 45 | from IPython.core.logger import Logger |
|
43 | 46 | from IPython.core.magic import Magic |
@@ -112,28 +115,6 b' class SpaceInInput(exceptions.Exception): pass' | |||
|
112 | 115 | |
|
113 | 116 | class Bunch: pass |
|
114 | 117 | |
|
115 | class BuiltinUndefined: pass | |
|
116 | BuiltinUndefined = BuiltinUndefined() | |
|
117 | ||
|
118 | ||
|
119 | class Quitter(object): | |
|
120 | """Simple class to handle exit, similar to Python 2.5's. | |
|
121 | ||
|
122 | It handles exiting in an ipython-safe manner, which the one in Python 2.5 | |
|
123 | doesn't do (obviously, since it doesn't know about ipython).""" | |
|
124 | ||
|
125 | def __init__(self, shell, name): | |
|
126 | self.shell = shell | |
|
127 | self.name = name | |
|
128 | ||
|
129 | def __repr__(self): | |
|
130 | return 'Type %s() to exit.' % self.name | |
|
131 | __str__ = __repr__ | |
|
132 | ||
|
133 | def __call__(self): | |
|
134 | self.shell.exit() | |
|
135 | ||
|
136 | ||
|
137 | 118 | class InputList(list): |
|
138 | 119 | """Class to store user input. |
|
139 | 120 | |
@@ -340,7 +321,6 b' class InteractiveShell(Component, Magic):' | |||
|
340 | 321 | self.hooks.late_startup_hook() |
|
341 | 322 | |
|
342 | 323 | def cleanup(self): |
|
343 | self.remove_builtins() | |
|
344 | 324 | self.restore_sys_module_state() |
|
345 | 325 | |
|
346 | 326 | #------------------------------------------------------------------------- |
@@ -834,10 +814,7 b' class InteractiveShell(Component, Magic):' | |||
|
834 | 814 | self.magic_alias(alias) |
|
835 | 815 | |
|
836 | 816 | def init_builtins(self): |
|
837 | # track which builtins we add, so we can clean up later | |
|
838 | self._orig_builtins = {} | |
|
839 | self._builtins_added = False | |
|
840 | self.add_builtins() | |
|
817 | self.builtin_trap = BuiltinTrap(self) | |
|
841 | 818 | |
|
842 | 819 | def init_shadow_hist(self): |
|
843 | 820 | try: |
@@ -1075,60 +1052,6 b' class InteractiveShell(Component, Magic):' | |||
|
1075 | 1052 | except ImportError: |
|
1076 | 1053 | warn('help() not available - check site.py') |
|
1077 | 1054 | |
|
1078 | def add_builtin(self, key, value): | |
|
1079 | """Add a builtin and save the original.""" | |
|
1080 | orig = __builtin__.__dict__.get(key, BuiltinUndefined) | |
|
1081 | self._orig_builtins[key] = orig | |
|
1082 | __builtin__.__dict__[key] = value | |
|
1083 | ||
|
1084 | def remove_builtin(self, key): | |
|
1085 | """Remove an added builtin and re-set the original.""" | |
|
1086 | try: | |
|
1087 | orig = self._orig_builtins.pop(key) | |
|
1088 | except KeyError: | |
|
1089 | pass | |
|
1090 | else: | |
|
1091 | if orig is BuiltinUndefined: | |
|
1092 | del __builtin__.__dict__[key] | |
|
1093 | else: | |
|
1094 | __builtin__.__dict__[key] = orig | |
|
1095 | ||
|
1096 | def add_builtins(self): | |
|
1097 | """Store ipython references into the __builtin__ namespace. | |
|
1098 | ||
|
1099 | We strive to modify the __builtin__ namespace as little as possible. | |
|
1100 | """ | |
|
1101 | if not self._builtins_added: | |
|
1102 | self.add_builtin('exit', Quitter(self,'exit')) | |
|
1103 | self.add_builtin('quit', Quitter(self,'quit')) | |
|
1104 | ||
|
1105 | # Recursive reload function | |
|
1106 | try: | |
|
1107 | from IPython.lib import deepreload | |
|
1108 | if self.deep_reload: | |
|
1109 | self.add_builtin('reload', deepreload.reload) | |
|
1110 | else: | |
|
1111 | self.add_builtin('dreload', deepreload.reload) | |
|
1112 | del deepreload | |
|
1113 | except ImportError: | |
|
1114 | pass | |
|
1115 | ||
|
1116 | # Keep in the builtins a flag for when IPython is active. We set it | |
|
1117 | # with setdefault so that multiple nested IPythons don't clobber one | |
|
1118 | # another. Each will increase its value by one upon being activated, | |
|
1119 | # which also gives us a way to determine the nesting level. | |
|
1120 | __builtin__.__dict__.setdefault('__IPYTHON__active',0) | |
|
1121 | self._builtins_added = True | |
|
1122 | ||
|
1123 | def remove_builtins(self): | |
|
1124 | """Remove any builtins which might have been added by add_builtins, or | |
|
1125 | restore overwritten ones to their previous values.""" | |
|
1126 | if self._builtins_added: | |
|
1127 | for key in self._orig_builtins.keys(): | |
|
1128 | self.remove_builtin(key) | |
|
1129 | self._orig_builtins.clear() | |
|
1130 | self._builtins_added = False | |
|
1131 | ||
|
1132 | 1055 | def save_sys_module_state(self): |
|
1133 | 1056 | """Save the state of hooks in the sys module. |
|
1134 | 1057 | |
@@ -1328,7 +1251,9 b' class InteractiveShell(Component, Magic):' | |||
|
1328 | 1251 | error("Magic function `%s` not found." % magic_name) |
|
1329 | 1252 | else: |
|
1330 | 1253 | magic_args = self.var_expand(magic_args,1) |
|
1331 | return fn(magic_args) | |
|
1254 | with self.builtin_trap: | |
|
1255 | result = fn(magic_args) | |
|
1256 | return result | |
|
1332 | 1257 | |
|
1333 | 1258 | def define_magic(self, magicname, func): |
|
1334 | 1259 | """Expose own function as magic function for ipython |
@@ -1423,6 +1348,7 b' class InteractiveShell(Component, Magic):' | |||
|
1423 | 1348 | |
|
1424 | 1349 | def ex(self, cmd): |
|
1425 | 1350 | """Execute a normal python statement in user namespace.""" |
|
1351 | with self.builtin_trap: | |
|
1426 | 1352 | exec cmd in self.user_global_ns, self.user_ns |
|
1427 | 1353 | |
|
1428 | 1354 | def ev(self, expr): |
@@ -1430,7 +1356,9 b' class InteractiveShell(Component, Magic):' | |||
|
1430 | 1356 | |
|
1431 | 1357 | Returns the result of evaluation |
|
1432 | 1358 | """ |
|
1433 | return eval(expr, self.user_global_ns, self.user_ns) | |
|
1359 | with self.builtin_trap: | |
|
1360 | result = eval(expr, self.user_global_ns, self.user_ns) | |
|
1361 | return result | |
|
1434 | 1362 | |
|
1435 | 1363 | def getoutput(self, cmd): |
|
1436 | 1364 | return getoutput(self.var_expand(cmd,depth=2), |
@@ -1468,6 +1396,8 b' class InteractiveShell(Component, Magic):' | |||
|
1468 | 1396 | Out[10]: ['x.ljust', 'x.lower', 'x.lstrip'] |
|
1469 | 1397 | """ |
|
1470 | 1398 | |
|
1399 | # Inject names into __builtin__ so we can complete on the added names. | |
|
1400 | with self.builtin_trap: | |
|
1471 | 1401 | complete = self.Completer.complete |
|
1472 | 1402 | state = 0 |
|
1473 | 1403 | # use a dict so we get unique keys, since ipyhton's multiple |
@@ -1875,6 +1805,8 b' class InteractiveShell(Component, Magic):' | |||
|
1875 | 1805 | If an optional banner argument is given, it will override the |
|
1876 | 1806 | internally created default banner. |
|
1877 | 1807 | """ |
|
1808 | ||
|
1809 | with self.builtin_trap: | |
|
1878 | 1810 | if self.c: # Emulate Python's -c option |
|
1879 | 1811 | self.exec_init_cmd() |
|
1880 | 1812 | |
@@ -1909,77 +1841,6 b' class InteractiveShell(Component, Magic):' | |||
|
1909 | 1841 | if not self.interactive: |
|
1910 | 1842 | self.ask_exit() |
|
1911 | 1843 | |
|
1912 | def embed_mainloop(self,header='',local_ns=None,global_ns=None,stack_depth=0): | |
|
1913 | """Embeds IPython into a running python program. | |
|
1914 | ||
|
1915 | Input: | |
|
1916 | ||
|
1917 | - header: An optional header message can be specified. | |
|
1918 | ||
|
1919 | - local_ns, global_ns: working namespaces. If given as None, the | |
|
1920 | IPython-initialized one is updated with __main__.__dict__, so that | |
|
1921 | program variables become visible but user-specific configuration | |
|
1922 | remains possible. | |
|
1923 | ||
|
1924 | - stack_depth: specifies how many levels in the stack to go to | |
|
1925 | looking for namespaces (when local_ns and global_ns are None). This | |
|
1926 | allows an intermediate caller to make sure that this function gets | |
|
1927 | the namespace from the intended level in the stack. By default (0) | |
|
1928 | it will get its locals and globals from the immediate caller. | |
|
1929 | ||
|
1930 | Warning: it's possible to use this in a program which is being run by | |
|
1931 | IPython itself (via %run), but some funny things will happen (a few | |
|
1932 | globals get overwritten). In the future this will be cleaned up, as | |
|
1933 | there is no fundamental reason why it can't work perfectly.""" | |
|
1934 | ||
|
1935 | # Get locals and globals from caller | |
|
1936 | if local_ns is None or global_ns is None: | |
|
1937 | call_frame = sys._getframe(stack_depth).f_back | |
|
1938 | ||
|
1939 | if local_ns is None: | |
|
1940 | local_ns = call_frame.f_locals | |
|
1941 | if global_ns is None: | |
|
1942 | global_ns = call_frame.f_globals | |
|
1943 | ||
|
1944 | # Update namespaces and fire up interpreter | |
|
1945 | ||
|
1946 | # The global one is easy, we can just throw it in | |
|
1947 | self.user_global_ns = global_ns | |
|
1948 | ||
|
1949 | # but the user/local one is tricky: ipython needs it to store internal | |
|
1950 | # data, but we also need the locals. We'll copy locals in the user | |
|
1951 | # one, but will track what got copied so we can delete them at exit. | |
|
1952 | # This is so that a later embedded call doesn't see locals from a | |
|
1953 | # previous call (which most likely existed in a separate scope). | |
|
1954 | local_varnames = local_ns.keys() | |
|
1955 | self.user_ns.update(local_ns) | |
|
1956 | #self.user_ns['local_ns'] = local_ns # dbg | |
|
1957 | ||
|
1958 | # Patch for global embedding to make sure that things don't overwrite | |
|
1959 | # user globals accidentally. Thanks to Richard <rxe@renre-europe.com> | |
|
1960 | # FIXME. Test this a bit more carefully (the if.. is new) | |
|
1961 | if local_ns is None and global_ns is None: | |
|
1962 | self.user_global_ns.update(__main__.__dict__) | |
|
1963 | ||
|
1964 | # make sure the tab-completer has the correct frame information, so it | |
|
1965 | # actually completes using the frame's locals/globals | |
|
1966 | self.set_completer_frame() | |
|
1967 | ||
|
1968 | # before activating the interactive mode, we need to make sure that | |
|
1969 | # all names in the builtin namespace needed by ipython point to | |
|
1970 | # ourselves, and not to other instances. | |
|
1971 | self.add_builtins() | |
|
1972 | ||
|
1973 | self.interact(header) | |
|
1974 | ||
|
1975 | # now, purge out the user namespace from anything we might have added | |
|
1976 | # from the caller's local namespace | |
|
1977 | delvar = self.user_ns.pop | |
|
1978 | for var in local_varnames: | |
|
1979 | delvar(var,None) | |
|
1980 | # and clean builtins we may have overridden | |
|
1981 | self.remove_builtins() | |
|
1982 | ||
|
1983 | 1844 | def interact_prompt(self): |
|
1984 | 1845 | """ Print the prompt (in read-eval-print loop) |
|
1985 | 1846 | |
@@ -2377,6 +2238,7 b' class InteractiveShell(Component, Magic):' | |||
|
2377 | 2238 | lines = lines.splitlines() |
|
2378 | 2239 | more = 0 |
|
2379 | 2240 | |
|
2241 | with self.builtin_trap: | |
|
2380 | 2242 | for line in lines: |
|
2381 | 2243 | # skip blank lines so we don't mess up the prompt counter, but do |
|
2382 | 2244 | # NOT skip even a blank line if we are in a code block (more is |
General Comments 0
You need to be logged in to leave comments.
Login now