• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1# -*- coding: iso-8859-1 -*-
2"""Get useful information from live Python objects.
3
4This module encapsulates the interface provided by the internal special
5attributes (func_*, co_*, im_*, tb_*, etc.) in a friendlier fashion.
6It also provides some help for examining source code and class layout.
7
8Here are some of the useful functions provided by this module:
9
10    ismodule(), isclass(), ismethod(), isfunction(), isgeneratorfunction(),
11        isgenerator(), istraceback(), isframe(), iscode(), isbuiltin(),
12        isroutine() - check object types
13    getmembers() - get members of an object that satisfy a given condition
14
15    getfile(), getsourcefile(), getsource() - find an object's source code
16    getdoc(), getcomments() - get documentation on an object
17    getmodule() - determine the module that an object came from
18    getclasstree() - arrange classes so as to represent their hierarchy
19
20    getargspec(), getargvalues(), getcallargs() - get info about function arguments
21    formatargspec(), formatargvalues() - format an argument spec
22    getouterframes(), getinnerframes() - get info about frames
23    currentframe() - get the current stack frame
24    stack(), trace() - get info about frames on the stack or in a traceback
25"""
26
27# This module is in the public domain.  No warranties.
28
29__author__ = 'Ka-Ping Yee <ping@lfw.org>'
30__date__ = '1 Jan 2001'
31
32import sys
33import os
34import types
35import string
36import re
37import dis
38import imp
39import tokenize
40import linecache
41from operator import attrgetter
42from collections import namedtuple
43
44# These constants are from Include/code.h.
45CO_OPTIMIZED, CO_NEWLOCALS, CO_VARARGS, CO_VARKEYWORDS = 0x1, 0x2, 0x4, 0x8
46CO_NESTED, CO_GENERATOR, CO_NOFREE = 0x10, 0x20, 0x40
47# See Include/object.h
48TPFLAGS_IS_ABSTRACT = 1 << 20
49
50# ----------------------------------------------------------- type-checking
51def ismodule(object):
52    """Return true if the object is a module.
53
54    Module objects provide these attributes:
55        __doc__         documentation string
56        __file__        filename (missing for built-in modules)"""
57    return isinstance(object, types.ModuleType)
58
59def isclass(object):
60    """Return true if the object is a class.
61
62    Class objects provide these attributes:
63        __doc__         documentation string
64        __module__      name of module in which this class was defined"""
65    return isinstance(object, (type, types.ClassType))
66
67def ismethod(object):
68    """Return true if the object is an instance method.
69
70    Instance method objects provide these attributes:
71        __doc__         documentation string
72        __name__        name with which this method was defined
73        im_class        class object in which this method belongs
74        im_func         function object containing implementation of method
75        im_self         instance to which this method is bound, or None"""
76    return isinstance(object, types.MethodType)
77
78def ismethoddescriptor(object):
79    """Return true if the object is a method descriptor.
80
81    But not if ismethod() or isclass() or isfunction() are true.
82
83    This is new in Python 2.2, and, for example, is true of int.__add__.
84    An object passing this test has a __get__ attribute but not a __set__
85    attribute, but beyond that the set of attributes varies.  __name__ is
86    usually sensible, and __doc__ often is.
87
88    Methods implemented via descriptors that also pass one of the other
89    tests return false from the ismethoddescriptor() test, simply because
90    the other tests promise more -- you can, e.g., count on having the
91    im_func attribute (etc) when an object passes ismethod()."""
92    return (hasattr(object, "__get__")
93            and not hasattr(object, "__set__") # else it's a data descriptor
94            and not ismethod(object)           # mutual exclusion
95            and not isfunction(object)
96            and not isclass(object))
97
98def isdatadescriptor(object):
99    """Return true if the object is a data descriptor.
100
101    Data descriptors have both a __get__ and a __set__ attribute.  Examples are
102    properties (defined in Python) and getsets and members (defined in C).
103    Typically, data descriptors will also have __name__ and __doc__ attributes
104    (properties, getsets, and members have both of these attributes), but this
105    is not guaranteed."""
106    return (hasattr(object, "__set__") and hasattr(object, "__get__"))
107
108if hasattr(types, 'MemberDescriptorType'):
109    # CPython and equivalent
110    def ismemberdescriptor(object):
111        """Return true if the object is a member descriptor.
112
113        Member descriptors are specialized descriptors defined in extension
114        modules."""
115        return isinstance(object, types.MemberDescriptorType)
116else:
117    # Other implementations
118    def ismemberdescriptor(object):
119        """Return true if the object is a member descriptor.
120
121        Member descriptors are specialized descriptors defined in extension
122        modules."""
123        return False
124
125if hasattr(types, 'GetSetDescriptorType'):
126    # CPython and equivalent
127    def isgetsetdescriptor(object):
128        """Return true if the object is a getset descriptor.
129
130        getset descriptors are specialized descriptors defined in extension
131        modules."""
132        return isinstance(object, types.GetSetDescriptorType)
133else:
134    # Other implementations
135    def isgetsetdescriptor(object):
136        """Return true if the object is a getset descriptor.
137
138        getset descriptors are specialized descriptors defined in extension
139        modules."""
140        return False
141
142def isfunction(object):
143    """Return true if the object is a user-defined function.
144
145    Function objects provide these attributes:
146        __doc__         documentation string
147        __name__        name with which this function was defined
148        func_code       code object containing compiled function bytecode
149        func_defaults   tuple of any default values for arguments
150        func_doc        (same as __doc__)
151        func_globals    global namespace in which this function was defined
152        func_name       (same as __name__)"""
153    return isinstance(object, types.FunctionType)
154
155def isgeneratorfunction(object):
156    """Return true if the object is a user-defined generator function.
157
158    Generator function objects provide the same attributes as functions.
159    See help(isfunction) for a list of attributes."""
160    return bool((isfunction(object) or ismethod(object)) and
161                object.func_code.co_flags & CO_GENERATOR)
162
163def isgenerator(object):
164    """Return true if the object is a generator.
165
166    Generator objects provide these attributes:
167        __iter__        defined to support iteration over container
168        close           raises a new GeneratorExit exception inside the
169                        generator to terminate the iteration
170        gi_code         code object
171        gi_frame        frame object or possibly None once the generator has
172                        been exhausted
173        gi_running      set to 1 when generator is executing, 0 otherwise
174        next            return the next item from the container
175        send            resumes the generator and "sends" a value that becomes
176                        the result of the current yield-expression
177        throw           used to raise an exception inside the generator"""
178    return isinstance(object, types.GeneratorType)
179
180def istraceback(object):
181    """Return true if the object is a traceback.
182
183    Traceback objects provide these attributes:
184        tb_frame        frame object at this level
185        tb_lasti        index of last attempted instruction in bytecode
186        tb_lineno       current line number in Python source code
187        tb_next         next inner traceback object (called by this level)"""
188    return isinstance(object, types.TracebackType)
189
190def isframe(object):
191    """Return true if the object is a frame object.
192
193    Frame objects provide these attributes:
194        f_back          next outer frame object (this frame's caller)
195        f_builtins      built-in namespace seen by this frame
196        f_code          code object being executed in this frame
197        f_exc_traceback traceback if raised in this frame, or None
198        f_exc_type      exception type if raised in this frame, or None
199        f_exc_value     exception value if raised in this frame, or None
200        f_globals       global namespace seen by this frame
201        f_lasti         index of last attempted instruction in bytecode
202        f_lineno        current line number in Python source code
203        f_locals        local namespace seen by this frame
204        f_restricted    0 or 1 if frame is in restricted execution mode
205        f_trace         tracing function for this frame, or None"""
206    return isinstance(object, types.FrameType)
207
208def iscode(object):
209    """Return true if the object is a code object.
210
211    Code objects provide these attributes:
212        co_argcount     number of arguments (not including * or ** args)
213        co_code         string of raw compiled bytecode
214        co_consts       tuple of constants used in the bytecode
215        co_filename     name of file in which this code object was created
216        co_firstlineno  number of first line in Python source code
217        co_flags        bitmap: 1=optimized | 2=newlocals | 4=*arg | 8=**arg
218        co_lnotab       encoded mapping of line numbers to bytecode indices
219        co_name         name with which this code object was defined
220        co_names        tuple of names of local variables
221        co_nlocals      number of local variables
222        co_stacksize    virtual machine stack space required
223        co_varnames     tuple of names of arguments and local variables"""
224    return isinstance(object, types.CodeType)
225
226def isbuiltin(object):
227    """Return true if the object is a built-in function or method.
228
229    Built-in functions and methods provide these attributes:
230        __doc__         documentation string
231        __name__        original name of this function or method
232        __self__        instance to which a method is bound, or None"""
233    return isinstance(object, types.BuiltinFunctionType)
234
235def isroutine(object):
236    """Return true if the object is any kind of function or method."""
237    return (isbuiltin(object)
238            or isfunction(object)
239            or ismethod(object)
240            or ismethoddescriptor(object))
241
242def isabstract(object):
243    """Return true if the object is an abstract base class (ABC)."""
244    return bool(isinstance(object, type) and object.__flags__ & TPFLAGS_IS_ABSTRACT)
245
246def getmembers(object, predicate=None):
247    """Return all members of an object as (name, value) pairs sorted by name.
248    Optionally, only return members that satisfy a given predicate."""
249    results = []
250    for key in dir(object):
251        try:
252            value = getattr(object, key)
253        except AttributeError:
254            continue
255        if not predicate or predicate(value):
256            results.append((key, value))
257    results.sort()
258    return results
259
260Attribute = namedtuple('Attribute', 'name kind defining_class object')
261
262def classify_class_attrs(cls):
263    """Return list of attribute-descriptor tuples.
264
265    For each name in dir(cls), the return list contains a 4-tuple
266    with these elements:
267
268        0. The name (a string).
269
270        1. The kind of attribute this is, one of these strings:
271               'class method'    created via classmethod()
272               'static method'   created via staticmethod()
273               'property'        created via property()
274               'method'          any other flavor of method
275               'data'            not a method
276
277        2. The class which defined this attribute (a class).
278
279        3. The object as obtained directly from the defining class's
280           __dict__, not via getattr.  This is especially important for
281           data attributes:  C.data is just a data object, but
282           C.__dict__['data'] may be a data descriptor with additional
283           info, like a __doc__ string.
284    """
285
286    mro = getmro(cls)
287    names = dir(cls)
288    result = []
289    for name in names:
290        # Get the object associated with the name, and where it was defined.
291        # Getting an obj from the __dict__ sometimes reveals more than
292        # using getattr.  Static and class methods are dramatic examples.
293        # Furthermore, some objects may raise an Exception when fetched with
294        # getattr(). This is the case with some descriptors (bug #1785).
295        # Thus, we only use getattr() as a last resort.
296        homecls = None
297        for base in (cls,) + mro:
298            if name in base.__dict__:
299                obj = base.__dict__[name]
300                homecls = base
301                break
302        else:
303            obj = getattr(cls, name)
304            homecls = getattr(obj, "__objclass__", homecls)
305
306        # Classify the object.
307        if isinstance(obj, staticmethod):
308            kind = "static method"
309        elif isinstance(obj, classmethod):
310            kind = "class method"
311        elif isinstance(obj, property):
312            kind = "property"
313        elif ismethoddescriptor(obj):
314            kind = "method"
315        elif isdatadescriptor(obj):
316            kind = "data"
317        else:
318            obj_via_getattr = getattr(cls, name)
319            if (ismethod(obj_via_getattr) or
320                ismethoddescriptor(obj_via_getattr)):
321                kind = "method"
322            else:
323                kind = "data"
324            obj = obj_via_getattr
325
326        result.append(Attribute(name, kind, homecls, obj))
327
328    return result
329
330# ----------------------------------------------------------- class helpers
331def _searchbases(cls, accum):
332    # Simulate the "classic class" search order.
333    if cls in accum:
334        return
335    accum.append(cls)
336    for base in cls.__bases__:
337        _searchbases(base, accum)
338
339def getmro(cls):
340    "Return tuple of base classes (including cls) in method resolution order."
341    if hasattr(cls, "__mro__"):
342        return cls.__mro__
343    else:
344        result = []
345        _searchbases(cls, result)
346        return tuple(result)
347
348# -------------------------------------------------- source code extraction
349def indentsize(line):
350    """Return the indent size, in spaces, at the start of a line of text."""
351    expline = string.expandtabs(line)
352    return len(expline) - len(string.lstrip(expline))
353
354def getdoc(object):
355    """Get the documentation string for an object.
356
357    All tabs are expanded to spaces.  To clean up docstrings that are
358    indented to line up with blocks of code, any whitespace than can be
359    uniformly removed from the second line onwards is removed."""
360    try:
361        doc = object.__doc__
362    except AttributeError:
363        return None
364    if not isinstance(doc, types.StringTypes):
365        return None
366    return cleandoc(doc)
367
368def cleandoc(doc):
369    """Clean up indentation from docstrings.
370
371    Any whitespace that can be uniformly removed from the second line
372    onwards is removed."""
373    try:
374        lines = string.split(string.expandtabs(doc), '\n')
375    except UnicodeError:
376        return None
377    else:
378        # Find minimum indentation of any non-blank lines after first line.
379        margin = sys.maxint
380        for line in lines[1:]:
381            content = len(string.lstrip(line))
382            if content:
383                indent = len(line) - content
384                margin = min(margin, indent)
385        # Remove indentation.
386        if lines:
387            lines[0] = lines[0].lstrip()
388        if margin < sys.maxint:
389            for i in range(1, len(lines)): lines[i] = lines[i][margin:]
390        # Remove any trailing or leading blank lines.
391        while lines and not lines[-1]:
392            lines.pop()
393        while lines and not lines[0]:
394            lines.pop(0)
395        return string.join(lines, '\n')
396
397def getfile(object):
398    """Work out which source or compiled file an object was defined in."""
399    if ismodule(object):
400        if hasattr(object, '__file__'):
401            return object.__file__
402        raise TypeError('{!r} is a built-in module'.format(object))
403    if isclass(object):
404        object = sys.modules.get(object.__module__)
405        if hasattr(object, '__file__'):
406            return object.__file__
407        raise TypeError('{!r} is a built-in class'.format(object))
408    if ismethod(object):
409        object = object.im_func
410    if isfunction(object):
411        object = object.func_code
412    if istraceback(object):
413        object = object.tb_frame
414    if isframe(object):
415        object = object.f_code
416    if iscode(object):
417        return object.co_filename
418    raise TypeError('{!r} is not a module, class, method, '
419                    'function, traceback, frame, or code object'.format(object))
420
421ModuleInfo = namedtuple('ModuleInfo', 'name suffix mode module_type')
422
423def getmoduleinfo(path):
424    """Get the module name, suffix, mode, and module type for a given file."""
425    filename = os.path.basename(path)
426    suffixes = map(lambda info:
427                   (-len(info[0]), info[0], info[1], info[2]),
428                    imp.get_suffixes())
429    suffixes.sort() # try longest suffixes first, in case they overlap
430    for neglen, suffix, mode, mtype in suffixes:
431        if filename[neglen:] == suffix:
432            return ModuleInfo(filename[:neglen], suffix, mode, mtype)
433
434def getmodulename(path):
435    """Return the module name for a given file, or None."""
436    info = getmoduleinfo(path)
437    if info: return info[0]
438
439def getsourcefile(object):
440    """Return the filename that can be used to locate an object's source.
441    Return None if no way can be identified to get the source.
442    """
443    filename = getfile(object)
444    if string.lower(filename[-4:]) in ('.pyc', '.pyo'):
445        filename = filename[:-4] + '.py'
446    for suffix, mode, kind in imp.get_suffixes():
447        if 'b' in mode and string.lower(filename[-len(suffix):]) == suffix:
448            # Looks like a binary file.  We want to only return a text file.
449            return None
450    if os.path.exists(filename):
451        return filename
452    # only return a non-existent filename if the module has a PEP 302 loader
453    if hasattr(getmodule(object, filename), '__loader__'):
454        return filename
455    # or it is in the linecache
456    if filename in linecache.cache:
457        return filename
458
459def getabsfile(object, _filename=None):
460    """Return an absolute path to the source or compiled file for an object.
461
462    The idea is for each object to have a unique origin, so this routine
463    normalizes the result as much as possible."""
464    if _filename is None:
465        _filename = getsourcefile(object) or getfile(object)
466    return os.path.normcase(os.path.abspath(_filename))
467
468modulesbyfile = {}
469_filesbymodname = {}
470
471def getmodule(object, _filename=None):
472    """Return the module an object was defined in, or None if not found."""
473    if ismodule(object):
474        return object
475    if hasattr(object, '__module__'):
476        return sys.modules.get(object.__module__)
477    # Try the filename to modulename cache
478    if _filename is not None and _filename in modulesbyfile:
479        return sys.modules.get(modulesbyfile[_filename])
480    # Try the cache again with the absolute file name
481    try:
482        file = getabsfile(object, _filename)
483    except TypeError:
484        return None
485    if file in modulesbyfile:
486        return sys.modules.get(modulesbyfile[file])
487    # Update the filename to module name cache and check yet again
488    # Copy sys.modules in order to cope with changes while iterating
489    for modname, module in sys.modules.items():
490        if ismodule(module) and hasattr(module, '__file__'):
491            f = module.__file__
492            if f == _filesbymodname.get(modname, None):
493                # Have already mapped this module, so skip it
494                continue
495            _filesbymodname[modname] = f
496            f = getabsfile(module)
497            # Always map to the name the module knows itself by
498            modulesbyfile[f] = modulesbyfile[
499                os.path.realpath(f)] = module.__name__
500    if file in modulesbyfile:
501        return sys.modules.get(modulesbyfile[file])
502    # Check the main module
503    main = sys.modules['__main__']
504    if not hasattr(object, '__name__'):
505        return None
506    if hasattr(main, object.__name__):
507        mainobject = getattr(main, object.__name__)
508        if mainobject is object:
509            return main
510    # Check builtins
511    builtin = sys.modules['__builtin__']
512    if hasattr(builtin, object.__name__):
513        builtinobject = getattr(builtin, object.__name__)
514        if builtinobject is object:
515            return builtin
516
517def findsource(object):
518    """Return the entire source file and starting line number for an object.
519
520    The argument may be a module, class, method, function, traceback, frame,
521    or code object.  The source code is returned as a list of all the lines
522    in the file and the line number indexes a line in that list.  An IOError
523    is raised if the source code cannot be retrieved."""
524
525    file = getfile(object)
526    sourcefile = getsourcefile(object)
527    if not sourcefile and file[:1] + file[-1:] != '<>':
528        raise IOError('source code not available')
529    file = sourcefile if sourcefile else file
530
531    module = getmodule(object, file)
532    if module:
533        lines = linecache.getlines(file, module.__dict__)
534    else:
535        lines = linecache.getlines(file)
536    if not lines:
537        raise IOError('could not get source code')
538
539    if ismodule(object):
540        return lines, 0
541
542    if isclass(object):
543        name = object.__name__
544        pat = re.compile(r'^(\s*)class\s*' + name + r'\b')
545        # make some effort to find the best matching class definition:
546        # use the one with the least indentation, which is the one
547        # that's most probably not inside a function definition.
548        candidates = []
549        for i in range(len(lines)):
550            match = pat.match(lines[i])
551            if match:
552                # if it's at toplevel, it's already the best one
553                if lines[i][0] == 'c':
554                    return lines, i
555                # else add whitespace to candidate list
556                candidates.append((match.group(1), i))
557        if candidates:
558            # this will sort by whitespace, and by line number,
559            # less whitespace first
560            candidates.sort()
561            return lines, candidates[0][1]
562        else:
563            raise IOError('could not find class definition')
564
565    if ismethod(object):
566        object = object.im_func
567    if isfunction(object):
568        object = object.func_code
569    if istraceback(object):
570        object = object.tb_frame
571    if isframe(object):
572        object = object.f_code
573    if iscode(object):
574        if not hasattr(object, 'co_firstlineno'):
575            raise IOError('could not find function definition')
576        lnum = object.co_firstlineno - 1
577        pat = re.compile(r'^(\s*def\s)|(.*(?<!\w)lambda(:|\s))|^(\s*@)')
578        while lnum > 0:
579            if pat.match(lines[lnum]): break
580            lnum = lnum - 1
581        return lines, lnum
582    raise IOError('could not find code object')
583
584def getcomments(object):
585    """Get lines of comments immediately preceding an object's source code.
586
587    Returns None when source can't be found.
588    """
589    try:
590        lines, lnum = findsource(object)
591    except (IOError, TypeError):
592        return None
593
594    if ismodule(object):
595        # Look for a comment block at the top of the file.
596        start = 0
597        if lines and lines[0][:2] == '#!': start = 1
598        while start < len(lines) and string.strip(lines[start]) in ('', '#'):
599            start = start + 1
600        if start < len(lines) and lines[start][:1] == '#':
601            comments = []
602            end = start
603            while end < len(lines) and lines[end][:1] == '#':
604                comments.append(string.expandtabs(lines[end]))
605                end = end + 1
606            return string.join(comments, '')
607
608    # Look for a preceding block of comments at the same indentation.
609    elif lnum > 0:
610        indent = indentsize(lines[lnum])
611        end = lnum - 1
612        if end >= 0 and string.lstrip(lines[end])[:1] == '#' and \
613            indentsize(lines[end]) == indent:
614            comments = [string.lstrip(string.expandtabs(lines[end]))]
615            if end > 0:
616                end = end - 1
617                comment = string.lstrip(string.expandtabs(lines[end]))
618                while comment[:1] == '#' and indentsize(lines[end]) == indent:
619                    comments[:0] = [comment]
620                    end = end - 1
621                    if end < 0: break
622                    comment = string.lstrip(string.expandtabs(lines[end]))
623            while comments and string.strip(comments[0]) == '#':
624                comments[:1] = []
625            while comments and string.strip(comments[-1]) == '#':
626                comments[-1:] = []
627            return string.join(comments, '')
628
629class EndOfBlock(Exception): pass
630
631class BlockFinder:
632    """Provide a tokeneater() method to detect the end of a code block."""
633    def __init__(self):
634        self.indent = 0
635        self.islambda = False
636        self.started = False
637        self.passline = False
638        self.last = 1
639
640    def tokeneater(self, type, token, srow_scol, erow_ecol, line):
641        srow, scol = srow_scol
642        erow, ecol = erow_ecol
643        if not self.started:
644            # look for the first "def", "class" or "lambda"
645            if token in ("def", "class", "lambda"):
646                if token == "lambda":
647                    self.islambda = True
648                self.started = True
649            self.passline = True    # skip to the end of the line
650        elif type == tokenize.NEWLINE:
651            self.passline = False   # stop skipping when a NEWLINE is seen
652            self.last = srow
653            if self.islambda:       # lambdas always end at the first NEWLINE
654                raise EndOfBlock
655        elif self.passline:
656            pass
657        elif type == tokenize.INDENT:
658            self.indent = self.indent + 1
659            self.passline = True
660        elif type == tokenize.DEDENT:
661            self.indent = self.indent - 1
662            # the end of matching indent/dedent pairs end a block
663            # (note that this only works for "def"/"class" blocks,
664            #  not e.g. for "if: else:" or "try: finally:" blocks)
665            if self.indent <= 0:
666                raise EndOfBlock
667        elif self.indent == 0 and type not in (tokenize.COMMENT, tokenize.NL):
668            # any other token on the same indentation level end the previous
669            # block as well, except the pseudo-tokens COMMENT and NL.
670            raise EndOfBlock
671
672def getblock(lines):
673    """Extract the block of code at the top of the given list of lines."""
674    blockfinder = BlockFinder()
675    try:
676        tokenize.tokenize(iter(lines).next, blockfinder.tokeneater)
677    except (EndOfBlock, IndentationError):
678        pass
679    return lines[:blockfinder.last]
680
681def getsourcelines(object):
682    """Return a list of source lines and starting line number for an object.
683
684    The argument may be a module, class, method, function, traceback, frame,
685    or code object.  The source code is returned as a list of the lines
686    corresponding to the object and the line number indicates where in the
687    original source file the first line of code was found.  An IOError is
688    raised if the source code cannot be retrieved."""
689    lines, lnum = findsource(object)
690
691    if istraceback(object):
692        object = object.tb_frame
693
694    # for module or frame that corresponds to module, return all source lines
695    if (ismodule(object) or
696        (isframe(object) and object.f_code.co_name == "<module>")):
697        return lines, 0
698    else:
699        return getblock(lines[lnum:]), lnum + 1
700
701def getsource(object):
702    """Return the text of the source code for an object.
703
704    The argument may be a module, class, method, function, traceback, frame,
705    or code object.  The source code is returned as a single string.  An
706    IOError is raised if the source code cannot be retrieved."""
707    lines, lnum = getsourcelines(object)
708    return string.join(lines, '')
709
710# --------------------------------------------------- class tree extraction
711def walktree(classes, children, parent):
712    """Recursive helper function for getclasstree()."""
713    results = []
714    classes.sort(key=attrgetter('__module__', '__name__'))
715    for c in classes:
716        results.append((c, c.__bases__))
717        if c in children:
718            results.append(walktree(children[c], children, c))
719    return results
720
721def getclasstree(classes, unique=0):
722    """Arrange the given list of classes into a hierarchy of nested lists.
723
724    Where a nested list appears, it contains classes derived from the class
725    whose entry immediately precedes the list.  Each entry is a 2-tuple
726    containing a class and a tuple of its base classes.  If the 'unique'
727    argument is true, exactly one entry appears in the returned structure
728    for each class in the given list.  Otherwise, classes using multiple
729    inheritance and their descendants will appear multiple times."""
730    children = {}
731    roots = []
732    for c in classes:
733        if c.__bases__:
734            for parent in c.__bases__:
735                if not parent in children:
736                    children[parent] = []
737                if c not in children[parent]:
738                    children[parent].append(c)
739                if unique and parent in classes: break
740        elif c not in roots:
741            roots.append(c)
742    for parent in children:
743        if parent not in classes:
744            roots.append(parent)
745    return walktree(roots, children, None)
746
747# ------------------------------------------------ argument list extraction
748Arguments = namedtuple('Arguments', 'args varargs keywords')
749
750def getargs(co):
751    """Get information about the arguments accepted by a code object.
752
753    Three things are returned: (args, varargs, varkw), where 'args' is
754    a list of argument names (possibly containing nested lists), and
755    'varargs' and 'varkw' are the names of the * and ** arguments or None."""
756
757    if not iscode(co):
758        raise TypeError('{!r} is not a code object'.format(co))
759
760    nargs = co.co_argcount
761    names = co.co_varnames
762    args = list(names[:nargs])
763    step = 0
764
765    # The following acrobatics are for anonymous (tuple) arguments.
766    for i in range(nargs):
767        if args[i][:1] in ('', '.'):
768            stack, remain, count = [], [], []
769            while step < len(co.co_code):
770                op = ord(co.co_code[step])
771                step = step + 1
772                if op >= dis.HAVE_ARGUMENT:
773                    opname = dis.opname[op]
774                    value = ord(co.co_code[step]) + ord(co.co_code[step+1])*256
775                    step = step + 2
776                    if opname in ('UNPACK_TUPLE', 'UNPACK_SEQUENCE'):
777                        remain.append(value)
778                        count.append(value)
779                    elif opname in ('STORE_FAST', 'STORE_DEREF'):
780                        if opname == 'STORE_FAST':
781                            stack.append(names[value])
782                        else:
783                            stack.append(co.co_cellvars[value])
784
785                        # Special case for sublists of length 1: def foo((bar))
786                        # doesn't generate the UNPACK_TUPLE bytecode, so if
787                        # `remain` is empty here, we have such a sublist.
788                        if not remain:
789                            stack[0] = [stack[0]]
790                            break
791                        else:
792                            remain[-1] = remain[-1] - 1
793                            while remain[-1] == 0:
794                                remain.pop()
795                                size = count.pop()
796                                stack[-size:] = [stack[-size:]]
797                                if not remain: break
798                                remain[-1] = remain[-1] - 1
799                            if not remain: break
800            args[i] = stack[0]
801
802    varargs = None
803    if co.co_flags & CO_VARARGS:
804        varargs = co.co_varnames[nargs]
805        nargs = nargs + 1
806    varkw = None
807    if co.co_flags & CO_VARKEYWORDS:
808        varkw = co.co_varnames[nargs]
809    return Arguments(args, varargs, varkw)
810
811ArgSpec = namedtuple('ArgSpec', 'args varargs keywords defaults')
812
813def getargspec(func):
814    """Get the names and default values of a function's arguments.
815
816    A tuple of four things is returned: (args, varargs, varkw, defaults).
817    'args' is a list of the argument names (it may contain nested lists).
818    'varargs' and 'varkw' are the names of the * and ** arguments or None.
819    'defaults' is an n-tuple of the default values of the last n arguments.
820    """
821
822    if ismethod(func):
823        func = func.im_func
824    if not isfunction(func):
825        raise TypeError('{!r} is not a Python function'.format(func))
826    args, varargs, varkw = getargs(func.func_code)
827    return ArgSpec(args, varargs, varkw, func.func_defaults)
828
829ArgInfo = namedtuple('ArgInfo', 'args varargs keywords locals')
830
831def getargvalues(frame):
832    """Get information about arguments passed into a particular frame.
833
834    A tuple of four things is returned: (args, varargs, varkw, locals).
835    'args' is a list of the argument names (it may contain nested lists).
836    'varargs' and 'varkw' are the names of the * and ** arguments or None.
837    'locals' is the locals dictionary of the given frame."""
838    args, varargs, varkw = getargs(frame.f_code)
839    return ArgInfo(args, varargs, varkw, frame.f_locals)
840
841def joinseq(seq):
842    if len(seq) == 1:
843        return '(' + seq[0] + ',)'
844    else:
845        return '(' + string.join(seq, ', ') + ')'
846
847def strseq(object, convert, join=joinseq):
848    """Recursively walk a sequence, stringifying each element."""
849    if type(object) in (list, tuple):
850        return join(map(lambda o, c=convert, j=join: strseq(o, c, j), object))
851    else:
852        return convert(object)
853
854def formatargspec(args, varargs=None, varkw=None, defaults=None,
855                  formatarg=str,
856                  formatvarargs=lambda name: '*' + name,
857                  formatvarkw=lambda name: '**' + name,
858                  formatvalue=lambda value: '=' + repr(value),
859                  join=joinseq):
860    """Format an argument spec from the 4 values returned by getargspec.
861
862    The first four arguments are (args, varargs, varkw, defaults).  The
863    other four arguments are the corresponding optional formatting functions
864    that are called to turn names and values into strings.  The ninth
865    argument is an optional function to format the sequence of arguments."""
866    specs = []
867    if defaults:
868        firstdefault = len(args) - len(defaults)
869    for i, arg in enumerate(args):
870        spec = strseq(arg, formatarg, join)
871        if defaults and i >= firstdefault:
872            spec = spec + formatvalue(defaults[i - firstdefault])
873        specs.append(spec)
874    if varargs is not None:
875        specs.append(formatvarargs(varargs))
876    if varkw is not None:
877        specs.append(formatvarkw(varkw))
878    return '(' + string.join(specs, ', ') + ')'
879
880def formatargvalues(args, varargs, varkw, locals,
881                    formatarg=str,
882                    formatvarargs=lambda name: '*' + name,
883                    formatvarkw=lambda name: '**' + name,
884                    formatvalue=lambda value: '=' + repr(value),
885                    join=joinseq):
886    """Format an argument spec from the 4 values returned by getargvalues.
887
888    The first four arguments are (args, varargs, varkw, locals).  The
889    next four arguments are the corresponding optional formatting functions
890    that are called to turn names and values into strings.  The ninth
891    argument is an optional function to format the sequence of arguments."""
892    def convert(name, locals=locals,
893                formatarg=formatarg, formatvalue=formatvalue):
894        return formatarg(name) + formatvalue(locals[name])
895    specs = []
896    for i in range(len(args)):
897        specs.append(strseq(args[i], convert, join))
898    if varargs:
899        specs.append(formatvarargs(varargs) + formatvalue(locals[varargs]))
900    if varkw:
901        specs.append(formatvarkw(varkw) + formatvalue(locals[varkw]))
902    return '(' + string.join(specs, ', ') + ')'
903
904def getcallargs(func, *positional, **named):
905    """Get the mapping of arguments to values.
906
907    A dict is returned, with keys the function argument names (including the
908    names of the * and ** arguments, if any), and values the respective bound
909    values from 'positional' and 'named'."""
910    args, varargs, varkw, defaults = getargspec(func)
911    f_name = func.__name__
912    arg2value = {}
913
914    # The following closures are basically because of tuple parameter unpacking.
915    assigned_tuple_params = []
916    def assign(arg, value):
917        if isinstance(arg, str):
918            arg2value[arg] = value
919        else:
920            assigned_tuple_params.append(arg)
921            value = iter(value)
922            for i, subarg in enumerate(arg):
923                try:
924                    subvalue = next(value)
925                except StopIteration:
926                    raise ValueError('need more than %d %s to unpack' %
927                                     (i, 'values' if i > 1 else 'value'))
928                assign(subarg,subvalue)
929            try:
930                next(value)
931            except StopIteration:
932                pass
933            else:
934                raise ValueError('too many values to unpack')
935    def is_assigned(arg):
936        if isinstance(arg,str):
937            return arg in arg2value
938        return arg in assigned_tuple_params
939    if ismethod(func) and func.im_self is not None:
940        # implicit 'self' (or 'cls' for classmethods) argument
941        positional = (func.im_self,) + positional
942    num_pos = len(positional)
943    num_total = num_pos + len(named)
944    num_args = len(args)
945    num_defaults = len(defaults) if defaults else 0
946    for arg, value in zip(args, positional):
947        assign(arg, value)
948    if varargs:
949        if num_pos > num_args:
950            assign(varargs, positional[-(num_pos-num_args):])
951        else:
952            assign(varargs, ())
953    elif 0 < num_args < num_pos:
954        raise TypeError('%s() takes %s %d %s (%d given)' % (
955            f_name, 'at most' if defaults else 'exactly', num_args,
956            'arguments' if num_args > 1 else 'argument', num_total))
957    elif num_args == 0 and num_total:
958        if varkw:
959            if num_pos:
960                # XXX: We should use num_pos, but Python also uses num_total:
961                raise TypeError('%s() takes exactly 0 arguments '
962                                '(%d given)' % (f_name, num_total))
963        else:
964            raise TypeError('%s() takes no arguments (%d given)' %
965                            (f_name, num_total))
966    for arg in args:
967        if isinstance(arg, str) and arg in named:
968            if is_assigned(arg):
969                raise TypeError("%s() got multiple values for keyword "
970                                "argument '%s'" % (f_name, arg))
971            else:
972                assign(arg, named.pop(arg))
973    if defaults:    # fill in any missing values with the defaults
974        for arg, value in zip(args[-num_defaults:], defaults):
975            if not is_assigned(arg):
976                assign(arg, value)
977    if varkw:
978        assign(varkw, named)
979    elif named:
980        unexpected = next(iter(named))
981        try:
982            unicode
983        except NameError:
984            pass
985        else:
986            if isinstance(unexpected, unicode):
987                unexpected = unexpected.encode(sys.getdefaultencoding(), 'replace')
988        raise TypeError("%s() got an unexpected keyword argument '%s'" %
989                        (f_name, unexpected))
990    unassigned = num_args - len([arg for arg in args if is_assigned(arg)])
991    if unassigned:
992        num_required = num_args - num_defaults
993        raise TypeError('%s() takes %s %d %s (%d given)' % (
994            f_name, 'at least' if defaults else 'exactly', num_required,
995            'arguments' if num_required > 1 else 'argument', num_total))
996    return arg2value
997
998# -------------------------------------------------- stack frame extraction
999
1000Traceback = namedtuple('Traceback', 'filename lineno function code_context index')
1001
1002def getframeinfo(frame, context=1):
1003    """Get information about a frame or traceback object.
1004
1005    A tuple of five things is returned: the filename, the line number of
1006    the current line, the function name, a list of lines of context from
1007    the source code, and the index of the current line within that list.
1008    The optional second argument specifies the number of lines of context
1009    to return, which are centered around the current line."""
1010    if istraceback(frame):
1011        lineno = frame.tb_lineno
1012        frame = frame.tb_frame
1013    else:
1014        lineno = frame.f_lineno
1015    if not isframe(frame):
1016        raise TypeError('{!r} is not a frame or traceback object'.format(frame))
1017
1018    filename = getsourcefile(frame) or getfile(frame)
1019    if context > 0:
1020        start = lineno - 1 - context//2
1021        try:
1022            lines, lnum = findsource(frame)
1023        except IOError:
1024            lines = index = None
1025        else:
1026            start = max(start, 1)
1027            start = max(0, min(start, len(lines) - context))
1028            lines = lines[start:start+context]
1029            index = lineno - 1 - start
1030    else:
1031        lines = index = None
1032
1033    return Traceback(filename, lineno, frame.f_code.co_name, lines, index)
1034
1035def getlineno(frame):
1036    """Get the line number from a frame object, allowing for optimization."""
1037    # FrameType.f_lineno is now a descriptor that grovels co_lnotab
1038    return frame.f_lineno
1039
1040def getouterframes(frame, context=1):
1041    """Get a list of records for a frame and all higher (calling) frames.
1042
1043    Each record contains a frame object, filename, line number, function
1044    name, a list of lines of context, and index within the context."""
1045    framelist = []
1046    while frame:
1047        framelist.append((frame,) + getframeinfo(frame, context))
1048        frame = frame.f_back
1049    return framelist
1050
1051def getinnerframes(tb, context=1):
1052    """Get a list of records for a traceback's frame and all lower frames.
1053
1054    Each record contains a frame object, filename, line number, function
1055    name, a list of lines of context, and index within the context."""
1056    framelist = []
1057    while tb:
1058        framelist.append((tb.tb_frame,) + getframeinfo(tb, context))
1059        tb = tb.tb_next
1060    return framelist
1061
1062if hasattr(sys, '_getframe'):
1063    currentframe = sys._getframe
1064else:
1065    currentframe = lambda _=None: None
1066
1067def stack(context=1):
1068    """Return a list of records for the stack above the caller's frame."""
1069    return getouterframes(sys._getframe(1), context)
1070
1071def trace(context=1):
1072    """Return a list of records for the stack below the current exception."""
1073    return getinnerframes(sys.exc_info()[2], context)
1074