##// END OF EJS Templates
Removed shell.py entirely and made the embedded shell a proper subclass....
Brian Granger -
Show More
@@ -0,0 +1,176 b''
1 #!/usr/bin/env python
2 # encoding: utf-8
3 """
4 An embedded IPython shell.
5
6 Authors:
7
8 * Brian Granger
9 * Fernando Perez
10
11 Notes
12 -----
13 """
14
15 #-----------------------------------------------------------------------------
16 # Copyright (C) 2008-2009 The IPython Development Team
17 #
18 # Distributed under the terms of the BSD License. The full license is in
19 # the file COPYING, distributed as part of this software.
20 #-----------------------------------------------------------------------------
21
22 #-----------------------------------------------------------------------------
23 # Imports
24 #-----------------------------------------------------------------------------
25
26 import sys
27
28 from IPython.core import ultratb
29 from IPython.core.iplib import InteractiveShell
30
31 from IPython.utils.traitlets import Bool, Str
32 from IPython.utils.genutils import ask_yes_no
33
34 #-----------------------------------------------------------------------------
35 # Classes and functions
36 #-----------------------------------------------------------------------------
37
38 # This is an additional magic that is exposed in embedded shells.
39 def kill_embedded(self,parameter_s=''):
40 """%kill_embedded : deactivate for good the current embedded IPython.
41
42 This function (after asking for confirmation) sets an internal flag so that
43 an embedded IPython will never activate again. This is useful to
44 permanently disable a shell that is being called inside a loop: once you've
45 figured out what you needed from it, you may then kill it and the program
46 will then continue to run without the interactive shell interfering again.
47 """
48
49 kill = ask_yes_no("Are you sure you want to kill this embedded instance "
50 "(y/n)? [y/N] ",'n')
51 if kill:
52 self.embedded_active = False
53 print "This embedded IPython will not reactivate anymore once you exit."
54
55
56 class InteractiveShellEmbed(InteractiveShell):
57
58 dummy_mode = Bool(False)
59 exit_msg = Str('')
60
61 def __init__(self, parent=None, config=None, usage=None,
62 user_ns=None, user_global_ns=None,
63 banner1='', banner2='',
64 custom_exceptions=((),None), exit_msg=''):
65
66 # First we need to save the state of sys.displayhook and
67 # sys.ipcompleter so we can restore it when we are done.
68 self.save_sys_displayhook()
69 self.save_sys_ipcompleter()
70
71 super(InteractiveShellEmbed,self).__init__(
72 parent=parent, config=config, usage=usage,
73 user_ns=user_ns, user_global_ns=user_global_ns,
74 banner1=banner1, banner2=banner2,
75 custom_exceptions=custom_exceptions, embedded=True)
76
77 self.save_sys_displayhook_embed()
78 self.exit_msg = exit_msg
79 self.define_magic("kill_embedded", kill_embedded)
80
81 # don't use the ipython crash handler so that user exceptions aren't
82 # trapped
83 sys.excepthook = ultratb.FormattedTB(color_scheme = self.colors,
84 mode = self.xmode,
85 call_pdb = self.pdb)
86
87 self.restore_sys_displayhook()
88 self.restore_sys_ipcompleter()
89
90 def save_sys_displayhook(self):
91 # sys.displayhook is a global, we need to save the user's original
92 # Don't rely on __displayhook__, as the user may have changed that.
93 self.sys_displayhook_orig = sys.displayhook
94
95 def save_sys_ipcompleter(self):
96 """Save readline completer status."""
97 try:
98 #print 'Save completer',sys.ipcompleter # dbg
99 self.sys_ipcompleter_orig = sys.ipcompleter
100 except:
101 pass # not nested with IPython
102
103 def restore_sys_displayhook(self):
104 sys.displayhook = self.sys_displayhook_orig
105
106 def restore_sys_ipcompleter(self):
107 """Restores the readline completer which was in place.
108
109 This allows embedded IPython within IPython not to disrupt the
110 parent's completion.
111 """
112 try:
113 self.readline.set_completer(self.sys_ipcompleter_orig)
114 sys.ipcompleter = self.sys_ipcompleter_orig
115 except:
116 pass
117
118 def save_sys_displayhook_embed(self):
119 self.sys_displayhook_embed = sys.displayhook
120
121 def restore_sys_displayhook_embed(self):
122 sys.displayhook = self.sys_displayhook_embed
123
124 def __call__(self, header='', local_ns=None, global_ns=None, dummy=None):
125 """Activate the interactive interpreter.
126
127 __call__(self,header='',local_ns=None,global_ns,dummy=None) -> Start
128 the interpreter shell with the given local and global namespaces, and
129 optionally print a header string at startup.
130
131 The shell can be globally activated/deactivated using the
132 set/get_dummy_mode methods. This allows you to turn off a shell used
133 for debugging globally.
134
135 However, *each* time you call the shell you can override the current
136 state of dummy_mode with the optional keyword parameter 'dummy'. For
137 example, if you set dummy mode on with IPShell.set_dummy_mode(1), you
138 can still have a specific call work by making it as IPShell(dummy=0).
139
140 The optional keyword parameter dummy controls whether the call
141 actually does anything.
142 """
143
144 # If the user has turned it off, go away
145 if not self.embedded_active:
146 return
147
148 # Normal exits from interactive mode set this flag, so the shell can't
149 # re-enter (it checks this variable at the start of interactive mode).
150 self.exit_now = False
151
152 # Allow the dummy parameter to override the global __dummy_mode
153 if dummy or (dummy != 0 and self.dummy_mode):
154 return
155
156 self.restore_sys_displayhook_embed()
157
158 if self.has_readline:
159 self.set_completer()
160
161 if self.banner and header:
162 format = '%s\n%s\n'
163 else:
164 format = '%s%s\n'
165 banner = format % (self.banner,header)
166
167 # Call the embedding code with a stack depth of 1 so it can skip over
168 # our call and get the original caller's namespaces.
169 self.embed_mainloop(banner, local_ns, global_ns, stack_depth=1)
170
171 if self.exit_msg:
172 print self.exit_msg
173
174 # Restore global systems (display, completion)
175 self.restore_sys_displayhook()
176 self.restore_sys_ipcompleter()
@@ -19,11 +19,24 b' the new code in IPython.core.shell.'
19 from warnings import warn
19 from warnings import warn
20
20
21 msg = """
21 msg = """
22 This module (IPython.Shell) has been moved to a new location
22 This module (IPython.Shell) is deprecated. The classes that were in this
23 (IPython.core.shell) and is being refactored. Please update your code
23 module have been replaced by:
24 to use the new IPython.core.shell module"""
24
25 IPShell->IPython.core.iplib.InteractiveShell
26 IPShellEmbed->IPython.core.embed.InteractiveShellEmbed
27
28 Please migrate your code to use these classes instead.
29 """
25
30
26 warn(msg, category=DeprecationWarning, stacklevel=1)
31 warn(msg, category=DeprecationWarning, stacklevel=1)
27
32
28 from IPython.core.shell import start, IPShell, IPShellEmbed
33 from IPython.core.iplib import InteractiveShell as IPShell
34 from IPython.core.embed import InteractiveShellEmbed as IPShellEmbed
35
36 def start(user_ns=None, embedded=False):
37 """Return an instance of :class:`InteractiveShell`."""
38 if embedded:
39 return InteractiveShellEmbed(user_ns=user_ns)
40 else:
41 return InteractiveShell(user_ns=user_ns)
29
42
@@ -34,9 +34,6 b" if sys.version[0:3] < '2.4':"
34 # Therefore, non-IPython modules can be added to extensions directory
34 # Therefore, non-IPython modules can be added to extensions directory
35 sys.path.append(os.path.join(os.path.dirname(__file__), "extensions"))
35 sys.path.append(os.path.join(os.path.dirname(__file__), "extensions"))
36
36
37
38 # from IPython.core import shell
39 # Shell = shell
40 from IPython.core import iplib
37 from IPython.core import iplib
41
38
42
39
@@ -29,20 +29,11 b' Authors:'
29
29
30 from IPython.core.error import TryNext, UsageError
30 from IPython.core.error import TryNext, UsageError
31 from IPython.core.component import Component
31 from IPython.core.component import Component
32 from warnings import warn
33
32
34 #-----------------------------------------------------------------------------
33 #-----------------------------------------------------------------------------
35 # Classes and functions
34 # Classes and functions
36 #-----------------------------------------------------------------------------
35 #-----------------------------------------------------------------------------
37
36
38 msg = """
39 This module (IPython.core.ipapi) is being deprecated. For now, all we
40 offer here is the ``get`` function for getting the most recently created
41 InteractiveShell instance."""
42
43 warn(msg, category=DeprecationWarning, stacklevel=1)
44
45
46 def get():
37 def get():
47 """Get the most recently created InteractiveShell instance."""
38 """Get the most recently created InteractiveShell instance."""
48 insts = Component.get_instances(name='__IP')
39 insts = Component.get_instances(name='__IP')
@@ -50,7 +41,13 b' def get():'
50 for inst in insts[1:]:
41 for inst in insts[1:]:
51 if inst.created > most_recent.created:
42 if inst.created > most_recent.created:
52 most_recent = inst
43 most_recent = inst
53 return most_recent.getapi()
44 return most_recent
45
46 def launch_new_instance():
47 """Create a run a full blown IPython instance"""
48 from IPython.core.ipapp import IPythonApp
49 app = IPythonApp()
50 app.start()
54
51
55
52
56
53
@@ -304,7 +304,6 b' class IPythonApp(Application):'
304
304
305 # Create an InteractiveShell instance
305 # Create an InteractiveShell instance
306 self.shell = InteractiveShell(
306 self.shell = InteractiveShell(
307 name='__IP',
308 parent=None,
307 parent=None,
309 config=self.master_config
308 config=self.master_config
310 )
309 )
@@ -294,16 +294,16 b' class InteractiveShell(Component, Magic):'
294 # Subclasses with thread support should override this as needed.
294 # Subclasses with thread support should override this as needed.
295 isthreaded = False
295 isthreaded = False
296
296
297 def __init__(self, name, parent=None, config=None, usage=None,
297 def __init__(self, parent=None, config=None, usage=None,
298 user_ns=None, user_global_ns=None,
298 user_ns=None, user_global_ns=None,
299 banner1='', banner2='',
299 banner1=None, banner2=None,
300 custom_exceptions=((),None), embedded=False):
300 custom_exceptions=((),None), embedded=False):
301
301
302 # This is where traitlets with a config_key argument are updated
302 # This is where traitlets with a config_key argument are updated
303 # from the values on config.
303 # from the values on config.
304 # Ideally, from here on out, the config should only be used when
304 # Ideally, from here on out, the config should only be used when
305 # passing it to children components.
305 # passing it to children components.
306 super(InteractiveShell, self).__init__(parent, config=config, name=name)
306 super(InteractiveShell, self).__init__(parent, config=config, name='__IP')
307
307
308 self.init_instance_attrs()
308 self.init_instance_attrs()
309 self.init_term_title()
309 self.init_term_title()
@@ -423,9 +423,9 b' class InteractiveShell(Component, Magic):'
423 def init_banner(self, banner1, banner2):
423 def init_banner(self, banner1, banner2):
424 if self.c: # regular python doesn't print the banner with -c
424 if self.c: # regular python doesn't print the banner with -c
425 self.display_banner = False
425 self.display_banner = False
426 if banner1:
426 if banner1 is not None:
427 self.banner1 = banner1
427 self.banner1 = banner1
428 if banner2:
428 if banner2 is not None:
429 self.banner2 = banner2
429 self.banner2 = banner2
430 self.compute_banner()
430 self.compute_banner()
431
431
@@ -1066,10 +1066,10 b' class InteractiveShell(Component, Magic):'
1066 warn('help() not available - check site.py')
1066 warn('help() not available - check site.py')
1067
1067
1068 def add_builtins(self):
1068 def add_builtins(self):
1069 """Store ipython references into the builtin namespace.
1069 """Store ipython references into the __builtin__ namespace.
1070
1070
1071 Some parts of ipython operate via builtins injected here, which hold a
1071 We strive to modify the __builtin__ namespace as little as possible.
1072 reference to IPython itself."""
1072 """
1073
1073
1074 # Install our own quitter instead of the builtins.
1074 # Install our own quitter instead of the builtins.
1075 # This used to be in the __init__ method, but this is a better
1075 # This used to be in the __init__ method, but this is a better
@@ -1088,25 +1088,7 b' class InteractiveShell(Component, Magic):'
1088 del deepreload
1088 del deepreload
1089 except ImportError:
1089 except ImportError:
1090 pass
1090 pass
1091
1091
1092 # TODO: deprecate all of these, they are unsafe. Why though?
1093 builtins_new = dict(__IPYTHON__ = self,
1094 ip_set_hook = self.set_hook,
1095 jobs = self.jobs,
1096 # magic = self.magic,
1097 ipalias = wrap_deprecated(self.ipalias),
1098 # ipsystem = wrap_deprecated(self.ipsystem,'_ip.system()'),
1099 )
1100 for biname,bival in builtins_new.items():
1101 try:
1102 # store the orignal value so we can restore it
1103 self.builtins_added[biname] = __builtin__.__dict__[biname]
1104 except KeyError:
1105 # or mark that it wasn't defined, and we'll just delete it at
1106 # cleanup
1107 self.builtins_added[biname] = Undefined
1108 __builtin__.__dict__[biname] = bival
1109
1110 # Keep in the builtins a flag for when IPython is active. We set it
1092 # Keep in the builtins a flag for when IPython is active. We set it
1111 # with setdefault so that multiple nested IPythons don't clobber one
1093 # with setdefault so that multiple nested IPythons don't clobber one
1112 # another. Each will increase its value by one upon being activated,
1094 # another. Each will increase its value by one upon being activated,
@@ -25,5 +25,5 b' to use the new IPython.core.ipapi module"""'
25
25
26 warn(msg, category=DeprecationWarning, stacklevel=1)
26 warn(msg, category=DeprecationWarning, stacklevel=1)
27
27
28 from IPython.core.ipapi import get
28 from IPython.core.ipapi import get, launch_new_instance
29
29
@@ -23,7 +23,6 b' this mode, there is no way to pass IPython any command-line options, as those'
23 are trapped first by Python itself.
23 are trapped first by Python itself.
24 """
24 """
25
25
26 import IPython.core.ipapp import IPythonApp
26 import IPython.core.ipapi import launch_new_instance
27
27
28 app = IPythonApp()
28 launch_new_instance()
29 app.start()
1 NO CONTENT: file was removed
NO CONTENT: file was removed
General Comments 0
You need to be logged in to leave comments. Login now