Show More
@@ -298,14 +298,12 b' NoConfigDefault = NoConfigDefault()' | |||||
298 |
|
298 | |||
299 | class ArgParseConfigLoader(CommandLineConfigLoader): |
|
299 | class ArgParseConfigLoader(CommandLineConfigLoader): | |
300 |
|
300 | |||
301 | # arguments = [(('-f','--file'),dict(type=str,dest='file'))] |
|
301 | def __init__(self, argv=None, arguments=(), *args, **kw): | |
302 | arguments = () |
|
|||
303 |
|
||||
304 | def __init__(self, argv=None, *args, **kw): |
|
|||
305 | """Create a config loader for use with argparse. |
|
302 | """Create a config loader for use with argparse. | |
306 |
|
303 | |||
307 |
With the exception of argv, other args and kwargs |
|
304 | With the exception of ``argv`` and ``arguments``, other args and kwargs | |
308 | passed onto the constructor of :class:`argparse.ArgumentParser`. |
|
305 | arguments here are passed onto the constructor of | |
|
306 | :class:`argparse.ArgumentParser`. | |||
309 |
|
307 | |||
310 | Parameters |
|
308 | Parameters | |
311 | ---------- |
|
309 | ---------- | |
@@ -313,11 +311,16 b' class ArgParseConfigLoader(CommandLineConfigLoader):' | |||||
313 | argv : optional, list |
|
311 | argv : optional, list | |
314 | If given, used to read command-line arguments from, otherwise |
|
312 | If given, used to read command-line arguments from, otherwise | |
315 | sys.argv[1:] is used. |
|
313 | sys.argv[1:] is used. | |
|
314 | ||||
|
315 | arguments : optional, tuple | |||
|
316 | Description of valid command-line arguments, to be called in sequence | |||
|
317 | with parser.add_argument() to configure the parser. | |||
316 | """ |
|
318 | """ | |
317 | super(CommandLineConfigLoader, self).__init__() |
|
319 | super(CommandLineConfigLoader, self).__init__() | |
318 | if argv == None: |
|
320 | if argv == None: | |
319 | argv = sys.argv[1:] |
|
321 | argv = sys.argv[1:] | |
320 | self.argv = argv |
|
322 | self.argv = argv | |
|
323 | self.arguments = arguments | |||
321 | self.args = args |
|
324 | self.args = args | |
322 | self.kw = kw |
|
325 | self.kw = kw | |
323 |
|
326 |
@@ -66,15 +66,13 b' class TestArgParseCL(TestCase):' | |||||
66 |
|
66 | |||
67 | def test_basic(self): |
|
67 | def test_basic(self): | |
68 |
|
68 | |||
69 | class MyLoader(ArgParseConfigLoader): |
|
69 | arguments = ( | |
70 | arguments = ( |
|
|||
71 | (('-f','--foo'), dict(dest='Global.foo', type=str)), |
|
70 | (('-f','--foo'), dict(dest='Global.foo', type=str)), | |
72 | (('-b',), dict(dest='MyClass.bar', type=int)), |
|
71 | (('-b',), dict(dest='MyClass.bar', type=int)), | |
73 | (('-n',), dict(dest='n', action='store_true')), |
|
72 | (('-n',), dict(dest='n', action='store_true')), | |
74 | (('Global.bam',), dict(type=str)) |
|
73 | (('Global.bam',), dict(type=str)) | |
75 | ) |
|
74 | ) | |
76 |
|
75 | cl = ArgParseConfigLoader(arguments=arguments) | ||
77 | cl = MyLoader() |
|
|||
78 | config = cl.load_config('-f hi -b 10 -n wow'.split()) |
|
76 | config = cl.load_config('-f hi -b 10 -n wow'.split()) | |
79 | self.assertEquals(config.Global.foo, 'hi') |
|
77 | self.assertEquals(config.Global.foo, 'hi') | |
80 | self.assertEquals(config.MyClass.bar, 10) |
|
78 | self.assertEquals(config.MyClass.bar, 10) |
@@ -33,7 +33,7 b' import logging' | |||||
33 | import os |
|
33 | import os | |
34 | import sys |
|
34 | import sys | |
35 |
|
35 | |||
36 | from IPython.core import release |
|
36 | from IPython.core import release, crashhandler | |
37 | from IPython.utils.genutils import get_ipython_dir, get_ipython_package_dir |
|
37 | from IPython.utils.genutils import get_ipython_dir, get_ipython_package_dir | |
38 | from IPython.config.loader import ( |
|
38 | from IPython.config.loader import ( | |
39 | PyFileConfigLoader, |
|
39 | PyFileConfigLoader, | |
@@ -77,6 +77,29 b' class ApplicationError(Exception):' | |||||
77 | pass |
|
77 | pass | |
78 |
|
78 | |||
79 |
|
79 | |||
|
80 | app_cl_args = ( | |||
|
81 | (('--ipython-dir', ), dict( | |||
|
82 | dest='Global.ipython_dir',type=unicode, | |||
|
83 | help='Set to override default location of Global.ipython_dir.', | |||
|
84 | default=NoConfigDefault, | |||
|
85 | metavar='Global.ipython_dir') ), | |||
|
86 | (('-p', '--profile',), dict( | |||
|
87 | dest='Global.profile',type=unicode, | |||
|
88 | help='The string name of the ipython profile to be used.', | |||
|
89 | default=NoConfigDefault, | |||
|
90 | metavar='Global.profile') ), | |||
|
91 | (('--log-level',), dict( | |||
|
92 | dest="Global.log_level",type=int, | |||
|
93 | help='Set the log level (0,10,20,30,40,50). Default is 30.', | |||
|
94 | default=NoConfigDefault, | |||
|
95 | metavar='Global.log_level')), | |||
|
96 | (('--config-file',), dict( | |||
|
97 | dest='Global.config_file',type=unicode, | |||
|
98 | help='Set the config file name to override default.', | |||
|
99 | default=NoConfigDefault, | |||
|
100 | metavar='Global.config_file')), | |||
|
101 | ) | |||
|
102 | ||||
80 | class Application(object): |
|
103 | class Application(object): | |
81 | """Load a config, construct components and set them running.""" |
|
104 | """Load a config, construct components and set them running.""" | |
82 |
|
105 | |||
@@ -94,11 +117,17 b' class Application(object):' | |||||
94 | ipython_dir = None |
|
117 | ipython_dir = None | |
95 | #: A reference to the argv to be used (typically ends up being sys.argv[1:]) |
|
118 | #: A reference to the argv to be used (typically ends up being sys.argv[1:]) | |
96 | argv = None |
|
119 | argv = None | |
|
120 | #: Default command line arguments. Subclasses should create a new tuple | |||
|
121 | #: that *includes* these. | |||
|
122 | cl_arguments = app_cl_args | |||
97 |
|
123 | |||
98 | # Private attributes |
|
124 | # Private attributes | |
99 | _exiting = False |
|
125 | _exiting = False | |
100 | _initialized = False |
|
126 | _initialized = False | |
101 |
|
127 | |||
|
128 | # Class choices for things that will be instantiated at runtime. | |||
|
129 | _CrashHandler = crashhandler.CrashHandler | |||
|
130 | ||||
102 | def __init__(self, argv=None): |
|
131 | def __init__(self, argv=None): | |
103 | self.argv = sys.argv[1:] if argv is None else argv |
|
132 | self.argv = sys.argv[1:] if argv is None else argv | |
104 | self.init_logger() |
|
133 | self.init_logger() | |
@@ -125,39 +154,49 b' class Application(object):' | |||||
125 |
|
154 | |||
126 | if self._initialized: |
|
155 | if self._initialized: | |
127 | return |
|
156 | return | |
128 |
|
157 | |||
129 | self.attempt(self.create_default_config) |
|
158 | # The first part is protected with an 'attempt' wrapper, that will log | |
|
159 | # failures with the basic system traceback machinery. Once our crash | |||
|
160 | # handler is in place, we can let any subsequent exception propagate, | |||
|
161 | # as our handler will log it with much better detail than the default. | |||
|
162 | self.attempt(self.create_crash_handler) | |||
|
163 | self.create_default_config() | |||
130 | self.log_default_config() |
|
164 | self.log_default_config() | |
131 | self.set_default_config_log_level() |
|
165 | self.set_default_config_log_level() | |
132 |
self. |
|
166 | self.pre_load_command_line_config() | |
133 |
self. |
|
167 | self.load_command_line_config() | |
134 | self.set_command_line_config_log_level() |
|
168 | self.set_command_line_config_log_level() | |
135 |
self. |
|
169 | self.post_load_command_line_config() | |
136 | self.log_command_line_config() |
|
170 | self.log_command_line_config() | |
137 |
self. |
|
171 | self.find_ipython_dir() | |
138 |
self. |
|
172 | self.find_resources() | |
139 |
self. |
|
173 | self.find_config_file_name() | |
140 |
self. |
|
174 | self.find_config_file_paths() | |
141 |
self. |
|
175 | self.pre_load_file_config() | |
142 |
self. |
|
176 | self.load_file_config() | |
143 | self.set_file_config_log_level() |
|
177 | self.set_file_config_log_level() | |
144 |
self. |
|
178 | self.post_load_file_config() | |
145 | self.log_file_config() |
|
179 | self.log_file_config() | |
146 |
self. |
|
180 | self.merge_configs() | |
147 | self.log_master_config() |
|
181 | self.log_master_config() | |
148 |
self. |
|
182 | self.pre_construct() | |
149 |
self. |
|
183 | self.construct() | |
150 |
self. |
|
184 | self.post_construct() | |
151 | self._initialized = True |
|
185 | self._initialized = True | |
152 |
|
186 | |||
153 | def start(self): |
|
187 | def start(self): | |
154 | self.initialize() |
|
188 | self.initialize() | |
155 |
self. |
|
189 | self.start_app() | |
156 |
|
190 | |||
157 | #------------------------------------------------------------------------- |
|
191 | #------------------------------------------------------------------------- | |
158 | # Various stages of Application creation |
|
192 | # Various stages of Application creation | |
159 | #------------------------------------------------------------------------- |
|
193 | #------------------------------------------------------------------------- | |
160 |
|
194 | |||
|
195 | def create_crash_handler(self): | |||
|
196 | """Create a crash handler, typically setting sys.excepthook to it.""" | |||
|
197 | self.crash_handler = self._CrashHandler(self, self.name) | |||
|
198 | sys.excepthook = self.crash_handler | |||
|
199 | ||||
161 | def create_default_config(self): |
|
200 | def create_default_config(self): | |
162 | """Create defaults that can't be set elsewhere. |
|
201 | """Create defaults that can't be set elsewhere. | |
163 |
|
202 | |||
@@ -185,10 +224,9 b' class Application(object):' | |||||
185 |
|
224 | |||
186 | def create_command_line_config(self): |
|
225 | def create_command_line_config(self): | |
187 | """Create and return a command line config loader.""" |
|
226 | """Create and return a command line config loader.""" | |
188 |
return |
|
227 | return ArgParseConfigLoader(self.argv, self.cl_arguments, | |
189 | description=self.description, |
|
228 | description=self.description, | |
190 | version=release.version |
|
229 | version=release.version) | |
191 | ) |
|
|||
192 |
|
230 | |||
193 | def pre_load_command_line_config(self): |
|
231 | def pre_load_command_line_config(self): | |
194 | """Do actions just before loading the command line config.""" |
|
232 | """Do actions just before loading the command line config.""" | |
@@ -384,7 +422,10 b' class Application(object):' | |||||
384 | raise |
|
422 | raise | |
385 | except: |
|
423 | except: | |
386 | if action == 'abort': |
|
424 | if action == 'abort': | |
|
425 | self.log.critical("Aborting application: %s" % self.name, | |||
|
426 | exc_info=True) | |||
387 | self.abort() |
|
427 | self.abort() | |
|
428 | raise | |||
388 | elif action == 'exit': |
|
429 | elif action == 'exit': | |
389 | self.exit(0) |
|
430 | self.exit(0) | |
390 |
|
431 |
@@ -28,10 +28,8 b' from IPython.core import release' | |||||
28 | from IPython.core import ultratb |
|
28 | from IPython.core import ultratb | |
29 | from IPython.external.Itpl import itpl |
|
29 | from IPython.external.Itpl import itpl | |
30 |
|
30 | |||
31 | from IPython.utils.genutils import * |
|
|||
32 |
|
||||
33 | #**************************************************************************** |
|
31 | #**************************************************************************** | |
34 | class CrashHandler: |
|
32 | class CrashHandler(object): | |
35 | """Customizable crash handlers for IPython-based systems. |
|
33 | """Customizable crash handlers for IPython-based systems. | |
36 |
|
34 | |||
37 | Instances of this class provide a __call__ method which can be used as a |
|
35 | Instances of this class provide a __call__ method which can be used as a | |
@@ -41,15 +39,15 b' class CrashHandler:' | |||||
41 |
|
39 | |||
42 | """ |
|
40 | """ | |
43 |
|
41 | |||
44 |
def __init__(self, |
|
42 | def __init__(self,app, app_name, contact_name=None, contact_email=None, | |
45 | bug_tracker,crash_report_fname, |
|
43 | bug_tracker=None, crash_report_fname='CrashReport.txt', | |
46 | show_crash_traceback=True): |
|
44 | show_crash_traceback=True): | |
47 | """New crash handler. |
|
45 | """New crash handler. | |
48 |
|
46 | |||
49 | Inputs: |
|
47 | Inputs: | |
50 |
|
48 | |||
51 |
- |
|
49 | - app: a running application instance, which will be queried at crash | |
52 | for internal information. |
|
50 | time for internal information. | |
53 |
|
51 | |||
54 | - app_name: a string containing the name of your application. |
|
52 | - app_name: a string containing the name of your application. | |
55 |
|
53 | |||
@@ -77,13 +75,14 b' class CrashHandler:' | |||||
77 | """ |
|
75 | """ | |
78 |
|
76 | |||
79 | # apply args into instance |
|
77 | # apply args into instance | |
80 | self.IP = IP # IPython instance |
|
78 | self.app = app | |
81 | self.app_name = app_name |
|
79 | self.app_name = app_name | |
82 | self.contact_name = contact_name |
|
80 | self.contact_name = contact_name | |
83 | self.contact_email = contact_email |
|
81 | self.contact_email = contact_email | |
84 | self.bug_tracker = bug_tracker |
|
82 | self.bug_tracker = bug_tracker | |
85 | self.crash_report_fname = crash_report_fname |
|
83 | self.crash_report_fname = crash_report_fname | |
86 | self.show_crash_traceback = show_crash_traceback |
|
84 | self.show_crash_traceback = show_crash_traceback | |
|
85 | self.section_sep = '\n\n'+'*'*75+'\n\n' | |||
87 |
|
86 | |||
88 | # Hardcoded defaults, which can be overridden either by subclasses or |
|
87 | # Hardcoded defaults, which can be overridden either by subclasses or | |
89 | # at runtime for the instance. |
|
88 | # at runtime for the instance. | |
@@ -124,7 +123,7 b' $self.bug_tracker' | |||||
124 | #color_scheme = 'Linux' # dbg |
|
123 | #color_scheme = 'Linux' # dbg | |
125 |
|
124 | |||
126 | try: |
|
125 | try: | |
127 |
rptdir = self. |
|
126 | rptdir = self.app.ipython_dir | |
128 | except: |
|
127 | except: | |
129 | rptdir = os.getcwd() |
|
128 | rptdir = os.getcwd() | |
130 | if not os.path.isdir(rptdir): |
|
129 | if not os.path.isdir(rptdir): | |
@@ -134,7 +133,7 b' $self.bug_tracker' | |||||
134 | # properly expanded out in the user message template |
|
133 | # properly expanded out in the user message template | |
135 | self.crash_report_fname = report_name |
|
134 | self.crash_report_fname = report_name | |
136 | TBhandler = ultratb.VerboseTB(color_scheme=color_scheme, |
|
135 | TBhandler = ultratb.VerboseTB(color_scheme=color_scheme, | |
137 |
|
|
136 | long_header=1) | |
138 | traceback = TBhandler.text(etype,evalue,etb,context=31) |
|
137 | traceback = TBhandler.text(etype,evalue,etb,context=31) | |
139 |
|
138 | |||
140 | # print traceback to screen |
|
139 | # print traceback to screen | |
@@ -159,70 +158,62 b' $self.bug_tracker' | |||||
159 |
|
158 | |||
160 | def make_report(self,traceback): |
|
159 | def make_report(self,traceback): | |
161 | """Return a string containing a crash report.""" |
|
160 | """Return a string containing a crash report.""" | |
162 |
|
161 | import platform | ||
163 | sec_sep = '\n\n'+'*'*75+'\n\n' |
|
162 | ||
164 |
|
163 | sec_sep = self.section_sep | ||
|
164 | ||||
165 | report = [] |
|
165 | report = [] | |
166 | rpt_add = report.append |
|
166 | rpt_add = report.append | |
167 |
|
167 | |||
168 | rpt_add('*'*75+'\n\n'+'IPython post-mortem report\n\n') |
|
168 | rpt_add('*'*75+'\n\n'+'IPython post-mortem report\n\n') | |
169 |
rpt_add('IPython version: %s |
|
169 | rpt_add('IPython version: %s \n' % release.version) | |
170 |
rpt_add('BZR revision : %s |
|
170 | rpt_add('BZR revision : %s \n' % release.revision) | |
171 | rpt_add('Platform info : os.name -> %s, sys.platform -> %s' % |
|
171 | rpt_add('Platform info : os.name -> %s, sys.platform -> %s\n' % | |
172 | (os.name,sys.platform) ) |
|
172 | (os.name,sys.platform) ) | |
173 | rpt_add(sec_sep+'Current user configuration structure:\n\n') |
|
173 | rpt_add(' : %s\n' % platform.platform()) | |
174 | rpt_add(pformat(self.IP.dict())) |
|
174 | rpt_add('Python info : %s\n' % sys.version) | |
175 | rpt_add(sec_sep+'Crash traceback:\n\n' + traceback) |
|
175 | ||
176 | try: |
|
176 | try: | |
177 | rpt_add(sec_sep+"History of session input:") |
|
177 | config = pformat(self.app.config) | |
178 | for line in self.IP.user_ns['_ih']: |
|
178 | rpt_add(sec_sep+'Current user configuration structure:\n\n') | |
179 |
|
|
179 | rpt_add(config) | |
180 | rpt_add('\n*** Last line of input (may not be in above history):\n') |
|
|||
181 | rpt_add(self.IP._last_input_line+'\n') |
|
|||
182 | except: |
|
180 | except: | |
183 | pass |
|
181 | pass | |
|
182 | rpt_add(sec_sep+'Crash traceback:\n\n' + traceback) | |||
184 |
|
183 | |||
185 | return ''.join(report) |
|
184 | return ''.join(report) | |
186 |
|
185 | |||
|
186 | ||||
187 | class IPythonCrashHandler(CrashHandler): |
|
187 | class IPythonCrashHandler(CrashHandler): | |
188 | """sys.excepthook for IPython itself, leaves a detailed report on disk.""" |
|
188 | """sys.excepthook for IPython itself, leaves a detailed report on disk.""" | |
189 |
|
189 | |||
190 | def __init__(self,IP): |
|
190 | def __init__(self, app, app_name='IPython'): | |
191 |
|
191 | |||
192 | # Set here which of the IPython authors should be listed as contact |
|
192 | # Set here which of the IPython authors should be listed as contact | |
193 | AUTHOR_CONTACT = 'Fernando' |
|
193 | AUTHOR_CONTACT = 'Fernando' | |
194 |
|
194 | |||
195 | # Set argument defaults |
|
195 | # Set argument defaults | |
196 | app_name = 'IPython' |
|
|||
197 | bug_tracker = 'https://bugs.launchpad.net/ipython/+filebug' |
|
196 | bug_tracker = 'https://bugs.launchpad.net/ipython/+filebug' | |
198 | contact_name,contact_email = release.authors[AUTHOR_CONTACT][:2] |
|
197 | contact_name,contact_email = release.authors[AUTHOR_CONTACT][:2] | |
199 | crash_report_fname = 'IPython_crash_report.txt' |
|
198 | crash_report_fname = 'IPython_crash_report.txt' | |
200 | # Call parent constructor |
|
199 | # Call parent constructor | |
201 |
CrashHandler.__init__(self, |
|
200 | CrashHandler.__init__(self,app,app_name,contact_name,contact_email, | |
202 | bug_tracker,crash_report_fname) |
|
201 | bug_tracker,crash_report_fname) | |
203 |
|
202 | |||
204 | def make_report(self,traceback): |
|
203 | def make_report(self,traceback): | |
205 | """Return a string containing a crash report.""" |
|
204 | """Return a string containing a crash report.""" | |
206 |
|
205 | |||
207 | sec_sep = '\n\n'+'*'*75+'\n\n' |
|
206 | sec_sep = self.section_sep | |
208 |
|
207 | # Start with parent report | ||
209 | report = [] |
|
208 | report = [super(IPythonCrashHandler, self).make_report(traceback)] | |
|
209 | # Add interactive-specific info we may have | |||
210 | rpt_add = report.append |
|
210 | rpt_add = report.append | |
211 |
|
||||
212 | rpt_add('*'*75+'\n\n'+'IPython post-mortem report\n\n') |
|
|||
213 | rpt_add('IPython version: %s \n\n' % release.version) |
|
|||
214 | rpt_add('BZR revision : %s \n\n' % release.revision) |
|
|||
215 | rpt_add('Platform info : os.name -> %s, sys.platform -> %s' % |
|
|||
216 | (os.name,sys.platform) ) |
|
|||
217 | rpt_add(sec_sep+'Current user configuration structure:\n\n') |
|
|||
218 | # rpt_add(pformat(self.IP.dict())) |
|
|||
219 | rpt_add(sec_sep+'Crash traceback:\n\n' + traceback) |
|
|||
220 | try: |
|
211 | try: | |
221 | rpt_add(sec_sep+"History of session input:") |
|
212 | rpt_add(sec_sep+"History of session input:") | |
222 |
for line in self. |
|
213 | for line in self.app.shell.user_ns['_ih']: | |
223 | rpt_add(line) |
|
214 | rpt_add(line) | |
224 | rpt_add('\n*** Last line of input (may not be in above history):\n') |
|
215 | rpt_add('\n*** Last line of input (may not be in above history):\n') | |
225 |
rpt_add(self. |
|
216 | rpt_add(self.app.shell._last_input_line+'\n') | |
226 | except: |
|
217 | except: | |
227 | pass |
|
218 | pass | |
228 |
|
219 |
@@ -28,6 +28,7 b' import logging' | |||||
28 | import os |
|
28 | import os | |
29 | import sys |
|
29 | import sys | |
30 |
|
30 | |||
|
31 | from IPython.core import crashhandler | |||
31 | from IPython.core import release |
|
32 | from IPython.core import release | |
32 | from IPython.core.application import Application, BaseAppArgParseConfigLoader |
|
33 | from IPython.core.application import Application, BaseAppArgParseConfigLoader | |
33 | from IPython.core.error import UsageError |
|
34 | from IPython.core.error import UsageError | |
@@ -280,19 +281,18 b' cl_args = (' | |||||
280 | ) |
|
281 | ) | |
281 |
|
282 | |||
282 |
|
283 | |||
283 | class IPythonAppCLConfigLoader(BaseAppArgParseConfigLoader): |
|
|||
284 |
|
||||
285 | arguments = cl_args |
|
|||
286 |
|
||||
287 |
|
||||
288 | default_config_file_name = u'ipython_config.py' |
|
284 | default_config_file_name = u'ipython_config.py' | |
289 |
|
285 | |||
290 |
|
||||
291 | class IPythonApp(Application): |
|
286 | class IPythonApp(Application): | |
292 | name = u'ipython' |
|
287 | name = u'ipython' | |
293 | description = 'IPython: an enhanced interactive Python shell.' |
|
288 | description = 'IPython: an enhanced interactive Python shell.' | |
294 | config_file_name = default_config_file_name |
|
289 | config_file_name = default_config_file_name | |
295 |
|
290 | |||
|
291 | cl_arguments = Application.cl_arguments + cl_args | |||
|
292 | ||||
|
293 | # Private and configuration attributes | |||
|
294 | _CrashHandler = crashhandler.IPythonCrashHandler | |||
|
295 | ||||
296 | def __init__(self, argv=None, **shell_params): |
|
296 | def __init__(self, argv=None, **shell_params): | |
297 | """Create a new IPythonApp. |
|
297 | """Create a new IPythonApp. | |
298 |
|
298 | |||
@@ -309,6 +309,7 b' class IPythonApp(Application):' | |||||
309 | super(IPythonApp, self).__init__(argv) |
|
309 | super(IPythonApp, self).__init__(argv) | |
310 | self.shell_params = shell_params |
|
310 | self.shell_params = shell_params | |
311 |
|
311 | |||
|
312 | ||||
312 | def create_default_config(self): |
|
313 | def create_default_config(self): | |
313 | super(IPythonApp, self).create_default_config() |
|
314 | super(IPythonApp, self).create_default_config() | |
314 | # Eliminate multiple lookups |
|
315 | # Eliminate multiple lookups | |
@@ -340,13 +341,6 b' class IPythonApp(Application):' | |||||
340 | Global.wthread = False |
|
341 | Global.wthread = False | |
341 | Global.gthread = False |
|
342 | Global.gthread = False | |
342 |
|
343 | |||
343 | def create_command_line_config(self): |
|
|||
344 | """Create and return a command line config loader.""" |
|
|||
345 | return IPythonAppCLConfigLoader(self.argv, |
|
|||
346 | description=self.description, |
|
|||
347 | version=release.version |
|
|||
348 | ) |
|
|||
349 |
|
||||
350 | def load_file_config(self): |
|
344 | def load_file_config(self): | |
351 | if hasattr(self.command_line_config.Global, 'quick'): |
|
345 | if hasattr(self.command_line_config.Global, 'quick'): | |
352 | if self.command_line_config.Global.quick: |
|
346 | if self.command_line_config.Global.quick: |
@@ -1167,37 +1167,14 b' class InteractiveShell(Component, Magic):' | |||||
1167 | color_scheme='NoColor', |
|
1167 | color_scheme='NoColor', | |
1168 | tb_offset = 1) |
|
1168 | tb_offset = 1) | |
1169 |
|
1169 | |||
1170 | # IPython itself shouldn't crash. This will produce a detailed |
|
1170 | # The instance will store a pointer to the system-wide exception hook, | |
1171 | # post-mortem if it does. But we only install the crash handler for |
|
1171 | # so that runtime code (such as magics) can access it. This is because | |
1172 | # non-threaded shells, the threaded ones use a normal verbose reporter |
|
1172 | # during the read-eval loop, it may get temporarily overwritten. | |
1173 | # and lose the crash handler. This is because exceptions in the main |
|
1173 | self.sys_excepthook = sys.excepthook | |
1174 | # thread (such as in GUI code) propagate directly to sys.excepthook, |
|
|||
1175 | # and there's no point in printing crash dumps for every user exception. |
|
|||
1176 | if self.isthreaded: |
|
|||
1177 | ipCrashHandler = ultratb.FormattedTB() |
|
|||
1178 | else: |
|
|||
1179 | from IPython.core import crashhandler |
|
|||
1180 | ipCrashHandler = crashhandler.IPythonCrashHandler(self) |
|
|||
1181 | self.set_crash_handler(ipCrashHandler) |
|
|||
1182 |
|
1174 | |||
1183 | # and add any custom exception handlers the user may have specified |
|
1175 | # and add any custom exception handlers the user may have specified | |
1184 | self.set_custom_exc(*custom_exceptions) |
|
1176 | self.set_custom_exc(*custom_exceptions) | |
1185 |
|
1177 | |||
1186 | def set_crash_handler(self, crashHandler): |
|
|||
1187 | """Set the IPython crash handler. |
|
|||
1188 |
|
||||
1189 | This must be a callable with a signature suitable for use as |
|
|||
1190 | sys.excepthook.""" |
|
|||
1191 |
|
||||
1192 | # Install the given crash handler as the Python exception hook |
|
|||
1193 | sys.excepthook = crashHandler |
|
|||
1194 |
|
||||
1195 | # The instance will store a pointer to this, so that runtime code |
|
|||
1196 | # (such as magics) can access it. This is because during the |
|
|||
1197 | # read-eval loop, it gets temporarily overwritten (to deal with GUI |
|
|||
1198 | # frameworks). |
|
|||
1199 | self.sys_excepthook = sys.excepthook |
|
|||
1200 |
|
||||
1201 | def set_custom_exc(self,exc_tuple,handler): |
|
1178 | def set_custom_exc(self,exc_tuple,handler): | |
1202 | """set_custom_exc(exc_tuple,handler) |
|
1179 | """set_custom_exc(exc_tuple,handler) | |
1203 |
|
1180 | |||
@@ -1880,7 +1857,7 b' class InteractiveShell(Component, Magic):' | |||||
1880 | if (self.SyntaxTB.last_syntax_error and |
|
1857 | if (self.SyntaxTB.last_syntax_error and | |
1881 | self.autoedit_syntax): |
|
1858 | self.autoedit_syntax): | |
1882 | self.edit_syntax_error() |
|
1859 | self.edit_syntax_error() | |
1883 |
|
1860 | |||
1884 | # We are off again... |
|
1861 | # We are off again... | |
1885 | __builtin__.__dict__['__IPYTHON__active'] -= 1 |
|
1862 | __builtin__.__dict__['__IPYTHON__active'] -= 1 | |
1886 |
|
1863 |
@@ -77,12 +77,6 b' class PrefilterFrontEnd(LineFrontEndBase):' | |||||
77 | """ |
|
77 | """ | |
78 | if argv is None: |
|
78 | if argv is None: | |
79 | argv = ['--no-banner'] |
|
79 | argv = ['--no-banner'] | |
80 | # This is a hack to avoid the IPython exception hook to trigger |
|
|||
81 | # on exceptions (https://bugs.launchpad.net/bugs/337105) |
|
|||
82 | # XXX: This is horrible: module-leve monkey patching -> side |
|
|||
83 | # effects. |
|
|||
84 | from IPython.core import iplib |
|
|||
85 | iplib.InteractiveShell.isthreaded = True |
|
|||
86 |
|
80 | |||
87 | LineFrontEndBase.__init__(self, *args, **kwargs) |
|
81 | LineFrontEndBase.__init__(self, *args, **kwargs) | |
88 | self.shell.output_trap = RedirectorOutputTrap( |
|
82 | self.shell.output_trap = RedirectorOutputTrap( |
@@ -88,9 +88,6 b' def isolate_ipython0(func):' | |||||
88 | del user_ns[k] |
|
88 | del user_ns[k] | |
89 | for k in new_globals: |
|
89 | for k in new_globals: | |
90 | del user_global_ns[k] |
|
90 | del user_global_ns[k] | |
91 | # Undo the hack at creation of PrefilterFrontEnd |
|
|||
92 | from IPython.core import iplib |
|
|||
93 | iplib.InteractiveShell.isthreaded = False |
|
|||
94 | return out |
|
91 | return out | |
95 |
|
92 | |||
96 | my_func.__name__ = func.__name__ |
|
93 | my_func.__name__ = func.__name__ |
General Comments 0
You need to be logged in to leave comments.
Login now