PyXR

c:\python24\lib \ inspect.py



0001 # -*- coding: iso-8859-1 -*-
0002 """Get useful information from live Python objects.
0003 
0004 This module encapsulates the interface provided by the internal special
0005 attributes (func_*, co_*, im_*, tb_*, etc.) in a friendlier fashion.
0006 It also provides some help for examining source code and class layout.
0007 
0008 Here are some of the useful functions provided by this module:
0009 
0010     ismodule(), isclass(), ismethod(), isfunction(), istraceback(),
0011         isframe(), iscode(), isbuiltin(), isroutine() - check object types
0012     getmembers() - get members of an object that satisfy a given condition
0013 
0014     getfile(), getsourcefile(), getsource() - find an object's source code
0015     getdoc(), getcomments() - get documentation on an object
0016     getmodule() - determine the module that an object came from
0017     getclasstree() - arrange classes so as to represent their hierarchy
0018 
0019     getargspec(), getargvalues() - get info about function arguments
0020     formatargspec(), formatargvalues() - format an argument spec
0021     getouterframes(), getinnerframes() - get info about frames
0022     currentframe() - get the current stack frame
0023     stack(), trace() - get info about frames on the stack or in a traceback
0024 """
0025 
0026 # This module is in the public domain.  No warranties.
0027 
0028 __author__ = 'Ka-Ping Yee <ping@lfw.org>'
0029 __date__ = '1 Jan 2001'
0030 
0031 import sys, os, types, string, re, dis, imp, tokenize, linecache
0032 
0033 # ----------------------------------------------------------- type-checking
0034 def ismodule(object):
0035     """Return true if the object is a module.
0036 
0037     Module objects provide these attributes:
0038         __doc__         documentation string
0039         __file__        filename (missing for built-in modules)"""
0040     return isinstance(object, types.ModuleType)
0041 
0042 def isclass(object):
0043     """Return true if the object is a class.
0044 
0045     Class objects provide these attributes:
0046         __doc__         documentation string
0047         __module__      name of module in which this class was defined"""
0048     return isinstance(object, types.ClassType) or hasattr(object, '__bases__')
0049 
0050 def ismethod(object):
0051     """Return true if the object is an instance method.
0052 
0053     Instance method objects provide these attributes:
0054         __doc__         documentation string
0055         __name__        name with which this method was defined
0056         im_class        class object in which this method belongs
0057         im_func         function object containing implementation of method
0058         im_self         instance to which this method is bound, or None"""
0059     return isinstance(object, types.MethodType)
0060 
0061 def ismethoddescriptor(object):
0062     """Return true if the object is a method descriptor.
0063 
0064     But not if ismethod() or isclass() or isfunction() are true.
0065 
0066     This is new in Python 2.2, and, for example, is true of int.__add__.
0067     An object passing this test has a __get__ attribute but not a __set__
0068     attribute, but beyond that the set of attributes varies.  __name__ is
0069     usually sensible, and __doc__ often is.
0070 
0071     Methods implemented via descriptors that also pass one of the other
0072     tests return false from the ismethoddescriptor() test, simply because
0073     the other tests promise more -- you can, e.g., count on having the
0074     im_func attribute (etc) when an object passes ismethod()."""
0075     return (hasattr(object, "__get__")
0076             and not hasattr(object, "__set__") # else it's a data descriptor
0077             and not ismethod(object)           # mutual exclusion
0078             and not isfunction(object)
0079             and not isclass(object))
0080 
0081 def isdatadescriptor(object):
0082     """Return true if the object is a data descriptor.
0083 
0084     Data descriptors have both a __get__ and a __set__ attribute.  Examples are
0085     properties (defined in Python) and getsets and members (defined in C).
0086     Typically, data descriptors will also have __name__ and __doc__ attributes
0087     (properties, getsets, and members have both of these attributes), but this
0088     is not guaranteed."""
0089     return (hasattr(object, "__set__") and hasattr(object, "__get__"))
0090 
0091 def isfunction(object):
0092     """Return true if the object is a user-defined function.
0093 
0094     Function objects provide these attributes:
0095         __doc__         documentation string
0096         __name__        name with which this function was defined
0097         func_code       code object containing compiled function bytecode
0098         func_defaults   tuple of any default values for arguments
0099         func_doc        (same as __doc__)
0100         func_globals    global namespace in which this function was defined
0101         func_name       (same as __name__)"""
0102     return isinstance(object, types.FunctionType)
0103 
0104 def istraceback(object):
0105     """Return true if the object is a traceback.
0106 
0107     Traceback objects provide these attributes:
0108         tb_frame        frame object at this level
0109         tb_lasti        index of last attempted instruction in bytecode
0110         tb_lineno       current line number in Python source code
0111         tb_next         next inner traceback object (called by this level)"""
0112     return isinstance(object, types.TracebackType)
0113 
0114 def isframe(object):
0115     """Return true if the object is a frame object.
0116 
0117     Frame objects provide these attributes:
0118         f_back          next outer frame object (this frame's caller)
0119         f_builtins      built-in namespace seen by this frame
0120         f_code          code object being executed in this frame
0121         f_exc_traceback traceback if raised in this frame, or None
0122         f_exc_type      exception type if raised in this frame, or None
0123         f_exc_value     exception value if raised in this frame, or None
0124         f_globals       global namespace seen by this frame
0125         f_lasti         index of last attempted instruction in bytecode
0126         f_lineno        current line number in Python source code
0127         f_locals        local namespace seen by this frame
0128         f_restricted    0 or 1 if frame is in restricted execution mode
0129         f_trace         tracing function for this frame, or None"""
0130     return isinstance(object, types.FrameType)
0131 
0132 def iscode(object):
0133     """Return true if the object is a code object.
0134 
0135     Code objects provide these attributes:
0136         co_argcount     number of arguments (not including * or ** args)
0137         co_code         string of raw compiled bytecode
0138         co_consts       tuple of constants used in the bytecode
0139         co_filename     name of file in which this code object was created
0140         co_firstlineno  number of first line in Python source code
0141         co_flags        bitmap: 1=optimized | 2=newlocals | 4=*arg | 8=**arg
0142         co_lnotab       encoded mapping of line numbers to bytecode indices
0143         co_name         name with which this code object was defined
0144         co_names        tuple of names of local variables
0145         co_nlocals      number of local variables
0146         co_stacksize    virtual machine stack space required
0147         co_varnames     tuple of names of arguments and local variables"""
0148     return isinstance(object, types.CodeType)
0149 
0150 def isbuiltin(object):
0151     """Return true if the object is a built-in function or method.
0152 
0153     Built-in functions and methods provide these attributes:
0154         __doc__         documentation string
0155         __name__        original name of this function or method
0156         __self__        instance to which a method is bound, or None"""
0157     return isinstance(object, types.BuiltinFunctionType)
0158 
0159 def isroutine(object):
0160     """Return true if the object is any kind of function or method."""
0161     return (isbuiltin(object)
0162             or isfunction(object)
0163             or ismethod(object)
0164             or ismethoddescriptor(object))
0165 
0166 def getmembers(object, predicate=None):
0167     """Return all members of an object as (name, value) pairs sorted by name.
0168     Optionally, only return members that satisfy a given predicate."""
0169     results = []
0170     for key in dir(object):
0171         value = getattr(object, key)
0172         if not predicate or predicate(value):
0173             results.append((key, value))
0174     results.sort()
0175     return results
0176 
0177 def classify_class_attrs(cls):
0178     """Return list of attribute-descriptor tuples.
0179 
0180     For each name in dir(cls), the return list contains a 4-tuple
0181     with these elements:
0182 
0183         0. The name (a string).
0184 
0185         1. The kind of attribute this is, one of these strings:
0186                'class method'    created via classmethod()
0187                'static method'   created via staticmethod()
0188                'property'        created via property()
0189                'method'          any other flavor of method
0190                'data'            not a method
0191 
0192         2. The class which defined this attribute (a class).
0193 
0194         3. The object as obtained directly from the defining class's
0195            __dict__, not via getattr.  This is especially important for
0196            data attributes:  C.data is just a data object, but
0197            C.__dict__['data'] may be a data descriptor with additional
0198            info, like a __doc__ string.
0199     """
0200 
0201     mro = getmro(cls)
0202     names = dir(cls)
0203     result = []
0204     for name in names:
0205         # Get the object associated with the name.
0206         # Getting an obj from the __dict__ sometimes reveals more than
0207         # using getattr.  Static and class methods are dramatic examples.
0208         if name in cls.__dict__:
0209             obj = cls.__dict__[name]
0210         else:
0211             obj = getattr(cls, name)
0212 
0213         # Figure out where it was defined.
0214         homecls = getattr(obj, "__objclass__", None)
0215         if homecls is None:
0216             # search the dicts.
0217             for base in mro:
0218                 if name in base.__dict__:
0219                     homecls = base
0220                     break
0221 
0222         # Get the object again, in order to get it from the defining
0223         # __dict__ instead of via getattr (if possible).
0224         if homecls is not None and name in homecls.__dict__:
0225             obj = homecls.__dict__[name]
0226 
0227         # Also get the object via getattr.
0228         obj_via_getattr = getattr(cls, name)
0229 
0230         # Classify the object.
0231         if isinstance(obj, staticmethod):
0232             kind = "static method"
0233         elif isinstance(obj, classmethod):
0234             kind = "class method"
0235         elif isinstance(obj, property):
0236             kind = "property"
0237         elif (ismethod(obj_via_getattr) or
0238               ismethoddescriptor(obj_via_getattr)):
0239             kind = "method"
0240         else:
0241             kind = "data"
0242 
0243         result.append((name, kind, homecls, obj))
0244 
0245     return result
0246 
0247 # ----------------------------------------------------------- class helpers
0248 def _searchbases(cls, accum):
0249     # Simulate the "classic class" search order.
0250     if cls in accum:
0251         return
0252     accum.append(cls)
0253     for base in cls.__bases__:
0254         _searchbases(base, accum)
0255 
0256 def getmro(cls):
0257     "Return tuple of base classes (including cls) in method resolution order."
0258     if hasattr(cls, "__mro__"):
0259         return cls.__mro__
0260     else:
0261         result = []
0262         _searchbases(cls, result)
0263         return tuple(result)
0264 
0265 # -------------------------------------------------- source code extraction
0266 def indentsize(line):
0267     """Return the indent size, in spaces, at the start of a line of text."""
0268     expline = string.expandtabs(line)
0269     return len(expline) - len(string.lstrip(expline))
0270 
0271 def getdoc(object):
0272     """Get the documentation string for an object.
0273 
0274     All tabs are expanded to spaces.  To clean up docstrings that are
0275     indented to line up with blocks of code, any whitespace than can be
0276     uniformly removed from the second line onwards is removed."""
0277     try:
0278         doc = object.__doc__
0279     except AttributeError:
0280         return None
0281     if not isinstance(doc, types.StringTypes):
0282         return None
0283     try:
0284         lines = string.split(string.expandtabs(doc), '\n')
0285     except UnicodeError:
0286         return None
0287     else:
0288         # Find minimum indentation of any non-blank lines after first line.
0289         margin = sys.maxint
0290         for line in lines[1:]:
0291             content = len(string.lstrip(line))
0292             if content:
0293                 indent = len(line) - content
0294                 margin = min(margin, indent)
0295         # Remove indentation.
0296         if lines:
0297             lines[0] = lines[0].lstrip()
0298         if margin < sys.maxint:
0299             for i in range(1, len(lines)): lines[i] = lines[i][margin:]
0300         # Remove any trailing or leading blank lines.
0301         while lines and not lines[-1]:
0302             lines.pop()
0303         while lines and not lines[0]:
0304             lines.pop(0)
0305         return string.join(lines, '\n')
0306 
0307 def getfile(object):
0308     """Work out which source or compiled file an object was defined in."""
0309     if ismodule(object):
0310         if hasattr(object, '__file__'):
0311             return object.__file__
0312         raise TypeError('arg is a built-in module')
0313     if isclass(object):
0314         object = sys.modules.get(object.__module__)
0315         if hasattr(object, '__file__'):
0316             return object.__file__
0317         raise TypeError('arg is a built-in class')
0318     if ismethod(object):
0319         object = object.im_func
0320     if isfunction(object):
0321         object = object.func_code
0322     if istraceback(object):
0323         object = object.tb_frame
0324     if isframe(object):
0325         object = object.f_code
0326     if iscode(object):
0327         return object.co_filename
0328     raise TypeError('arg is not a module, class, method, '
0329                     'function, traceback, frame, or code object')
0330 
0331 def getmoduleinfo(path):
0332     """Get the module name, suffix, mode, and module type for a given file."""
0333     filename = os.path.basename(path)
0334     suffixes = map(lambda (suffix, mode, mtype):
0335                    (-len(suffix), suffix, mode, mtype), imp.get_suffixes())
0336     suffixes.sort() # try longest suffixes first, in case they overlap
0337     for neglen, suffix, mode, mtype in suffixes:
0338         if filename[neglen:] == suffix:
0339             return filename[:neglen], suffix, mode, mtype
0340 
0341 def getmodulename(path):
0342     """Return the module name for a given file, or None."""
0343     info = getmoduleinfo(path)
0344     if info: return info[0]
0345 
0346 def getsourcefile(object):
0347     """Return the Python source file an object was defined in, if it exists."""
0348     filename = getfile(object)
0349     if string.lower(filename[-4:]) in ['.pyc', '.pyo']:
0350         filename = filename[:-4] + '.py'
0351     for suffix, mode, kind in imp.get_suffixes():
0352         if 'b' in mode and string.lower(filename[-len(suffix):]) == suffix:
0353             # Looks like a binary file.  We want to only return a text file.
0354             return None
0355     if os.path.exists(filename):
0356         return filename
0357 
0358 def getabsfile(object):
0359     """Return an absolute path to the source or compiled file for an object.
0360 
0361     The idea is for each object to have a unique origin, so this routine
0362     normalizes the result as much as possible."""
0363     return os.path.normcase(
0364         os.path.abspath(getsourcefile(object) or getfile(object)))
0365 
0366 modulesbyfile = {}
0367 
0368 def getmodule(object):
0369     """Return the module an object was defined in, or None if not found."""
0370     if ismodule(object):
0371         return object
0372     if hasattr(object, '__module__'):
0373         return sys.modules.get(object.__module__)
0374     try:
0375         file = getabsfile(object)
0376     except TypeError:
0377         return None
0378     if file in modulesbyfile:
0379         return sys.modules.get(modulesbyfile[file])
0380     for module in sys.modules.values():
0381         if hasattr(module, '__file__'):
0382             modulesbyfile[
0383                 os.path.realpath(
0384                         getabsfile(module))] = module.__name__
0385     if file in modulesbyfile:
0386         return sys.modules.get(modulesbyfile[file])
0387     main = sys.modules['__main__']
0388     if not hasattr(object, '__name__'):
0389         return None
0390     if hasattr(main, object.__name__):
0391         mainobject = getattr(main, object.__name__)
0392         if mainobject is object:
0393             return main
0394     builtin = sys.modules['__builtin__']
0395     if hasattr(builtin, object.__name__):
0396         builtinobject = getattr(builtin, object.__name__)
0397         if builtinobject is object:
0398             return builtin
0399 
0400 def findsource(object):
0401     """Return the entire source file and starting line number for an object.
0402 
0403     The argument may be a module, class, method, function, traceback, frame,
0404     or code object.  The source code is returned as a list of all the lines
0405     in the file and the line number indexes a line in that list.  An IOError
0406     is raised if the source code cannot be retrieved."""
0407     file = getsourcefile(object) or getfile(object)
0408     lines = linecache.getlines(file)
0409     if not lines:
0410         raise IOError('could not get source code')
0411 
0412     if ismodule(object):
0413         return lines, 0
0414 
0415     if isclass(object):
0416         name = object.__name__
0417         pat = re.compile(r'^\s*class\s*' + name + r'\b')
0418         for i in range(len(lines)):
0419             if pat.match(lines[i]): return lines, i
0420         else:
0421             raise IOError('could not find class definition')
0422 
0423     if ismethod(object):
0424         object = object.im_func
0425     if isfunction(object):
0426         object = object.func_code
0427     if istraceback(object):
0428         object = object.tb_frame
0429     if isframe(object):
0430         object = object.f_code
0431     if iscode(object):
0432         if not hasattr(object, 'co_firstlineno'):
0433             raise IOError('could not find function definition')
0434         lnum = object.co_firstlineno - 1
0435         pat = re.compile(r'^(\s*def\s)|(.*\slambda(:|\s))|^(\s*@)')
0436         while lnum > 0:
0437             if pat.match(lines[lnum]): break
0438             lnum = lnum - 1
0439         return lines, lnum
0440     raise IOError('could not find code object')
0441 
0442 def getcomments(object):
0443     """Get lines of comments immediately preceding an object's source code.
0444 
0445     Returns None when source can't be found.
0446     """
0447     try:
0448         lines, lnum = findsource(object)
0449     except (IOError, TypeError):
0450         return None
0451 
0452     if ismodule(object):
0453         # Look for a comment block at the top of the file.
0454         start = 0
0455         if lines and lines[0][:2] == '#!': start = 1
0456         while start < len(lines) and string.strip(lines[start]) in ['', '#']:
0457             start = start + 1
0458         if start < len(lines) and lines[start][:1] == '#':
0459             comments = []
0460             end = start
0461             while end < len(lines) and lines[end][:1] == '#':
0462                 comments.append(string.expandtabs(lines[end]))
0463                 end = end + 1
0464             return string.join(comments, '')
0465 
0466     # Look for a preceding block of comments at the same indentation.
0467     elif lnum > 0:
0468         indent = indentsize(lines[lnum])
0469         end = lnum - 1
0470         if end >= 0 and string.lstrip(lines[end])[:1] == '#' and \
0471             indentsize(lines[end]) == indent:
0472             comments = [string.lstrip(string.expandtabs(lines[end]))]
0473             if end > 0:
0474                 end = end - 1
0475                 comment = string.lstrip(string.expandtabs(lines[end]))
0476                 while comment[:1] == '#' and indentsize(lines[end]) == indent:
0477                     comments[:0] = [comment]
0478                     end = end - 1
0479                     if end < 0: break
0480                     comment = string.lstrip(string.expandtabs(lines[end]))
0481             while comments and string.strip(comments[0]) == '#':
0482                 comments[:1] = []
0483             while comments and string.strip(comments[-1]) == '#':
0484                 comments[-1:] = []
0485             return string.join(comments, '')
0486 
0487 class ListReader:
0488     """Provide a readline() method to return lines from a list of strings."""
0489     def __init__(self, lines):
0490         self.lines = lines
0491         self.index = 0
0492 
0493     def readline(self):
0494         i = self.index
0495         if i < len(self.lines):
0496             self.index = i + 1
0497             return self.lines[i]
0498         else: return ''
0499 
0500 class EndOfBlock(Exception): pass
0501 
0502 class BlockFinder:
0503     """Provide a tokeneater() method to detect the end of a code block."""
0504     def __init__(self):
0505         self.indent = 0
0506         self.started = 0
0507         self.last = 0
0508 
0509     def tokeneater(self, type, token, (srow, scol), (erow, ecol), line):
0510         if not self.started:
0511             if '@' in line: pass
0512             elif type == tokenize.NAME: self.started = 1
0513         elif type == tokenize.NEWLINE:
0514             self.last = srow
0515         elif type == tokenize.INDENT:
0516             self.indent = self.indent + 1
0517         elif type == tokenize.DEDENT:
0518             self.indent = self.indent - 1
0519             if self.indent == 0:
0520                 raise EndOfBlock, self.last
0521         elif type == tokenize.NAME and scol == 0:
0522             raise EndOfBlock, self.last
0523 
0524 def getblock(lines):
0525     """Extract the block of code at the top of the given list of lines."""
0526     try:
0527         tokenize.tokenize(ListReader(lines).readline, BlockFinder().tokeneater)
0528     except EndOfBlock, eob:
0529         return lines[:eob.args[0]]
0530     # Fooling the indent/dedent logic implies a one-line definition
0531     return lines[:1]
0532 
0533 def getsourcelines(object):
0534     """Return a list of source lines and starting line number for an object.
0535 
0536     The argument may be a module, class, method, function, traceback, frame,
0537     or code object.  The source code is returned as a list of the lines
0538     corresponding to the object and the line number indicates where in the
0539     original source file the first line of code was found.  An IOError is
0540     raised if the source code cannot be retrieved."""
0541     lines, lnum = findsource(object)
0542 
0543     if ismodule(object): return lines, 0
0544     else: return getblock(lines[lnum:]), lnum + 1
0545 
0546 def getsource(object):
0547     """Return the text of the source code for an object.
0548 
0549     The argument may be a module, class, method, function, traceback, frame,
0550     or code object.  The source code is returned as a single string.  An
0551     IOError is raised if the source code cannot be retrieved."""
0552     lines, lnum = getsourcelines(object)
0553     return string.join(lines, '')
0554 
0555 # --------------------------------------------------- class tree extraction
0556 def walktree(classes, children, parent):
0557     """Recursive helper function for getclasstree()."""
0558     results = []
0559     classes.sort(key=lambda c: (c.__module__, c.__name__))
0560     for c in classes:
0561         results.append((c, c.__bases__))
0562         if c in children:
0563             results.append(walktree(children[c], children, c))
0564     return results
0565 
0566 def getclasstree(classes, unique=0):
0567     """Arrange the given list of classes into a hierarchy of nested lists.
0568 
0569     Where a nested list appears, it contains classes derived from the class
0570     whose entry immediately precedes the list.  Each entry is a 2-tuple
0571     containing a class and a tuple of its base classes.  If the 'unique'
0572     argument is true, exactly one entry appears in the returned structure
0573     for each class in the given list.  Otherwise, classes using multiple
0574     inheritance and their descendants will appear multiple times."""
0575     children = {}
0576     roots = []
0577     for c in classes:
0578         if c.__bases__:
0579             for parent in c.__bases__:
0580                 if not parent in children:
0581                     children[parent] = []
0582                 children[parent].append(c)
0583                 if unique and parent in classes: break
0584         elif c not in roots:
0585             roots.append(c)
0586     for parent in children:
0587         if parent not in classes:
0588             roots.append(parent)
0589     return walktree(roots, children, None)
0590 
0591 # ------------------------------------------------ argument list extraction
0592 # These constants are from Python's compile.h.
0593 CO_OPTIMIZED, CO_NEWLOCALS, CO_VARARGS, CO_VARKEYWORDS = 1, 2, 4, 8
0594 
0595 def getargs(co):
0596     """Get information about the arguments accepted by a code object.
0597 
0598     Three things are returned: (args, varargs, varkw), where 'args' is
0599     a list of argument names (possibly containing nested lists), and
0600     'varargs' and 'varkw' are the names of the * and ** arguments or None."""
0601 
0602     if not iscode(co):
0603         raise TypeError('arg is not a code object')
0604 
0605     code = co.co_code
0606     nargs = co.co_argcount
0607     names = co.co_varnames
0608     args = list(names[:nargs])
0609     step = 0
0610 
0611     # The following acrobatics are for anonymous (tuple) arguments.
0612     for i in range(nargs):
0613         if args[i][:1] in ['', '.']:
0614             stack, remain, count = [], [], []
0615             while step < len(code):
0616                 op = ord(code[step])
0617                 step = step + 1
0618                 if op >= dis.HAVE_ARGUMENT:
0619                     opname = dis.opname[op]
0620                     value = ord(code[step]) + ord(code[step+1])*256
0621                     step = step + 2
0622                     if opname in ['UNPACK_TUPLE', 'UNPACK_SEQUENCE']:
0623                         remain.append(value)
0624                         count.append(value)
0625                     elif opname == 'STORE_FAST':
0626                         stack.append(names[value])
0627 
0628                         # Special case for sublists of length 1: def foo((bar))
0629                         # doesn't generate the UNPACK_TUPLE bytecode, so if
0630                         # `remain` is empty here, we have such a sublist.
0631                         if not remain:
0632                             stack[0] = [stack[0]]
0633                             break
0634                         else:
0635                             remain[-1] = remain[-1] - 1
0636                             while remain[-1] == 0:
0637                                 remain.pop()
0638                                 size = count.pop()
0639                                 stack[-size:] = [stack[-size:]]
0640                                 if not remain: break
0641                                 remain[-1] = remain[-1] - 1
0642                             if not remain: break
0643             args[i] = stack[0]
0644 
0645     varargs = None
0646     if co.co_flags & CO_VARARGS:
0647         varargs = co.co_varnames[nargs]
0648         nargs = nargs + 1
0649     varkw = None
0650     if co.co_flags & CO_VARKEYWORDS:
0651         varkw = co.co_varnames[nargs]
0652     return args, varargs, varkw
0653 
0654 def getargspec(func):
0655     """Get the names and default values of a function's arguments.
0656 
0657     A tuple of four things is returned: (args, varargs, varkw, defaults).
0658     'args' is a list of the argument names (it may contain nested lists).
0659     'varargs' and 'varkw' are the names of the * and ** arguments or None.
0660     'defaults' is an n-tuple of the default values of the last n arguments.
0661     """
0662 
0663     if ismethod(func):
0664         func = func.im_func
0665     if not isfunction(func):
0666         raise TypeError('arg is not a Python function')
0667     args, varargs, varkw = getargs(func.func_code)
0668     return args, varargs, varkw, func.func_defaults
0669 
0670 def getargvalues(frame):
0671     """Get information about arguments passed into a particular frame.
0672 
0673     A tuple of four things is returned: (args, varargs, varkw, locals).
0674     'args' is a list of the argument names (it may contain nested lists).
0675     'varargs' and 'varkw' are the names of the * and ** arguments or None.
0676     'locals' is the locals dictionary of the given frame."""
0677     args, varargs, varkw = getargs(frame.f_code)
0678     return args, varargs, varkw, frame.f_locals
0679 
0680 def joinseq(seq):
0681     if len(seq) == 1:
0682         return '(' + seq[0] + ',)'
0683     else:
0684         return '(' + string.join(seq, ', ') + ')'
0685 
0686 def strseq(object, convert, join=joinseq):
0687     """Recursively walk a sequence, stringifying each element."""
0688     if type(object) in [types.ListType, types.TupleType]:
0689         return join(map(lambda o, c=convert, j=join: strseq(o, c, j), object))
0690     else:
0691         return convert(object)
0692 
0693 def formatargspec(args, varargs=None, varkw=None, defaults=None,
0694                   formatarg=str,
0695                   formatvarargs=lambda name: '*' + name,
0696                   formatvarkw=lambda name: '**' + name,
0697                   formatvalue=lambda value: '=' + repr(value),
0698                   join=joinseq):
0699     """Format an argument spec from the 4 values returned by getargspec.
0700 
0701     The first four arguments are (args, varargs, varkw, defaults).  The
0702     other four arguments are the corresponding optional formatting functions
0703     that are called to turn names and values into strings.  The ninth
0704     argument is an optional function to format the sequence of arguments."""
0705     specs = []
0706     if defaults:
0707         firstdefault = len(args) - len(defaults)
0708     for i in range(len(args)):
0709         spec = strseq(args[i], formatarg, join)
0710         if defaults and i >= firstdefault:
0711             spec = spec + formatvalue(defaults[i - firstdefault])
0712         specs.append(spec)
0713     if varargs is not None:
0714         specs.append(formatvarargs(varargs))
0715     if varkw is not None:
0716         specs.append(formatvarkw(varkw))
0717     return '(' + string.join(specs, ', ') + ')'
0718 
0719 def formatargvalues(args, varargs, varkw, locals,
0720                     formatarg=str,
0721                     formatvarargs=lambda name: '*' + name,
0722                     formatvarkw=lambda name: '**' + name,
0723                     formatvalue=lambda value: '=' + repr(value),
0724                     join=joinseq):
0725     """Format an argument spec from the 4 values returned by getargvalues.
0726 
0727     The first four arguments are (args, varargs, varkw, locals).  The
0728     next four arguments are the corresponding optional formatting functions
0729     that are called to turn names and values into strings.  The ninth
0730     argument is an optional function to format the sequence of arguments."""
0731     def convert(name, locals=locals,
0732                 formatarg=formatarg, formatvalue=formatvalue):
0733         return formatarg(name) + formatvalue(locals[name])
0734     specs = []
0735     for i in range(len(args)):
0736         specs.append(strseq(args[i], convert, join))
0737     if varargs:
0738         specs.append(formatvarargs(varargs) + formatvalue(locals[varargs]))
0739     if varkw:
0740         specs.append(formatvarkw(varkw) + formatvalue(locals[varkw]))
0741     return '(' + string.join(specs, ', ') + ')'
0742 
0743 # -------------------------------------------------- stack frame extraction
0744 def getframeinfo(frame, context=1):
0745     """Get information about a frame or traceback object.
0746 
0747     A tuple of five things is returned: the filename, the line number of
0748     the current line, the function name, a list of lines of context from
0749     the source code, and the index of the current line within that list.
0750     The optional second argument specifies the number of lines of context
0751     to return, which are centered around the current line."""
0752     if istraceback(frame):
0753         lineno = frame.tb_lineno
0754         frame = frame.tb_frame
0755     else:
0756         lineno = frame.f_lineno
0757     if not isframe(frame):
0758         raise TypeError('arg is not a frame or traceback object')
0759 
0760     filename = getsourcefile(frame) or getfile(frame)
0761     if context > 0:
0762         start = lineno - 1 - context//2
0763         try:
0764             lines, lnum = findsource(frame)
0765         except IOError:
0766             lines = index = None
0767         else:
0768             start = max(start, 1)
0769             start = max(0, min(start, len(lines) - context))
0770             lines = lines[start:start+context]
0771             index = lineno - 1 - start
0772     else:
0773         lines = index = None
0774 
0775     return (filename, lineno, frame.f_code.co_name, lines, index)
0776 
0777 def getlineno(frame):
0778     """Get the line number from a frame object, allowing for optimization."""
0779     # FrameType.f_lineno is now a descriptor that grovels co_lnotab
0780     return frame.f_lineno
0781 
0782 def getouterframes(frame, context=1):
0783     """Get a list of records for a frame and all higher (calling) frames.
0784 
0785     Each record contains a frame object, filename, line number, function
0786     name, a list of lines of context, and index within the context."""
0787     framelist = []
0788     while frame:
0789         framelist.append((frame,) + getframeinfo(frame, context))
0790         frame = frame.f_back
0791     return framelist
0792 
0793 def getinnerframes(tb, context=1):
0794     """Get a list of records for a traceback's frame and all lower frames.
0795 
0796     Each record contains a frame object, filename, line number, function
0797     name, a list of lines of context, and index within the context."""
0798     framelist = []
0799     while tb:
0800         framelist.append((tb.tb_frame,) + getframeinfo(tb, context))
0801         tb = tb.tb_next
0802     return framelist
0803 
0804 currentframe = sys._getframe
0805 
0806 def stack(context=1):
0807     """Return a list of records for the stack above the caller's frame."""
0808     return getouterframes(sys._getframe(1), context)
0809 
0810 def trace(context=1):
0811     """Return a list of records for the stack below the current exception."""
0812     return getinnerframes(sys.exc_info()[2], context)
0813 

Generated by PyXR 0.9.4
SourceForge.net Logo