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