Show More
@@ -1,415 +1,414 b'' | |||||
1 | # -*- coding: utf-8 -*- |
|
1 | # -*- coding: utf-8 -*- | |
2 | """ |
|
2 | """ | |
3 | Pdb debugger class. |
|
3 | Pdb debugger class. | |
4 |
|
4 | |||
5 | Modified from the standard pdb.Pdb class to avoid including readline, so that |
|
5 | Modified from the standard pdb.Pdb class to avoid including readline, so that | |
6 | the command line completion of other programs which include this isn't |
|
6 | the command line completion of other programs which include this isn't | |
7 | damaged. |
|
7 | damaged. | |
8 |
|
8 | |||
9 | In the future, this class will be expanded with improvements over the standard |
|
9 | In the future, this class will be expanded with improvements over the standard | |
10 | pdb. |
|
10 | pdb. | |
11 |
|
11 | |||
12 | The code in this file is mainly lifted out of cmd.py in Python 2.2, with minor |
|
12 | The code in this file is mainly lifted out of cmd.py in Python 2.2, with minor | |
13 | changes. Licensing should therefore be under the standard Python terms. For |
|
13 | changes. Licensing should therefore be under the standard Python terms. For | |
14 | details on the PSF (Python Software Foundation) standard license, see: |
|
14 | details on the PSF (Python Software Foundation) standard license, see: | |
15 |
|
15 | |||
16 | http://www.python.org/2.2.3/license.html |
|
16 | http://www.python.org/2.2.3/license.html | |
17 |
|
17 | |||
18 |
$Id: Debugger.py 195 |
|
18 | $Id: Debugger.py 1954 2006-11-29 09:39:44Z vivainio $""" | |
19 |
|
19 | |||
20 | #***************************************************************************** |
|
20 | #***************************************************************************** | |
21 | # |
|
21 | # | |
22 | # Since this file is essentially a modified copy of the pdb module which is |
|
22 | # Since this file is essentially a modified copy of the pdb module which is | |
23 | # part of the standard Python distribution, I assume that the proper procedure |
|
23 | # part of the standard Python distribution, I assume that the proper procedure | |
24 | # is to maintain its copyright as belonging to the Python Software Foundation |
|
24 | # is to maintain its copyright as belonging to the Python Software Foundation | |
25 | # (in addition to my own, for all new code). |
|
25 | # (in addition to my own, for all new code). | |
26 | # |
|
26 | # | |
27 | # Copyright (C) 2001 Python Software Foundation, www.python.org |
|
27 | # Copyright (C) 2001 Python Software Foundation, www.python.org | |
28 | # Copyright (C) 2005-2006 Fernando Perez. <fperez@colorado.edu> |
|
28 | # Copyright (C) 2005-2006 Fernando Perez. <fperez@colorado.edu> | |
29 | # |
|
29 | # | |
30 | # Distributed under the terms of the BSD License. The full license is in |
|
30 | # Distributed under the terms of the BSD License. The full license is in | |
31 | # the file COPYING, distributed as part of this software. |
|
31 | # the file COPYING, distributed as part of this software. | |
32 | # |
|
32 | # | |
33 | #***************************************************************************** |
|
33 | #***************************************************************************** | |
34 |
|
34 | |||
35 | from IPython import Release |
|
35 | from IPython import Release | |
36 | __author__ = '%s <%s>' % Release.authors['Fernando'] |
|
36 | __author__ = '%s <%s>' % Release.authors['Fernando'] | |
37 | __license__ = 'Python' |
|
37 | __license__ = 'Python' | |
38 |
|
38 | |||
39 | import bdb |
|
39 | import bdb | |
40 | import cmd |
|
40 | import cmd | |
41 | import linecache |
|
41 | import linecache | |
42 | import os |
|
42 | import os | |
43 | import sys |
|
43 | import sys | |
44 |
|
44 | |||
45 | from IPython import PyColorize, ColorANSI |
|
45 | from IPython import PyColorize, ColorANSI | |
46 | from IPython.genutils import Term |
|
46 | from IPython.genutils import Term | |
47 | from IPython.excolors import ExceptionColors |
|
47 | from IPython.excolors import ExceptionColors | |
48 |
|
48 | |||
49 | # See if we can use pydb. |
|
49 | # See if we can use pydb. | |
50 | has_pydb = False |
|
50 | has_pydb = False | |
51 | prompt = 'ipdb>' |
|
51 | prompt = 'ipdb>' | |
52 | if sys.version[:3] >= '2.5': |
|
52 | try: | |
53 | try: |
|
53 | import pydb | |
54 | import pydb |
|
54 | if hasattr(pydb.pydb, "runl"): | |
55 | if hasattr(pydb.pydb, "runl"): |
|
55 | has_pydb = True | |
56 | has_pydb = True |
|
56 | from pydb import Pdb as OldPdb | |
57 | from pydb import Pdb as OldPdb |
|
57 | prompt = 'ipydb>' | |
58 | prompt = 'ipydb>' |
|
|||
59 | except ImportError: |
|
58 | except ImportError: | |
60 | pass |
|
59 | pass | |
61 |
|
60 | |||
62 | if has_pydb: |
|
61 | if has_pydb: | |
63 | from pydb import Pdb as OldPdb |
|
62 | from pydb import Pdb as OldPdb | |
64 | else: |
|
63 | else: | |
65 | from pdb import Pdb as OldPdb |
|
64 | from pdb import Pdb as OldPdb | |
66 |
|
65 | |||
67 | def decorate_fn_with_doc(new_fn, old_fn, additional_text=""): |
|
66 | def decorate_fn_with_doc(new_fn, old_fn, additional_text=""): | |
68 | """Make new_fn have old_fn's doc string. This is particularly useful |
|
67 | """Make new_fn have old_fn's doc string. This is particularly useful | |
69 | for the do_... commands that hook into the help system. |
|
68 | for the do_... commands that hook into the help system. | |
70 | Adapted from from a comp.lang.python posting |
|
69 | Adapted from from a comp.lang.python posting | |
71 | by Duncan Booth.""" |
|
70 | by Duncan Booth.""" | |
72 | def wrapper(*args, **kw): |
|
71 | def wrapper(*args, **kw): | |
73 | return new_fn(*args, **kw) |
|
72 | return new_fn(*args, **kw) | |
74 | if old_fn.__doc__: |
|
73 | if old_fn.__doc__: | |
75 | wrapper.__doc__ = old_fn.__doc__ + additional_text |
|
74 | wrapper.__doc__ = old_fn.__doc__ + additional_text | |
76 | return wrapper |
|
75 | return wrapper | |
77 |
|
76 | |||
78 | def _file_lines(fname): |
|
77 | def _file_lines(fname): | |
79 | """Return the contents of a named file as a list of lines. |
|
78 | """Return the contents of a named file as a list of lines. | |
80 |
|
79 | |||
81 | This function never raises an IOError exception: if the file can't be |
|
80 | This function never raises an IOError exception: if the file can't be | |
82 | read, it simply returns an empty list.""" |
|
81 | read, it simply returns an empty list.""" | |
83 |
|
82 | |||
84 | try: |
|
83 | try: | |
85 | outfile = open(fname) |
|
84 | outfile = open(fname) | |
86 | except IOError: |
|
85 | except IOError: | |
87 | return [] |
|
86 | return [] | |
88 | else: |
|
87 | else: | |
89 | out = outfile.readlines() |
|
88 | out = outfile.readlines() | |
90 | outfile.close() |
|
89 | outfile.close() | |
91 | return out |
|
90 | return out | |
92 |
|
91 | |||
93 | class Pdb(OldPdb): |
|
92 | class Pdb(OldPdb): | |
94 | """Modified Pdb class, does not load readline.""" |
|
93 | """Modified Pdb class, does not load readline.""" | |
95 |
|
94 | |||
96 | if sys.version[:3] >= '2.5': |
|
95 | if sys.version[:3] >= '2.5' or has_pydb: | |
97 | def __init__(self,color_scheme='NoColor',completekey=None, |
|
96 | def __init__(self,color_scheme='NoColor',completekey=None, | |
98 | stdin=None, stdout=None): |
|
97 | stdin=None, stdout=None): | |
99 |
|
98 | |||
100 | # Parent constructor: |
|
99 | # Parent constructor: | |
101 | OldPdb.__init__(self,completekey,stdin,stdout) |
|
100 | OldPdb.__init__(self,completekey,stdin,stdout) | |
102 |
|
101 | |||
103 | # IPython changes... |
|
102 | # IPython changes... | |
104 | self.prompt = prompt # The default prompt is '(Pdb)' |
|
103 | self.prompt = prompt # The default prompt is '(Pdb)' | |
105 | self.is_pydb = prompt == 'ipydb>' |
|
104 | self.is_pydb = prompt == 'ipydb>' | |
106 |
|
105 | |||
107 | if self.is_pydb: |
|
106 | if self.is_pydb: | |
108 |
|
107 | |||
109 | # iplib.py's ipalias seems to want pdb's checkline |
|
108 | # iplib.py's ipalias seems to want pdb's checkline | |
110 | # which located in pydb.fn |
|
109 | # which located in pydb.fn | |
111 | import pydb.fns |
|
110 | import pydb.fns | |
112 | self.checkline = lambda filename, lineno: \ |
|
111 | self.checkline = lambda filename, lineno: \ | |
113 | pydb.fns.checkline(self, filename, lineno) |
|
112 | pydb.fns.checkline(self, filename, lineno) | |
114 |
|
113 | |||
115 | self.curframe = None |
|
114 | self.curframe = None | |
116 | self.do_restart = self.new_do_restart |
|
115 | self.do_restart = self.new_do_restart | |
117 |
|
116 | |||
118 | self.old_all_completions = __IPYTHON__.Completer.all_completions |
|
117 | self.old_all_completions = __IPYTHON__.Completer.all_completions | |
119 | __IPYTHON__.Completer.all_completions=self.all_completions |
|
118 | __IPYTHON__.Completer.all_completions=self.all_completions | |
120 |
|
119 | |||
121 | # Do we have access to pydb's list command parser? |
|
120 | # Do we have access to pydb's list command parser? | |
122 | self.do_list = decorate_fn_with_doc(self.list_command_pydb, |
|
121 | self.do_list = decorate_fn_with_doc(self.list_command_pydb, | |
123 | OldPdb.do_list) |
|
122 | OldPdb.do_list) | |
124 | self.do_l = self.do_list |
|
123 | self.do_l = self.do_list | |
125 | self.do_frame = decorate_fn_with_doc(self.new_do_frame, |
|
124 | self.do_frame = decorate_fn_with_doc(self.new_do_frame, | |
126 | OldPdb.do_frame) |
|
125 | OldPdb.do_frame) | |
127 |
|
126 | |||
128 | self.aliases = {} |
|
127 | self.aliases = {} | |
129 |
|
128 | |||
130 | # Create color table: we copy the default one from the traceback |
|
129 | # Create color table: we copy the default one from the traceback | |
131 | # module and add a few attributes needed for debugging |
|
130 | # module and add a few attributes needed for debugging | |
132 | self.color_scheme_table = ExceptionColors.copy() |
|
131 | self.color_scheme_table = ExceptionColors.copy() | |
133 |
|
132 | |||
134 | # shorthands |
|
133 | # shorthands | |
135 | C = ColorANSI.TermColors |
|
134 | C = ColorANSI.TermColors | |
136 | cst = self.color_scheme_table |
|
135 | cst = self.color_scheme_table | |
137 |
|
136 | |||
138 | cst['NoColor'].colors.breakpoint_enabled = C.NoColor |
|
137 | cst['NoColor'].colors.breakpoint_enabled = C.NoColor | |
139 | cst['NoColor'].colors.breakpoint_disabled = C.NoColor |
|
138 | cst['NoColor'].colors.breakpoint_disabled = C.NoColor | |
140 |
|
139 | |||
141 | cst['Linux'].colors.breakpoint_enabled = C.LightRed |
|
140 | cst['Linux'].colors.breakpoint_enabled = C.LightRed | |
142 | cst['Linux'].colors.breakpoint_disabled = C.Red |
|
141 | cst['Linux'].colors.breakpoint_disabled = C.Red | |
143 |
|
142 | |||
144 | cst['LightBG'].colors.breakpoint_enabled = C.LightRed |
|
143 | cst['LightBG'].colors.breakpoint_enabled = C.LightRed | |
145 | cst['LightBG'].colors.breakpoint_disabled = C.Red |
|
144 | cst['LightBG'].colors.breakpoint_disabled = C.Red | |
146 |
|
145 | |||
147 | self.set_colors(color_scheme) |
|
146 | self.set_colors(color_scheme) | |
148 |
|
147 | |||
149 | else: |
|
148 | else: | |
150 | # Ugly hack: for Python 2.3-2.4, we can't call the parent constructor, |
|
149 | # Ugly hack: for Python 2.3-2.4, we can't call the parent constructor, | |
151 | # because it binds readline and breaks tab-completion. This means we |
|
150 | # because it binds readline and breaks tab-completion. This means we | |
152 | # have to COPY the constructor here. |
|
151 | # have to COPY the constructor here. | |
153 | def __init__(self,color_scheme='NoColor'): |
|
152 | def __init__(self,color_scheme='NoColor'): | |
154 | bdb.Bdb.__init__(self) |
|
153 | bdb.Bdb.__init__(self) | |
155 | cmd.Cmd.__init__(self,completekey=None) # don't load readline |
|
154 | cmd.Cmd.__init__(self,completekey=None) # don't load readline | |
156 | self.prompt = 'ipdb> ' # The default prompt is '(Pdb)' |
|
155 | self.prompt = 'ipdb> ' # The default prompt is '(Pdb)' | |
157 | self.aliases = {} |
|
156 | self.aliases = {} | |
158 |
|
157 | |||
159 | # These two lines are part of the py2.4 constructor, let's put them |
|
158 | # These two lines are part of the py2.4 constructor, let's put them | |
160 | # unconditionally here as they won't cause any problems in 2.3. |
|
159 | # unconditionally here as they won't cause any problems in 2.3. | |
161 | self.mainpyfile = '' |
|
160 | self.mainpyfile = '' | |
162 | self._wait_for_mainpyfile = 0 |
|
161 | self._wait_for_mainpyfile = 0 | |
163 |
|
162 | |||
164 | # Read $HOME/.pdbrc and ./.pdbrc |
|
163 | # Read $HOME/.pdbrc and ./.pdbrc | |
165 | try: |
|
164 | try: | |
166 | self.rcLines = _file_lines(os.path.join(os.environ['HOME'], |
|
165 | self.rcLines = _file_lines(os.path.join(os.environ['HOME'], | |
167 | ".pdbrc")) |
|
166 | ".pdbrc")) | |
168 | except KeyError: |
|
167 | except KeyError: | |
169 | self.rcLines = [] |
|
168 | self.rcLines = [] | |
170 | self.rcLines.extend(_file_lines(".pdbrc")) |
|
169 | self.rcLines.extend(_file_lines(".pdbrc")) | |
171 |
|
170 | |||
172 | # Create color table: we copy the default one from the traceback |
|
171 | # Create color table: we copy the default one from the traceback | |
173 | # module and add a few attributes needed for debugging |
|
172 | # module and add a few attributes needed for debugging | |
174 | self.color_scheme_table = ExceptionColors.copy() |
|
173 | self.color_scheme_table = ExceptionColors.copy() | |
175 |
|
174 | |||
176 | # shorthands |
|
175 | # shorthands | |
177 | C = ColorANSI.TermColors |
|
176 | C = ColorANSI.TermColors | |
178 | cst = self.color_scheme_table |
|
177 | cst = self.color_scheme_table | |
179 |
|
178 | |||
180 | cst['NoColor'].colors.breakpoint_enabled = C.NoColor |
|
179 | cst['NoColor'].colors.breakpoint_enabled = C.NoColor | |
181 | cst['NoColor'].colors.breakpoint_disabled = C.NoColor |
|
180 | cst['NoColor'].colors.breakpoint_disabled = C.NoColor | |
182 |
|
181 | |||
183 | cst['Linux'].colors.breakpoint_enabled = C.LightRed |
|
182 | cst['Linux'].colors.breakpoint_enabled = C.LightRed | |
184 | cst['Linux'].colors.breakpoint_disabled = C.Red |
|
183 | cst['Linux'].colors.breakpoint_disabled = C.Red | |
185 |
|
184 | |||
186 | cst['LightBG'].colors.breakpoint_enabled = C.LightRed |
|
185 | cst['LightBG'].colors.breakpoint_enabled = C.LightRed | |
187 | cst['LightBG'].colors.breakpoint_disabled = C.Red |
|
186 | cst['LightBG'].colors.breakpoint_disabled = C.Red | |
188 |
|
187 | |||
189 | self.set_colors(color_scheme) |
|
188 | self.set_colors(color_scheme) | |
190 |
|
189 | |||
191 | def set_colors(self, scheme): |
|
190 | def set_colors(self, scheme): | |
192 | """Shorthand access to the color table scheme selector method.""" |
|
191 | """Shorthand access to the color table scheme selector method.""" | |
193 | self.color_scheme_table.set_active_scheme(scheme) |
|
192 | self.color_scheme_table.set_active_scheme(scheme) | |
194 |
|
193 | |||
195 | def interaction(self, frame, traceback): |
|
194 | def interaction(self, frame, traceback): | |
196 | __IPYTHON__.set_completer_frame(frame) |
|
195 | __IPYTHON__.set_completer_frame(frame) | |
197 | OldPdb.interaction(self, frame, traceback) |
|
196 | OldPdb.interaction(self, frame, traceback) | |
198 |
|
197 | |||
199 | def new_do_up(self, arg): |
|
198 | def new_do_up(self, arg): | |
200 | OldPdb.do_up(self, arg) |
|
199 | OldPdb.do_up(self, arg) | |
201 | __IPYTHON__.set_completer_frame(self.curframe) |
|
200 | __IPYTHON__.set_completer_frame(self.curframe) | |
202 | do_u = do_up = decorate_fn_with_doc(new_do_up, OldPdb.do_up) |
|
201 | do_u = do_up = decorate_fn_with_doc(new_do_up, OldPdb.do_up) | |
203 |
|
202 | |||
204 | def new_do_down(self, arg): |
|
203 | def new_do_down(self, arg): | |
205 | OldPdb.do_down(self, arg) |
|
204 | OldPdb.do_down(self, arg) | |
206 | __IPYTHON__.set_completer_frame(self.curframe) |
|
205 | __IPYTHON__.set_completer_frame(self.curframe) | |
207 |
|
206 | |||
208 | do_d = do_down = decorate_fn_with_doc(new_do_down, OldPdb.do_down) |
|
207 | do_d = do_down = decorate_fn_with_doc(new_do_down, OldPdb.do_down) | |
209 |
|
208 | |||
210 | def new_do_frame(self, arg): |
|
209 | def new_do_frame(self, arg): | |
211 | OldPdb.do_frame(self, arg) |
|
210 | OldPdb.do_frame(self, arg) | |
212 | __IPYTHON__.set_completer_frame(self.curframe) |
|
211 | __IPYTHON__.set_completer_frame(self.curframe) | |
213 |
|
212 | |||
214 | def new_do_quit(self, arg): |
|
213 | def new_do_quit(self, arg): | |
215 |
|
214 | |||
216 | if hasattr(self, 'old_all_completions'): |
|
215 | if hasattr(self, 'old_all_completions'): | |
217 | __IPYTHON__.Completer.all_completions=self.old_all_completions |
|
216 | __IPYTHON__.Completer.all_completions=self.old_all_completions | |
218 |
|
217 | |||
219 |
|
218 | |||
220 | return OldPdb.do_quit(self, arg) |
|
219 | return OldPdb.do_quit(self, arg) | |
221 |
|
220 | |||
222 | do_q = do_quit = decorate_fn_with_doc(new_do_quit, OldPdb.do_quit) |
|
221 | do_q = do_quit = decorate_fn_with_doc(new_do_quit, OldPdb.do_quit) | |
223 |
|
222 | |||
224 | def new_do_restart(self, arg): |
|
223 | def new_do_restart(self, arg): | |
225 | """Restart command. In the context of ipython this is exactly the same |
|
224 | """Restart command. In the context of ipython this is exactly the same | |
226 | thing as 'quit'.""" |
|
225 | thing as 'quit'.""" | |
227 | self.msg("Restart doesn't make sense here. Using 'quit' instead.") |
|
226 | self.msg("Restart doesn't make sense here. Using 'quit' instead.") | |
228 | return self.do_quit(arg) |
|
227 | return self.do_quit(arg) | |
229 |
|
228 | |||
230 | def postloop(self): |
|
229 | def postloop(self): | |
231 | __IPYTHON__.set_completer_frame(None) |
|
230 | __IPYTHON__.set_completer_frame(None) | |
232 |
|
231 | |||
233 | def print_stack_trace(self): |
|
232 | def print_stack_trace(self): | |
234 | try: |
|
233 | try: | |
235 | for frame_lineno in self.stack: |
|
234 | for frame_lineno in self.stack: | |
236 | self.print_stack_entry(frame_lineno, context = 5) |
|
235 | self.print_stack_entry(frame_lineno, context = 5) | |
237 | except KeyboardInterrupt: |
|
236 | except KeyboardInterrupt: | |
238 | pass |
|
237 | pass | |
239 |
|
238 | |||
240 | def print_stack_entry(self,frame_lineno,prompt_prefix='\n-> ', |
|
239 | def print_stack_entry(self,frame_lineno,prompt_prefix='\n-> ', | |
241 | context = 3): |
|
240 | context = 3): | |
242 | frame, lineno = frame_lineno |
|
241 | frame, lineno = frame_lineno | |
243 | print >>Term.cout, self.format_stack_entry(frame_lineno, '', context) |
|
242 | print >>Term.cout, self.format_stack_entry(frame_lineno, '', context) | |
244 |
|
243 | |||
245 | def format_stack_entry(self, frame_lineno, lprefix=': ', context = 3): |
|
244 | def format_stack_entry(self, frame_lineno, lprefix=': ', context = 3): | |
246 | import linecache, repr |
|
245 | import linecache, repr | |
247 |
|
246 | |||
248 | ret = [] |
|
247 | ret = [] | |
249 |
|
248 | |||
250 | Colors = self.color_scheme_table.active_colors |
|
249 | Colors = self.color_scheme_table.active_colors | |
251 | ColorsNormal = Colors.Normal |
|
250 | ColorsNormal = Colors.Normal | |
252 | tpl_link = '%s%%s%s' % (Colors.filenameEm, ColorsNormal) |
|
251 | tpl_link = '%s%%s%s' % (Colors.filenameEm, ColorsNormal) | |
253 | tpl_call = '%s%%s%s%%s%s' % (Colors.vName, Colors.valEm, ColorsNormal) |
|
252 | tpl_call = '%s%%s%s%%s%s' % (Colors.vName, Colors.valEm, ColorsNormal) | |
254 | tpl_line = '%%s%s%%s %s%%s' % (Colors.lineno, ColorsNormal) |
|
253 | tpl_line = '%%s%s%%s %s%%s' % (Colors.lineno, ColorsNormal) | |
255 | tpl_line_em = '%%s%s%%s %s%%s%s' % (Colors.linenoEm, Colors.line, |
|
254 | tpl_line_em = '%%s%s%%s %s%%s%s' % (Colors.linenoEm, Colors.line, | |
256 | ColorsNormal) |
|
255 | ColorsNormal) | |
257 |
|
256 | |||
258 | frame, lineno = frame_lineno |
|
257 | frame, lineno = frame_lineno | |
259 |
|
258 | |||
260 | return_value = '' |
|
259 | return_value = '' | |
261 | if '__return__' in frame.f_locals: |
|
260 | if '__return__' in frame.f_locals: | |
262 | rv = frame.f_locals['__return__'] |
|
261 | rv = frame.f_locals['__return__'] | |
263 | #return_value += '->' |
|
262 | #return_value += '->' | |
264 | return_value += repr.repr(rv) + '\n' |
|
263 | return_value += repr.repr(rv) + '\n' | |
265 | ret.append(return_value) |
|
264 | ret.append(return_value) | |
266 |
|
265 | |||
267 | #s = filename + '(' + `lineno` + ')' |
|
266 | #s = filename + '(' + `lineno` + ')' | |
268 | filename = self.canonic(frame.f_code.co_filename) |
|
267 | filename = self.canonic(frame.f_code.co_filename) | |
269 | link = tpl_link % filename |
|
268 | link = tpl_link % filename | |
270 |
|
269 | |||
271 | if frame.f_code.co_name: |
|
270 | if frame.f_code.co_name: | |
272 | func = frame.f_code.co_name |
|
271 | func = frame.f_code.co_name | |
273 | else: |
|
272 | else: | |
274 | func = "<lambda>" |
|
273 | func = "<lambda>" | |
275 |
|
274 | |||
276 | call = '' |
|
275 | call = '' | |
277 | if func != '?': |
|
276 | if func != '?': | |
278 | if '__args__' in frame.f_locals: |
|
277 | if '__args__' in frame.f_locals: | |
279 | args = repr.repr(frame.f_locals['__args__']) |
|
278 | args = repr.repr(frame.f_locals['__args__']) | |
280 | else: |
|
279 | else: | |
281 | args = '()' |
|
280 | args = '()' | |
282 | call = tpl_call % (func, args) |
|
281 | call = tpl_call % (func, args) | |
283 |
|
282 | |||
284 | # The level info should be generated in the same format pdb uses, to |
|
283 | # The level info should be generated in the same format pdb uses, to | |
285 | # avoid breaking the pdbtrack functionality of python-mode in *emacs. |
|
284 | # avoid breaking the pdbtrack functionality of python-mode in *emacs. | |
286 | ret.append('> %s(%s)%s\n' % (link,lineno,call)) |
|
285 | ret.append('> %s(%s)%s\n' % (link,lineno,call)) | |
287 |
|
286 | |||
288 | start = lineno - 1 - context//2 |
|
287 | start = lineno - 1 - context//2 | |
289 | lines = linecache.getlines(filename) |
|
288 | lines = linecache.getlines(filename) | |
290 | start = max(start, 0) |
|
289 | start = max(start, 0) | |
291 | start = min(start, len(lines) - context) |
|
290 | start = min(start, len(lines) - context) | |
292 | lines = lines[start : start + context] |
|
291 | lines = lines[start : start + context] | |
293 |
|
292 | |||
294 | for i,line in enumerate(lines): |
|
293 | for i,line in enumerate(lines): | |
295 | show_arrow = (start + 1 + i == lineno) |
|
294 | show_arrow = (start + 1 + i == lineno) | |
296 | ret.append(self.__format_line(tpl_line_em, filename, |
|
295 | ret.append(self.__format_line(tpl_line_em, filename, | |
297 | start + 1 + i, line, |
|
296 | start + 1 + i, line, | |
298 | arrow = show_arrow) ) |
|
297 | arrow = show_arrow) ) | |
299 |
|
298 | |||
300 | return ''.join(ret) |
|
299 | return ''.join(ret) | |
301 |
|
300 | |||
302 | def __format_line(self, tpl_line, filename, lineno, line, arrow = False): |
|
301 | def __format_line(self, tpl_line, filename, lineno, line, arrow = False): | |
303 | bp_mark = "" |
|
302 | bp_mark = "" | |
304 | bp_mark_color = "" |
|
303 | bp_mark_color = "" | |
305 |
|
304 | |||
306 | bp = None |
|
305 | bp = None | |
307 | if lineno in self.get_file_breaks(filename): |
|
306 | if lineno in self.get_file_breaks(filename): | |
308 | bps = self.get_breaks(filename, lineno) |
|
307 | bps = self.get_breaks(filename, lineno) | |
309 | bp = bps[-1] |
|
308 | bp = bps[-1] | |
310 |
|
309 | |||
311 | if bp: |
|
310 | if bp: | |
312 | Colors = self.color_scheme_table.active_colors |
|
311 | Colors = self.color_scheme_table.active_colors | |
313 | bp_mark = str(bp.number) |
|
312 | bp_mark = str(bp.number) | |
314 | bp_mark_color = Colors.breakpoint_enabled |
|
313 | bp_mark_color = Colors.breakpoint_enabled | |
315 | if not bp.enabled: |
|
314 | if not bp.enabled: | |
316 | bp_mark_color = Colors.breakpoint_disabled |
|
315 | bp_mark_color = Colors.breakpoint_disabled | |
317 |
|
316 | |||
318 | numbers_width = 7 |
|
317 | numbers_width = 7 | |
319 | if arrow: |
|
318 | if arrow: | |
320 | # This is the line with the error |
|
319 | # This is the line with the error | |
321 | pad = numbers_width - len(str(lineno)) - len(bp_mark) |
|
320 | pad = numbers_width - len(str(lineno)) - len(bp_mark) | |
322 | if pad >= 3: |
|
321 | if pad >= 3: | |
323 | marker = '-'*(pad-3) + '-> ' |
|
322 | marker = '-'*(pad-3) + '-> ' | |
324 | elif pad == 2: |
|
323 | elif pad == 2: | |
325 | marker = '> ' |
|
324 | marker = '> ' | |
326 | elif pad == 1: |
|
325 | elif pad == 1: | |
327 | marker = '>' |
|
326 | marker = '>' | |
328 | else: |
|
327 | else: | |
329 | marker = '' |
|
328 | marker = '' | |
330 | num = '%s%s' % (marker, str(lineno)) |
|
329 | num = '%s%s' % (marker, str(lineno)) | |
331 | line = tpl_line % (bp_mark_color + bp_mark, num, line) |
|
330 | line = tpl_line % (bp_mark_color + bp_mark, num, line) | |
332 | else: |
|
331 | else: | |
333 | num = '%*s' % (numbers_width - len(bp_mark), str(lineno)) |
|
332 | num = '%*s' % (numbers_width - len(bp_mark), str(lineno)) | |
334 | line = tpl_line % (bp_mark_color + bp_mark, num, line) |
|
333 | line = tpl_line % (bp_mark_color + bp_mark, num, line) | |
335 |
|
334 | |||
336 | return line |
|
335 | return line | |
337 |
|
336 | |||
338 | def list_command_pydb(self, arg): |
|
337 | def list_command_pydb(self, arg): | |
339 | """List command to use if we have a newer pydb installed""" |
|
338 | """List command to use if we have a newer pydb installed""" | |
340 | filename, first, last = OldPdb.parse_list_cmd(self, arg) |
|
339 | filename, first, last = OldPdb.parse_list_cmd(self, arg) | |
341 | if filename is not None: |
|
340 | if filename is not None: | |
342 | self.print_list_lines(filename, first, last) |
|
341 | self.print_list_lines(filename, first, last) | |
343 |
|
342 | |||
344 | def print_list_lines(self, filename, first, last): |
|
343 | def print_list_lines(self, filename, first, last): | |
345 | """The printing (as opposed to the parsing part of a 'list' |
|
344 | """The printing (as opposed to the parsing part of a 'list' | |
346 | command.""" |
|
345 | command.""" | |
347 | try: |
|
346 | try: | |
348 | Colors = self.color_scheme_table.active_colors |
|
347 | Colors = self.color_scheme_table.active_colors | |
349 | ColorsNormal = Colors.Normal |
|
348 | ColorsNormal = Colors.Normal | |
350 | tpl_line = '%%s%s%%s %s%%s' % (Colors.lineno, ColorsNormal) |
|
349 | tpl_line = '%%s%s%%s %s%%s' % (Colors.lineno, ColorsNormal) | |
351 | tpl_line_em = '%%s%s%%s %s%%s%s' % (Colors.linenoEm, Colors.line, ColorsNormal) |
|
350 | tpl_line_em = '%%s%s%%s %s%%s%s' % (Colors.linenoEm, Colors.line, ColorsNormal) | |
352 | src = [] |
|
351 | src = [] | |
353 | for lineno in range(first, last+1): |
|
352 | for lineno in range(first, last+1): | |
354 | line = linecache.getline(filename, lineno) |
|
353 | line = linecache.getline(filename, lineno) | |
355 | if not line: |
|
354 | if not line: | |
356 | break |
|
355 | break | |
357 |
|
356 | |||
358 | if lineno == self.curframe.f_lineno: |
|
357 | if lineno == self.curframe.f_lineno: | |
359 | line = self.__format_line(tpl_line_em, filename, lineno, line, arrow = True) |
|
358 | line = self.__format_line(tpl_line_em, filename, lineno, line, arrow = True) | |
360 | else: |
|
359 | else: | |
361 | line = self.__format_line(tpl_line, filename, lineno, line, arrow = False) |
|
360 | line = self.__format_line(tpl_line, filename, lineno, line, arrow = False) | |
362 |
|
361 | |||
363 | src.append(line) |
|
362 | src.append(line) | |
364 | self.lineno = lineno |
|
363 | self.lineno = lineno | |
365 |
|
364 | |||
366 | print >>Term.cout, ''.join(src) |
|
365 | print >>Term.cout, ''.join(src) | |
367 |
|
366 | |||
368 | except KeyboardInterrupt: |
|
367 | except KeyboardInterrupt: | |
369 | pass |
|
368 | pass | |
370 |
|
369 | |||
371 | def do_list(self, arg): |
|
370 | def do_list(self, arg): | |
372 | self.lastcmd = 'list' |
|
371 | self.lastcmd = 'list' | |
373 | last = None |
|
372 | last = None | |
374 | if arg: |
|
373 | if arg: | |
375 | try: |
|
374 | try: | |
376 | x = eval(arg, {}, {}) |
|
375 | x = eval(arg, {}, {}) | |
377 | if type(x) == type(()): |
|
376 | if type(x) == type(()): | |
378 | first, last = x |
|
377 | first, last = x | |
379 | first = int(first) |
|
378 | first = int(first) | |
380 | last = int(last) |
|
379 | last = int(last) | |
381 | if last < first: |
|
380 | if last < first: | |
382 | # Assume it's a count |
|
381 | # Assume it's a count | |
383 | last = first + last |
|
382 | last = first + last | |
384 | else: |
|
383 | else: | |
385 | first = max(1, int(x) - 5) |
|
384 | first = max(1, int(x) - 5) | |
386 | except: |
|
385 | except: | |
387 | print '*** Error in argument:', `arg` |
|
386 | print '*** Error in argument:', `arg` | |
388 | return |
|
387 | return | |
389 | elif self.lineno is None: |
|
388 | elif self.lineno is None: | |
390 | first = max(1, self.curframe.f_lineno - 5) |
|
389 | first = max(1, self.curframe.f_lineno - 5) | |
391 | else: |
|
390 | else: | |
392 | first = self.lineno + 1 |
|
391 | first = self.lineno + 1 | |
393 | if last is None: |
|
392 | if last is None: | |
394 | last = first + 10 |
|
393 | last = first + 10 | |
395 | self.print_list_lines(self.curframe.f_code.co_filename, first, last) |
|
394 | self.print_list_lines(self.curframe.f_code.co_filename, first, last) | |
396 |
|
395 | |||
397 | do_l = do_list |
|
396 | do_l = do_list | |
398 |
|
397 | |||
399 | def do_pdef(self, arg): |
|
398 | def do_pdef(self, arg): | |
400 | """The debugger interface to magic_pdef""" |
|
399 | """The debugger interface to magic_pdef""" | |
401 | namespaces = [('Locals', self.curframe.f_locals), |
|
400 | namespaces = [('Locals', self.curframe.f_locals), | |
402 | ('Globals', self.curframe.f_globals)] |
|
401 | ('Globals', self.curframe.f_globals)] | |
403 | __IPYTHON__.magic_pdef(arg, namespaces=namespaces) |
|
402 | __IPYTHON__.magic_pdef(arg, namespaces=namespaces) | |
404 |
|
403 | |||
405 | def do_pdoc(self, arg): |
|
404 | def do_pdoc(self, arg): | |
406 | """The debugger interface to magic_pdoc""" |
|
405 | """The debugger interface to magic_pdoc""" | |
407 | namespaces = [('Locals', self.curframe.f_locals), |
|
406 | namespaces = [('Locals', self.curframe.f_locals), | |
408 | ('Globals', self.curframe.f_globals)] |
|
407 | ('Globals', self.curframe.f_globals)] | |
409 | __IPYTHON__.magic_pdoc(arg, namespaces=namespaces) |
|
408 | __IPYTHON__.magic_pdoc(arg, namespaces=namespaces) | |
410 |
|
409 | |||
411 | def do_pinfo(self, arg): |
|
410 | def do_pinfo(self, arg): | |
412 | """The debugger equivalant of ?obj""" |
|
411 | """The debugger equivalant of ?obj""" | |
413 | namespaces = [('Locals', self.curframe.f_locals), |
|
412 | namespaces = [('Locals', self.curframe.f_locals), | |
414 | ('Globals', self.curframe.f_globals)] |
|
413 | ('Globals', self.curframe.f_globals)] | |
415 | __IPYTHON__.magic_pinfo("pinfo %s" % arg, namespaces=namespaces) |
|
414 | __IPYTHON__.magic_pinfo("pinfo %s" % arg, namespaces=namespaces) |
@@ -1,86 +1,86 b'' | |||||
1 | # -*- coding: utf-8 -*- |
|
1 | # -*- coding: utf-8 -*- | |
2 | """Release data for the IPython project. |
|
2 | """Release data for the IPython project. | |
3 |
|
3 | |||
4 |
$Id: Release.py 195 |
|
4 | $Id: Release.py 1954 2006-11-29 09:39:44Z 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 | # Copyright (c) 2001 Janko Hauser <jhauser@zscout.de> and Nathaniel Gray |
|
9 | # Copyright (c) 2001 Janko Hauser <jhauser@zscout.de> and Nathaniel Gray | |
10 | # <n8gray@caltech.edu> |
|
10 | # <n8gray@caltech.edu> | |
11 | # |
|
11 | # | |
12 | # Distributed under the terms of the BSD License. The full license is in |
|
12 | # Distributed under the terms of the BSD License. The full license is in | |
13 | # the file COPYING, distributed as part of this software. |
|
13 | # the file COPYING, distributed as part of this software. | |
14 | #***************************************************************************** |
|
14 | #***************************************************************************** | |
15 |
|
15 | |||
16 | # Name of the package for release purposes. This is the name which labels |
|
16 | # Name of the package for release purposes. This is the name which labels | |
17 | # the tarballs and RPMs made by distutils, so it's best to lowercase it. |
|
17 | # the tarballs and RPMs made by distutils, so it's best to lowercase it. | |
18 | name = 'ipython' |
|
18 | name = 'ipython' | |
19 |
|
19 | |||
20 | # For versions with substrings (like 0.6.16.svn), use an extra . to separate |
|
20 | # For versions with substrings (like 0.6.16.svn), use an extra . to separate | |
21 | # the new substring. We have to avoid using either dashes or underscores, |
|
21 | # the new substring. We have to avoid using either dashes or underscores, | |
22 | # because bdist_rpm does not accept dashes (an RPM) convention, and |
|
22 | # because bdist_rpm does not accept dashes (an RPM) convention, and | |
23 | # bdist_deb does not accept underscores (a Debian convention). |
|
23 | # bdist_deb does not accept underscores (a Debian convention). | |
24 |
|
24 | |||
25 |
revision = '195 |
|
25 | revision = '1953' | |
26 |
|
26 | |||
27 | #version = '0.7.3.svn' |
|
27 | #version = '0.7.3.svn' | |
28 |
|
28 | |||
29 | version = '0.7.3.svn.r' + revision.rstrip('M') |
|
29 | version = '0.7.3.svn.r' + revision.rstrip('M') | |
30 |
|
30 | |||
31 |
|
31 | |||
32 | description = "An enhanced interactive Python shell." |
|
32 | description = "An enhanced interactive Python shell." | |
33 |
|
33 | |||
34 | long_description = \ |
|
34 | long_description = \ | |
35 | """ |
|
35 | """ | |
36 | IPython provides a replacement for the interactive Python interpreter with |
|
36 | IPython provides a replacement for the interactive Python interpreter with | |
37 | extra functionality. |
|
37 | extra functionality. | |
38 |
|
38 | |||
39 | Main features: |
|
39 | Main features: | |
40 |
|
40 | |||
41 | * Comprehensive object introspection. |
|
41 | * Comprehensive object introspection. | |
42 |
|
42 | |||
43 | * Input history, persistent across sessions. |
|
43 | * Input history, persistent across sessions. | |
44 |
|
44 | |||
45 | * Caching of output results during a session with automatically generated |
|
45 | * Caching of output results during a session with automatically generated | |
46 | references. |
|
46 | references. | |
47 |
|
47 | |||
48 | * Readline based name completion. |
|
48 | * Readline based name completion. | |
49 |
|
49 | |||
50 | * Extensible system of 'magic' commands for controlling the environment and |
|
50 | * Extensible system of 'magic' commands for controlling the environment and | |
51 | performing many tasks related either to IPython or the operating system. |
|
51 | performing many tasks related either to IPython or the operating system. | |
52 |
|
52 | |||
53 | * Configuration system with easy switching between different setups (simpler |
|
53 | * Configuration system with easy switching between different setups (simpler | |
54 | than changing $PYTHONSTARTUP environment variables every time). |
|
54 | than changing $PYTHONSTARTUP environment variables every time). | |
55 |
|
55 | |||
56 | * Session logging and reloading. |
|
56 | * Session logging and reloading. | |
57 |
|
57 | |||
58 | * Extensible syntax processing for special purpose situations. |
|
58 | * Extensible syntax processing for special purpose situations. | |
59 |
|
59 | |||
60 | * Access to the system shell with user-extensible alias system. |
|
60 | * Access to the system shell with user-extensible alias system. | |
61 |
|
61 | |||
62 | * Easily embeddable in other Python programs. |
|
62 | * Easily embeddable in other Python programs. | |
63 |
|
63 | |||
64 | * Integrated access to the pdb debugger and the Python profiler. |
|
64 | * Integrated access to the pdb debugger and the Python profiler. | |
65 |
|
65 | |||
66 | The latest development version is always available at the IPython subversion |
|
66 | The latest development version is always available at the IPython subversion | |
67 | repository_. |
|
67 | repository_. | |
68 |
|
68 | |||
69 | .. _repository: http://ipython.scipy.org/svn/ipython/ipython/trunk#egg=ipython-dev |
|
69 | .. _repository: http://ipython.scipy.org/svn/ipython/ipython/trunk#egg=ipython-dev | |
70 | """ |
|
70 | """ | |
71 |
|
71 | |||
72 | license = 'BSD' |
|
72 | license = 'BSD' | |
73 |
|
73 | |||
74 | authors = {'Fernando' : ('Fernando Perez','fperez@colorado.edu'), |
|
74 | authors = {'Fernando' : ('Fernando Perez','fperez@colorado.edu'), | |
75 | 'Janko' : ('Janko Hauser','jhauser@zscout.de'), |
|
75 | 'Janko' : ('Janko Hauser','jhauser@zscout.de'), | |
76 | 'Nathan' : ('Nathaniel Gray','n8gray@caltech.edu'), |
|
76 | 'Nathan' : ('Nathaniel Gray','n8gray@caltech.edu'), | |
77 | 'Ville' : ('Ville Vainio','vivainio@gmail.com') |
|
77 | 'Ville' : ('Ville Vainio','vivainio@gmail.com') | |
78 | } |
|
78 | } | |
79 |
|
79 | |||
80 | url = 'http://ipython.scipy.org' |
|
80 | url = 'http://ipython.scipy.org' | |
81 |
|
81 | |||
82 | download_url = 'http://ipython.scipy.org/dist' |
|
82 | download_url = 'http://ipython.scipy.org/dist' | |
83 |
|
83 | |||
84 | platforms = ['Linux','Mac OSX','Windows XP/2000/NT','Windows 95/98/ME'] |
|
84 | platforms = ['Linux','Mac OSX','Windows XP/2000/NT','Windows 95/98/ME'] | |
85 |
|
85 | |||
86 | keywords = ['Interactive','Interpreter','Shell'] |
|
86 | keywords = ['Interactive','Interpreter','Shell'] |
General Comments 0
You need to be logged in to leave comments.
Login now