|
74 | 74 | import re |
75 | 75 | import pprint |
76 | 76 | import traceback |
| 77 | +import inspect |
| 78 | +import types |
77 | 79 |
|
78 | 80 |
|
79 | 81 | class Restart(Exception): |
@@ -1028,25 +1030,62 @@ def do_list(self, arg): |
1028 | 1030 | filename = self.curframe.f_code.co_filename |
1029 | 1031 | breaklist = self.get_file_breaks(filename) |
1030 | 1032 | try: |
1031 | | - for lineno in range(first, last+1): |
1032 | | - line = linecache.getline(filename, lineno, |
1033 | | - self.curframe.f_globals) |
1034 | | - if not line: |
1035 | | - self.message('[EOF]') |
1036 | | - break |
1037 | | - else: |
1038 | | - s = repr(lineno).rjust(3) |
1039 | | - if len(s) < 4: s = s + ' ' |
1040 | | - if lineno in breaklist: s = s + 'B' |
1041 | | - else: s = s + ' ' |
1042 | | - if lineno == self.curframe.f_lineno: |
1043 | | - s = s + '->' |
1044 | | - self.message(s + '\t' + line.rstrip()) |
1045 | | - self.lineno = lineno |
| 1033 | + # XXX add tb_lineno feature |
| 1034 | + lines = linecache.getlines(filename, self.curframe.f_globals) |
| 1035 | + self._print_lines(lines[first-1:last], first, breaklist, |
| 1036 | + self.curframe.f_lineno, -1) |
| 1037 | + self.lineno = min(last, len(lines)) |
| 1038 | + if len(lines) < last: |
| 1039 | + self.message('[EOF]') |
1046 | 1040 | except KeyboardInterrupt: |
1047 | 1041 | pass |
1048 | 1042 | do_l = do_list |
1049 | 1043 |
|
| 1044 | + def do_longlist(self, arg): |
| 1045 | + """longlist | ll |
| 1046 | + List the whole source code for the current function or frame. |
| 1047 | + """ |
| 1048 | + filename = self.curframe.f_code.co_filename |
| 1049 | + breaklist = self.get_file_breaks(filename) |
| 1050 | + try: |
| 1051 | + lines, lineno = inspect.getsourcelines(self.curframe) |
| 1052 | + except IOError as err: |
| 1053 | + self.error(err) |
| 1054 | + return |
| 1055 | + self._print_lines(lines, lineno, breaklist, self.curframe.f_lineno, -1) |
| 1056 | + do_ll = do_longlist |
| 1057 | + |
| 1058 | + def do_source(self, arg): |
| 1059 | + """source expression |
| 1060 | + Try to get source code for the given object and display it. |
| 1061 | + """ |
| 1062 | + try: |
| 1063 | + obj = self._getval(arg) |
| 1064 | + except: |
| 1065 | + return |
| 1066 | + try: |
| 1067 | + lines, lineno = inspect.getsourcelines(obj) |
| 1068 | + except (IOError, TypeError) as err: |
| 1069 | + self.error(err) |
| 1070 | + return |
| 1071 | + self._print_lines(lines, lineno, [], -1, -1) |
| 1072 | + |
| 1073 | + def _print_lines(self, lines, start, breaks, current, special): |
| 1074 | + """Print a range of lines.""" |
| 1075 | + for lineno, line in enumerate(lines, start): |
| 1076 | + s = str(lineno).rjust(3) |
| 1077 | + if len(s) < 4: |
| 1078 | + s += ' ' |
| 1079 | + if lineno in breaks: |
| 1080 | + s += 'B' |
| 1081 | + else: |
| 1082 | + s += ' ' |
| 1083 | + if lineno == current: |
| 1084 | + s += '->' |
| 1085 | + elif lineno == special: |
| 1086 | + s += '>>' |
| 1087 | + self.message(s + '\t' + line.rstrip()) |
| 1088 | + |
1050 | 1089 | def do_whatis(self, arg): |
1051 | 1090 | """whatis arg |
1052 | 1091 | Print the type of the argument. |
@@ -1249,10 +1288,12 @@ def _runscript(self, filename): |
1249 | 1288 | _help_order = [ |
1250 | 1289 | 'help', 'where', 'down', 'up', 'break', 'tbreak', 'clear', 'disable', |
1251 | 1290 | 'enable', 'ignore', 'condition', 'commands', 'step', 'next', 'until', |
1252 | | - 'jump', 'return', 'retval', 'run', 'continue', 'list', 'args', 'print', |
1253 | | - 'whatis', 'alias', 'unalias', 'quit', |
| 1291 | + 'jump', 'return', 'retval', 'run', 'continue', 'list', 'longlist', |
| 1292 | + 'args', 'print', 'pp', 'whatis', 'source', 'alias', 'unalias', |
| 1293 | + 'debug', 'quit', |
1254 | 1294 | ] |
1255 | 1295 |
|
| 1296 | +docs = set() |
1256 | 1297 | for _command in _help_order: |
1257 | 1298 | __doc__ += getattr(Pdb, 'do_' + _command).__doc__.strip() + '\n\n' |
1258 | 1299 | __doc__ += Pdb.help_exec.__doc__ |
|
0 commit comments