##// END OF EJS Templates
Add support for set_trace-like functionality, but with IPython's enhanced...
fperez -
r506:20e0542a
parent child
Show More
@@ -15,7 +15,7 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 1961 2006-12-05 21:02:40Z vivainio $"""
18 $Id: Debugger.py 2014 2007-01-05 10:36:58Z fperez $"""
19
19
20 #*****************************************************************************
20 #*****************************************************************************
21 #
21 #
@@ -42,7 +42,7 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, ipapi
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
@@ -63,6 +63,86 if has_pydb:
63 else:
63 else:
64 from pdb import Pdb as OldPdb
64 from pdb import Pdb as OldPdb
65
65
66 # Allow the set_trace code to operate outside of an ipython instance, even if
67 # it does so with some limitations. The rest of this support is implemented in
68 # the Tracer constructor.
69 def BdbQuit_excepthook(et,ev,tb):
70 if et==bdb.BdbQuit:
71 print 'Exiting Debugger.'
72 else:
73 ehook.excepthook_ori(et,ev,tb)
74
75 def BdbQuit_IPython_excepthook(self,et,ev,tb):
76 print 'Exiting Debugger.'
77
78 class Tracer(object):
79 """Class for local debugging, similar to pdb.set_trace.
80
81 Instances of this class, when called, behave like pdb.set_trace, but
82 providing IPython's enhanced capabilities.
83
84 This is implemented as a class which must be initialized in your own code
85 and not as a standalone function because we need to detect at runtime
86 whether IPython is already active or not. That detection is done in the
87 constructor, ensuring that this code plays nicely with a running IPython,
88 while functioning acceptably (though with limitations) if outside of it.
89 """
90
91 def __init__(self,colors=None):
92 """Create a local debugger instance.
93
94 :Parameters:
95
96 - `colors` (None): a string containing the name of the color scheme to
97 use, it must be one of IPython's valid color schemes. If not given, the
98 function will default to the current IPython scheme when running inside
99 IPython, and to 'NoColor' otherwise.
100
101 Usage example:
102
103 from IPython.Debugger import Tracer; debug_here = Tracer()
104
105 ... later in your code
106 debug_here() # -> will open up the debugger at that point.
107
108 Once the debugger activates, you can use all of its regular commands to
109 step through code, set breakpoints, etc. See the pdb documentation
110 from the Python standard library for usage details.
111 """
112
113 global __IPYTHON__
114 try:
115 __IPYTHON__
116 except NameError:
117 # Outside of ipython, we set our own exception hook manually
118 __IPYTHON__ = ipapi.get(True,False)
119 BdbQuit_excepthook.excepthook_ori = sys.excepthook
120 sys.excepthook = BdbQuit_excepthook
121 def_colors = 'NoColor'
122 try:
123 # Limited tab completion support
124 import rlcompleter,readline
125 readline.parse_and_bind('tab: complete')
126 except ImportError:
127 pass
128 else:
129 # In ipython, we use its custom exception handler mechanism
130 ip = ipapi.get()
131 def_colors = ip.options.colors
132 ip.set_custom_exc((bdb.BdbQuit,),BdbQuit_IPython_excepthook)
133
134 if colors is None:
135 colors = def_colors
136 self.debugger = Pdb(colors)
137
138 def __call__(self):
139 """Starts an interactive debugger at the point where called.
140
141 This is similar to the pdb.set_trace() function from the std lib, but
142 using IPython's enhanced debugger."""
143
144 self.debugger.set_trace(sys._getframe().f_back)
145
66 def decorate_fn_with_doc(new_fn, old_fn, additional_text=""):
146 def decorate_fn_with_doc(new_fn, old_fn, additional_text=""):
67 """Make new_fn have old_fn's doc string. This is particularly useful
147 """Make new_fn have old_fn's doc string. This is particularly useful
68 for the do_... commands that hook into the help system.
148 for the do_... commands that hook into the help system.
@@ -172,6 +252,7 class Pdb(OldPdb):
172
252
173 # Create color table: we copy the default one from the traceback
253 # Create color table: we copy the default one from the traceback
174 # module and add a few attributes needed for debugging
254 # module and add a few attributes needed for debugging
255 ExceptionColors.set_active_scheme(color_scheme)
175 self.color_scheme_table = ExceptionColors.copy()
256 self.color_scheme_table = ExceptionColors.copy()
176
257
177 # shorthands
258 # shorthands
@@ -91,6 +91,12 class IPythonNotRunning:
91 without ipython. Obviously code which uses the ipython object for
91 without ipython. Obviously code which uses the ipython object for
92 computations will not work, but this allows a wider range of code to
92 computations will not work, but this allows a wider range of code to
93 transparently work whether ipython is being used or not."""
93 transparently work whether ipython is being used or not."""
94
95 def __init__(self,warn=True):
96 if warn:
97 self.dummy = self._dummy_warn
98 else:
99 self.dummy = self._dummy_silent
94
100
95 def __str__(self):
101 def __str__(self):
96 return "<IPythonNotRunning>"
102 return "<IPythonNotRunning>"
@@ -100,26 +106,33 class IPythonNotRunning:
100 def __getattr__(self,name):
106 def __getattr__(self,name):
101 return self.dummy
107 return self.dummy
102
108
103 def dummy(self,*args,**kw):
109 def _dummy_warn(self,*args,**kw):
104 """Dummy function, which doesn't do anything but warn."""
110 """Dummy function, which doesn't do anything but warn."""
111
105 warn("IPython is not running, this is a dummy no-op function")
112 warn("IPython is not running, this is a dummy no-op function")
106
113
114 def _dummy_silent(self,*args,**kw):
115 """Dummy function, which doesn't do anything and emits no warnings."""
116 pass
117
107 _recent = None
118 _recent = None
108
119
109
120
110 def get(allow_dummy=False):
121 def get(allow_dummy=False,dummy_warn=True):
111 """Get an IPApi object.
122 """Get an IPApi object.
112
123
113 If allow_dummy is true, returns an instance of IPythonNotRunning
124 If allow_dummy is true, returns an instance of IPythonNotRunning
114 instead of None if not running under IPython.
125 instead of None if not running under IPython.
115
126
127 If dummy_warn is false, the dummy instance will be completely silent.
128
116 Running this should be the first thing you do when writing extensions that
129 Running this should be the first thing you do when writing extensions that
117 can be imported as normal modules. You can then direct all the
130 can be imported as normal modules. You can then direct all the
118 configuration operations against the returned object.
131 configuration operations against the returned object.
119 """
132 """
120 global _recent
133 global _recent
121 if allow_dummy and not _recent:
134 if allow_dummy and not _recent:
122 _recent = IPythonNotRunning()
135 _recent = IPythonNotRunning(dummy_warn)
123 return _recent
136 return _recent
124
137
125 class IPApi:
138 class IPApi:
@@ -6,7 +6,7 Requires Python 2.3 or newer.
6
6
7 This file contains all the classes and helper functions specific to IPython.
7 This file contains all the classes and helper functions specific to IPython.
8
8
9 $Id: iplib.py 1977 2006-12-11 16:52:12Z fperez $
9 $Id: iplib.py 2014 2007-01-05 10:36:58Z fperez $
10 """
10 """
11
11
12 #*****************************************************************************
12 #*****************************************************************************
@@ -1460,6 +1460,7 want to merge them back into the new files.""" % locals()
1460 etype, value, tb = sys.exc_info()
1460 etype, value, tb = sys.exc_info()
1461 else:
1461 else:
1462 etype, value, tb = exc_tuple
1462 etype, value, tb = exc_tuple
1463
1463 if etype is SyntaxError:
1464 if etype is SyntaxError:
1464 self.showsyntaxerror(filename)
1465 self.showsyntaxerror(filename)
1465 else:
1466 else:
@@ -1470,11 +1471,14 want to merge them back into the new files.""" % locals()
1470 sys.last_type = etype
1471 sys.last_type = etype
1471 sys.last_value = value
1472 sys.last_value = value
1472 sys.last_traceback = tb
1473 sys.last_traceback = tb
1473
1474
1474 self.InteractiveTB(etype,value,tb,tb_offset=tb_offset)
1475 if etype in self.custom_exceptions:
1475 if self.InteractiveTB.call_pdb and self.has_readline:
1476 self.CustomTB(etype,value,tb)
1476 # pdb mucks up readline, fix it back
1477 else:
1477 self.readline.set_completer(self.Completer.complete)
1478 self.InteractiveTB(etype,value,tb,tb_offset=tb_offset)
1479 if self.InteractiveTB.call_pdb and self.has_readline:
1480 # pdb mucks up readline, fix it back
1481 self.readline.set_completer(self.Completer.complete)
1478
1482
1479 def mainloop(self,banner=None):
1483 def mainloop(self,banner=None):
1480 """Creates the local namespace and starts the mainloop.
1484 """Creates the local namespace and starts the mainloop.
@@ -1,3 +1,12
1 2007-01-05 Fernando Perez <Fernando.Perez@colorado.edu>
2
3 * IPython/iplib.py (showtraceback): ensure that we correctly call
4 custom handlers in all cases (some with pdb were slipping through,
5 but I'm not exactly sure why).
6
7 * IPython/Debugger.py (Tracer.__init__): added new class to
8 support set_trace-like usage of IPython's enhanced debugger.
9
1 2006-12-24 Ville Vainio <vivainio@gmail.com>
10 2006-12-24 Ville Vainio <vivainio@gmail.com>
2
11
3 * ipmaker.py: more informative message when ipy_user_conf
12 * ipmaker.py: more informative message when ipy_user_conf
@@ -12,7 +12,7 cd ~/ipython/ipython
12 ./setup.py sdist --formats=gztar
12 ./setup.py sdist --formats=gztar
13
13
14 # Build rpm
14 # Build rpm
15 python2.4 ./setup.py bdist_rpm --binary-only --release=py24 --python=/usr/bin/python2.4
15 #python2.4 ./setup.py bdist_rpm --binary-only --release=py24 --python=/usr/bin/python2.4
16
16
17 # Build eggs
17 # Build eggs
18 ./eggsetup.py bdist_egg
18 ./eggsetup.py bdist_egg
@@ -1,6 +1,6
1 #!/bin/sh
1 #!/bin/sh
2
2
3 # clean public testing/ dir and upload
3 # clean public testing/ dir and upload
4 ssh "rm -f ipython@ipython.scipy.org:www/dist/testing/*"
4 #ssh "rm -f ipython@ipython.scipy.org:www/dist/testing/*"
5 cd ~/ipython/ipython/dist
5 cd ~/ipython/ipython/dist
6 scp * ipython@ipython.scipy.org:www/dist/testing/
6 scp * ipython@ipython.scipy.org:www/dist/testing/
General Comments 0
You need to be logged in to leave comments. Login now