##// END OF EJS Templates
Use str.format instead of Itpl in crash handler.
Thomas Kluyver -
Show More
@@ -1,179 +1,180 b''
1 # encoding: utf-8
1 # encoding: utf-8
2 """sys.excepthook for IPython itself, leaves a detailed report on disk.
2 """sys.excepthook for IPython itself, leaves a detailed report on disk.
3
3
4 Authors:
4 Authors:
5
5
6 * Fernando Perez
6 * Fernando Perez
7 * Brian E. Granger
7 * Brian E. Granger
8 """
8 """
9
9
10 #-----------------------------------------------------------------------------
10 #-----------------------------------------------------------------------------
11 # Copyright (C) 2001-2007 Fernando Perez. <fperez@colorado.edu>
11 # Copyright (C) 2001-2007 Fernando Perez. <fperez@colorado.edu>
12 # Copyright (C) 2008-2010 The IPython Development Team
12 # Copyright (C) 2008-2010 The IPython Development Team
13 #
13 #
14 # Distributed under the terms of the BSD License. The full license is in
14 # Distributed under the terms of the BSD License. The full license is in
15 # the file COPYING, distributed as part of this software.
15 # the file COPYING, distributed as part of this software.
16 #-----------------------------------------------------------------------------
16 #-----------------------------------------------------------------------------
17
17
18 #-----------------------------------------------------------------------------
18 #-----------------------------------------------------------------------------
19 # Imports
19 # Imports
20 #-----------------------------------------------------------------------------
20 #-----------------------------------------------------------------------------
21
21
22 import os
22 import os
23 import sys
23 import sys
24 from pprint import pformat
24 from pprint import pformat
25
25
26 from IPython.core import ultratb
26 from IPython.core import ultratb
27 from IPython.external.Itpl import itpl
28 from IPython.utils.sysinfo import sys_info
27 from IPython.utils.sysinfo import sys_info
29
28
30 #-----------------------------------------------------------------------------
29 #-----------------------------------------------------------------------------
31 # Code
30 # Code
32 #-----------------------------------------------------------------------------
31 #-----------------------------------------------------------------------------
33
32
34 # Template for the user message.
33 # Template for the user message.
35 _default_message_template = """\
34 _default_message_template = """\
36 Oops, $self.app_name crashed. We do our best to make it stable, but...
35 Oops, {app_name} crashed. We do our best to make it stable, but...
37
36
38 A crash report was automatically generated with the following information:
37 A crash report was automatically generated with the following information:
39 - A verbatim copy of the crash traceback.
38 - A verbatim copy of the crash traceback.
40 - A copy of your input history during this session.
39 - A copy of your input history during this session.
41 - Data on your current $self.app_name configuration.
40 - Data on your current $self.app_name configuration.
42
41
43 It was left in the file named:
42 It was left in the file named:
44 \t'$self.crash_report_fname'
43 \t'{crash_report_fname}'
45 If you can email this file to the developers, the information in it will help
44 If you can email this file to the developers, the information in it will help
46 them in understanding and correcting the problem.
45 them in understanding and correcting the problem.
47
46
48 You can mail it to: $self.contact_name at $self.contact_email
47 You can mail it to: $self.contact_name at {contact_email}
49 with the subject '$self.app_name Crash Report'.
48 with the subject '{app_name} Crash Report'.
50
49
51 If you want to do it now, the following command will work (under Unix):
50 If you want to do it now, the following command will work (under Unix):
52 mail -s '$self.app_name Crash Report' $self.contact_email < $self.crash_report_fname
51 mail -s '{app_name} Crash Report' {contact_email} < {crash_report_fname}
53
52
54 To ensure accurate tracking of this issue, please file a report about it at:
53 To ensure accurate tracking of this issue, please file a report about it at:
55 $self.bug_tracker
54 {bug_tracker}
56 """
55 """
57
56
58
57
59 class CrashHandler(object):
58 class CrashHandler(object):
60 """Customizable crash handlers for IPython applications.
59 """Customizable crash handlers for IPython applications.
61
60
62 Instances of this class provide a :meth:`__call__` method which can be
61 Instances of this class provide a :meth:`__call__` method which can be
63 used as a ``sys.excepthook``. The :meth:`__call__` signature is::
62 used as a ``sys.excepthook``. The :meth:`__call__` signature is::
64
63
65 def __call__(self, etype, evalue, etb)
64 def __call__(self, etype, evalue, etb)
66 """
65 """
67
66
68 message_template = _default_message_template
67 message_template = _default_message_template
68 section_sep = '\n\n'+'*'*75+'\n\n'
69
69
70 def __init__(self, app, contact_name=None, contact_email=None,
70 def __init__(self, app, contact_name=None, contact_email=None,
71 bug_tracker=None, show_crash_traceback=True, call_pdb=False):
71 bug_tracker=None, show_crash_traceback=True, call_pdb=False):
72 """Create a new crash handler
72 """Create a new crash handler
73
73
74 Parameters
74 Parameters
75 ----------
75 ----------
76 app : Application
76 app : Application
77 A running :class:`Application` instance, which will be queried at
77 A running :class:`Application` instance, which will be queried at
78 crash time for internal information.
78 crash time for internal information.
79
79
80 contact_name : str
80 contact_name : str
81 A string with the name of the person to contact.
81 A string with the name of the person to contact.
82
82
83 contact_email : str
83 contact_email : str
84 A string with the email address of the contact.
84 A string with the email address of the contact.
85
85
86 bug_tracker : str
86 bug_tracker : str
87 A string with the URL for your project's bug tracker.
87 A string with the URL for your project's bug tracker.
88
88
89 show_crash_traceback : bool
89 show_crash_traceback : bool
90 If false, don't print the crash traceback on stderr, only generate
90 If false, don't print the crash traceback on stderr, only generate
91 the on-disk report
91 the on-disk report
92
92
93 Non-argument instance attributes:
93 Non-argument instance attributes:
94
94
95 These instances contain some non-argument attributes which allow for
95 These instances contain some non-argument attributes which allow for
96 further customization of the crash handler's behavior. Please see the
96 further customization of the crash handler's behavior. Please see the
97 source for further details.
97 source for further details.
98 """
98 """
99 self.crash_report_fname = "Crash_report_%s.txt" % app.name
99 self.app = app
100 self.app = app
100 self.app_name = self.app.name
101 self.contact_name = contact_name
102 self.contact_email = contact_email
103 self.bug_tracker = bug_tracker
104 self.crash_report_fname = "Crash_report_%s.txt" % self.app_name
105 self.show_crash_traceback = show_crash_traceback
106 self.section_sep = '\n\n'+'*'*75+'\n\n'
107 self.call_pdb = call_pdb
101 self.call_pdb = call_pdb
108 #self.call_pdb = True # dbg
102 #self.call_pdb = True # dbg
103 self.show_crash_traceback = show_crash_traceback
104 self.info = dict(app_name = app.name,
105 contact_name = contact_name,
106 contact_email = contact_email,
107 bug_tracker = bug_tracker,
108 crash_report_fname = self.crash_report_fname)
109
109
110
110 def __call__(self, etype, evalue, etb):
111 def __call__(self, etype, evalue, etb):
111 """Handle an exception, call for compatible with sys.excepthook"""
112 """Handle an exception, call for compatible with sys.excepthook"""
112
113
113 # Report tracebacks shouldn't use color in general (safer for users)
114 # Report tracebacks shouldn't use color in general (safer for users)
114 color_scheme = 'NoColor'
115 color_scheme = 'NoColor'
115
116
116 # Use this ONLY for developer debugging (keep commented out for release)
117 # Use this ONLY for developer debugging (keep commented out for release)
117 #color_scheme = 'Linux' # dbg
118 #color_scheme = 'Linux' # dbg
118 try:
119 try:
119 rptdir = self.app.ipython_dir
120 rptdir = self.app.ipython_dir
120 except:
121 except:
121 rptdir = os.getcwd()
122 rptdir = os.getcwd()
122 if rptdir is None or not os.path.isdir(rptdir):
123 if rptdir is None or not os.path.isdir(rptdir):
123 rptdir = os.getcwd()
124 rptdir = os.getcwd()
124 report_name = os.path.join(rptdir,self.crash_report_fname)
125 report_name = os.path.join(rptdir,self.crash_report_fname)
125 # write the report filename into the instance dict so it can get
126 # write the report filename into the instance dict so it can get
126 # properly expanded out in the user message template
127 # properly expanded out in the user message template
127 self.crash_report_fname = report_name
128 self.crash_report_fname = report_name
128 TBhandler = ultratb.VerboseTB(
129 TBhandler = ultratb.VerboseTB(
129 color_scheme=color_scheme,
130 color_scheme=color_scheme,
130 long_header=1,
131 long_header=1,
131 call_pdb=self.call_pdb,
132 call_pdb=self.call_pdb,
132 )
133 )
133 if self.call_pdb:
134 if self.call_pdb:
134 TBhandler(etype,evalue,etb)
135 TBhandler(etype,evalue,etb)
135 return
136 return
136 else:
137 else:
137 traceback = TBhandler.text(etype,evalue,etb,context=31)
138 traceback = TBhandler.text(etype,evalue,etb,context=31)
138
139
139 # print traceback to screen
140 # print traceback to screen
140 if self.show_crash_traceback:
141 if self.show_crash_traceback:
141 print >> sys.stderr, traceback
142 print >> sys.stderr, traceback
142
143
143 # and generate a complete report on disk
144 # and generate a complete report on disk
144 try:
145 try:
145 report = open(report_name,'w')
146 report = open(report_name,'w')
146 except:
147 except:
147 print >> sys.stderr, 'Could not create crash report on disk.'
148 print >> sys.stderr, 'Could not create crash report on disk.'
148 return
149 return
149
150
150 # Inform user on stderr of what happened
151 # Inform user on stderr of what happened
151 msg = itpl('\n'+'*'*70+'\n'+self.message_template)
152 print >> sys.stderr, '\n'+'*'*70+'\n'
152 print >> sys.stderr, msg
153 print >> sys.stderr, self.message_template.format(**self.info)
153
154
154 # Construct report on disk
155 # Construct report on disk
155 report.write(self.make_report(traceback))
156 report.write(self.make_report(traceback))
156 report.close()
157 report.close()
157 raw_input("Hit <Enter> to quit this message (your terminal may close):")
158 raw_input("Hit <Enter> to quit this message (your terminal may close):")
158
159
159 def make_report(self,traceback):
160 def make_report(self,traceback):
160 """Return a string containing a crash report."""
161 """Return a string containing a crash report."""
161
162
162 sec_sep = self.section_sep
163 sec_sep = self.section_sep
163
164
164 report = ['*'*75+'\n\n'+'IPython post-mortem report\n\n']
165 report = ['*'*75+'\n\n'+'IPython post-mortem report\n\n']
165 rpt_add = report.append
166 rpt_add = report.append
166 rpt_add(sys_info())
167 rpt_add(sys_info())
167
168
168 try:
169 try:
169 config = pformat(self.app.config)
170 config = pformat(self.app.config)
170 rpt_add(sec_sep)
171 rpt_add(sec_sep)
171 rpt_add('Application name: %s\n\n' % self.app_name)
172 rpt_add('Application name: %s\n\n' % self.app_name)
172 rpt_add('Current user configuration structure:\n\n')
173 rpt_add('Current user configuration structure:\n\n')
173 rpt_add(config)
174 rpt_add(config)
174 except:
175 except:
175 pass
176 pass
176 rpt_add(sec_sep+'Crash traceback:\n\n' + traceback)
177 rpt_add(sec_sep+'Crash traceback:\n\n' + traceback)
177
178
178 return ''.join(report)
179 return ''.join(report)
179
180
@@ -1,357 +1,332 b''
1 #!/usr/bin/env python
1 #!/usr/bin/env python
2 # encoding: utf-8
2 # encoding: utf-8
3 """
3 """
4 The :class:`~IPython.core.application.Application` object for the command
4 The :class:`~IPython.core.application.Application` object for the command
5 line :command:`ipython` program.
5 line :command:`ipython` program.
6
6
7 Authors
7 Authors
8 -------
8 -------
9
9
10 * Brian Granger
10 * Brian Granger
11 * Fernando Perez
11 * Fernando Perez
12 * Min Ragan-Kelley
12 * Min Ragan-Kelley
13 """
13 """
14
14
15 #-----------------------------------------------------------------------------
15 #-----------------------------------------------------------------------------
16 # Copyright (C) 2008-2010 The IPython Development Team
16 # Copyright (C) 2008-2010 The IPython Development Team
17 #
17 #
18 # Distributed under the terms of the BSD License. The full license is in
18 # Distributed under the terms of the BSD License. The full license is in
19 # the file COPYING, distributed as part of this software.
19 # the file COPYING, distributed as part of this software.
20 #-----------------------------------------------------------------------------
20 #-----------------------------------------------------------------------------
21
21
22 #-----------------------------------------------------------------------------
22 #-----------------------------------------------------------------------------
23 # Imports
23 # Imports
24 #-----------------------------------------------------------------------------
24 #-----------------------------------------------------------------------------
25
25
26 from __future__ import absolute_import
26 from __future__ import absolute_import
27
27
28 import logging
28 import logging
29 import os
29 import os
30 import sys
30 import sys
31
31
32 from IPython.config.loader import (
32 from IPython.config.loader import (
33 Config, PyFileConfigLoader
33 Config, PyFileConfigLoader
34 )
34 )
35 from IPython.config.application import boolean_flag
35 from IPython.config.application import boolean_flag
36 from IPython.core import release
36 from IPython.core import release
37 from IPython.core import usage
37 from IPython.core import usage
38 from IPython.core.crashhandler import CrashHandler
38 from IPython.core.crashhandler import CrashHandler
39 from IPython.core.formatters import PlainTextFormatter
39 from IPython.core.formatters import PlainTextFormatter
40 from IPython.core.application import (
40 from IPython.core.application import (
41 ProfileDir, BaseIPythonApplication, base_flags, base_aliases
41 ProfileDir, BaseIPythonApplication, base_flags, base_aliases
42 )
42 )
43 from IPython.core.shellapp import (
43 from IPython.core.shellapp import (
44 InteractiveShellApp, shell_flags, shell_aliases
44 InteractiveShellApp, shell_flags, shell_aliases
45 )
45 )
46 from IPython.frontend.terminal.interactiveshell import TerminalInteractiveShell
46 from IPython.frontend.terminal.interactiveshell import TerminalInteractiveShell
47 from IPython.lib import inputhook
47 from IPython.lib import inputhook
48 from IPython.utils.path import get_ipython_dir, check_for_old_config
48 from IPython.utils.path import get_ipython_dir, check_for_old_config
49 from IPython.utils.traitlets import (
49 from IPython.utils.traitlets import (
50 Bool, Dict, CaselessStrEnum
50 Bool, Dict, CaselessStrEnum
51 )
51 )
52
52
53 #-----------------------------------------------------------------------------
53 #-----------------------------------------------------------------------------
54 # Globals, utilities and helpers
54 # Globals, utilities and helpers
55 #-----------------------------------------------------------------------------
55 #-----------------------------------------------------------------------------
56
56
57 #: The default config file name for this application.
57 #: The default config file name for this application.
58 default_config_file_name = u'ipython_config.py'
58 default_config_file_name = u'ipython_config.py'
59
59
60
60
61 #-----------------------------------------------------------------------------
61 #-----------------------------------------------------------------------------
62 # Crash handler for this application
62 # Crash handler for this application
63 #-----------------------------------------------------------------------------
63 #-----------------------------------------------------------------------------
64
64
65 _message_template = """\
66 Oops, $self.app_name crashed. We do our best to make it stable, but...
67
68 A crash report was automatically generated with the following information:
69 - A verbatim copy of the crash traceback.
70 - A copy of your input history during this session.
71 - Data on your current $self.app_name configuration.
72
73 It was left in the file named:
74 \t'$self.crash_report_fname'
75 If you can email this file to the developers, the information in it will help
76 them in understanding and correcting the problem.
77
78 You can mail it to: $self.contact_name at $self.contact_email
79 with the subject '$self.app_name Crash Report'.
80
81 If you want to do it now, the following command will work (under Unix):
82 mail -s '$self.app_name Crash Report' $self.contact_email < $self.crash_report_fname
83
84 To ensure accurate tracking of this issue, please file a report about it at:
85 $self.bug_tracker
86 """
87
88 class IPAppCrashHandler(CrashHandler):
65 class IPAppCrashHandler(CrashHandler):
89 """sys.excepthook for IPython itself, leaves a detailed report on disk."""
66 """sys.excepthook for IPython itself, leaves a detailed report on disk."""
90
67
91 message_template = _message_template
92
93 def __init__(self, app):
68 def __init__(self, app):
94 contact_name = release.authors['Fernando'][0]
69 contact_name = release.authors['Fernando'][0]
95 contact_email = release.authors['Fernando'][1]
70 contact_email = release.authors['Fernando'][1]
96 bug_tracker = 'http://github.com/ipython/ipython/issues'
71 bug_tracker = 'http://github.com/ipython/ipython/issues'
97 super(IPAppCrashHandler,self).__init__(
72 super(IPAppCrashHandler,self).__init__(
98 app, contact_name, contact_email, bug_tracker
73 app, contact_name, contact_email, bug_tracker
99 )
74 )
100
75
101 def make_report(self,traceback):
76 def make_report(self,traceback):
102 """Return a string containing a crash report."""
77 """Return a string containing a crash report."""
103
78
104 sec_sep = self.section_sep
79 sec_sep = self.section_sep
105 # Start with parent report
80 # Start with parent report
106 report = [super(IPAppCrashHandler, self).make_report(traceback)]
81 report = [super(IPAppCrashHandler, self).make_report(traceback)]
107 # Add interactive-specific info we may have
82 # Add interactive-specific info we may have
108 rpt_add = report.append
83 rpt_add = report.append
109 try:
84 try:
110 rpt_add(sec_sep+"History of session input:")
85 rpt_add(sec_sep+"History of session input:")
111 for line in self.app.shell.user_ns['_ih']:
86 for line in self.app.shell.user_ns['_ih']:
112 rpt_add(line)
87 rpt_add(line)
113 rpt_add('\n*** Last line of input (may not be in above history):\n')
88 rpt_add('\n*** Last line of input (may not be in above history):\n')
114 rpt_add(self.app.shell._last_input_line+'\n')
89 rpt_add(self.app.shell._last_input_line+'\n')
115 except:
90 except:
116 pass
91 pass
117
92
118 return ''.join(report)
93 return ''.join(report)
119
94
120 #-----------------------------------------------------------------------------
95 #-----------------------------------------------------------------------------
121 # Aliases and Flags
96 # Aliases and Flags
122 #-----------------------------------------------------------------------------
97 #-----------------------------------------------------------------------------
123 flags = dict(base_flags)
98 flags = dict(base_flags)
124 flags.update(shell_flags)
99 flags.update(shell_flags)
125 addflag = lambda *args: flags.update(boolean_flag(*args))
100 addflag = lambda *args: flags.update(boolean_flag(*args))
126 addflag('autoedit-syntax', 'TerminalInteractiveShell.autoedit_syntax',
101 addflag('autoedit-syntax', 'TerminalInteractiveShell.autoedit_syntax',
127 'Turn on auto editing of files with syntax errors.',
102 'Turn on auto editing of files with syntax errors.',
128 'Turn off auto editing of files with syntax errors.'
103 'Turn off auto editing of files with syntax errors.'
129 )
104 )
130 addflag('banner', 'TerminalIPythonApp.display_banner',
105 addflag('banner', 'TerminalIPythonApp.display_banner',
131 "Display a banner upon starting IPython.",
106 "Display a banner upon starting IPython.",
132 "Don't display a banner upon starting IPython."
107 "Don't display a banner upon starting IPython."
133 )
108 )
134 addflag('confirm-exit', 'TerminalInteractiveShell.confirm_exit',
109 addflag('confirm-exit', 'TerminalInteractiveShell.confirm_exit',
135 """Set to confirm when you try to exit IPython with an EOF (Control-D
110 """Set to confirm when you try to exit IPython with an EOF (Control-D
136 in Unix, Control-Z/Enter in Windows). By typing 'exit' or 'quit',
111 in Unix, Control-Z/Enter in Windows). By typing 'exit' or 'quit',
137 you can force a direct exit without any confirmation.""",
112 you can force a direct exit without any confirmation.""",
138 "Don't prompt the user when exiting."
113 "Don't prompt the user when exiting."
139 )
114 )
140 addflag('term-title', 'TerminalInteractiveShell.term_title',
115 addflag('term-title', 'TerminalInteractiveShell.term_title',
141 "Enable auto setting the terminal title.",
116 "Enable auto setting the terminal title.",
142 "Disable auto setting the terminal title."
117 "Disable auto setting the terminal title."
143 )
118 )
144 classic_config = Config()
119 classic_config = Config()
145 classic_config.InteractiveShell.cache_size = 0
120 classic_config.InteractiveShell.cache_size = 0
146 classic_config.PlainTextFormatter.pprint = False
121 classic_config.PlainTextFormatter.pprint = False
147 classic_config.InteractiveShell.prompt_in1 = '>>> '
122 classic_config.InteractiveShell.prompt_in1 = '>>> '
148 classic_config.InteractiveShell.prompt_in2 = '... '
123 classic_config.InteractiveShell.prompt_in2 = '... '
149 classic_config.InteractiveShell.prompt_out = ''
124 classic_config.InteractiveShell.prompt_out = ''
150 classic_config.InteractiveShell.separate_in = ''
125 classic_config.InteractiveShell.separate_in = ''
151 classic_config.InteractiveShell.separate_out = ''
126 classic_config.InteractiveShell.separate_out = ''
152 classic_config.InteractiveShell.separate_out2 = ''
127 classic_config.InteractiveShell.separate_out2 = ''
153 classic_config.InteractiveShell.colors = 'NoColor'
128 classic_config.InteractiveShell.colors = 'NoColor'
154 classic_config.InteractiveShell.xmode = 'Plain'
129 classic_config.InteractiveShell.xmode = 'Plain'
155
130
156 flags['classic']=(
131 flags['classic']=(
157 classic_config,
132 classic_config,
158 "Gives IPython a similar feel to the classic Python prompt."
133 "Gives IPython a similar feel to the classic Python prompt."
159 )
134 )
160 # # log doesn't make so much sense this way anymore
135 # # log doesn't make so much sense this way anymore
161 # paa('--log','-l',
136 # paa('--log','-l',
162 # action='store_true', dest='InteractiveShell.logstart',
137 # action='store_true', dest='InteractiveShell.logstart',
163 # help="Start logging to the default log file (./ipython_log.py).")
138 # help="Start logging to the default log file (./ipython_log.py).")
164 #
139 #
165 # # quick is harder to implement
140 # # quick is harder to implement
166 flags['quick']=(
141 flags['quick']=(
167 {'TerminalIPythonApp' : {'quick' : True}},
142 {'TerminalIPythonApp' : {'quick' : True}},
168 "Enable quick startup with no config files."
143 "Enable quick startup with no config files."
169 )
144 )
170
145
171 flags['i'] = (
146 flags['i'] = (
172 {'TerminalIPythonApp' : {'force_interact' : True}},
147 {'TerminalIPythonApp' : {'force_interact' : True}},
173 "If running code from the command line, become interactive afterwards."
148 "If running code from the command line, become interactive afterwards."
174 )
149 )
175 flags['pylab'] = (
150 flags['pylab'] = (
176 {'TerminalIPythonApp' : {'pylab' : 'auto'}},
151 {'TerminalIPythonApp' : {'pylab' : 'auto'}},
177 """Pre-load matplotlib and numpy for interactive use with
152 """Pre-load matplotlib and numpy for interactive use with
178 the default matplotlib backend."""
153 the default matplotlib backend."""
179 )
154 )
180
155
181 aliases = dict(base_aliases)
156 aliases = dict(base_aliases)
182 aliases.update(shell_aliases)
157 aliases.update(shell_aliases)
183
158
184 # it's possible we don't want short aliases for *all* of these:
159 # it's possible we don't want short aliases for *all* of these:
185 aliases.update(dict(
160 aliases.update(dict(
186 gui='TerminalIPythonApp.gui',
161 gui='TerminalIPythonApp.gui',
187 pylab='TerminalIPythonApp.pylab',
162 pylab='TerminalIPythonApp.pylab',
188 ))
163 ))
189
164
190 #-----------------------------------------------------------------------------
165 #-----------------------------------------------------------------------------
191 # Main classes and functions
166 # Main classes and functions
192 #-----------------------------------------------------------------------------
167 #-----------------------------------------------------------------------------
193
168
194 class TerminalIPythonApp(BaseIPythonApplication, InteractiveShellApp):
169 class TerminalIPythonApp(BaseIPythonApplication, InteractiveShellApp):
195 name = u'ipython'
170 name = u'ipython'
196 description = usage.cl_usage
171 description = usage.cl_usage
197 default_config_file_name = default_config_file_name
172 default_config_file_name = default_config_file_name
198 crash_handler_class = IPAppCrashHandler
173 crash_handler_class = IPAppCrashHandler
199
174
200 flags = Dict(flags)
175 flags = Dict(flags)
201 aliases = Dict(aliases)
176 aliases = Dict(aliases)
202 classes = [InteractiveShellApp, TerminalInteractiveShell, ProfileDir, PlainTextFormatter]
177 classes = [InteractiveShellApp, TerminalInteractiveShell, ProfileDir, PlainTextFormatter]
203 subcommands = Dict(dict(
178 subcommands = Dict(dict(
204 qtconsole=('IPython.frontend.qt.console.qtconsoleapp.IPythonQtConsoleApp',
179 qtconsole=('IPython.frontend.qt.console.qtconsoleapp.IPythonQtConsoleApp',
205 """Launch the IPython Qt Console."""
180 """Launch the IPython Qt Console."""
206 ),
181 ),
207 profile = ("IPython.core.profileapp.ProfileApp",
182 profile = ("IPython.core.profileapp.ProfileApp",
208 "Create and manage IPython profiles.")
183 "Create and manage IPython profiles.")
209 ))
184 ))
210
185
211 # *do* autocreate requested profile, but don't create the config file.
186 # *do* autocreate requested profile, but don't create the config file.
212 auto_create=Bool(True)
187 auto_create=Bool(True)
213 # configurables
188 # configurables
214 ignore_old_config=Bool(False, config=True,
189 ignore_old_config=Bool(False, config=True,
215 help="Suppress warning messages about legacy config files"
190 help="Suppress warning messages about legacy config files"
216 )
191 )
217 quick = Bool(False, config=True,
192 quick = Bool(False, config=True,
218 help="""Start IPython quickly by skipping the loading of config files."""
193 help="""Start IPython quickly by skipping the loading of config files."""
219 )
194 )
220 def _quick_changed(self, name, old, new):
195 def _quick_changed(self, name, old, new):
221 if new:
196 if new:
222 self.load_config_file = lambda *a, **kw: None
197 self.load_config_file = lambda *a, **kw: None
223 self.ignore_old_config=True
198 self.ignore_old_config=True
224
199
225 gui = CaselessStrEnum(('qt','wx','gtk'), config=True,
200 gui = CaselessStrEnum(('qt','wx','gtk'), config=True,
226 help="Enable GUI event loop integration ('qt', 'wx', 'gtk')."
201 help="Enable GUI event loop integration ('qt', 'wx', 'gtk')."
227 )
202 )
228 pylab = CaselessStrEnum(['tk', 'qt', 'wx', 'gtk', 'osx', 'auto'],
203 pylab = CaselessStrEnum(['tk', 'qt', 'wx', 'gtk', 'osx', 'auto'],
229 config=True,
204 config=True,
230 help="""Pre-load matplotlib and numpy for interactive use,
205 help="""Pre-load matplotlib and numpy for interactive use,
231 selecting a particular matplotlib backend and loop integration.
206 selecting a particular matplotlib backend and loop integration.
232 """
207 """
233 )
208 )
234 display_banner = Bool(True, config=True,
209 display_banner = Bool(True, config=True,
235 help="Whether to display a banner upon starting IPython."
210 help="Whether to display a banner upon starting IPython."
236 )
211 )
237
212
238 # if there is code of files to run from the cmd line, don't interact
213 # if there is code of files to run from the cmd line, don't interact
239 # unless the --i flag (App.force_interact) is true.
214 # unless the --i flag (App.force_interact) is true.
240 force_interact = Bool(False, config=True,
215 force_interact = Bool(False, config=True,
241 help="""If a command or file is given via the command-line,
216 help="""If a command or file is given via the command-line,
242 e.g. 'ipython foo.py"""
217 e.g. 'ipython foo.py"""
243 )
218 )
244 def _force_interact_changed(self, name, old, new):
219 def _force_interact_changed(self, name, old, new):
245 if new:
220 if new:
246 self.interact = True
221 self.interact = True
247
222
248 def _file_to_run_changed(self, name, old, new):
223 def _file_to_run_changed(self, name, old, new):
249 if new and not self.force_interact:
224 if new and not self.force_interact:
250 self.interact = False
225 self.interact = False
251 _code_to_run_changed = _file_to_run_changed
226 _code_to_run_changed = _file_to_run_changed
252
227
253 # internal, not-configurable
228 # internal, not-configurable
254 interact=Bool(True)
229 interact=Bool(True)
255
230
256
231
257 def initialize(self, argv=None):
232 def initialize(self, argv=None):
258 """Do actions after construct, but before starting the app."""
233 """Do actions after construct, but before starting the app."""
259 super(TerminalIPythonApp, self).initialize(argv)
234 super(TerminalIPythonApp, self).initialize(argv)
260 if self.subapp is not None:
235 if self.subapp is not None:
261 # don't bother initializing further, starting subapp
236 # don't bother initializing further, starting subapp
262 return
237 return
263 if not self.ignore_old_config:
238 if not self.ignore_old_config:
264 check_for_old_config(self.ipython_dir)
239 check_for_old_config(self.ipython_dir)
265 # print self.extra_args
240 # print self.extra_args
266 if self.extra_args:
241 if self.extra_args:
267 self.file_to_run = self.extra_args[0]
242 self.file_to_run = self.extra_args[0]
268 # create the shell
243 # create the shell
269 self.init_shell()
244 self.init_shell()
270 # and draw the banner
245 # and draw the banner
271 self.init_banner()
246 self.init_banner()
272 # Now a variety of things that happen after the banner is printed.
247 # Now a variety of things that happen after the banner is printed.
273 self.init_gui_pylab()
248 self.init_gui_pylab()
274 self.init_extensions()
249 self.init_extensions()
275 self.init_code()
250 self.init_code()
276
251
277 def init_shell(self):
252 def init_shell(self):
278 """initialize the InteractiveShell instance"""
253 """initialize the InteractiveShell instance"""
279 # I am a little hesitant to put these into InteractiveShell itself.
254 # I am a little hesitant to put these into InteractiveShell itself.
280 # But that might be the place for them
255 # But that might be the place for them
281 sys.path.insert(0, '')
256 sys.path.insert(0, '')
282
257
283 # Create an InteractiveShell instance.
258 # Create an InteractiveShell instance.
284 # shell.display_banner should always be False for the terminal
259 # shell.display_banner should always be False for the terminal
285 # based app, because we call shell.show_banner() by hand below
260 # based app, because we call shell.show_banner() by hand below
286 # so the banner shows *before* all extension loading stuff.
261 # so the banner shows *before* all extension loading stuff.
287 self.shell = TerminalInteractiveShell.instance(config=self.config,
262 self.shell = TerminalInteractiveShell.instance(config=self.config,
288 display_banner=False, profile_dir=self.profile_dir,
263 display_banner=False, profile_dir=self.profile_dir,
289 ipython_dir=self.ipython_dir)
264 ipython_dir=self.ipython_dir)
290
265
291 def init_banner(self):
266 def init_banner(self):
292 """optionally display the banner"""
267 """optionally display the banner"""
293 if self.display_banner and self.interact:
268 if self.display_banner and self.interact:
294 self.shell.show_banner()
269 self.shell.show_banner()
295 # Make sure there is a space below the banner.
270 # Make sure there is a space below the banner.
296 if self.log_level <= logging.INFO: print
271 if self.log_level <= logging.INFO: print
297
272
298
273
299 def init_gui_pylab(self):
274 def init_gui_pylab(self):
300 """Enable GUI event loop integration, taking pylab into account."""
275 """Enable GUI event loop integration, taking pylab into account."""
301 gui = self.gui
276 gui = self.gui
302
277
303 # Using `pylab` will also require gui activation, though which toolkit
278 # Using `pylab` will also require gui activation, though which toolkit
304 # to use may be chosen automatically based on mpl configuration.
279 # to use may be chosen automatically based on mpl configuration.
305 if self.pylab:
280 if self.pylab:
306 activate = self.shell.enable_pylab
281 activate = self.shell.enable_pylab
307 if self.pylab == 'auto':
282 if self.pylab == 'auto':
308 gui = None
283 gui = None
309 else:
284 else:
310 gui = self.pylab
285 gui = self.pylab
311 else:
286 else:
312 # Enable only GUI integration, no pylab
287 # Enable only GUI integration, no pylab
313 activate = inputhook.enable_gui
288 activate = inputhook.enable_gui
314
289
315 if gui or self.pylab:
290 if gui or self.pylab:
316 try:
291 try:
317 self.log.info("Enabling GUI event loop integration, "
292 self.log.info("Enabling GUI event loop integration, "
318 "toolkit=%s, pylab=%s" % (gui, self.pylab) )
293 "toolkit=%s, pylab=%s" % (gui, self.pylab) )
319 activate(gui)
294 activate(gui)
320 except:
295 except:
321 self.log.warn("Error in enabling GUI event loop integration:")
296 self.log.warn("Error in enabling GUI event loop integration:")
322 self.shell.showtraceback()
297 self.shell.showtraceback()
323
298
324 def start(self):
299 def start(self):
325 if self.subapp is not None:
300 if self.subapp is not None:
326 return self.subapp.start()
301 return self.subapp.start()
327 # perform any prexec steps:
302 # perform any prexec steps:
328 if self.interact:
303 if self.interact:
329 self.log.debug("Starting IPython's mainloop...")
304 self.log.debug("Starting IPython's mainloop...")
330 self.shell.mainloop()
305 self.shell.mainloop()
331 else:
306 else:
332 self.log.debug("IPython not interactive...")
307 self.log.debug("IPython not interactive...")
333
308
334
309
335 def load_default_config(ipython_dir=None):
310 def load_default_config(ipython_dir=None):
336 """Load the default config file from the default ipython_dir.
311 """Load the default config file from the default ipython_dir.
337
312
338 This is useful for embedded shells.
313 This is useful for embedded shells.
339 """
314 """
340 if ipython_dir is None:
315 if ipython_dir is None:
341 ipython_dir = get_ipython_dir()
316 ipython_dir = get_ipython_dir()
342 profile_dir = os.path.join(ipython_dir, 'profile_default')
317 profile_dir = os.path.join(ipython_dir, 'profile_default')
343 cl = PyFileConfigLoader(default_config_file_name, profile_dir)
318 cl = PyFileConfigLoader(default_config_file_name, profile_dir)
344 config = cl.load_config()
319 config = cl.load_config()
345 return config
320 return config
346
321
347
322
348 def launch_new_instance():
323 def launch_new_instance():
349 """Create and run a full blown IPython instance"""
324 """Create and run a full blown IPython instance"""
350 app = TerminalIPythonApp.instance()
325 app = TerminalIPythonApp.instance()
351 app.initialize()
326 app.initialize()
352 app.start()
327 app.start()
353
328
354
329
355 if __name__ == '__main__':
330 if __name__ == '__main__':
356 launch_new_instance()
331 launch_new_instance()
357
332
General Comments 0
You need to be logged in to leave comments. Login now