blob: c5c67097984d17de24373042f52210132e5d0b4e [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)"""
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.
203 # A complication: static classes in 2.2 copy dict entries from
204 # bases into derived classes, so it's not enough just to look for
205 # "the first" class with the name in its dict. OTOH:
206 # 1. Some-- but not all --methods in 2.2 come with an __objclass__
207 # attr that answers the question directly.
208 # 2. Some-- but not all --classes in 2.2 have a __defined__ dict
209 # saying which names were defined by the class.
210 homecls = getattr(obj, "__objclass__", None)
211 if homecls is None:
212 # Try __defined__.
213 for base in mro:
214 if hasattr(base, "__defined__"):
215 if name in base.__defined__:
216 homecls = base
217 break
218 if homecls is None:
219 # Last chance (and first chance for classic classes): search
220 # the dicts.
221 for base in mro:
222 if name in base.__dict__:
223 homecls = base
224 break
225
226 # Get the object again, in order to get it from the defining
227 # __dict__ instead of via getattr (if possible).
228 if homecls is not None and name in homecls.__dict__:
229 obj = homecls.__dict__[name]
230
231 # Also get the object via getattr.
232 obj_via_getattr = getattr(cls, name)
233
234 # Classify the object.
235 if isinstance(obj, staticmethod):
236 kind = "static method"
237 elif isinstance(obj, classmethod):
238 kind = "class method"
239 elif isinstance(obj, property):
240 kind = "property"
241 elif (ismethod(obj_via_getattr) or
242 ismethoddescriptor(obj_via_getattr)):
243 kind = "method"
244 else:
245 kind = "data"
246
247 result.append((name, kind, homecls, obj))
248
249 return result
250
Tim Peterse0b2d7a2001-09-22 06:10:55 +0000251# ----------------------------------------------------------- class helpers
252def _searchbases(cls, accum):
253 # Simulate the "classic class" search order.
254 if cls in accum:
255 return
256 accum.append(cls)
257 for base in cls.__bases__:
258 _searchbases(base, accum)
259
260def getmro(cls):
261 "Return tuple of base classes (including cls) in method resolution order."
262 if hasattr(cls, "__mro__"):
263 return cls.__mro__
264 else:
265 result = []
266 _searchbases(cls, result)
267 return tuple(result)
268
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +0000269# -------------------------------------------------- source code extraction
270def indentsize(line):
271 """Return the indent size, in spaces, at the start of a line of text."""
272 expline = string.expandtabs(line)
273 return len(expline) - len(string.lstrip(expline))
274
275def getdoc(object):
276 """Get the documentation string for an object.
277
278 All tabs are expanded to spaces. To clean up docstrings that are
279 indented to line up with blocks of code, any whitespace than can be
280 uniformly removed from the second line onwards is removed."""
281 if hasattr(object, '__doc__') and object.__doc__:
282 lines = string.split(string.expandtabs(object.__doc__), '\n')
283 margin = None
284 for line in lines[1:]:
285 content = len(string.lstrip(line))
286 if not content: continue
287 indent = len(line) - content
288 if margin is None: margin = indent
289 else: margin = min(margin, indent)
290 if margin is not None:
291 for i in range(1, len(lines)): lines[i] = lines[i][margin:]
292 return string.join(lines, '\n')
293
294def getfile(object):
Ka-Ping Yeec113c242001-03-02 02:08:53 +0000295 """Work out which source or compiled file an object was defined in."""
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +0000296 if ismodule(object):
297 if hasattr(object, '__file__'):
298 return object.__file__
299 raise TypeError, 'arg is a built-in module'
300 if isclass(object):
Ka-Ping Yeec99e0f12001-04-13 12:10:40 +0000301 object = sys.modules.get(object.__module__)
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +0000302 if hasattr(object, '__file__'):
303 return object.__file__
304 raise TypeError, 'arg is a built-in class'
305 if ismethod(object):
306 object = object.im_func
307 if isfunction(object):
308 object = object.func_code
309 if istraceback(object):
310 object = object.tb_frame
311 if isframe(object):
312 object = object.f_code
313 if iscode(object):
314 return object.co_filename
315 raise TypeError, 'arg is not a module, class, method, ' \
316 'function, traceback, frame, or code object'
317
Ka-Ping Yee4d6fc7f2001-04-10 11:43:00 +0000318def getmoduleinfo(path):
319 """Get the module name, suffix, mode, and module type for a given file."""
320 filename = os.path.basename(path)
321 suffixes = map(lambda (suffix, mode, mtype):
322 (-len(suffix), suffix, mode, mtype), imp.get_suffixes())
323 suffixes.sort() # try longest suffixes first, in case they overlap
324 for neglen, suffix, mode, mtype in suffixes:
325 if filename[neglen:] == suffix:
326 return filename[:neglen], suffix, mode, mtype
327
328def getmodulename(path):
329 """Return the module name for a given file, or None."""
330 info = getmoduleinfo(path)
331 if info: return info[0]
332
Ka-Ping Yeec113c242001-03-02 02:08:53 +0000333def getsourcefile(object):
334 """Return the Python source file an object was defined in, if it exists."""
335 filename = getfile(object)
336 if string.lower(filename[-4:]) in ['.pyc', '.pyo']:
337 filename = filename[:-4] + '.py'
Ka-Ping Yee4eb0c002001-03-02 05:50:34 +0000338 for suffix, mode, kind in imp.get_suffixes():
339 if 'b' in mode and string.lower(filename[-len(suffix):]) == suffix:
340 # Looks like a binary file. We want to only return a text file.
341 return None
342 if os.path.exists(filename):
Ka-Ping Yeec113c242001-03-02 02:08:53 +0000343 return filename
344
345def getabsfile(object):
Ka-Ping Yee4eb0c002001-03-02 05:50:34 +0000346 """Return an absolute path to the source or compiled file for an object.
Ka-Ping Yeec113c242001-03-02 02:08:53 +0000347
Ka-Ping Yee4eb0c002001-03-02 05:50:34 +0000348 The idea is for each object to have a unique origin, so this routine
349 normalizes the result as much as possible."""
350 return os.path.normcase(
351 os.path.abspath(getsourcefile(object) or getfile(object)))
Ka-Ping Yeec113c242001-03-02 02:08:53 +0000352
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +0000353modulesbyfile = {}
354
355def getmodule(object):
Ka-Ping Yee4eb0c002001-03-02 05:50:34 +0000356 """Return the module an object was defined in, or None if not found."""
Ka-Ping Yee202c99b2001-04-13 09:15:08 +0000357 if ismodule(object):
358 return object
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +0000359 if isclass(object):
Ka-Ping Yee8b58b842001-03-01 13:56:16 +0000360 return sys.modules.get(object.__module__)
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +0000361 try:
Ka-Ping Yeec113c242001-03-02 02:08:53 +0000362 file = getabsfile(object)
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +0000363 except TypeError:
364 return None
365 if modulesbyfile.has_key(file):
366 return sys.modules[modulesbyfile[file]]
367 for module in sys.modules.values():
368 if hasattr(module, '__file__'):
Ka-Ping Yeec113c242001-03-02 02:08:53 +0000369 modulesbyfile[getabsfile(module)] = module.__name__
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +0000370 if modulesbyfile.has_key(file):
371 return sys.modules[modulesbyfile[file]]
372 main = sys.modules['__main__']
Ka-Ping Yee4eb0c002001-03-02 05:50:34 +0000373 if hasattr(main, object.__name__):
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +0000374 mainobject = getattr(main, object.__name__)
Ka-Ping Yee4eb0c002001-03-02 05:50:34 +0000375 if mainobject is object:
376 return main
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +0000377 builtin = sys.modules['__builtin__']
Ka-Ping Yee4eb0c002001-03-02 05:50:34 +0000378 if hasattr(builtin, object.__name__):
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +0000379 builtinobject = getattr(builtin, object.__name__)
Ka-Ping Yee4eb0c002001-03-02 05:50:34 +0000380 if builtinobject is object:
381 return builtin
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +0000382
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +0000383def findsource(object):
384 """Return the entire source file and starting line number for an object.
385
386 The argument may be a module, class, method, function, traceback, frame,
387 or code object. The source code is returned as a list of all the lines
388 in the file and the line number indexes a line in that list. An IOError
389 is raised if the source code cannot be retrieved."""
390 try:
391 file = open(getsourcefile(object))
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +0000392 except (TypeError, IOError):
393 raise IOError, 'could not get source code'
Ka-Ping Yee4eb0c002001-03-02 05:50:34 +0000394 lines = file.readlines()
395 file.close()
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +0000396
397 if ismodule(object):
398 return lines, 0
399
400 if isclass(object):
401 name = object.__name__
Ka-Ping Yeea6e59712001-03-10 09:31:55 +0000402 pat = re.compile(r'^\s*class\s*' + name + r'\b')
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +0000403 for i in range(len(lines)):
Ka-Ping Yeea6e59712001-03-10 09:31:55 +0000404 if pat.match(lines[i]): return lines, i
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +0000405 else: raise IOError, 'could not find class definition'
406
407 if ismethod(object):
408 object = object.im_func
409 if isfunction(object):
410 object = object.func_code
411 if istraceback(object):
412 object = object.tb_frame
413 if isframe(object):
414 object = object.f_code
415 if iscode(object):
Ka-Ping Yee4eb0c002001-03-02 05:50:34 +0000416 if not hasattr(object, 'co_firstlineno'):
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +0000417 raise IOError, 'could not find function definition'
Ka-Ping Yee4eb0c002001-03-02 05:50:34 +0000418 lnum = object.co_firstlineno - 1
Ka-Ping Yeea6e59712001-03-10 09:31:55 +0000419 pat = re.compile(r'^\s*def\s')
Ka-Ping Yee4eb0c002001-03-02 05:50:34 +0000420 while lnum > 0:
Ka-Ping Yeea6e59712001-03-10 09:31:55 +0000421 if pat.match(lines[lnum]): break
Ka-Ping Yee4eb0c002001-03-02 05:50:34 +0000422 lnum = lnum - 1
423 return lines, lnum
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +0000424
425def getcomments(object):
426 """Get lines of comments immediately preceding an object's source code."""
427 try: lines, lnum = findsource(object)
Ka-Ping Yee4eb0c002001-03-02 05:50:34 +0000428 except IOError: return None
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +0000429
430 if ismodule(object):
431 # Look for a comment block at the top of the file.
432 start = 0
Ka-Ping Yeeb910efe2001-04-12 13:17:17 +0000433 if lines and lines[0][:2] == '#!': start = 1
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +0000434 while start < len(lines) and string.strip(lines[start]) in ['', '#']:
435 start = start + 1
Ka-Ping Yeeb910efe2001-04-12 13:17:17 +0000436 if start < len(lines) and lines[start][:1] == '#':
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +0000437 comments = []
438 end = start
439 while end < len(lines) and lines[end][:1] == '#':
440 comments.append(string.expandtabs(lines[end]))
441 end = end + 1
442 return string.join(comments, '')
443
444 # Look for a preceding block of comments at the same indentation.
445 elif lnum > 0:
446 indent = indentsize(lines[lnum])
447 end = lnum - 1
448 if end >= 0 and string.lstrip(lines[end])[:1] == '#' and \
449 indentsize(lines[end]) == indent:
450 comments = [string.lstrip(string.expandtabs(lines[end]))]
451 if end > 0:
452 end = end - 1
453 comment = string.lstrip(string.expandtabs(lines[end]))
454 while comment[:1] == '#' and indentsize(lines[end]) == indent:
455 comments[:0] = [comment]
456 end = end - 1
457 if end < 0: break
458 comment = string.lstrip(string.expandtabs(lines[end]))
459 while comments and string.strip(comments[0]) == '#':
460 comments[:1] = []
461 while comments and string.strip(comments[-1]) == '#':
462 comments[-1:] = []
463 return string.join(comments, '')
464
465class ListReader:
466 """Provide a readline() method to return lines from a list of strings."""
467 def __init__(self, lines):
468 self.lines = lines
469 self.index = 0
470
471 def readline(self):
472 i = self.index
473 if i < len(self.lines):
474 self.index = i + 1
475 return self.lines[i]
476 else: return ''
477
Tim Peters4efb6e92001-06-29 23:51:08 +0000478class EndOfBlock(Exception): pass
479
480class BlockFinder:
481 """Provide a tokeneater() method to detect the end of a code block."""
482 def __init__(self):
483 self.indent = 0
484 self.started = 0
485 self.last = 0
486
487 def tokeneater(self, type, token, (srow, scol), (erow, ecol), line):
488 if not self.started:
489 if type == tokenize.NAME: self.started = 1
490 elif type == tokenize.NEWLINE:
491 self.last = srow
492 elif type == tokenize.INDENT:
493 self.indent = self.indent + 1
494 elif type == tokenize.DEDENT:
495 self.indent = self.indent - 1
496 if self.indent == 0: raise EndOfBlock, self.last
497
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +0000498def getblock(lines):
499 """Extract the block of code at the top of the given list of lines."""
Tim Peters4efb6e92001-06-29 23:51:08 +0000500 try:
501 tokenize.tokenize(ListReader(lines).readline, BlockFinder().tokeneater)
502 except EndOfBlock, eob:
503 return lines[:eob.args[0]]
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +0000504
505def getsourcelines(object):
506 """Return a list of source lines and starting line number for an object.
507
508 The argument may be a module, class, method, function, traceback, frame,
509 or code object. The source code is returned as a list of the lines
510 corresponding to the object and the line number indicates where in the
511 original source file the first line of code was found. An IOError is
512 raised if the source code cannot be retrieved."""
513 lines, lnum = findsource(object)
514
515 if ismodule(object): return lines, 0
516 else: return getblock(lines[lnum:]), lnum + 1
517
518def getsource(object):
519 """Return the text of the source code for an object.
520
521 The argument may be a module, class, method, function, traceback, frame,
522 or code object. The source code is returned as a single string. An
523 IOError is raised if the source code cannot be retrieved."""
524 lines, lnum = getsourcelines(object)
525 return string.join(lines, '')
526
527# --------------------------------------------------- class tree extraction
528def walktree(classes, children, parent):
529 """Recursive helper function for getclasstree()."""
530 results = []
531 classes.sort(lambda a, b: cmp(a.__name__, b.__name__))
532 for c in classes:
533 results.append((c, c.__bases__))
534 if children.has_key(c):
535 results.append(walktree(children[c], children, c))
536 return results
537
538def getclasstree(classes, unique=0):
539 """Arrange the given list of classes into a hierarchy of nested lists.
540
541 Where a nested list appears, it contains classes derived from the class
542 whose entry immediately precedes the list. Each entry is a 2-tuple
543 containing a class and a tuple of its base classes. If the 'unique'
544 argument is true, exactly one entry appears in the returned structure
545 for each class in the given list. Otherwise, classes using multiple
546 inheritance and their descendants will appear multiple times."""
547 children = {}
548 roots = []
549 for c in classes:
550 if c.__bases__:
551 for parent in c.__bases__:
552 if not children.has_key(parent):
553 children[parent] = []
554 children[parent].append(c)
555 if unique and parent in classes: break
556 elif c not in roots:
557 roots.append(c)
558 for parent in children.keys():
559 if parent not in classes:
560 roots.append(parent)
561 return walktree(roots, children, None)
562
563# ------------------------------------------------ argument list extraction
564# These constants are from Python's compile.h.
565CO_OPTIMIZED, CO_NEWLOCALS, CO_VARARGS, CO_VARKEYWORDS = 1, 2, 4, 8
566
567def getargs(co):
568 """Get information about the arguments accepted by a code object.
569
570 Three things are returned: (args, varargs, varkw), where 'args' is
571 a list of argument names (possibly containing nested lists), and
572 'varargs' and 'varkw' are the names of the * and ** arguments or None."""
573 if not iscode(co): raise TypeError, 'arg is not a code object'
574
575 code = co.co_code
576 nargs = co.co_argcount
577 names = co.co_varnames
578 args = list(names[:nargs])
579 step = 0
580
581 # The following acrobatics are for anonymous (tuple) arguments.
582 for i in range(nargs):
583 if args[i][:1] in ['', '.']:
584 stack, remain, count = [], [], []
585 while step < len(code):
586 op = ord(code[step])
587 step = step + 1
588 if op >= dis.HAVE_ARGUMENT:
589 opname = dis.opname[op]
590 value = ord(code[step]) + ord(code[step+1])*256
591 step = step + 2
592 if opname in ['UNPACK_TUPLE', 'UNPACK_SEQUENCE']:
593 remain.append(value)
594 count.append(value)
595 elif opname == 'STORE_FAST':
596 stack.append(names[value])
597 remain[-1] = remain[-1] - 1
598 while remain[-1] == 0:
599 remain.pop()
600 size = count.pop()
601 stack[-size:] = [stack[-size:]]
602 if not remain: break
603 remain[-1] = remain[-1] - 1
604 if not remain: break
605 args[i] = stack[0]
606
607 varargs = None
608 if co.co_flags & CO_VARARGS:
609 varargs = co.co_varnames[nargs]
610 nargs = nargs + 1
611 varkw = None
612 if co.co_flags & CO_VARKEYWORDS:
613 varkw = co.co_varnames[nargs]
614 return args, varargs, varkw
615
616def getargspec(func):
617 """Get the names and default values of a function's arguments.
618
619 A tuple of four things is returned: (args, varargs, varkw, defaults).
620 'args' is a list of the argument names (it may contain nested lists).
621 'varargs' and 'varkw' are the names of the * and ** arguments or None.
622 'defaults' is an n-tuple of the default values of the last n arguments."""
623 if not isfunction(func): raise TypeError, 'arg is not a Python function'
624 args, varargs, varkw = getargs(func.func_code)
625 return args, varargs, varkw, func.func_defaults
626
627def getargvalues(frame):
628 """Get information about arguments passed into a particular frame.
629
630 A tuple of four things is returned: (args, varargs, varkw, locals).
631 'args' is a list of the argument names (it may contain nested lists).
632 'varargs' and 'varkw' are the names of the * and ** arguments or None.
633 'locals' is the locals dictionary of the given frame."""
634 args, varargs, varkw = getargs(frame.f_code)
635 return args, varargs, varkw, frame.f_locals
636
637def joinseq(seq):
638 if len(seq) == 1:
639 return '(' + seq[0] + ',)'
640 else:
641 return '(' + string.join(seq, ', ') + ')'
642
643def strseq(object, convert, join=joinseq):
644 """Recursively walk a sequence, stringifying each element."""
645 if type(object) in [types.ListType, types.TupleType]:
646 return join(map(lambda o, c=convert, j=join: strseq(o, c, j), object))
647 else:
648 return convert(object)
649
650def formatargspec(args, varargs=None, varkw=None, defaults=None,
651 formatarg=str,
652 formatvarargs=lambda name: '*' + name,
653 formatvarkw=lambda name: '**' + name,
654 formatvalue=lambda value: '=' + repr(value),
655 join=joinseq):
656 """Format an argument spec from the 4 values returned by getargspec.
657
658 The first four arguments are (args, varargs, varkw, defaults). The
659 other four arguments are the corresponding optional formatting functions
660 that are called to turn names and values into strings. The ninth
661 argument is an optional function to format the sequence of arguments."""
662 specs = []
663 if defaults:
664 firstdefault = len(args) - len(defaults)
665 for i in range(len(args)):
666 spec = strseq(args[i], formatarg, join)
667 if defaults and i >= firstdefault:
668 spec = spec + formatvalue(defaults[i - firstdefault])
669 specs.append(spec)
670 if varargs:
671 specs.append(formatvarargs(varargs))
672 if varkw:
673 specs.append(formatvarkw(varkw))
674 return '(' + string.join(specs, ', ') + ')'
675
676def formatargvalues(args, varargs, varkw, locals,
677 formatarg=str,
678 formatvarargs=lambda name: '*' + name,
679 formatvarkw=lambda name: '**' + name,
680 formatvalue=lambda value: '=' + repr(value),
681 join=joinseq):
682 """Format an argument spec from the 4 values returned by getargvalues.
683
684 The first four arguments are (args, varargs, varkw, locals). The
685 next four arguments are the corresponding optional formatting functions
686 that are called to turn names and values into strings. The ninth
687 argument is an optional function to format the sequence of arguments."""
688 def convert(name, locals=locals,
689 formatarg=formatarg, formatvalue=formatvalue):
690 return formatarg(name) + formatvalue(locals[name])
691 specs = []
692 for i in range(len(args)):
693 specs.append(strseq(args[i], convert, join))
694 if varargs:
695 specs.append(formatvarargs(varargs) + formatvalue(locals[varargs]))
696 if varkw:
697 specs.append(formatvarkw(varkw) + formatvalue(locals[varkw]))
698 return '(' + string.join(specs, ', ') + ')'
699
700# -------------------------------------------------- stack frame extraction
701def getframeinfo(frame, context=1):
702 """Get information about a frame or traceback object.
703
704 A tuple of five things is returned: the filename, the line number of
705 the current line, the function name, a list of lines of context from
706 the source code, and the index of the current line within that list.
707 The optional second argument specifies the number of lines of context
708 to return, which are centered around the current line."""
709 if istraceback(frame):
710 frame = frame.tb_frame
711 if not isframe(frame):
712 raise TypeError, 'arg is not a frame or traceback object'
713
714 filename = getsourcefile(frame)
Ka-Ping Yee59ade082001-03-01 03:55:35 +0000715 lineno = getlineno(frame)
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +0000716 if context > 0:
Guido van Rossum54e54c62001-09-04 19:14:14 +0000717 start = lineno - 1 - context//2
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +0000718 try:
719 lines, lnum = findsource(frame)
Ka-Ping Yee4eb0c002001-03-02 05:50:34 +0000720 except IOError:
721 lines = index = None
722 else:
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +0000723 start = max(start, 1)
724 start = min(start, len(lines) - context)
725 lines = lines[start:start+context]
Ka-Ping Yee59ade082001-03-01 03:55:35 +0000726 index = lineno - 1 - start
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +0000727 else:
728 lines = index = None
729
Ka-Ping Yee59ade082001-03-01 03:55:35 +0000730 return (filename, lineno, frame.f_code.co_name, lines, index)
731
732def getlineno(frame):
733 """Get the line number from a frame object, allowing for optimization."""
734 # Written by Marc-André Lemburg; revised by Jim Hugunin and Fredrik Lundh.
735 lineno = frame.f_lineno
736 code = frame.f_code
737 if hasattr(code, 'co_lnotab'):
738 table = code.co_lnotab
739 lineno = code.co_firstlineno
740 addr = 0
741 for i in range(0, len(table), 2):
742 addr = addr + ord(table[i])
743 if addr > frame.f_lasti: break
744 lineno = lineno + ord(table[i+1])
745 return lineno
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +0000746
747def getouterframes(frame, context=1):
748 """Get a list of records for a frame and all higher (calling) frames.
749
750 Each record contains a frame object, filename, line number, function
751 name, a list of lines of context, and index within the context."""
752 framelist = []
753 while frame:
754 framelist.append((frame,) + getframeinfo(frame, context))
755 frame = frame.f_back
756 return framelist
757
758def getinnerframes(tb, context=1):
759 """Get a list of records for a traceback's frame and all lower frames.
760
761 Each record contains a frame object, filename, line number, function
762 name, a list of lines of context, and index within the context."""
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +0000763 framelist = []
764 while tb:
765 framelist.append((tb.tb_frame,) + getframeinfo(tb, context))
766 tb = tb.tb_next
767 return framelist
768
769def currentframe():
770 """Return the frame object for the caller's stack frame."""
771 try:
772 raise 'catch me'
773 except:
774 return sys.exc_traceback.tb_frame.f_back
775
776if hasattr(sys, '_getframe'): currentframe = sys._getframe
777
778def stack(context=1):
779 """Return a list of records for the stack above the caller's frame."""
780 return getouterframes(currentframe().f_back, context)
781
782def trace(context=1):
Tim Peters85ba6732001-02-28 08:26:44 +0000783 """Return a list of records for the stack below the current exception."""
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +0000784 return getinnerframes(sys.exc_traceback, context)