blob: eeb54d231adfccd9a19567531cec4f424def331c [file] [log] [blame]
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +00001"""Get useful information from live Python objects.
2
3This module encapsulates the interface provided by the internal special
4attributes (func_*, co_*, im_*, tb_*, etc.) in a friendlier fashion.
5It also provides some help for examining source code and class layout.
6
7Here are some of the useful functions provided by this module:
8
9 ismodule(), isclass(), ismethod(), isfunction(), istraceback(),
10 isframe(), iscode(), isbuiltin(), isroutine() - check object types
11 getmembers() - get members of an object that satisfy a given condition
12
13 getfile(), getsourcefile(), getsource() - find an object's source code
14 getdoc(), getcomments() - get documentation on an object
15 getmodule() - determine the module that an object came from
16 getclasstree() - arrange classes so as to represent their hierarchy
17
18 getargspec(), getargvalues() - get info about function arguments
19 formatargspec(), formatargvalues() - format an argument spec
20 getouterframes(), getinnerframes() - get info about frames
21 currentframe() - get the current stack frame
22 stack(), trace() - get info about frames on the stack or in a traceback
23"""
24
25# This module is in the public domain. No warranties.
26
Ka-Ping Yee8b58b842001-03-01 13:56:16 +000027__author__ = 'Ka-Ping Yee <ping@lfw.org>'
28__date__ = '1 Jan 2001'
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +000029
Ka-Ping Yeea6e59712001-03-10 09:31:55 +000030import sys, os, types, string, re, dis, imp, tokenize
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +000031
32# ----------------------------------------------------------- type-checking
33def ismodule(object):
34 """Return true if the object is a module.
35
36 Module objects provide these attributes:
37 __doc__ documentation string
38 __file__ filename (missing for built-in modules)"""
39 return type(object) is types.ModuleType
40
41def isclass(object):
42 """Return true if the object is a class.
43
44 Class objects provide these attributes:
45 __doc__ documentation string
46 __module__ name of module in which this class was defined"""
Ka-Ping Yeea9c6c8d2001-03-23 15:29:59 +000047 return type(object) is types.ClassType or hasattr(object, '__bases__')
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +000048
49def ismethod(object):
50 """Return true if the object is an instance method.
51
52 Instance method objects provide these attributes:
53 __doc__ documentation string
54 __name__ name with which this method was defined
55 im_class class object in which this method belongs
56 im_func function object containing implementation of method
57 im_self instance to which this method is bound, or None"""
58 return type(object) is types.MethodType
59
60def isfunction(object):
61 """Return true if the object is a user-defined function.
62
63 Function objects provide these attributes:
64 __doc__ documentation string
65 __name__ name with which this function was defined
66 func_code code object containing compiled function bytecode
67 func_defaults tuple of any default values for arguments
68 func_doc (same as __doc__)
69 func_globals global namespace in which this function was defined
70 func_name (same as __name__)"""
71 return type(object) in [types.FunctionType, types.LambdaType]
72
73def istraceback(object):
74 """Return true if the object is a traceback.
75
76 Traceback objects provide these attributes:
77 tb_frame frame object at this level
78 tb_lasti index of last attempted instruction in bytecode
79 tb_lineno current line number in Python source code
80 tb_next next inner traceback object (called by this level)"""
81 return type(object) is types.TracebackType
82
83def isframe(object):
84 """Return true if the object is a frame object.
85
86 Frame objects provide these attributes:
87 f_back next outer frame object (this frame's caller)
88 f_builtins built-in namespace seen by this frame
89 f_code code object being executed in this frame
90 f_exc_traceback traceback if raised in this frame, or None
91 f_exc_type exception type if raised in this frame, or None
92 f_exc_value exception value if raised in this frame, or None
93 f_globals global namespace seen by this frame
94 f_lasti index of last attempted instruction in bytecode
95 f_lineno current line number in Python source code
96 f_locals local namespace seen by this frame
97 f_restricted 0 or 1 if frame is in restricted execution mode
98 f_trace tracing function for this frame, or None"""
99 return type(object) is types.FrameType
100
101def iscode(object):
102 """Return true if the object is a code object.
103
104 Code objects provide these attributes:
105 co_argcount number of arguments (not including * or ** args)
106 co_code string of raw compiled bytecode
107 co_consts tuple of constants used in the bytecode
108 co_filename name of file in which this code object was created
109 co_firstlineno number of first line in Python source code
110 co_flags bitmap: 1=optimized | 2=newlocals | 4=*arg | 8=**arg
111 co_lnotab encoded mapping of line numbers to bytecode indices
112 co_name name with which this code object was defined
113 co_names tuple of names of local variables
114 co_nlocals number of local variables
115 co_stacksize virtual machine stack space required
116 co_varnames tuple of names of arguments and local variables"""
117 return type(object) is types.CodeType
118
119def isbuiltin(object):
120 """Return true if the object is a built-in function or method.
121
122 Built-in functions and methods provide these attributes:
123 __doc__ documentation string
124 __name__ original name of this function or method
125 __self__ instance to which a method is bound, or None"""
Ka-Ping Yee202c99b2001-04-13 09:15:08 +0000126 return type(object) is types.BuiltinFunctionType
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +0000127
128def isroutine(object):
129 """Return true if the object is any kind of function or method."""
Ka-Ping Yee022171f2001-04-13 14:04:02 +0000130 return isbuiltin(object) or isfunction(object) or ismethod(object)
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +0000131
132def getmembers(object, predicate=None):
133 """Return all members of an object as (name, value) pairs sorted by name.
134 Optionally, only return members that satisfy a given predicate."""
135 results = []
136 for key in dir(object):
137 value = getattr(object, key)
138 if not predicate or predicate(value):
139 results.append((key, value))
140 results.sort()
141 return results
142
143# -------------------------------------------------- source code extraction
144def indentsize(line):
145 """Return the indent size, in spaces, at the start of a line of text."""
146 expline = string.expandtabs(line)
147 return len(expline) - len(string.lstrip(expline))
148
149def getdoc(object):
150 """Get the documentation string for an object.
151
152 All tabs are expanded to spaces. To clean up docstrings that are
153 indented to line up with blocks of code, any whitespace than can be
154 uniformly removed from the second line onwards is removed."""
155 if hasattr(object, '__doc__') and object.__doc__:
156 lines = string.split(string.expandtabs(object.__doc__), '\n')
157 margin = None
158 for line in lines[1:]:
159 content = len(string.lstrip(line))
160 if not content: continue
161 indent = len(line) - content
162 if margin is None: margin = indent
163 else: margin = min(margin, indent)
164 if margin is not None:
165 for i in range(1, len(lines)): lines[i] = lines[i][margin:]
166 return string.join(lines, '\n')
167
168def getfile(object):
Ka-Ping Yeec113c242001-03-02 02:08:53 +0000169 """Work out which source or compiled file an object was defined in."""
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +0000170 if ismodule(object):
171 if hasattr(object, '__file__'):
172 return object.__file__
173 raise TypeError, 'arg is a built-in module'
174 if isclass(object):
Ka-Ping Yeec99e0f12001-04-13 12:10:40 +0000175 object = sys.modules.get(object.__module__)
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +0000176 if hasattr(object, '__file__'):
177 return object.__file__
178 raise TypeError, 'arg is a built-in class'
179 if ismethod(object):
180 object = object.im_func
181 if isfunction(object):
182 object = object.func_code
183 if istraceback(object):
184 object = object.tb_frame
185 if isframe(object):
186 object = object.f_code
187 if iscode(object):
188 return object.co_filename
189 raise TypeError, 'arg is not a module, class, method, ' \
190 'function, traceback, frame, or code object'
191
Ka-Ping Yee4d6fc7f2001-04-10 11:43:00 +0000192def getmoduleinfo(path):
193 """Get the module name, suffix, mode, and module type for a given file."""
194 filename = os.path.basename(path)
195 suffixes = map(lambda (suffix, mode, mtype):
196 (-len(suffix), suffix, mode, mtype), imp.get_suffixes())
197 suffixes.sort() # try longest suffixes first, in case they overlap
198 for neglen, suffix, mode, mtype in suffixes:
199 if filename[neglen:] == suffix:
200 return filename[:neglen], suffix, mode, mtype
201
202def getmodulename(path):
203 """Return the module name for a given file, or None."""
204 info = getmoduleinfo(path)
205 if info: return info[0]
206
Ka-Ping Yeec113c242001-03-02 02:08:53 +0000207def getsourcefile(object):
208 """Return the Python source file an object was defined in, if it exists."""
209 filename = getfile(object)
210 if string.lower(filename[-4:]) in ['.pyc', '.pyo']:
211 filename = filename[:-4] + '.py'
Ka-Ping Yee4eb0c002001-03-02 05:50:34 +0000212 for suffix, mode, kind in imp.get_suffixes():
213 if 'b' in mode and string.lower(filename[-len(suffix):]) == suffix:
214 # Looks like a binary file. We want to only return a text file.
215 return None
216 if os.path.exists(filename):
Ka-Ping Yeec113c242001-03-02 02:08:53 +0000217 return filename
218
219def getabsfile(object):
Ka-Ping Yee4eb0c002001-03-02 05:50:34 +0000220 """Return an absolute path to the source or compiled file for an object.
Ka-Ping Yeec113c242001-03-02 02:08:53 +0000221
Ka-Ping Yee4eb0c002001-03-02 05:50:34 +0000222 The idea is for each object to have a unique origin, so this routine
223 normalizes the result as much as possible."""
224 return os.path.normcase(
225 os.path.abspath(getsourcefile(object) or getfile(object)))
Ka-Ping Yeec113c242001-03-02 02:08:53 +0000226
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +0000227modulesbyfile = {}
228
229def getmodule(object):
Ka-Ping Yee4eb0c002001-03-02 05:50:34 +0000230 """Return the module an object was defined in, or None if not found."""
Ka-Ping Yee202c99b2001-04-13 09:15:08 +0000231 if ismodule(object):
232 return object
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +0000233 if isclass(object):
Ka-Ping Yee8b58b842001-03-01 13:56:16 +0000234 return sys.modules.get(object.__module__)
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +0000235 try:
Ka-Ping Yeec113c242001-03-02 02:08:53 +0000236 file = getabsfile(object)
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +0000237 except TypeError:
238 return None
239 if modulesbyfile.has_key(file):
240 return sys.modules[modulesbyfile[file]]
241 for module in sys.modules.values():
242 if hasattr(module, '__file__'):
Ka-Ping Yeec113c242001-03-02 02:08:53 +0000243 modulesbyfile[getabsfile(module)] = module.__name__
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +0000244 if modulesbyfile.has_key(file):
245 return sys.modules[modulesbyfile[file]]
246 main = sys.modules['__main__']
Ka-Ping Yee4eb0c002001-03-02 05:50:34 +0000247 if hasattr(main, object.__name__):
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +0000248 mainobject = getattr(main, object.__name__)
Ka-Ping Yee4eb0c002001-03-02 05:50:34 +0000249 if mainobject is object:
250 return main
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +0000251 builtin = sys.modules['__builtin__']
Ka-Ping Yee4eb0c002001-03-02 05:50:34 +0000252 if hasattr(builtin, object.__name__):
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +0000253 builtinobject = getattr(builtin, object.__name__)
Ka-Ping Yee4eb0c002001-03-02 05:50:34 +0000254 if builtinobject is object:
255 return builtin
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +0000256
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +0000257def findsource(object):
258 """Return the entire source file and starting line number for an object.
259
260 The argument may be a module, class, method, function, traceback, frame,
261 or code object. The source code is returned as a list of all the lines
262 in the file and the line number indexes a line in that list. An IOError
263 is raised if the source code cannot be retrieved."""
264 try:
265 file = open(getsourcefile(object))
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +0000266 except (TypeError, IOError):
267 raise IOError, 'could not get source code'
Ka-Ping Yee4eb0c002001-03-02 05:50:34 +0000268 lines = file.readlines()
269 file.close()
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +0000270
271 if ismodule(object):
272 return lines, 0
273
274 if isclass(object):
275 name = object.__name__
Ka-Ping Yeea6e59712001-03-10 09:31:55 +0000276 pat = re.compile(r'^\s*class\s*' + name + r'\b')
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +0000277 for i in range(len(lines)):
Ka-Ping Yeea6e59712001-03-10 09:31:55 +0000278 if pat.match(lines[i]): return lines, i
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +0000279 else: raise IOError, 'could not find class definition'
280
281 if ismethod(object):
282 object = object.im_func
283 if isfunction(object):
284 object = object.func_code
285 if istraceback(object):
286 object = object.tb_frame
287 if isframe(object):
288 object = object.f_code
289 if iscode(object):
Ka-Ping Yee4eb0c002001-03-02 05:50:34 +0000290 if not hasattr(object, 'co_firstlineno'):
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +0000291 raise IOError, 'could not find function definition'
Ka-Ping Yee4eb0c002001-03-02 05:50:34 +0000292 lnum = object.co_firstlineno - 1
Ka-Ping Yeea6e59712001-03-10 09:31:55 +0000293 pat = re.compile(r'^\s*def\s')
Ka-Ping Yee4eb0c002001-03-02 05:50:34 +0000294 while lnum > 0:
Ka-Ping Yeea6e59712001-03-10 09:31:55 +0000295 if pat.match(lines[lnum]): break
Ka-Ping Yee4eb0c002001-03-02 05:50:34 +0000296 lnum = lnum - 1
297 return lines, lnum
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +0000298
299def getcomments(object):
300 """Get lines of comments immediately preceding an object's source code."""
301 try: lines, lnum = findsource(object)
Ka-Ping Yee4eb0c002001-03-02 05:50:34 +0000302 except IOError: return None
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +0000303
304 if ismodule(object):
305 # Look for a comment block at the top of the file.
306 start = 0
Ka-Ping Yeeb910efe2001-04-12 13:17:17 +0000307 if lines and lines[0][:2] == '#!': start = 1
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +0000308 while start < len(lines) and string.strip(lines[start]) in ['', '#']:
309 start = start + 1
Ka-Ping Yeeb910efe2001-04-12 13:17:17 +0000310 if start < len(lines) and lines[start][:1] == '#':
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +0000311 comments = []
312 end = start
313 while end < len(lines) and lines[end][:1] == '#':
314 comments.append(string.expandtabs(lines[end]))
315 end = end + 1
316 return string.join(comments, '')
317
318 # Look for a preceding block of comments at the same indentation.
319 elif lnum > 0:
320 indent = indentsize(lines[lnum])
321 end = lnum - 1
322 if end >= 0 and string.lstrip(lines[end])[:1] == '#' and \
323 indentsize(lines[end]) == indent:
324 comments = [string.lstrip(string.expandtabs(lines[end]))]
325 if end > 0:
326 end = end - 1
327 comment = string.lstrip(string.expandtabs(lines[end]))
328 while comment[:1] == '#' and indentsize(lines[end]) == indent:
329 comments[:0] = [comment]
330 end = end - 1
331 if end < 0: break
332 comment = string.lstrip(string.expandtabs(lines[end]))
333 while comments and string.strip(comments[0]) == '#':
334 comments[:1] = []
335 while comments and string.strip(comments[-1]) == '#':
336 comments[-1:] = []
337 return string.join(comments, '')
338
339class ListReader:
340 """Provide a readline() method to return lines from a list of strings."""
341 def __init__(self, lines):
342 self.lines = lines
343 self.index = 0
344
345 def readline(self):
346 i = self.index
347 if i < len(self.lines):
348 self.index = i + 1
349 return self.lines[i]
350 else: return ''
351
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +0000352def getblock(lines):
353 """Extract the block of code at the top of the given list of lines."""
Tim Peters5ca576e2001-06-18 22:08:13 +0000354
355 indent = 0
356 started = 0
357 last = 0
358 tokens = tokenize.generate_tokens(ListReader(lines).readline)
359
360 for (type, token, (srow, scol), (erow, ecol), line) in tokens:
361 if not started:
362 if type == tokenize.NAME:
363 started = 1
364 elif type == tokenize.NEWLINE:
365 last = srow
366 elif type == tokenize.INDENT:
367 indent = indent + 1
368 elif type == tokenize.DEDENT:
369 indent = indent - 1
370 if indent == 0:
371 return lines[:last]
372 else:
373 raise ValueError, "unable to find block"
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +0000374
375def getsourcelines(object):
376 """Return a list of source lines and starting line number for an object.
377
378 The argument may be a module, class, method, function, traceback, frame,
379 or code object. The source code is returned as a list of the lines
380 corresponding to the object and the line number indicates where in the
381 original source file the first line of code was found. An IOError is
382 raised if the source code cannot be retrieved."""
383 lines, lnum = findsource(object)
384
385 if ismodule(object): return lines, 0
386 else: return getblock(lines[lnum:]), lnum + 1
387
388def getsource(object):
389 """Return the text of the source code for an object.
390
391 The argument may be a module, class, method, function, traceback, frame,
392 or code object. The source code is returned as a single string. An
393 IOError is raised if the source code cannot be retrieved."""
394 lines, lnum = getsourcelines(object)
395 return string.join(lines, '')
396
397# --------------------------------------------------- class tree extraction
398def walktree(classes, children, parent):
399 """Recursive helper function for getclasstree()."""
400 results = []
401 classes.sort(lambda a, b: cmp(a.__name__, b.__name__))
402 for c in classes:
403 results.append((c, c.__bases__))
404 if children.has_key(c):
405 results.append(walktree(children[c], children, c))
406 return results
407
408def getclasstree(classes, unique=0):
409 """Arrange the given list of classes into a hierarchy of nested lists.
410
411 Where a nested list appears, it contains classes derived from the class
412 whose entry immediately precedes the list. Each entry is a 2-tuple
413 containing a class and a tuple of its base classes. If the 'unique'
414 argument is true, exactly one entry appears in the returned structure
415 for each class in the given list. Otherwise, classes using multiple
416 inheritance and their descendants will appear multiple times."""
417 children = {}
418 roots = []
419 for c in classes:
420 if c.__bases__:
421 for parent in c.__bases__:
422 if not children.has_key(parent):
423 children[parent] = []
424 children[parent].append(c)
425 if unique and parent in classes: break
426 elif c not in roots:
427 roots.append(c)
428 for parent in children.keys():
429 if parent not in classes:
430 roots.append(parent)
431 return walktree(roots, children, None)
432
433# ------------------------------------------------ argument list extraction
434# These constants are from Python's compile.h.
435CO_OPTIMIZED, CO_NEWLOCALS, CO_VARARGS, CO_VARKEYWORDS = 1, 2, 4, 8
436
437def getargs(co):
438 """Get information about the arguments accepted by a code object.
439
440 Three things are returned: (args, varargs, varkw), where 'args' is
441 a list of argument names (possibly containing nested lists), and
442 'varargs' and 'varkw' are the names of the * and ** arguments or None."""
443 if not iscode(co): raise TypeError, 'arg is not a code object'
444
445 code = co.co_code
446 nargs = co.co_argcount
447 names = co.co_varnames
448 args = list(names[:nargs])
449 step = 0
450
451 # The following acrobatics are for anonymous (tuple) arguments.
452 for i in range(nargs):
453 if args[i][:1] in ['', '.']:
454 stack, remain, count = [], [], []
455 while step < len(code):
456 op = ord(code[step])
457 step = step + 1
458 if op >= dis.HAVE_ARGUMENT:
459 opname = dis.opname[op]
460 value = ord(code[step]) + ord(code[step+1])*256
461 step = step + 2
462 if opname in ['UNPACK_TUPLE', 'UNPACK_SEQUENCE']:
463 remain.append(value)
464 count.append(value)
465 elif opname == 'STORE_FAST':
466 stack.append(names[value])
467 remain[-1] = remain[-1] - 1
468 while remain[-1] == 0:
469 remain.pop()
470 size = count.pop()
471 stack[-size:] = [stack[-size:]]
472 if not remain: break
473 remain[-1] = remain[-1] - 1
474 if not remain: break
475 args[i] = stack[0]
476
477 varargs = None
478 if co.co_flags & CO_VARARGS:
479 varargs = co.co_varnames[nargs]
480 nargs = nargs + 1
481 varkw = None
482 if co.co_flags & CO_VARKEYWORDS:
483 varkw = co.co_varnames[nargs]
484 return args, varargs, varkw
485
486def getargspec(func):
487 """Get the names and default values of a function's arguments.
488
489 A tuple of four things is returned: (args, varargs, varkw, defaults).
490 'args' is a list of the argument names (it may contain nested lists).
491 'varargs' and 'varkw' are the names of the * and ** arguments or None.
492 'defaults' is an n-tuple of the default values of the last n arguments."""
493 if not isfunction(func): raise TypeError, 'arg is not a Python function'
494 args, varargs, varkw = getargs(func.func_code)
495 return args, varargs, varkw, func.func_defaults
496
497def getargvalues(frame):
498 """Get information about arguments passed into a particular frame.
499
500 A tuple of four things is returned: (args, varargs, varkw, locals).
501 'args' is a list of the argument names (it may contain nested lists).
502 'varargs' and 'varkw' are the names of the * and ** arguments or None.
503 'locals' is the locals dictionary of the given frame."""
504 args, varargs, varkw = getargs(frame.f_code)
505 return args, varargs, varkw, frame.f_locals
506
507def joinseq(seq):
508 if len(seq) == 1:
509 return '(' + seq[0] + ',)'
510 else:
511 return '(' + string.join(seq, ', ') + ')'
512
513def strseq(object, convert, join=joinseq):
514 """Recursively walk a sequence, stringifying each element."""
515 if type(object) in [types.ListType, types.TupleType]:
516 return join(map(lambda o, c=convert, j=join: strseq(o, c, j), object))
517 else:
518 return convert(object)
519
520def formatargspec(args, varargs=None, varkw=None, defaults=None,
521 formatarg=str,
522 formatvarargs=lambda name: '*' + name,
523 formatvarkw=lambda name: '**' + name,
524 formatvalue=lambda value: '=' + repr(value),
525 join=joinseq):
526 """Format an argument spec from the 4 values returned by getargspec.
527
528 The first four arguments are (args, varargs, varkw, defaults). The
529 other four arguments are the corresponding optional formatting functions
530 that are called to turn names and values into strings. The ninth
531 argument is an optional function to format the sequence of arguments."""
532 specs = []
533 if defaults:
534 firstdefault = len(args) - len(defaults)
535 for i in range(len(args)):
536 spec = strseq(args[i], formatarg, join)
537 if defaults and i >= firstdefault:
538 spec = spec + formatvalue(defaults[i - firstdefault])
539 specs.append(spec)
540 if varargs:
541 specs.append(formatvarargs(varargs))
542 if varkw:
543 specs.append(formatvarkw(varkw))
544 return '(' + string.join(specs, ', ') + ')'
545
546def formatargvalues(args, varargs, varkw, locals,
547 formatarg=str,
548 formatvarargs=lambda name: '*' + name,
549 formatvarkw=lambda name: '**' + name,
550 formatvalue=lambda value: '=' + repr(value),
551 join=joinseq):
552 """Format an argument spec from the 4 values returned by getargvalues.
553
554 The first four arguments are (args, varargs, varkw, locals). The
555 next four arguments are the corresponding optional formatting functions
556 that are called to turn names and values into strings. The ninth
557 argument is an optional function to format the sequence of arguments."""
558 def convert(name, locals=locals,
559 formatarg=formatarg, formatvalue=formatvalue):
560 return formatarg(name) + formatvalue(locals[name])
561 specs = []
562 for i in range(len(args)):
563 specs.append(strseq(args[i], convert, join))
564 if varargs:
565 specs.append(formatvarargs(varargs) + formatvalue(locals[varargs]))
566 if varkw:
567 specs.append(formatvarkw(varkw) + formatvalue(locals[varkw]))
568 return '(' + string.join(specs, ', ') + ')'
569
570# -------------------------------------------------- stack frame extraction
571def getframeinfo(frame, context=1):
572 """Get information about a frame or traceback object.
573
574 A tuple of five things is returned: the filename, the line number of
575 the current line, the function name, a list of lines of context from
576 the source code, and the index of the current line within that list.
577 The optional second argument specifies the number of lines of context
578 to return, which are centered around the current line."""
579 if istraceback(frame):
580 frame = frame.tb_frame
581 if not isframe(frame):
582 raise TypeError, 'arg is not a frame or traceback object'
583
584 filename = getsourcefile(frame)
Ka-Ping Yee59ade082001-03-01 03:55:35 +0000585 lineno = getlineno(frame)
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +0000586 if context > 0:
Ka-Ping Yee59ade082001-03-01 03:55:35 +0000587 start = lineno - 1 - context/2
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +0000588 try:
589 lines, lnum = findsource(frame)
Ka-Ping Yee4eb0c002001-03-02 05:50:34 +0000590 except IOError:
591 lines = index = None
592 else:
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +0000593 start = max(start, 1)
594 start = min(start, len(lines) - context)
595 lines = lines[start:start+context]
Ka-Ping Yee59ade082001-03-01 03:55:35 +0000596 index = lineno - 1 - start
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +0000597 else:
598 lines = index = None
599
Ka-Ping Yee59ade082001-03-01 03:55:35 +0000600 return (filename, lineno, frame.f_code.co_name, lines, index)
601
602def getlineno(frame):
603 """Get the line number from a frame object, allowing for optimization."""
604 # Written by Marc-André Lemburg; revised by Jim Hugunin and Fredrik Lundh.
605 lineno = frame.f_lineno
606 code = frame.f_code
607 if hasattr(code, 'co_lnotab'):
608 table = code.co_lnotab
609 lineno = code.co_firstlineno
610 addr = 0
611 for i in range(0, len(table), 2):
612 addr = addr + ord(table[i])
613 if addr > frame.f_lasti: break
614 lineno = lineno + ord(table[i+1])
615 return lineno
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +0000616
617def getouterframes(frame, context=1):
618 """Get a list of records for a frame and all higher (calling) frames.
619
620 Each record contains a frame object, filename, line number, function
621 name, a list of lines of context, and index within the context."""
622 framelist = []
623 while frame:
624 framelist.append((frame,) + getframeinfo(frame, context))
625 frame = frame.f_back
626 return framelist
627
628def getinnerframes(tb, context=1):
629 """Get a list of records for a traceback's frame and all lower frames.
630
631 Each record contains a frame object, filename, line number, function
632 name, a list of lines of context, and index within the context."""
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +0000633 framelist = []
634 while tb:
635 framelist.append((tb.tb_frame,) + getframeinfo(tb, context))
636 tb = tb.tb_next
637 return framelist
638
639def currentframe():
640 """Return the frame object for the caller's stack frame."""
641 try:
642 raise 'catch me'
643 except:
644 return sys.exc_traceback.tb_frame.f_back
645
646if hasattr(sys, '_getframe'): currentframe = sys._getframe
647
648def stack(context=1):
649 """Return a list of records for the stack above the caller's frame."""
650 return getouterframes(currentframe().f_back, context)
651
652def trace(context=1):
Tim Peters85ba6732001-02-28 08:26:44 +0000653 """Return a list of records for the stack below the current exception."""
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +0000654 return getinnerframes(sys.exc_traceback, context)