##// END OF EJS Templates
crlf -> lf
Ville M. Vainio -
r1032:4aabf05c
parent child
Show More

The requested changes are too big and content was truncated. Show full diff

@@ -1,170 +1,170
1 # -*- coding: utf-8 -*-
1 # -*- coding: utf-8 -*-
2 """Tools for coloring text in ANSI terminals.
2 """Tools for coloring text in ANSI terminals.
3
3
4 $Id: ColorANSI.py 2167 2007-03-21 06:57:50Z fperez $"""
4 $Id: ColorANSI.py 2167 2007-03-21 06:57:50Z fperez $"""
5
5
6 #*****************************************************************************
6 #*****************************************************************************
7 # Copyright (C) 2002-2006 Fernando Perez. <fperez@colorado.edu>
7 # Copyright (C) 2002-2006 Fernando Perez. <fperez@colorado.edu>
8 #
8 #
9 # Distributed under the terms of the BSD License. The full license is in
9 # Distributed under the terms of the BSD License. The full license is in
10 # the file COPYING, distributed as part of this software.
10 # the file COPYING, distributed as part of this software.
11 #*****************************************************************************
11 #*****************************************************************************
12
12
13 from IPython import Release
13 from IPython import Release
14 __author__ = '%s <%s>' % Release.authors['Fernando']
14 __author__ = '%s <%s>' % Release.authors['Fernando']
15 __license__ = Release.license
15 __license__ = Release.license
16
16
17 __all__ = ['TermColors','InputTermColors','ColorScheme','ColorSchemeTable']
17 __all__ = ['TermColors','InputTermColors','ColorScheme','ColorSchemeTable']
18
18
19 import os
19 import os
20
20
21 from IPython.ipstruct import Struct
21 from IPython.ipstruct import Struct
22
22
23 def make_color_table(in_class):
23 def make_color_table(in_class):
24 """Build a set of color attributes in a class.
24 """Build a set of color attributes in a class.
25
25
26 Helper function for building the *TermColors classes."""
26 Helper function for building the *TermColors classes."""
27
27
28 color_templates = (
28 color_templates = (
29 ("Black" , "0;30"),
29 ("Black" , "0;30"),
30 ("Red" , "0;31"),
30 ("Red" , "0;31"),
31 ("Green" , "0;32"),
31 ("Green" , "0;32"),
32 ("Brown" , "0;33"),
32 ("Brown" , "0;33"),
33 ("Blue" , "0;34"),
33 ("Blue" , "0;34"),
34 ("Purple" , "0;35"),
34 ("Purple" , "0;35"),
35 ("Cyan" , "0;36"),
35 ("Cyan" , "0;36"),
36 ("LightGray" , "0;37"),
36 ("LightGray" , "0;37"),
37 ("DarkGray" , "1;30"),
37 ("DarkGray" , "1;30"),
38 ("LightRed" , "1;31"),
38 ("LightRed" , "1;31"),
39 ("LightGreen" , "1;32"),
39 ("LightGreen" , "1;32"),
40 ("Yellow" , "1;33"),
40 ("Yellow" , "1;33"),
41 ("LightBlue" , "1;34"),
41 ("LightBlue" , "1;34"),
42 ("LightPurple" , "1;35"),
42 ("LightPurple" , "1;35"),
43 ("LightCyan" , "1;36"),
43 ("LightCyan" , "1;36"),
44 ("White" , "1;37"), )
44 ("White" , "1;37"), )
45
45
46 for name,value in color_templates:
46 for name,value in color_templates:
47 setattr(in_class,name,in_class._base % value)
47 setattr(in_class,name,in_class._base % value)
48
48
49 class TermColors:
49 class TermColors:
50 """Color escape sequences.
50 """Color escape sequences.
51
51
52 This class defines the escape sequences for all the standard (ANSI?)
52 This class defines the escape sequences for all the standard (ANSI?)
53 colors in terminals. Also defines a NoColor escape which is just the null
53 colors in terminals. Also defines a NoColor escape which is just the null
54 string, suitable for defining 'dummy' color schemes in terminals which get
54 string, suitable for defining 'dummy' color schemes in terminals which get
55 confused by color escapes.
55 confused by color escapes.
56
56
57 This class should be used as a mixin for building color schemes."""
57 This class should be used as a mixin for building color schemes."""
58
58
59 NoColor = '' # for color schemes in color-less terminals.
59 NoColor = '' # for color schemes in color-less terminals.
60 Normal = '\033[0m' # Reset normal coloring
60 Normal = '\033[0m' # Reset normal coloring
61 _base = '\033[%sm' # Template for all other colors
61 _base = '\033[%sm' # Template for all other colors
62
62
63 # Build the actual color table as a set of class attributes:
63 # Build the actual color table as a set of class attributes:
64 make_color_table(TermColors)
64 make_color_table(TermColors)
65
65
66 class InputTermColors:
66 class InputTermColors:
67 """Color escape sequences for input prompts.
67 """Color escape sequences for input prompts.
68
68
69 This class is similar to TermColors, but the escapes are wrapped in \001
69 This class is similar to TermColors, but the escapes are wrapped in \001
70 and \002 so that readline can properly know the length of each line and
70 and \002 so that readline can properly know the length of each line and
71 can wrap lines accordingly. Use this class for any colored text which
71 can wrap lines accordingly. Use this class for any colored text which
72 needs to be used in input prompts, such as in calls to raw_input().
72 needs to be used in input prompts, such as in calls to raw_input().
73
73
74 This class defines the escape sequences for all the standard (ANSI?)
74 This class defines the escape sequences for all the standard (ANSI?)
75 colors in terminals. Also defines a NoColor escape which is just the null
75 colors in terminals. Also defines a NoColor escape which is just the null
76 string, suitable for defining 'dummy' color schemes in terminals which get
76 string, suitable for defining 'dummy' color schemes in terminals which get
77 confused by color escapes.
77 confused by color escapes.
78
78
79 This class should be used as a mixin for building color schemes."""
79 This class should be used as a mixin for building color schemes."""
80
80
81 NoColor = '' # for color schemes in color-less terminals.
81 NoColor = '' # for color schemes in color-less terminals.
82
82
83 if os.name == 'nt' and os.environ.get('TERM','dumb') == 'emacs':
83 if os.name == 'nt' and os.environ.get('TERM','dumb') == 'emacs':
84 # (X)emacs on W32 gets confused with \001 and \002 so we remove them
84 # (X)emacs on W32 gets confused with \001 and \002 so we remove them
85 Normal = '\033[0m' # Reset normal coloring
85 Normal = '\033[0m' # Reset normal coloring
86 _base = '\033[%sm' # Template for all other colors
86 _base = '\033[%sm' # Template for all other colors
87 else:
87 else:
88 Normal = '\001\033[0m\002' # Reset normal coloring
88 Normal = '\001\033[0m\002' # Reset normal coloring
89 _base = '\001\033[%sm\002' # Template for all other colors
89 _base = '\001\033[%sm\002' # Template for all other colors
90
90
91 # Build the actual color table as a set of class attributes:
91 # Build the actual color table as a set of class attributes:
92 make_color_table(InputTermColors)
92 make_color_table(InputTermColors)
93
93
94 class ColorScheme:
94 class ColorScheme:
95 """Generic color scheme class. Just a name and a Struct."""
95 """Generic color scheme class. Just a name and a Struct."""
96 def __init__(self,__scheme_name_,colordict=None,**colormap):
96 def __init__(self,__scheme_name_,colordict=None,**colormap):
97 self.name = __scheme_name_
97 self.name = __scheme_name_
98 if colordict is None:
98 if colordict is None:
99 self.colors = Struct(**colormap)
99 self.colors = Struct(**colormap)
100 else:
100 else:
101 self.colors = Struct(colordict)
101 self.colors = Struct(colordict)
102
102
103 def copy(self,name=None):
103 def copy(self,name=None):
104 """Return a full copy of the object, optionally renaming it."""
104 """Return a full copy of the object, optionally renaming it."""
105 if name is None:
105 if name is None:
106 name = self.name
106 name = self.name
107 return ColorScheme(name,self.colors.__dict__)
107 return ColorScheme(name,self.colors.__dict__)
108
108
109 class ColorSchemeTable(dict):
109 class ColorSchemeTable(dict):
110 """General class to handle tables of color schemes.
110 """General class to handle tables of color schemes.
111
111
112 It's basically a dict of color schemes with a couple of shorthand
112 It's basically a dict of color schemes with a couple of shorthand
113 attributes and some convenient methods.
113 attributes and some convenient methods.
114
114
115 active_scheme_name -> obvious
115 active_scheme_name -> obvious
116 active_colors -> actual color table of the active scheme"""
116 active_colors -> actual color table of the active scheme"""
117
117
118 def __init__(self,scheme_list=None,default_scheme=''):
118 def __init__(self,scheme_list=None,default_scheme=''):
119 """Create a table of color schemes.
119 """Create a table of color schemes.
120
120
121 The table can be created empty and manually filled or it can be
121 The table can be created empty and manually filled or it can be
122 created with a list of valid color schemes AND the specification for
122 created with a list of valid color schemes AND the specification for
123 the default active scheme.
123 the default active scheme.
124 """
124 """
125
125
126 # create object attributes to be set later
126 # create object attributes to be set later
127 self.active_scheme_name = ''
127 self.active_scheme_name = ''
128 self.active_colors = None
128 self.active_colors = None
129
129
130 if scheme_list:
130 if scheme_list:
131 if default_scheme == '':
131 if default_scheme == '':
132 raise ValueError,'you must specify the default color scheme'
132 raise ValueError,'you must specify the default color scheme'
133 for scheme in scheme_list:
133 for scheme in scheme_list:
134 self.add_scheme(scheme)
134 self.add_scheme(scheme)
135 self.set_active_scheme(default_scheme)
135 self.set_active_scheme(default_scheme)
136
136
137 def copy(self):
137 def copy(self):
138 """Return full copy of object"""
138 """Return full copy of object"""
139 return ColorSchemeTable(self.values(),self.active_scheme_name)
139 return ColorSchemeTable(self.values(),self.active_scheme_name)
140
140
141 def add_scheme(self,new_scheme):
141 def add_scheme(self,new_scheme):
142 """Add a new color scheme to the table."""
142 """Add a new color scheme to the table."""
143 if not isinstance(new_scheme,ColorScheme):
143 if not isinstance(new_scheme,ColorScheme):
144 raise ValueError,'ColorSchemeTable only accepts ColorScheme instances'
144 raise ValueError,'ColorSchemeTable only accepts ColorScheme instances'
145 self[new_scheme.name] = new_scheme
145 self[new_scheme.name] = new_scheme
146
146
147 def set_active_scheme(self,scheme,case_sensitive=0):
147 def set_active_scheme(self,scheme,case_sensitive=0):
148 """Set the currently active scheme.
148 """Set the currently active scheme.
149
149
150 Names are by default compared in a case-insensitive way, but this can
150 Names are by default compared in a case-insensitive way, but this can
151 be changed by setting the parameter case_sensitive to true."""
151 be changed by setting the parameter case_sensitive to true."""
152
152
153 scheme_names = self.keys()
153 scheme_names = self.keys()
154 if case_sensitive:
154 if case_sensitive:
155 valid_schemes = scheme_names
155 valid_schemes = scheme_names
156 scheme_test = scheme
156 scheme_test = scheme
157 else:
157 else:
158 valid_schemes = [s.lower() for s in scheme_names]
158 valid_schemes = [s.lower() for s in scheme_names]
159 scheme_test = scheme.lower()
159 scheme_test = scheme.lower()
160 try:
160 try:
161 scheme_idx = valid_schemes.index(scheme_test)
161 scheme_idx = valid_schemes.index(scheme_test)
162 except ValueError:
162 except ValueError:
163 raise ValueError,'Unrecognized color scheme: ' + scheme + \
163 raise ValueError,'Unrecognized color scheme: ' + scheme + \
164 '\nValid schemes: '+str(scheme_names).replace("'', ",'')
164 '\nValid schemes: '+str(scheme_names).replace("'', ",'')
165 else:
165 else:
166 active = scheme_names[scheme_idx]
166 active = scheme_names[scheme_idx]
167 self.active_scheme_name = active
167 self.active_scheme_name = active
168 self.active_colors = self[active].colors
168 self.active_colors = self[active].colors
169 # Now allow using '' as an index for the current active scheme
169 # Now allow using '' as an index for the current active scheme
170 self[''] = self[active]
170 self[''] = self[active]
@@ -1,116 +1,116
1 # -*- coding: utf-8 -*-
1 # -*- coding: utf-8 -*-
2 """Configuration loader
2 """Configuration loader
3
3
4 $Id: ConfigLoader.py 1005 2006-01-12 08:39:26Z fperez $"""
4 $Id: ConfigLoader.py 1005 2006-01-12 08:39:26Z fperez $"""
5
5
6 #*****************************************************************************
6 #*****************************************************************************
7 # Copyright (C) 2001-2006 Fernando Perez. <fperez@colorado.edu>
7 # Copyright (C) 2001-2006 Fernando Perez. <fperez@colorado.edu>
8 #
8 #
9 # Distributed under the terms of the BSD License. The full license is in
9 # Distributed under the terms of the BSD License. The full license is in
10 # the file COPYING, distributed as part of this software.
10 # the file COPYING, distributed as part of this software.
11 #*****************************************************************************
11 #*****************************************************************************
12
12
13 from IPython import Release
13 from IPython import Release
14 __author__ = '%s <%s>' % Release.authors['Fernando']
14 __author__ = '%s <%s>' % Release.authors['Fernando']
15 __license__ = Release.license
15 __license__ = Release.license
16
16
17 import exceptions
17 import exceptions
18 import os
18 import os
19 from pprint import pprint
19 from pprint import pprint
20
20
21 from IPython import ultraTB
21 from IPython import ultraTB
22 from IPython.ipstruct import Struct
22 from IPython.ipstruct import Struct
23 from IPython.genutils import *
23 from IPython.genutils import *
24
24
25 class ConfigLoaderError(exceptions.Exception):
25 class ConfigLoaderError(exceptions.Exception):
26 """Exception for ConfigLoader class."""
26 """Exception for ConfigLoader class."""
27
27
28 def __init__(self,args=None):
28 def __init__(self,args=None):
29 self.args = args
29 self.args = args
30
30
31 class ConfigLoader:
31 class ConfigLoader:
32
32
33 """Configuration file loader capable of handling recursive inclusions and
33 """Configuration file loader capable of handling recursive inclusions and
34 with parametrized conflict resolution for multiply found keys."""
34 with parametrized conflict resolution for multiply found keys."""
35
35
36 def __init__(self,conflict=None,field_sep=None,reclimit=15):
36 def __init__(self,conflict=None,field_sep=None,reclimit=15):
37
37
38 """The reclimit parameter controls the number of recursive
38 """The reclimit parameter controls the number of recursive
39 configuration file inclusions. This way we can stop early on (before
39 configuration file inclusions. This way we can stop early on (before
40 python's own recursion limit is hit) if there is a circular
40 python's own recursion limit is hit) if there is a circular
41 inclusion.
41 inclusion.
42
42
43 - conflict: dictionary for conflict resolutions (see Struct.merge())
43 - conflict: dictionary for conflict resolutions (see Struct.merge())
44
44
45 """
45 """
46 self.conflict = conflict
46 self.conflict = conflict
47 self.field_sep = field_sep
47 self.field_sep = field_sep
48 self.reset(reclimit)
48 self.reset(reclimit)
49
49
50 def reset(self,reclimit=15):
50 def reset(self,reclimit=15):
51 self.reclimit = reclimit
51 self.reclimit = reclimit
52 self.recdepth = 0
52 self.recdepth = 0
53 self.included = []
53 self.included = []
54
54
55 def load(self,fname,convert=None,recurse_key='',incpath = '.',**kw):
55 def load(self,fname,convert=None,recurse_key='',incpath = '.',**kw):
56 """Load a configuration file, return the resulting Struct.
56 """Load a configuration file, return the resulting Struct.
57
57
58 Call: load_config(fname,convert=None,conflict=None,recurse_key='')
58 Call: load_config(fname,convert=None,conflict=None,recurse_key='')
59
59
60 - fname: file to load from.
60 - fname: file to load from.
61 - convert: dictionary of type conversions (see read_dict())
61 - convert: dictionary of type conversions (see read_dict())
62 - recurse_key: keyword in dictionary to trigger recursive file
62 - recurse_key: keyword in dictionary to trigger recursive file
63 inclusions.
63 inclusions.
64 """
64 """
65
65
66 if self.recdepth > self.reclimit:
66 if self.recdepth > self.reclimit:
67 raise ConfigLoaderError, 'maximum recursive inclusion of rcfiles '+\
67 raise ConfigLoaderError, 'maximum recursive inclusion of rcfiles '+\
68 'exceeded: ' + `self.recdepth` + \
68 'exceeded: ' + `self.recdepth` + \
69 '.\nMaybe you have a circular chain of inclusions?'
69 '.\nMaybe you have a circular chain of inclusions?'
70 self.recdepth += 1
70 self.recdepth += 1
71 fname = filefind(fname,incpath)
71 fname = filefind(fname,incpath)
72 data = Struct()
72 data = Struct()
73 # avoid including the same file more than once
73 # avoid including the same file more than once
74 if fname in self.included:
74 if fname in self.included:
75 return data
75 return data
76 Xinfo = ultraTB.AutoFormattedTB()
76 Xinfo = ultraTB.AutoFormattedTB()
77 if convert==None and recurse_key : convert = {qwflat:recurse_key}
77 if convert==None and recurse_key : convert = {qwflat:recurse_key}
78 # for production, change warn to 0:
78 # for production, change warn to 0:
79 data.merge(read_dict(fname,convert,fs=self.field_sep,strip=1,
79 data.merge(read_dict(fname,convert,fs=self.field_sep,strip=1,
80 warn=0,no_empty=0,**kw))
80 warn=0,no_empty=0,**kw))
81 # keep track of successfully loaded files
81 # keep track of successfully loaded files
82 self.included.append(fname)
82 self.included.append(fname)
83 if recurse_key in data.keys():
83 if recurse_key in data.keys():
84 for incfilename in data[recurse_key]:
84 for incfilename in data[recurse_key]:
85 found=0
85 found=0
86 try:
86 try:
87 incfile = filefind(incfilename,incpath)
87 incfile = filefind(incfilename,incpath)
88 except IOError:
88 except IOError:
89 if os.name in ['nt','dos']:
89 if os.name in ['nt','dos']:
90 try:
90 try:
91 # Try again with '.ini' extension
91 # Try again with '.ini' extension
92 incfilename += '.ini'
92 incfilename += '.ini'
93 incfile = filefind(incfilename,incpath)
93 incfile = filefind(incfilename,incpath)
94 except IOError:
94 except IOError:
95 found = 0
95 found = 0
96 else:
96 else:
97 found = 1
97 found = 1
98 else:
98 else:
99 found = 0
99 found = 0
100 else:
100 else:
101 found = 1
101 found = 1
102 if found:
102 if found:
103 try:
103 try:
104 data.merge(self.load(incfile,convert,recurse_key,
104 data.merge(self.load(incfile,convert,recurse_key,
105 incpath,**kw),
105 incpath,**kw),
106 self.conflict)
106 self.conflict)
107 except:
107 except:
108 Xinfo()
108 Xinfo()
109 warn('Problem loading included file: '+
109 warn('Problem loading included file: '+
110 `incfilename` + '. Ignoring it...')
110 `incfilename` + '. Ignoring it...')
111 else:
111 else:
112 warn('File `%s` not found. Included by %s' % (incfilename,fname))
112 warn('File `%s` not found. Included by %s' % (incfilename,fname))
113
113
114 return data
114 return data
115
115
116 # end ConfigLoader
116 # end ConfigLoader
@@ -1,228 +1,228
1 # -*- coding: utf-8 -*-
1 # -*- coding: 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 $Id: CrashHandler.py 2908 2007-12-30 21:07:46Z vivainio $"""
4 $Id: CrashHandler.py 2908 2007-12-30 21:07:46Z vivainio $"""
5
5
6 #*****************************************************************************
6 #*****************************************************************************
7 # Copyright (C) 2001-2006 Fernando Perez. <fperez@colorado.edu>
7 # Copyright (C) 2001-2006 Fernando Perez. <fperez@colorado.edu>
8 #
8 #
9 # Distributed under the terms of the BSD License. The full license is in
9 # Distributed under the terms of the BSD License. The full license is in
10 # the file COPYING, distributed as part of this software.
10 # the file COPYING, distributed as part of this software.
11 #*****************************************************************************
11 #*****************************************************************************
12
12
13 from IPython import Release
13 from IPython import Release
14 __author__ = '%s <%s>' % Release.authors['Fernando']
14 __author__ = '%s <%s>' % Release.authors['Fernando']
15 __license__ = Release.license
15 __license__ = Release.license
16 __version__ = Release.version
16 __version__ = Release.version
17
17
18 #****************************************************************************
18 #****************************************************************************
19 # Required modules
19 # Required modules
20
20
21 # From the standard library
21 # From the standard library
22 import os
22 import os
23 import sys
23 import sys
24 from pprint import pprint,pformat
24 from pprint import pprint,pformat
25
25
26 # Homebrewed
26 # Homebrewed
27 from IPython.Itpl import Itpl,itpl,printpl
27 from IPython.Itpl import Itpl,itpl,printpl
28 from IPython.ColorANSI import ColorScheme,ColorSchemeTable # too long names
28 from IPython.ColorANSI import ColorScheme,ColorSchemeTable # too long names
29 from IPython import ultraTB
29 from IPython import ultraTB
30 from IPython.genutils import *
30 from IPython.genutils import *
31
31
32 #****************************************************************************
32 #****************************************************************************
33 class CrashHandler:
33 class CrashHandler:
34 """Customizable crash handlers for IPython-based systems.
34 """Customizable crash handlers for IPython-based systems.
35
35
36 Instances of this class provide a __call__ method which can be used as a
36 Instances of this class provide a __call__ method which can be used as a
37 sys.excepthook, i.e., the __call__ signature is:
37 sys.excepthook, i.e., the __call__ signature is:
38
38
39 def __call__(self,etype, evalue, etb)
39 def __call__(self,etype, evalue, etb)
40
40
41 """
41 """
42
42
43 def __init__(self,IP,app_name,contact_name,contact_email,
43 def __init__(self,IP,app_name,contact_name,contact_email,
44 bug_tracker,crash_report_fname,
44 bug_tracker,crash_report_fname,
45 show_crash_traceback=True):
45 show_crash_traceback=True):
46 """New crash handler.
46 """New crash handler.
47
47
48 Inputs:
48 Inputs:
49
49
50 - IP: a running IPython instance, which will be queried at crash time
50 - IP: a running IPython instance, which will be queried at crash time
51 for internal information.
51 for internal information.
52
52
53 - app_name: a string containing the name of your application.
53 - app_name: a string containing the name of your application.
54
54
55 - contact_name: a string with the name of the person to contact.
55 - contact_name: a string with the name of the person to contact.
56
56
57 - contact_email: a string with the email address of the contact.
57 - contact_email: a string with the email address of the contact.
58
58
59 - bug_tracker: a string with the URL for your project's bug tracker.
59 - bug_tracker: a string with the URL for your project's bug tracker.
60
60
61 - crash_report_fname: a string with the filename for the crash report
61 - crash_report_fname: a string with the filename for the crash report
62 to be saved in. These reports are left in the ipython user directory
62 to be saved in. These reports are left in the ipython user directory
63 as determined by the running IPython instance.
63 as determined by the running IPython instance.
64
64
65 Optional inputs:
65 Optional inputs:
66
66
67 - show_crash_traceback(True): if false, don't print the crash
67 - show_crash_traceback(True): if false, don't print the crash
68 traceback on stderr, only generate the on-disk report
68 traceback on stderr, only generate the on-disk report
69
69
70
70
71 Non-argument instance attributes:
71 Non-argument instance attributes:
72
72
73 These instances contain some non-argument attributes which allow for
73 These instances contain some non-argument attributes which allow for
74 further customization of the crash handler's behavior. Please see the
74 further customization of the crash handler's behavior. Please see the
75 source for further details.
75 source for further details.
76 """
76 """
77
77
78 # apply args into instance
78 # apply args into instance
79 self.IP = IP # IPython instance
79 self.IP = IP # IPython instance
80 self.app_name = app_name
80 self.app_name = app_name
81 self.contact_name = contact_name
81 self.contact_name = contact_name
82 self.contact_email = contact_email
82 self.contact_email = contact_email
83 self.bug_tracker = bug_tracker
83 self.bug_tracker = bug_tracker
84 self.crash_report_fname = crash_report_fname
84 self.crash_report_fname = crash_report_fname
85 self.show_crash_traceback = show_crash_traceback
85 self.show_crash_traceback = show_crash_traceback
86
86
87 # Hardcoded defaults, which can be overridden either by subclasses or
87 # Hardcoded defaults, which can be overridden either by subclasses or
88 # at runtime for the instance.
88 # at runtime for the instance.
89
89
90 # Template for the user message. Subclasses which completely override
90 # Template for the user message. Subclasses which completely override
91 # this, or user apps, can modify it to suit their tastes. It gets
91 # this, or user apps, can modify it to suit their tastes. It gets
92 # expanded using itpl, so calls of the kind $self.foo are valid.
92 # expanded using itpl, so calls of the kind $self.foo are valid.
93 self.user_message_template = """
93 self.user_message_template = """
94 Oops, $self.app_name crashed. We do our best to make it stable, but...
94 Oops, $self.app_name crashed. We do our best to make it stable, but...
95
95
96 A crash report was automatically generated with the following information:
96 A crash report was automatically generated with the following information:
97 - A verbatim copy of the crash traceback.
97 - A verbatim copy of the crash traceback.
98 - A copy of your input history during this session.
98 - A copy of your input history during this session.
99 - Data on your current $self.app_name configuration.
99 - Data on your current $self.app_name configuration.
100
100
101 It was left in the file named:
101 It was left in the file named:
102 \t'$self.crash_report_fname'
102 \t'$self.crash_report_fname'
103 If you can email this file to the developers, the information in it will help
103 If you can email this file to the developers, the information in it will help
104 them in understanding and correcting the problem.
104 them in understanding and correcting the problem.
105
105
106 You can mail it to: $self.contact_name at $self.contact_email
106 You can mail it to: $self.contact_name at $self.contact_email
107 with the subject '$self.app_name Crash Report'.
107 with the subject '$self.app_name Crash Report'.
108
108
109 If you want to do it now, the following command will work (under Unix):
109 If you want to do it now, the following command will work (under Unix):
110 mail -s '$self.app_name Crash Report' $self.contact_email < $self.crash_report_fname
110 mail -s '$self.app_name Crash Report' $self.contact_email < $self.crash_report_fname
111
111
112 To ensure accurate tracking of this issue, please file a report about it at:
112 To ensure accurate tracking of this issue, please file a report about it at:
113 $self.bug_tracker
113 $self.bug_tracker
114 """
114 """
115
115
116 def __call__(self,etype, evalue, etb):
116 def __call__(self,etype, evalue, etb):
117 """Handle an exception, call for compatible with sys.excepthook"""
117 """Handle an exception, call for compatible with sys.excepthook"""
118
118
119 # Report tracebacks shouldn't use color in general (safer for users)
119 # Report tracebacks shouldn't use color in general (safer for users)
120 color_scheme = 'NoColor'
120 color_scheme = 'NoColor'
121
121
122 # Use this ONLY for developer debugging (keep commented out for release)
122 # Use this ONLY for developer debugging (keep commented out for release)
123 #color_scheme = 'Linux' # dbg
123 #color_scheme = 'Linux' # dbg
124
124
125 try:
125 try:
126 rptdir = self.IP.rc.ipythondir
126 rptdir = self.IP.rc.ipythondir
127 except:
127 except:
128 rptdir = os.getcwd()
128 rptdir = os.getcwd()
129 if not os.path.isdir(rptdir):
129 if not os.path.isdir(rptdir):
130 rptdir = os.getcwd()
130 rptdir = os.getcwd()
131 report_name = os.path.join(rptdir,self.crash_report_fname)
131 report_name = os.path.join(rptdir,self.crash_report_fname)
132 # write the report filename into the instance dict so it can get
132 # write the report filename into the instance dict so it can get
133 # properly expanded out in the user message template
133 # properly expanded out in the user message template
134 self.crash_report_fname = report_name
134 self.crash_report_fname = report_name
135 TBhandler = ultraTB.VerboseTB(color_scheme=color_scheme,
135 TBhandler = ultraTB.VerboseTB(color_scheme=color_scheme,
136 long_header=1)
136 long_header=1)
137 traceback = TBhandler.text(etype,evalue,etb,context=31)
137 traceback = TBhandler.text(etype,evalue,etb,context=31)
138
138
139 # print traceback to screen
139 # print traceback to screen
140 if self.show_crash_traceback:
140 if self.show_crash_traceback:
141 print >> sys.stderr, traceback
141 print >> sys.stderr, traceback
142
142
143 # and generate a complete report on disk
143 # and generate a complete report on disk
144 try:
144 try:
145 report = open(report_name,'w')
145 report = open(report_name,'w')
146 except:
146 except:
147 print >> sys.stderr, 'Could not create crash report on disk.'
147 print >> sys.stderr, 'Could not create crash report on disk.'
148 return
148 return
149
149
150 # Inform user on stderr of what happened
150 # Inform user on stderr of what happened
151 msg = itpl('\n'+'*'*70+'\n'+self.user_message_template)
151 msg = itpl('\n'+'*'*70+'\n'+self.user_message_template)
152 print >> sys.stderr, msg
152 print >> sys.stderr, msg
153
153
154 # Construct report on disk
154 # Construct report on disk
155 report.write(self.make_report(traceback))
155 report.write(self.make_report(traceback))
156 report.close()
156 report.close()
157 raw_input("Press enter to exit:")
157 raw_input("Press enter to exit:")
158
158
159 def make_report(self,traceback):
159 def make_report(self,traceback):
160 """Return a string containing a crash report."""
160 """Return a string containing a crash report."""
161
161
162 sec_sep = '\n\n'+'*'*75+'\n\n'
162 sec_sep = '\n\n'+'*'*75+'\n\n'
163
163
164 report = []
164 report = []
165 rpt_add = report.append
165 rpt_add = report.append
166
166
167 rpt_add('*'*75+'\n\n'+'IPython post-mortem report\n\n')
167 rpt_add('*'*75+'\n\n'+'IPython post-mortem report\n\n')
168 rpt_add('IPython version: %s \n\n' % Release.version)
168 rpt_add('IPython version: %s \n\n' % Release.version)
169 rpt_add('SVN revision : %s \n\n' % Release.revision)
169 rpt_add('SVN revision : %s \n\n' % Release.revision)
170 rpt_add('Platform info : os.name -> %s, sys.platform -> %s' %
170 rpt_add('Platform info : os.name -> %s, sys.platform -> %s' %
171 (os.name,sys.platform) )
171 (os.name,sys.platform) )
172 rpt_add(sec_sep+'Current user configuration structure:\n\n')
172 rpt_add(sec_sep+'Current user configuration structure:\n\n')
173 rpt_add(pformat(self.IP.rc.dict()))
173 rpt_add(pformat(self.IP.rc.dict()))
174 rpt_add(sec_sep+'Crash traceback:\n\n' + traceback)
174 rpt_add(sec_sep+'Crash traceback:\n\n' + traceback)
175 try:
175 try:
176 rpt_add(sec_sep+"History of session input:")
176 rpt_add(sec_sep+"History of session input:")
177 for line in self.IP.user_ns['_ih']:
177 for line in self.IP.user_ns['_ih']:
178 rpt_add(line)
178 rpt_add(line)
179 rpt_add('\n*** Last line of input (may not be in above history):\n')
179 rpt_add('\n*** Last line of input (may not be in above history):\n')
180 rpt_add(self.IP._last_input_line+'\n')
180 rpt_add(self.IP._last_input_line+'\n')
181 except:
181 except:
182 pass
182 pass
183
183
184 return ''.join(report)
184 return ''.join(report)
185
185
186 class IPythonCrashHandler(CrashHandler):
186 class IPythonCrashHandler(CrashHandler):
187 """sys.excepthook for IPython itself, leaves a detailed report on disk."""
187 """sys.excepthook for IPython itself, leaves a detailed report on disk."""
188
188
189 def __init__(self,IP):
189 def __init__(self,IP):
190
190
191 # Set here which of the IPython authors should be listed as contact
191 # Set here which of the IPython authors should be listed as contact
192 AUTHOR_CONTACT = 'Ville'
192 AUTHOR_CONTACT = 'Ville'
193
193
194 # Set argument defaults
194 # Set argument defaults
195 app_name = 'IPython'
195 app_name = 'IPython'
196 bug_tracker = 'http://projects.scipy.org/ipython/ipython/report'
196 bug_tracker = 'http://projects.scipy.org/ipython/ipython/report'
197 contact_name,contact_email = Release.authors[AUTHOR_CONTACT][:2]
197 contact_name,contact_email = Release.authors[AUTHOR_CONTACT][:2]
198 crash_report_fname = 'IPython_crash_report.txt'
198 crash_report_fname = 'IPython_crash_report.txt'
199 # Call parent constructor
199 # Call parent constructor
200 CrashHandler.__init__(self,IP,app_name,contact_name,contact_email,
200 CrashHandler.__init__(self,IP,app_name,contact_name,contact_email,
201 bug_tracker,crash_report_fname)
201 bug_tracker,crash_report_fname)
202
202
203 def make_report(self,traceback):
203 def make_report(self,traceback):
204 """Return a string containing a crash report."""
204 """Return a string containing a crash report."""
205
205
206 sec_sep = '\n\n'+'*'*75+'\n\n'
206 sec_sep = '\n\n'+'*'*75+'\n\n'
207
207
208 report = []
208 report = []
209 rpt_add = report.append
209 rpt_add = report.append
210
210
211 rpt_add('*'*75+'\n\n'+'IPython post-mortem report\n\n')
211 rpt_add('*'*75+'\n\n'+'IPython post-mortem report\n\n')
212 rpt_add('IPython version: %s \n\n' % Release.version)
212 rpt_add('IPython version: %s \n\n' % Release.version)
213 rpt_add('SVN revision : %s \n\n' % Release.revision)
213 rpt_add('SVN revision : %s \n\n' % Release.revision)
214 rpt_add('Platform info : os.name -> %s, sys.platform -> %s' %
214 rpt_add('Platform info : os.name -> %s, sys.platform -> %s' %
215 (os.name,sys.platform) )
215 (os.name,sys.platform) )
216 rpt_add(sec_sep+'Current user configuration structure:\n\n')
216 rpt_add(sec_sep+'Current user configuration structure:\n\n')
217 rpt_add(pformat(self.IP.rc.dict()))
217 rpt_add(pformat(self.IP.rc.dict()))
218 rpt_add(sec_sep+'Crash traceback:\n\n' + traceback)
218 rpt_add(sec_sep+'Crash traceback:\n\n' + traceback)
219 try:
219 try:
220 rpt_add(sec_sep+"History of session input:")
220 rpt_add(sec_sep+"History of session input:")
221 for line in self.IP.user_ns['_ih']:
221 for line in self.IP.user_ns['_ih']:
222 rpt_add(line)
222 rpt_add(line)
223 rpt_add('\n*** Last line of input (may not be in above history):\n')
223 rpt_add('\n*** Last line of input (may not be in above history):\n')
224 rpt_add(self.IP._last_input_line+'\n')
224 rpt_add(self.IP._last_input_line+'\n')
225 except:
225 except:
226 pass
226 pass
227
227
228 return ''.join(report)
228 return ''.join(report)
This diff has been collapsed as it changes many lines, (1386 lines changed) Show them Hide them
@@ -1,693 +1,693
1 # -*- coding: utf-8 -*-
1 # -*- coding: utf-8 -*-
2 """DPyGetOpt -- Demiurge Python GetOptions Module
2 """DPyGetOpt -- Demiurge Python GetOptions Module
3
3
4 $Id: DPyGetOpt.py 2872 2007-11-25 17:58:05Z fperez $
4 $Id: DPyGetOpt.py 2872 2007-11-25 17:58:05Z fperez $
5
5
6 This module is modeled after perl's Getopt::Long module-- which
6 This module is modeled after perl's Getopt::Long module-- which
7 is, in turn, modeled after GNU's extended getopt() function.
7 is, in turn, modeled after GNU's extended getopt() function.
8
8
9 Upon instantiation, the option specification should be a sequence
9 Upon instantiation, the option specification should be a sequence
10 (list) of option definitions.
10 (list) of option definitions.
11
11
12 Options that take no arguments should simply contain the name of
12 Options that take no arguments should simply contain the name of
13 the option. If a ! is post-pended, the option can be negated by
13 the option. If a ! is post-pended, the option can be negated by
14 prepending 'no'; ie 'debug!' specifies that -debug and -nodebug
14 prepending 'no'; ie 'debug!' specifies that -debug and -nodebug
15 should be accepted.
15 should be accepted.
16
16
17 Mandatory arguments to options are specified using a postpended
17 Mandatory arguments to options are specified using a postpended
18 '=' + a type specifier. '=s' specifies a mandatory string
18 '=' + a type specifier. '=s' specifies a mandatory string
19 argument, '=i' specifies a mandatory integer argument, and '=f'
19 argument, '=i' specifies a mandatory integer argument, and '=f'
20 specifies a mandatory real number. In all cases, the '=' can be
20 specifies a mandatory real number. In all cases, the '=' can be
21 substituted with ':' to specify that the argument is optional.
21 substituted with ':' to specify that the argument is optional.
22
22
23 Dashes '-' in option names are allowed.
23 Dashes '-' in option names are allowed.
24
24
25 If an option has the character '@' postpended (after the
25 If an option has the character '@' postpended (after the
26 argumentation specification), it can appear multiple times within
26 argumentation specification), it can appear multiple times within
27 each argument list that is processed. The results will be stored
27 each argument list that is processed. The results will be stored
28 in a list.
28 in a list.
29
29
30 The option name can actually be a list of names separated by '|'
30 The option name can actually be a list of names separated by '|'
31 characters; ie-- 'foo|bar|baz=f@' specifies that all -foo, -bar,
31 characters; ie-- 'foo|bar|baz=f@' specifies that all -foo, -bar,
32 and -baz options that appear on within the parsed argument list
32 and -baz options that appear on within the parsed argument list
33 must have a real number argument and that the accumulated list
33 must have a real number argument and that the accumulated list
34 of values will be available under the name 'foo'
34 of values will be available under the name 'foo'
35
35
36 $Id: DPyGetOpt.py 2872 2007-11-25 17:58:05Z fperez $"""
36 $Id: DPyGetOpt.py 2872 2007-11-25 17:58:05Z fperez $"""
37
37
38 #*****************************************************************************
38 #*****************************************************************************
39 #
39 #
40 # Copyright (c) 2001 Bill Bumgarner <bbum@friday.com>
40 # Copyright (c) 2001 Bill Bumgarner <bbum@friday.com>
41 #
41 #
42 #
42 #
43 # Published under the terms of the MIT license, hereby reproduced:
43 # Published under the terms of the MIT license, hereby reproduced:
44 #
44 #
45 # Permission is hereby granted, free of charge, to any person obtaining a copy
45 # Permission is hereby granted, free of charge, to any person obtaining a copy
46 # of this software and associated documentation files (the "Software"), to
46 # of this software and associated documentation files (the "Software"), to
47 # deal in the Software without restriction, including without limitation the
47 # deal in the Software without restriction, including without limitation the
48 # rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
48 # rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
49 # sell copies of the Software, and to permit persons to whom the Software is
49 # sell copies of the Software, and to permit persons to whom the Software is
50 # furnished to do so, subject to the following conditions:
50 # furnished to do so, subject to the following conditions:
51 #
51 #
52 # The above copyright notice and this permission notice shall be included in
52 # The above copyright notice and this permission notice shall be included in
53 # all copies or substantial portions of the Software.
53 # all copies or substantial portions of the Software.
54 #
54 #
55 # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
55 # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
56 # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
56 # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
57 # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
57 # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
58 # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
58 # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
59 # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
59 # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
60 # FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
60 # FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
61 # IN THE SOFTWARE.
61 # IN THE SOFTWARE.
62 #
62 #
63 #*****************************************************************************
63 #*****************************************************************************
64
64
65 __author__ = 'Bill Bumgarner <bbum@friday.com>'
65 __author__ = 'Bill Bumgarner <bbum@friday.com>'
66 __license__ = 'MIT'
66 __license__ = 'MIT'
67 __version__ = '1.2'
67 __version__ = '1.2'
68
68
69 # Modified to use re instead of regex and regsub modules.
69 # Modified to use re instead of regex and regsub modules.
70 # 2001/5/7, Jonathan Hogg <jonathan@onegoodidea.com>
70 # 2001/5/7, Jonathan Hogg <jonathan@onegoodidea.com>
71
71
72 import re
72 import re
73 import string
73 import string
74 import sys
74 import sys
75 import types
75 import types
76
76
77 class Error(Exception):
77 class Error(Exception):
78 """Base class for exceptions in the DPyGetOpt module."""
78 """Base class for exceptions in the DPyGetOpt module."""
79
79
80 class ArgumentError(Error):
80 class ArgumentError(Error):
81 """Exception indicating an error in the arguments passed to
81 """Exception indicating an error in the arguments passed to
82 DPyGetOpt.processArguments."""
82 DPyGetOpt.processArguments."""
83
83
84 class SpecificationError(Error):
84 class SpecificationError(Error):
85 """Exception indicating an error with an option specification."""
85 """Exception indicating an error with an option specification."""
86
86
87 class TerminationError(Error):
87 class TerminationError(Error):
88 """Exception indicating an error with an option processing terminator."""
88 """Exception indicating an error with an option processing terminator."""