blob: 175f5d6eb17f434d2a79034782a5acfe58a0deda [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
Neil Schemenauerf06f8532002-03-23 23:51:04 +000030import sys, os, types, string, re, dis, imp, tokenize, linecache
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)"""
Tim Peters28bc59f2001-09-16 08:40:16 +000039 return isinstance(object, types.ModuleType)
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +000040
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"""
Tim Peters28bc59f2001-09-16 08:40:16 +000047 return isinstance(object, 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"""
Tim Peters28bc59f2001-09-16 08:40:16 +000058 return isinstance(object, types.MethodType)
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +000059
Tim Peters536d2262001-09-20 05:13:38 +000060def ismethoddescriptor(object):
Tim Petersf1d90b92001-09-20 05:47:55 +000061 """Return true if the object is a method descriptor.
62
63 But not if ismethod() or isclass() or isfunction() are true.
Tim Peters536d2262001-09-20 05:13:38 +000064
65 This is new in Python 2.2, and, for example, is true of int.__add__.
66 An object passing this test has a __get__ attribute but not a __set__
67 attribute, but beyond that the set of attributes varies. __name__ is
68 usually sensible, and __doc__ often is.
69
Tim Petersf1d90b92001-09-20 05:47:55 +000070 Methods implemented via descriptors that also pass one of the other
71 tests return false from the ismethoddescriptor() test, simply because
72 the other tests promise more -- you can, e.g., count on having the
73 im_func attribute (etc) when an object passes ismethod()."""
Tim Peters536d2262001-09-20 05:13:38 +000074 return (hasattr(object, "__get__")
75 and not hasattr(object, "__set__") # else it's a data descriptor
76 and not ismethod(object) # mutual exclusion
Tim Petersf1d90b92001-09-20 05:47:55 +000077 and not isfunction(object)
Tim Peters536d2262001-09-20 05:13:38 +000078 and not isclass(object))
79
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +000080def isfunction(object):
81 """Return true if the object is a user-defined function.
82
83 Function objects provide these attributes:
84 __doc__ documentation string
85 __name__ name with which this function was defined
86 func_code code object containing compiled function bytecode
87 func_defaults tuple of any default values for arguments
88 func_doc (same as __doc__)
89 func_globals global namespace in which this function was defined
90 func_name (same as __name__)"""
Tim Peters28bc59f2001-09-16 08:40:16 +000091 return isinstance(object, types.FunctionType)
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +000092
93def istraceback(object):
94 """Return true if the object is a traceback.
95
96 Traceback objects provide these attributes:
97 tb_frame frame object at this level
98 tb_lasti index of last attempted instruction in bytecode
99 tb_lineno current line number in Python source code
100 tb_next next inner traceback object (called by this level)"""
Tim Peters28bc59f2001-09-16 08:40:16 +0000101 return isinstance(object, types.TracebackType)
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +0000102
103def isframe(object):
104 """Return true if the object is a frame object.
105
106 Frame objects provide these attributes:
107 f_back next outer frame object (this frame's caller)
108 f_builtins built-in namespace seen by this frame
109 f_code code object being executed in this frame
110 f_exc_traceback traceback if raised in this frame, or None
111 f_exc_type exception type if raised in this frame, or None
112 f_exc_value exception value if raised in this frame, or None
113 f_globals global namespace seen by this frame
114 f_lasti index of last attempted instruction in bytecode
115 f_lineno current line number in Python source code
116 f_locals local namespace seen by this frame
117 f_restricted 0 or 1 if frame is in restricted execution mode
118 f_trace tracing function for this frame, or None"""
Tim Peters28bc59f2001-09-16 08:40:16 +0000119 return isinstance(object, types.FrameType)
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +0000120
121def iscode(object):
122 """Return true if the object is a code object.
123
124 Code objects provide these attributes:
125 co_argcount number of arguments (not including * or ** args)
126 co_code string of raw compiled bytecode
127 co_consts tuple of constants used in the bytecode
128 co_filename name of file in which this code object was created
129 co_firstlineno number of first line in Python source code
130 co_flags bitmap: 1=optimized | 2=newlocals | 4=*arg | 8=**arg
131 co_lnotab encoded mapping of line numbers to bytecode indices
132 co_name name with which this code object was defined
133 co_names tuple of names of local variables
134 co_nlocals number of local variables
135 co_stacksize virtual machine stack space required
136 co_varnames tuple of names of arguments and local variables"""
Tim Peters28bc59f2001-09-16 08:40:16 +0000137 return isinstance(object, types.CodeType)
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +0000138
139def isbuiltin(object):
140 """Return true if the object is a built-in function or method.
141
142 Built-in functions and methods provide these attributes:
143 __doc__ documentation string
144 __name__ original name of this function or method
145 __self__ instance to which a method is bound, or None"""
Tim Peters28bc59f2001-09-16 08:40:16 +0000146 return isinstance(object, types.BuiltinFunctionType)
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +0000147
148def isroutine(object):
149 """Return true if the object is any kind of function or method."""
Tim Peters536d2262001-09-20 05:13:38 +0000150 return (isbuiltin(object)
151 or isfunction(object)
152 or ismethod(object)
153 or ismethoddescriptor(object))
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +0000154
155def getmembers(object, predicate=None):
156 """Return all members of an object as (name, value) pairs sorted by name.
157 Optionally, only return members that satisfy a given predicate."""
158 results = []
159 for key in dir(object):
160 value = getattr(object, key)
161 if not predicate or predicate(value):
162 results.append((key, value))
163 results.sort()
164 return results
165
Tim Peters13b49d32001-09-23 02:00:29 +0000166def classify_class_attrs(cls):
167 """Return list of attribute-descriptor tuples.
168
169 For each name in dir(cls), the return list contains a 4-tuple
170 with these elements:
171
172 0. The name (a string).
173
174 1. The kind of attribute this is, one of these strings:
175 'class method' created via classmethod()
176 'static method' created via staticmethod()
177 'property' created via property()
178 'method' any other flavor of method
179 'data' not a method
180
181 2. The class which defined this attribute (a class).
182
183 3. The object as obtained directly from the defining class's
184 __dict__, not via getattr. This is especially important for
185 data attributes: C.data is just a data object, but
186 C.__dict__['data'] may be a data descriptor with additional
187 info, like a __doc__ string.
188 """
189
190 mro = getmro(cls)
191 names = dir(cls)
192 result = []
193 for name in names:
194 # Get the object associated with the name.
195 # Getting an obj from the __dict__ sometimes reveals more than
196 # using getattr. Static and class methods are dramatic examples.
197 if name in cls.__dict__:
198 obj = cls.__dict__[name]
199 else:
200 obj = getattr(cls, name)
201
202 # Figure out where it was defined.
Tim Peters13b49d32001-09-23 02:00:29 +0000203 homecls = getattr(obj, "__objclass__", None)
204 if homecls is None:
Guido van Rossum687ae002001-10-15 22:03:32 +0000205 # search the dicts.
Tim Peters13b49d32001-09-23 02:00:29 +0000206 for base in mro:
207 if name in base.__dict__:
208 homecls = base
209 break
210
211 # Get the object again, in order to get it from the defining
212 # __dict__ instead of via getattr (if possible).
213 if homecls is not None and name in homecls.__dict__:
214 obj = homecls.__dict__[name]
215
216 # Also get the object via getattr.
217 obj_via_getattr = getattr(cls, name)
218
219 # Classify the object.
220 if isinstance(obj, staticmethod):
221 kind = "static method"
222 elif isinstance(obj, classmethod):
223 kind = "class method"
224 elif isinstance(obj, property):
225 kind = "property"
226 elif (ismethod(obj_via_getattr) or
227 ismethoddescriptor(obj_via_getattr)):
228 kind = "method"
229 else:
230 kind = "data"
231
232 result.append((name, kind, homecls, obj))
233
234 return result
235
Tim Peterse0b2d7a2001-09-22 06:10:55 +0000236# ----------------------------------------------------------- class helpers
237def _searchbases(cls, accum):
238 # Simulate the "classic class" search order.
239 if cls in accum:
240 return
241 accum.append(cls)
242 for base in cls.__bases__:
243 _searchbases(base, accum)
244
245def getmro(cls):
246 "Return tuple of base classes (including cls) in method resolution order."
247 if hasattr(cls, "__mro__"):
248 return cls.__mro__
249 else:
250 result = []
251 _searchbases(cls, result)
252 return tuple(result)
253
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +0000254# -------------------------------------------------- source code extraction
255def indentsize(line):
256 """Return the indent size, in spaces, at the start of a line of text."""
257 expline = string.expandtabs(line)
258 return len(expline) - len(string.lstrip(expline))
259
260def getdoc(object):
261 """Get the documentation string for an object.
262
263 All tabs are expanded to spaces. To clean up docstrings that are
264 indented to line up with blocks of code, any whitespace than can be
265 uniformly removed from the second line onwards is removed."""
Tim Peters24008312002-03-17 18:56:20 +0000266 try:
267 doc = object.__doc__
268 except AttributeError:
269 return None
270 if not isinstance(doc, (str, unicode)):
271 return None
272 try:
273 lines = string.split(string.expandtabs(doc), '\n')
274 except UnicodeError:
275 return None
276 else:
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +0000277 margin = None
278 for line in lines[1:]:
279 content = len(string.lstrip(line))
280 if not content: continue
281 indent = len(line) - content
282 if margin is None: margin = indent
283 else: margin = min(margin, indent)
284 if margin is not None:
285 for i in range(1, len(lines)): lines[i] = lines[i][margin:]
286 return string.join(lines, '\n')
287
288def getfile(object):
Ka-Ping Yeec113c242001-03-02 02:08:53 +0000289 """Work out which source or compiled file an object was defined in."""
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +0000290 if ismodule(object):
291 if hasattr(object, '__file__'):
292 return object.__file__
293 raise TypeError, 'arg is a built-in module'
294 if isclass(object):
Ka-Ping Yeec99e0f12001-04-13 12:10:40 +0000295 object = sys.modules.get(object.__module__)
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +0000296 if hasattr(object, '__file__'):
297 return object.__file__
298 raise TypeError, 'arg is a built-in class'
299 if ismethod(object):
300 object = object.im_func
301 if isfunction(object):
302 object = object.func_code
303 if istraceback(object):
304 object = object.tb_frame
305 if isframe(object):
306 object = object.f_code
307 if iscode(object):
308 return object.co_filename
309 raise TypeError, 'arg is not a module, class, method, ' \
310 'function, traceback, frame, or code object'
311
Ka-Ping Yee4d6fc7f2001-04-10 11:43:00 +0000312def getmoduleinfo(path):
313 """Get the module name, suffix, mode, and module type for a given file."""
314 filename = os.path.basename(path)
315 suffixes = map(lambda (suffix, mode, mtype):
316 (-len(suffix), suffix, mode, mtype), imp.get_suffixes())
317 suffixes.sort() # try longest suffixes first, in case they overlap
318 for neglen, suffix, mode, mtype in suffixes:
319 if filename[neglen:] == suffix:
320 return filename[:neglen], suffix, mode, mtype
321
322def getmodulename(path):
323 """Return the module name for a given file, or None."""
324 info = getmoduleinfo(path)
325 if info: return info[0]
326
Ka-Ping Yeec113c242001-03-02 02:08:53 +0000327def getsourcefile(object):
328 """Return the Python source file an object was defined in, if it exists."""
329 filename = getfile(object)
330 if string.lower(filename[-4:]) in ['.pyc', '.pyo']:
331 filename = filename[:-4] + '.py'
Ka-Ping Yee4eb0c002001-03-02 05:50:34 +0000332 for suffix, mode, kind in imp.get_suffixes():
333 if 'b' in mode and string.lower(filename[-len(suffix):]) == suffix:
334 # Looks like a binary file. We want to only return a text file.
335 return None
336 if os.path.exists(filename):
Ka-Ping Yeec113c242001-03-02 02:08:53 +0000337 return filename
338
339def getabsfile(object):
Ka-Ping Yee4eb0c002001-03-02 05:50:34 +0000340 """Return an absolute path to the source or compiled file for an object.
Ka-Ping Yeec113c242001-03-02 02:08:53 +0000341
Ka-Ping Yee4eb0c002001-03-02 05:50:34 +0000342 The idea is for each object to have a unique origin, so this routine
343 normalizes the result as much as possible."""
344 return os.path.normcase(
345 os.path.abspath(getsourcefile(object) or getfile(object)))
Ka-Ping Yeec113c242001-03-02 02:08:53 +0000346
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +0000347modulesbyfile = {}
348
349def getmodule(object):
Ka-Ping Yee4eb0c002001-03-02 05:50:34 +0000350 """Return the module an object was defined in, or None if not found."""
Ka-Ping Yee202c99b2001-04-13 09:15:08 +0000351 if ismodule(object):
352 return object
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +0000353 if isclass(object):
Ka-Ping Yee8b58b842001-03-01 13:56:16 +0000354 return sys.modules.get(object.__module__)
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +0000355 try:
Ka-Ping Yeec113c242001-03-02 02:08:53 +0000356 file = getabsfile(object)
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +0000357 except TypeError:
358 return None
359 if modulesbyfile.has_key(file):
360 return sys.modules[modulesbyfile[file]]
361 for module in sys.modules.values():
362 if hasattr(module, '__file__'):
Ka-Ping Yeec113c242001-03-02 02:08:53 +0000363 modulesbyfile[getabsfile(module)] = module.__name__
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +0000364 if modulesbyfile.has_key(file):
365 return sys.modules[modulesbyfile[file]]
366 main = sys.modules['__main__']
Ka-Ping Yee4eb0c002001-03-02 05:50:34 +0000367 if hasattr(main, object.__name__):
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +0000368 mainobject = getattr(main, object.__name__)
Ka-Ping Yee4eb0c002001-03-02 05:50:34 +0000369 if mainobject is object:
370 return main
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +0000371 builtin = sys.modules['__builtin__']
Ka-Ping Yee4eb0c002001-03-02 05:50:34 +0000372 if hasattr(builtin, object.__name__):
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +0000373 builtinobject = getattr(builtin, object.__name__)
Ka-Ping Yee4eb0c002001-03-02 05:50:34 +0000374 if builtinobject is object:
375 return builtin
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +0000376
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +0000377def findsource(object):
378 """Return the entire source file and starting line number for an object.
379
380 The argument may be a module, class, method, function, traceback, frame,
381 or code object. The source code is returned as a list of all the lines
382 in the file and the line number indexes a line in that list. An IOError
383 is raised if the source code cannot be retrieved."""
Neil Schemenauerf06f8532002-03-23 23:51:04 +0000384 file = getsourcefile(object) or getfile(object)
385 lines = linecache.getlines(file)
386 if not lines:
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +0000387 raise IOError, 'could not get source code'
388
389 if ismodule(object):
390 return lines, 0
391
392 if isclass(object):
393 name = object.__name__
Ka-Ping Yeea6e59712001-03-10 09:31:55 +0000394 pat = re.compile(r'^\s*class\s*' + name + r'\b')
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +0000395 for i in range(len(lines)):
Ka-Ping Yeea6e59712001-03-10 09:31:55 +0000396 if pat.match(lines[i]): return lines, i
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +0000397 else: raise IOError, 'could not find class definition'
398
399 if ismethod(object):
400 object = object.im_func
401 if isfunction(object):
402 object = object.func_code
403 if istraceback(object):
404 object = object.tb_frame
405 if isframe(object):
406 object = object.f_code
407 if iscode(object):
Ka-Ping Yee4eb0c002001-03-02 05:50:34 +0000408 if not hasattr(object, 'co_firstlineno'):
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +0000409 raise IOError, 'could not find function definition'
Ka-Ping Yee4eb0c002001-03-02 05:50:34 +0000410 lnum = object.co_firstlineno - 1
Ka-Ping Yeea6e59712001-03-10 09:31:55 +0000411 pat = re.compile(r'^\s*def\s')
Ka-Ping Yee4eb0c002001-03-02 05:50:34 +0000412 while lnum > 0:
Ka-Ping Yeea6e59712001-03-10 09:31:55 +0000413 if pat.match(lines[lnum]): break
Ka-Ping Yee4eb0c002001-03-02 05:50:34 +0000414 lnum = lnum - 1
415 return lines, lnum
Neal Norwitz8a11f5d2002-03-13 03:14:26 +0000416 raise IOError, 'could not find code object'
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +0000417
418def getcomments(object):
419 """Get lines of comments immediately preceding an object's source code."""
420 try: lines, lnum = findsource(object)
Ka-Ping Yee4eb0c002001-03-02 05:50:34 +0000421 except IOError: return None
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +0000422
423 if ismodule(object):
424 # Look for a comment block at the top of the file.
425 start = 0
Ka-Ping Yeeb910efe2001-04-12 13:17:17 +0000426 if lines and lines[0][:2] == '#!': start = 1
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +0000427 while start < len(lines) and string.strip(lines[start]) in ['', '#']:
428 start = start + 1
Ka-Ping Yeeb910efe2001-04-12 13:17:17 +0000429 if start < len(lines) and lines[start][:1] == '#':
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +0000430 comments = []
431 end = start
432 while end < len(lines) and lines[end][:1] == '#':
433 comments.append(string.expandtabs(lines[end]))
434 end = end + 1
435 return string.join(comments, '')
436
437 # Look for a preceding block of comments at the same indentation.
438 elif lnum > 0:
439 indent = indentsize(lines[lnum])
440 end = lnum - 1
441 if end >= 0 and string.lstrip(lines[end])[:1] == '#' and \
442 indentsize(lines[end]) == indent:
443 comments = [string.lstrip(string.expandtabs(lines[end]))]
444 if end > 0:
445 end = end - 1
446 comment = string.lstrip(string.expandtabs(lines[end]))
447 while comment[:1] == '#' and indentsize(lines[end]) == indent:
448 comments[:0] = [comment]
449 end = end - 1
450 if end < 0: break
451 comment = string.lstrip(string.expandtabs(lines[end]))
452 while comments and string.strip(comments[0]) == '#':
453 comments[:1] = []
454 while comments and string.strip(comments[-1]) == '#':
455 comments[-1:] = []
456 return string.join(comments, '')
457
458class ListReader:
459 """Provide a readline() method to return lines from a list of strings."""
460 def __init__(self, lines):
461 self.lines = lines
462 self.index = 0
463
464 def readline(self):
465 i = self.index
466 if i < len(self.lines):
467 self.index = i + 1
468 return self.lines[i]
469 else: return ''
470
Tim Peters4efb6e92001-06-29 23:51:08 +0000471class EndOfBlock(Exception): pass
472
473class BlockFinder:
474 """Provide a tokeneater() method to detect the end of a code block."""
475 def __init__(self):
476 self.indent = 0
477 self.started = 0
478 self.last = 0
479
480 def tokeneater(self, type, token, (srow, scol), (erow, ecol), line):
481 if not self.started:
482 if type == tokenize.NAME: self.started = 1
483 elif type == tokenize.NEWLINE:
484 self.last = srow
485 elif type == tokenize.INDENT:
486 self.indent = self.indent + 1
487 elif type == tokenize.DEDENT:
488 self.indent = self.indent - 1
489 if self.indent == 0: raise EndOfBlock, self.last
490
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +0000491def getblock(lines):
492 """Extract the block of code at the top of the given list of lines."""
Tim Peters4efb6e92001-06-29 23:51:08 +0000493 try:
494 tokenize.tokenize(ListReader(lines).readline, BlockFinder().tokeneater)
495 except EndOfBlock, eob:
496 return lines[:eob.args[0]]
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +0000497
498def getsourcelines(object):
499 """Return a list of source lines and starting line number for an object.
500
501 The argument may be a module, class, method, function, traceback, frame,
502 or code object. The source code is returned as a list of the lines
503 corresponding to the object and the line number indicates where in the
504 original source file the first line of code was found. An IOError is
505 raised if the source code cannot be retrieved."""
506 lines, lnum = findsource(object)
507
508 if ismodule(object): return lines, 0
509 else: return getblock(lines[lnum:]), lnum + 1
510
511def getsource(object):
512 """Return the text of the source code for an object.
513
514 The argument may be a module, class, method, function, traceback, frame,
515 or code object. The source code is returned as a single string. An
516 IOError is raised if the source code cannot be retrieved."""
517 lines, lnum = getsourcelines(object)
518 return string.join(lines, '')
519
520# --------------------------------------------------- class tree extraction
521def walktree(classes, children, parent):
522 """Recursive helper function for getclasstree()."""
523 results = []
524 classes.sort(lambda a, b: cmp(a.__name__, b.__name__))
525 for c in classes:
526 results.append((c, c.__bases__))
527 if children.has_key(c):
528 results.append(walktree(children[c], children, c))
529 return results
530
531def getclasstree(classes, unique=0):
532 """Arrange the given list of classes into a hierarchy of nested lists.
533
534 Where a nested list appears, it contains classes derived from the class
535 whose entry immediately precedes the list. Each entry is a 2-tuple
536 containing a class and a tuple of its base classes. If the 'unique'
537 argument is true, exactly one entry appears in the returned structure
538 for each class in the given list. Otherwise, classes using multiple
539 inheritance and their descendants will appear multiple times."""
540 children = {}
541 roots = []
542 for c in classes:
543 if c.__bases__:
544 for parent in c.__bases__:
545 if not children.has_key(parent):
546 children[parent] = []
547 children[parent].append(c)
548 if unique and parent in classes: break
549 elif c not in roots:
550 roots.append(c)
551 for parent in children.keys():
552 if parent not in classes:
553 roots.append(parent)
554 return walktree(roots, children, None)
555
556# ------------------------------------------------ argument list extraction
557# These constants are from Python's compile.h.
558CO_OPTIMIZED, CO_NEWLOCALS, CO_VARARGS, CO_VARKEYWORDS = 1, 2, 4, 8
559
560def getargs(co):
561 """Get information about the arguments accepted by a code object.
562
563 Three things are returned: (args, varargs, varkw), where 'args' is
564 a list of argument names (possibly containing nested lists), and
565 'varargs' and 'varkw' are the names of the * and ** arguments or None."""
566 if not iscode(co): raise TypeError, 'arg is not a code object'
567
568 code = co.co_code
569 nargs = co.co_argcount
570 names = co.co_varnames
571 args = list(names[:nargs])
572 step = 0
573
574 # The following acrobatics are for anonymous (tuple) arguments.
575 for i in range(nargs):
576 if args[i][:1] in ['', '.']:
577 stack, remain, count = [], [], []
578 while step < len(code):
579 op = ord(code[step])
580 step = step + 1
581 if op >= dis.HAVE_ARGUMENT:
582 opname = dis.opname[op]
583 value = ord(code[step]) + ord(code[step+1])*256
584 step = step + 2
585 if opname in ['UNPACK_TUPLE', 'UNPACK_SEQUENCE']:
586 remain.append(value)
587 count.append(value)
588 elif opname == 'STORE_FAST':
589 stack.append(names[value])
590 remain[-1] = remain[-1] - 1
591 while remain[-1] == 0:
592 remain.pop()
593 size = count.pop()
594 stack[-size:] = [stack[-size:]]
595 if not remain: break
596 remain[-1] = remain[-1] - 1
597 if not remain: break
598 args[i] = stack[0]
599
600 varargs = None
601 if co.co_flags & CO_VARARGS:
602 varargs = co.co_varnames[nargs]
603 nargs = nargs + 1
604 varkw = None
605 if co.co_flags & CO_VARKEYWORDS:
606 varkw = co.co_varnames[nargs]
607 return args, varargs, varkw
608
609def getargspec(func):
610 """Get the names and default values of a function's arguments.
611
612 A tuple of four things is returned: (args, varargs, varkw, defaults).
613 'args' is a list of the argument names (it may contain nested lists).
614 'varargs' and 'varkw' are the names of the * and ** arguments or None.
615 'defaults' is an n-tuple of the default values of the last n arguments."""
616 if not isfunction(func): raise TypeError, 'arg is not a Python function'
617 args, varargs, varkw = getargs(func.func_code)
618 return args, varargs, varkw, func.func_defaults
619
620def getargvalues(frame):
621 """Get information about arguments passed into a particular frame.
622
623 A tuple of four things is returned: (args, varargs, varkw, locals).
624 'args' is a list of the argument names (it may contain nested lists).
625 'varargs' and 'varkw' are the names of the * and ** arguments or None.
626 'locals' is the locals dictionary of the given frame."""
627 args, varargs, varkw = getargs(frame.f_code)
628 return args, varargs, varkw, frame.f_locals
629
630def joinseq(seq):
631 if len(seq) == 1:
632 return '(' + seq[0] + ',)'
633 else:
634 return '(' + string.join(seq, ', ') + ')'
635
636def strseq(object, convert, join=joinseq):
637 """Recursively walk a sequence, stringifying each element."""
638 if type(object) in [types.ListType, types.TupleType]:
639 return join(map(lambda o, c=convert, j=join: strseq(o, c, j), object))
640 else:
641 return convert(object)
642
643def formatargspec(args, varargs=None, varkw=None, defaults=None,
644 formatarg=str,
645 formatvarargs=lambda name: '*' + name,
646 formatvarkw=lambda name: '**' + name,
647 formatvalue=lambda value: '=' + repr(value),
648 join=joinseq):
649 """Format an argument spec from the 4 values returned by getargspec.
650
651 The first four arguments are (args, varargs, varkw, defaults). The
652 other four arguments are the corresponding optional formatting functions
653 that are called to turn names and values into strings. The ninth
654 argument is an optional function to format the sequence of arguments."""
655 specs = []
656 if defaults:
657 firstdefault = len(args) - len(defaults)
658 for i in range(len(args)):
659 spec = strseq(args[i], formatarg, join)
660 if defaults and i >= firstdefault:
661 spec = spec + formatvalue(defaults[i - firstdefault])
662 specs.append(spec)
663 if varargs:
664 specs.append(formatvarargs(varargs))
665 if varkw:
666 specs.append(formatvarkw(varkw))
667 return '(' + string.join(specs, ', ') + ')'
668
669def formatargvalues(args, varargs, varkw, locals,
670 formatarg=str,
671 formatvarargs=lambda name: '*' + name,
672 formatvarkw=lambda name: '**' + name,
673 formatvalue=lambda value: '=' + repr(value),
674 join=joinseq):
675 """Format an argument spec from the 4 values returned by getargvalues.
676
677 The first four arguments are (args, varargs, varkw, locals). The
678 next four arguments are the corresponding optional formatting functions
679 that are called to turn names and values into strings. The ninth
680 argument is an optional function to format the sequence of arguments."""
681 def convert(name, locals=locals,
682 formatarg=formatarg, formatvalue=formatvalue):
683 return formatarg(name) + formatvalue(locals[name])
684 specs = []
685 for i in range(len(args)):
686 specs.append(strseq(args[i], convert, join))
687 if varargs:
688 specs.append(formatvarargs(varargs) + formatvalue(locals[varargs]))
689 if varkw:
690 specs.append(formatvarkw(varkw) + formatvalue(locals[varkw]))
691 return '(' + string.join(specs, ', ') + ')'
692
693# -------------------------------------------------- stack frame extraction
694def getframeinfo(frame, context=1):
695 """Get information about a frame or traceback object.
696
697 A tuple of five things is returned: the filename, the line number of
698 the current line, the function name, a list of lines of context from
699 the source code, and the index of the current line within that list.
700 The optional second argument specifies the number of lines of context
701 to return, which are centered around the current line."""
702 if istraceback(frame):
703 frame = frame.tb_frame
704 if not isframe(frame):
705 raise TypeError, 'arg is not a frame or traceback object'
706
Neil Schemenauerf06f8532002-03-23 23:51:04 +0000707 filename = getsourcefile(frame) or getfile(frame)
Ka-Ping Yee59ade082001-03-01 03:55:35 +0000708 lineno = getlineno(frame)
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +0000709 if context > 0:
Guido van Rossum54e54c62001-09-04 19:14:14 +0000710 start = lineno - 1 - context//2
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +0000711 try:
712 lines, lnum = findsource(frame)
Ka-Ping Yee4eb0c002001-03-02 05:50:34 +0000713 except IOError:
714 lines = index = None
715 else:
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +0000716 start = max(start, 1)
717 start = min(start, len(lines) - context)
718 lines = lines[start:start+context]
Ka-Ping Yee59ade082001-03-01 03:55:35 +0000719 index = lineno - 1 - start
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +0000720 else:
721 lines = index = None
722
Ka-Ping Yee59ade082001-03-01 03:55:35 +0000723 return (filename, lineno, frame.f_code.co_name, lines, index)
724
725def getlineno(frame):
726 """Get the line number from a frame object, allowing for optimization."""
727 # Written by Marc-André Lemburg; revised by Jim Hugunin and Fredrik Lundh.
728 lineno = frame.f_lineno
729 code = frame.f_code
730 if hasattr(code, 'co_lnotab'):
731 table = code.co_lnotab
732 lineno = code.co_firstlineno
733 addr = 0
734 for i in range(0, len(table), 2):
735 addr = addr + ord(table[i])
736 if addr > frame.f_lasti: break
737 lineno = lineno + ord(table[i+1])
738 return lineno
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +0000739
740def getouterframes(frame, context=1):
741 """Get a list of records for a frame and all higher (calling) frames.
742
743 Each record contains a frame object, filename, line number, function
744 name, a list of lines of context, and index within the context."""
745 framelist = []
746 while frame:
747 framelist.append((frame,) + getframeinfo(frame, context))
748 frame = frame.f_back
749 return framelist
750
751def getinnerframes(tb, context=1):
752 """Get a list of records for a traceback's frame and all lower frames.
753
754 Each record contains a frame object, filename, line number, function
755 name, a list of lines of context, and index within the context."""
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +0000756 framelist = []
757 while tb:
758 framelist.append((tb.tb_frame,) + getframeinfo(tb, context))
759 tb = tb.tb_next
760 return framelist
761
762def currentframe():
763 """Return the frame object for the caller's stack frame."""
764 try:
Skip Montanaroa959a362002-03-25 21:37:54 +0000765 1/0
766 except ZeroDivisionError:
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +0000767 return sys.exc_traceback.tb_frame.f_back
768
769if hasattr(sys, '_getframe'): currentframe = sys._getframe
770
771def stack(context=1):
772 """Return a list of records for the stack above the caller's frame."""
773 return getouterframes(currentframe().f_back, context)
774
775def trace(context=1):
Tim Peters85ba6732001-02-28 08:26:44 +0000776 """Return a list of records for the stack below the current exception."""
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +0000777 return getinnerframes(sys.exc_traceback, context)