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