inspect.py 38.9 KB
Newer Older
1
# -*- coding: iso-8859-1 -*-
2 3 4
"""Get useful information from live Python objects.

This module encapsulates the interface provided by the internal special
5
attributes (co_*, im_*, tb_*, etc.) in a friendlier fashion.
6 7 8 9
It also provides some help for examining source code and class layout.

Here are some of the useful functions provided by this module:

Christian Heimes's avatar
Christian Heimes committed
10 11 12
    ismodule(), isclass(), ismethod(), isfunction(), isgeneratorfunction(),
        isgenerator(), istraceback(), isframe(), iscode(), isbuiltin(),
        isroutine() - check object types
13 14 15 16 17 18 19 20
    getmembers() - get members of an object that satisfy a given condition

    getfile(), getsourcefile(), getsource() - find an object's source code
    getdoc(), getcomments() - get documentation on an object
    getmodule() - determine the module that an object came from
    getclasstree() - arrange classes so as to represent their hierarchy

    getargspec(), getargvalues() - get info about function arguments
21
    getfullargspec() - same, with support for Python-3000 features
22 23 24 25 26 27 28 29
    formatargspec(), formatargvalues() - format an argument spec
    getouterframes(), getinnerframes() - get info about frames
    currentframe() - get the current stack frame
    stack(), trace() - get info about frames on the stack or in a traceback
"""

# This module is in the public domain.  No warranties.

Ka-Ping Yee's avatar
Ka-Ping Yee committed
30 31
__author__ = 'Ka-Ping Yee <ping@lfw.org>'
__date__ = '1 Jan 2001'
32

Christian Heimes's avatar
Christian Heimes committed
33 34 35 36 37 38 39 40 41
import sys
import os
import types
import string
import re
import dis
import imp
import tokenize
import linecache
42
from operator import attrgetter
43
from collections import namedtuple
Christian Heimes's avatar
Christian Heimes committed
44 45 46
# These constants are from Include/code.h.
CO_OPTIMIZED, CO_NEWLOCALS, CO_VARARGS, CO_VARKEYWORDS = 0x1, 0x2, 0x4, 0x8
CO_NESTED, CO_GENERATOR, CO_NOFREE = 0x10, 0x20, 0x40
47

48 49 50
# See Include/object.h
TPFLAGS_IS_ABSTRACT = 1 << 20

51 52 53 54 55 56 57
# ----------------------------------------------------------- type-checking
def ismodule(object):
    """Return true if the object is a module.

    Module objects provide these attributes:
        __doc__         documentation string
        __file__        filename (missing for built-in modules)"""
58
    return isinstance(object, types.ModuleType)
59 60 61 62 63 64 65

def isclass(object):
    """Return true if the object is a class.

    Class objects provide these attributes:
        __doc__         documentation string
        __module__      name of module in which this class was defined"""
66
    return isinstance(object, type)
67 68 69 70 71 72 73

def ismethod(object):
    """Return true if the object is an instance method.

    Instance method objects provide these attributes:
        __doc__         documentation string
        __name__        name with which this method was defined
74 75
        __func__        function object containing implementation of method
        __self__        instance to which this method is bound"""
76
    return isinstance(object, types.MethodType)
77

78
def ismethoddescriptor(object):
79 80 81
    """Return true if the object is a method descriptor.

    But not if ismethod() or isclass() or isfunction() are true.
82 83 84 85 86 87

    This is new in Python 2.2, and, for example, is true of int.__add__.
    An object passing this test has a __get__ attribute but not a __set__
    attribute, but beyond that the set of attributes varies.  __name__ is
    usually sensible, and __doc__ often is.

88 89 90
    Methods implemented via descriptors that also pass one of the other
    tests return false from the ismethoddescriptor() test, simply because
    the other tests promise more -- you can, e.g., count on having the
91
    __func__ attribute (etc) when an object passes ismethod()."""
92 93 94
    return (hasattr(object, "__get__")
            and not hasattr(object, "__set__") # else it's a data descriptor
            and not ismethod(object)           # mutual exclusion
95
            and not isfunction(object)
96 97
            and not isclass(object))

98 99 100 101 102 103 104 105 106 107
def isdatadescriptor(object):
    """Return true if the object is a data descriptor.

    Data descriptors have both a __get__ and a __set__ attribute.  Examples are
    properties (defined in Python) and getsets and members (defined in C).
    Typically, data descriptors will also have __name__ and __doc__ attributes
    (properties, getsets, and members have both of these attributes), but this
    is not guaranteed."""
    return (hasattr(object, "__set__") and hasattr(object, "__get__"))

108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141
if hasattr(types, 'MemberDescriptorType'):
    # CPython and equivalent
    def ismemberdescriptor(object):
        """Return true if the object is a member descriptor.

        Member descriptors are specialized descriptors defined in extension
        modules."""
        return isinstance(object, types.MemberDescriptorType)
else:
    # Other implementations
    def ismemberdescriptor(object):
        """Return true if the object is a member descriptor.

        Member descriptors are specialized descriptors defined in extension
        modules."""
        return False

if hasattr(types, 'GetSetDescriptorType'):
    # CPython and equivalent
    def isgetsetdescriptor(object):
        """Return true if the object is a getset descriptor.

        getset descriptors are specialized descriptors defined in extension
        modules."""
        return isinstance(object, types.GetSetDescriptorType)
else:
    # Other implementations
    def isgetsetdescriptor(object):
        """Return true if the object is a getset descriptor.

        getset descriptors are specialized descriptors defined in extension
        modules."""
        return False

142 143 144 145 146 147
def isfunction(object):
    """Return true if the object is a user-defined function.

    Function objects provide these attributes:
        __doc__         documentation string
        __name__        name with which this function was defined
148 149 150 151 152
        __code__        code object containing compiled function bytecode
        __defaults__    tuple of any default values for arguments
        __globals__     global namespace in which this function was defined
        __annotations__ dict of parameter annotations
        __kwdefaults__  dict of keyword only parameters with defaults"""
153
    return isinstance(object, types.FunctionType)
154

Christian Heimes's avatar
Christian Heimes committed
155 156 157 158 159 160
def isgeneratorfunction(object):
    """Return true if the object is a user-defined generator function.

    Generator function objects provides same attributes as functions.

    See isfunction.__doc__ for attributes listing."""
161 162
    return bool((isfunction(object) or ismethod(object)) and
                object.__code__.co_flags & CO_GENERATOR)
Christian Heimes's avatar
Christian Heimes committed
163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180

def isgenerator(object):
    """Return true if the object is a generator.

    Generator objects provide these attributes:
        __iter__        defined to support interation over container
        close           raises a new GeneratorExit exception inside the
                        generator to terminate the iteration
        gi_code         code object
        gi_frame        frame object or possibly None once the generator has
                        been exhausted
        gi_running      set to 1 when generator is executing, 0 otherwise
        next            return the next item from the container
        send            resumes the generator and "sends" a value that becomes
                        the result of the current yield-expression
        throw           used to raise an exception inside the generator"""
    return isinstance(object, types.GeneratorType)

181 182 183 184 185 186 187 188
def istraceback(object):
    """Return true if the object is a traceback.

    Traceback objects provide these attributes:
        tb_frame        frame object at this level
        tb_lasti        index of last attempted instruction in bytecode
        tb_lineno       current line number in Python source code
        tb_next         next inner traceback object (called by this level)"""
189
    return isinstance(object, types.TracebackType)
190 191 192 193 194 195 196 197 198 199 200 201 202

def isframe(object):
    """Return true if the object is a frame object.

    Frame objects provide these attributes:
        f_back          next outer frame object (this frame's caller)
        f_builtins      built-in namespace seen by this frame
        f_code          code object being executed in this frame
        f_globals       global namespace seen by this frame
        f_lasti         index of last attempted instruction in bytecode
        f_lineno        current line number in Python source code
        f_locals        local namespace seen by this frame
        f_trace         tracing function for this frame, or None"""
203
    return isinstance(object, types.FrameType)
204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220

def iscode(object):
    """Return true if the object is a code object.

    Code objects provide these attributes:
        co_argcount     number of arguments (not including * or ** args)
        co_code         string of raw compiled bytecode
        co_consts       tuple of constants used in the bytecode
        co_filename     name of file in which this code object was created
        co_firstlineno  number of first line in Python source code
        co_flags        bitmap: 1=optimized | 2=newlocals | 4=*arg | 8=**arg
        co_lnotab       encoded mapping of line numbers to bytecode indices
        co_name         name with which this code object was defined
        co_names        tuple of names of local variables
        co_nlocals      number of local variables
        co_stacksize    virtual machine stack space required
        co_varnames     tuple of names of arguments and local variables"""
221
    return isinstance(object, types.CodeType)
222 223 224 225 226 227 228 229

def isbuiltin(object):
    """Return true if the object is a built-in function or method.

    Built-in functions and methods provide these attributes:
        __doc__         documentation string
        __name__        original name of this function or method
        __self__        instance to which a method is bound, or None"""
230
    return isinstance(object, types.BuiltinFunctionType)
231 232 233

def isroutine(object):
    """Return true if the object is any kind of function or method."""
234 235 236 237
    return (isbuiltin(object)
            or isfunction(object)
            or ismethod(object)
            or ismethoddescriptor(object))
238

Christian Heimes's avatar
Christian Heimes committed
239 240 241 242
def isgenerator(object):
    """Return true if the object is a generator object."""
    return isinstance(object, types.GeneratorType)

243 244
def isabstract(object):
    """Return true if the object is an abstract base class (ABC)."""
Christian Heimes's avatar
Christian Heimes committed
245
    return isinstance(object, type) and object.__flags__ & TPFLAGS_IS_ABSTRACT
246

247 248 249 250 251
def getmembers(object, predicate=None):
    """Return all members of an object as (name, value) pairs sorted by name.
    Optionally, only return members that satisfy a given predicate."""
    results = []
    for key in dir(object):
Benjamin Peterson's avatar
Benjamin Peterson committed
252 253 254 255
        try:
            value = getattr(object, key)
        except AttributeError:
            continue
256 257 258 259 260
        if not predicate or predicate(value):
            results.append((key, value))
    results.sort()
    return results

261 262
Attribute = namedtuple('Attribute', 'name kind defining_class object')

263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301
def classify_class_attrs(cls):
    """Return list of attribute-descriptor tuples.

    For each name in dir(cls), the return list contains a 4-tuple
    with these elements:

        0. The name (a string).

        1. The kind of attribute this is, one of these strings:
               'class method'    created via classmethod()
               'static method'   created via staticmethod()
               'property'        created via property()
               'method'          any other flavor of method
               'data'            not a method

        2. The class which defined this attribute (a class).

        3. The object as obtained directly from the defining class's
           __dict__, not via getattr.  This is especially important for
           data attributes:  C.data is just a data object, but
           C.__dict__['data'] may be a data descriptor with additional
           info, like a __doc__ string.
    """

    mro = getmro(cls)
    names = dir(cls)
    result = []
    for name in names:
        # Get the object associated with the name.
        # Getting an obj from the __dict__ sometimes reveals more than
        # using getattr.  Static and class methods are dramatic examples.
        if name in cls.__dict__:
            obj = cls.__dict__[name]
        else:
            obj = getattr(cls, name)

        # Figure out where it was defined.
        homecls = getattr(obj, "__objclass__", None)
        if homecls is None:
302
            # search the dicts.
303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322
            for base in mro:
                if name in base.__dict__:
                    homecls = base
                    break

        # Get the object again, in order to get it from the defining
        # __dict__ instead of via getattr (if possible).
        if homecls is not None and name in homecls.__dict__:
            obj = homecls.__dict__[name]

        # Also get the object via getattr.
        obj_via_getattr = getattr(cls, name)

        # Classify the object.
        if isinstance(obj, staticmethod):
            kind = "static method"
        elif isinstance(obj, classmethod):
            kind = "class method"
        elif isinstance(obj, property):
            kind = "property"
323
        elif (isfunction(obj_via_getattr) or
324 325 326 327 328
              ismethoddescriptor(obj_via_getattr)):
            kind = "method"
        else:
            kind = "data"

329
        result.append(Attribute(name, kind, homecls, obj))
330 331 332

    return result

333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350
# ----------------------------------------------------------- class helpers
def _searchbases(cls, accum):
    # Simulate the "classic class" search order.
    if cls in accum:
        return
    accum.append(cls)
    for base in cls.__bases__:
        _searchbases(base, accum)

def getmro(cls):
    "Return tuple of base classes (including cls) in method resolution order."
    if hasattr(cls, "__mro__"):
        return cls.__mro__
    else:
        result = []
        _searchbases(cls, result)
        return tuple(result)

351 352 353
# -------------------------------------------------- source code extraction
def indentsize(line):
    """Return the indent size, in spaces, at the start of a line of text."""
354 355
    expline = line.expandtabs()
    return len(expline) - len(expline.lstrip())
356 357 358 359 360 361 362

def getdoc(object):
    """Get the documentation string for an object.

    All tabs are expanded to spaces.  To clean up docstrings that are
    indented to line up with blocks of code, any whitespace than can be
    uniformly removed from the second line onwards is removed."""
363 364 365 366
    try:
        doc = object.__doc__
    except AttributeError:
        return None
367
    if not isinstance(doc, str):
368
        return None
Georg Brandl's avatar
Georg Brandl committed
369 370 371 372 373 374 375
    return cleandoc(doc)

def cleandoc(doc):
    """Clean up indentation from docstrings.

    Any whitespace that can be uniformly removed from the second line
    onwards is removed."""
376
    try:
377
        lines = doc.expandtabs().split('\n')
378 379 380
    except UnicodeError:
        return None
    else:
Ka-Ping Yee's avatar
Ka-Ping Yee committed
381
        # Find minimum indentation of any non-blank lines after first line.
382
        margin = sys.maxsize
383
        for line in lines[1:]:
384
            content = len(line.lstrip())
Ka-Ping Yee's avatar
Ka-Ping Yee committed
385 386 387 388 389 390
            if content:
                indent = len(line) - content
                margin = min(margin, indent)
        # Remove indentation.
        if lines:
            lines[0] = lines[0].lstrip()
391
        if margin < sys.maxsize:
392
            for i in range(1, len(lines)): lines[i] = lines[i][margin:]
Ka-Ping Yee's avatar
Ka-Ping Yee committed
393 394 395 396 397
        # Remove any trailing or leading blank lines.
        while lines and not lines[-1]:
            lines.pop()
        while lines and not lines[0]:
            lines.pop(0)
398
        return '\n'.join(lines)
399 400

def getfile(object):
401
    """Work out which source or compiled file an object was defined in."""
402 403 404
    if ismodule(object):
        if hasattr(object, '__file__'):
            return object.__file__
405
        raise TypeError('arg is a built-in module')
406
    if isclass(object):
407
        object = sys.modules.get(object.__module__)
408 409
        if hasattr(object, '__file__'):
            return object.__file__
410
        raise TypeError('arg is a built-in class')
411
    if ismethod(object):
412
        object = object.__func__
413
    if isfunction(object):
414
        object = object.__code__
415 416 417 418 419 420
    if istraceback(object):
        object = object.tb_frame
    if isframe(object):
        object = object.f_code
    if iscode(object):
        return object.co_filename
Tim Peters's avatar
Tim Peters committed
421
    raise TypeError('arg is not a module, class, method, '
422
                    'function, traceback, frame, or code object')
423

424 425
ModuleInfo = namedtuple('ModuleInfo', 'name suffix mode module_type')

426 427 428
def getmoduleinfo(path):
    """Get the module name, suffix, mode, and module type for a given file."""
    filename = os.path.basename(path)
429 430
    suffixes = [(-len(suffix), suffix, mode, mtype)
                    for suffix, mode, mtype in imp.get_suffixes()]
431 432 433
    suffixes.sort() # try longest suffixes first, in case they overlap
    for neglen, suffix, mode, mtype in suffixes:
        if filename[neglen:] == suffix:
434
            return ModuleInfo(filename[:neglen], suffix, mode, mtype)
435 436 437 438 439 440

def getmodulename(path):
    """Return the module name for a given file, or None."""
    info = getmoduleinfo(path)
    if info: return info[0]

441 442 443
def getsourcefile(object):
    """Return the Python source file an object was defined in, if it exists."""
    filename = getfile(object)
444
    if filename[-4:].lower() in ('.pyc', '.pyo'):
445
        filename = filename[:-4] + '.py'
446
    for suffix, mode, kind in imp.get_suffixes():
447
        if 'b' in mode and filename[-len(suffix):].lower() == suffix:
448 449
            # Looks like a binary file.  We want to only return a text file.
            return None
450 451
    if os.path.exists(filename):
        return filename
452 453
    # only return a non-existent filename if the module has a PEP 302 loader
    if hasattr(getmodule(object, filename), '__loader__'):
454 455
        return filename

456
def getabsfile(object, _filename=None):
457
    """Return an absolute path to the source or compiled file for an object.
458

459 460
    The idea is for each object to have a unique origin, so this routine
    normalizes the result as much as possible."""
461 462 463
    if _filename is None:
        _filename = getsourcefile(object) or getfile(object)
    return os.path.normcase(os.path.abspath(_filename))
464

465
modulesbyfile = {}
466
_filesbymodname = {}
467

468
def getmodule(object, _filename=None):
469
    """Return the module an object was defined in, or None if not found."""
470 471
    if ismodule(object):
        return object
472
    if hasattr(object, '__module__'):
Ka-Ping Yee's avatar
Ka-Ping Yee committed
473
        return sys.modules.get(object.__module__)
474 475 476 477
    # Try the filename to modulename cache
    if _filename is not None and _filename in modulesbyfile:
        return sys.modules.get(modulesbyfile[_filename])
    # Try the cache again with the absolute file name
478
    try:
479
        file = getabsfile(object, _filename)
480 481
    except TypeError:
        return None
482
    if file in modulesbyfile:
483
        return sys.modules.get(modulesbyfile[file])
484 485 486
    # Update the filename to module name cache and check yet again
    # Copy sys.modules in order to cope with changes while iterating
    for modname, module in sys.modules.items():
487
        if ismodule(module) and hasattr(module, '__file__'):
488 489 490 491 492
            f = module.__file__
            if f == _filesbymodname.get(modname, None):
                # Have already mapped this module, so skip it
                continue
            _filesbymodname[modname] = f
493
            f = getabsfile(module)
494
            # Always map to the name the module knows itself by
495 496
            modulesbyfile[f] = modulesbyfile[
                os.path.realpath(f)] = module.__name__
497
    if file in modulesbyfile:
498
        return sys.modules.get(modulesbyfile[file])
499
    # Check the main module
500
    main = sys.modules['__main__']
501 502
    if not hasattr(object, '__name__'):
        return None
503
    if hasattr(main, object.__name__):
504
        mainobject = getattr(main, object.__name__)
505 506
        if mainobject is object:
            return main
507
    # Check builtins
508
    builtin = sys.modules['builtins']
509
    if hasattr(builtin, object.__name__):
510
        builtinobject = getattr(builtin, object.__name__)
511 512
        if builtinobject is object:
            return builtin
513 514 515 516 517 518 519 520

def findsource(object):
    """Return the entire source file and starting line number for an object.

    The argument may be a module, class, method, function, traceback, frame,
    or code object.  The source code is returned as a list of all the lines
    in the file and the line number indexes a line in that list.  An IOError
    is raised if the source code cannot be retrieved."""
521
    file = getsourcefile(object) or getfile(object)
522
    module = getmodule(object, file)
523 524 525 526
    if module:
        lines = linecache.getlines(file, module.__dict__)
    else:
        lines = linecache.getlines(file)
527
    if not lines:
528
        raise IOError('could not get source code')
529 530 531 532 533 534

    if ismodule(object):
        return lines, 0

    if isclass(object):
        name = object.__name__
535 536 537 538 539
        pat = re.compile(r'^(\s*)class\s*' + name + r'\b')
        # make some effort to find the best matching class definition:
        # use the one with the least indentation, which is the one
        # that's most probably not inside a function definition.
        candidates = []
540
        for i in range(len(lines)):
541 542 543 544 545 546 547 548 549 550 551 552
            match = pat.match(lines[i])
            if match:
                # if it's at toplevel, it's already the best one
                if lines[i][0] == 'c':
                    return lines, i
                # else add whitespace to candidate list
                candidates.append((match.group(1), i))
        if candidates:
            # this will sort by whitespace, and by line number,
            # less whitespace first
            candidates.sort()
            return lines, candidates[0][1]
553 554
        else:
            raise IOError('could not find class definition')
555 556

    if ismethod(object):
557
        object = object.__func__
558
    if isfunction(object):
559
        object = object.__code__
560 561 562 563 564
    if istraceback(object):
        object = object.tb_frame
    if isframe(object):
        object = object.f_code
    if iscode(object):
565
        if not hasattr(object, 'co_firstlineno'):
566
            raise IOError('could not find function definition')
567
        lnum = object.co_firstlineno - 1
568
        pat = re.compile(r'^(\s*def\s)|(.*(?<!\w)lambda(:|\s))|^(\s*@)')
569
        while lnum > 0:
570
            if pat.match(lines[lnum]): break
571 572
            lnum = lnum - 1
        return lines, lnum
573
    raise IOError('could not find code object')
574 575

def getcomments(object):
576 577 578 579 580 581 582 583
    """Get lines of comments immediately preceding an object's source code.

    Returns None when source can't be found.
    """
    try:
        lines, lnum = findsource(object)
    except (IOError, TypeError):
        return None
584 585 586 587

    if ismodule(object):
        # Look for a comment block at the top of the file.
        start = 0
588
        if lines and lines[0][:2] == '#!': start = 1
589
        while start < len(lines) and lines[start].strip() in ('', '#'):
590
            start = start + 1
591
        if start < len(lines) and lines[start][:1] == '#':
592 593 594
            comments = []
            end = start
            while end < len(lines) and lines[end][:1] == '#':
595
                comments.append(lines[end].expandtabs())
596
                end = end + 1
597
            return ''.join(comments)
598 599 600 601 602

    # Look for a preceding block of comments at the same indentation.
    elif lnum > 0:
        indent = indentsize(lines[lnum])
        end = lnum - 1
603
        if end >= 0 and lines[end].lstrip()[:1] == '#' and \
604
            indentsize(lines[end]) == indent:
605
            comments = [lines[end].expandtabs().lstrip()]
606 607
            if end > 0:
                end = end - 1
608
                comment = lines[end].expandtabs().lstrip()
609 610 611 612
                while comment[:1] == '#' and indentsize(lines[end]) == indent:
                    comments[:0] = [comment]
                    end = end - 1
                    if end < 0: break
613 614
                    comment = lines[end].expandtabs().lstrip()
            while comments and comments[0].strip() == '#':
615
                comments[:1] = []
616
            while comments and comments[-1].strip() == '#':
617
                comments[-1:] = []
618
            return ''.join(comments)
619

620 621 622 623 624 625
class EndOfBlock(Exception): pass

class BlockFinder:
    """Provide a tokeneater() method to detect the end of a code block."""
    def __init__(self):
        self.indent = 0
626
        self.islambda = False
627 628
        self.started = False
        self.passline = False
629
        self.last = 1
630

631
    def tokeneater(self, type, token, srowcol, erowcol, line):
632
        if not self.started:
633
            # look for the first "def", "class" or "lambda"
634
            if token in ("def", "class", "lambda"):
635 636
                if token == "lambda":
                    self.islambda = True
637
                self.started = True
638
            self.passline = True    # skip to the end of the line
639
        elif type == tokenize.NEWLINE:
640
            self.passline = False   # stop skipping when a NEWLINE is seen
641
            self.last = srowcol[0]
642 643
            if self.islambda:       # lambdas always end at the first NEWLINE
                raise EndOfBlock
644 645
        elif self.passline:
            pass
646
        elif type == tokenize.INDENT:
647
            self.indent = self.indent + 1
648
            self.passline = True
649
        elif type == tokenize.DEDENT:
650
            self.indent = self.indent - 1
651 652 653 654 655 656 657 658 659
            # the end of matching indent/dedent pairs end a block
            # (note that this only works for "def"/"class" blocks,
            #  not e.g. for "if: else:" or "try: finally:" blocks)
            if self.indent <= 0:
                raise EndOfBlock
        elif self.indent == 0 and type not in (tokenize.COMMENT, tokenize.NL):
            # any other token on the same indentation level end the previous
            # block as well, except the pseudo-tokens COMMENT and NL.
            raise EndOfBlock
660 661 662

def getblock(lines):
    """Extract the block of code at the top of the given list of lines."""
663
    blockfinder = BlockFinder()
664
    try:
665 666 667
        tokens = tokenize.generate_tokens(iter(lines).__next__)
        for _token in tokens:
            blockfinder.tokeneater(*_token)
668 669 670
    except (EndOfBlock, IndentationError):
        pass
    return lines[:blockfinder.last]
671 672 673 674 675 676 677 678 679 680 681 682 683 684 685 686 687 688 689 690 691

def getsourcelines(object):
    """Return a list of source lines and starting line number for an object.

    The argument may be a module, class, method, function, traceback, frame,
    or code object.  The source code is returned as a list of the lines
    corresponding to the object and the line number indicates where in the
    original source file the first line of code was found.  An IOError is
    raised if the source code cannot be retrieved."""
    lines, lnum = findsource(object)

    if ismodule(object): return lines, 0
    else: return getblock(lines[lnum:]), lnum + 1

def getsource(object):
    """Return the text of the source code for an object.

    The argument may be a module, class, method, function, traceback, frame,
    or code object.  The source code is returned as a single string.  An
    IOError is raised if the source code cannot be retrieved."""
    lines, lnum = getsourcelines(object)
692
    return ''.join(lines)
693 694 695 696 697

# --------------------------------------------------- class tree extraction
def walktree(classes, children, parent):
    """Recursive helper function for getclasstree()."""
    results = []
698
    classes.sort(key=attrgetter('__module__', '__name__'))
699 700
    for c in classes:
        results.append((c, c.__bases__))
701
        if c in children:
702 703 704 705 706 707 708 709 710 711 712 713 714 715 716 717 718
            results.append(walktree(children[c], children, c))
    return results

def getclasstree(classes, unique=0):
    """Arrange the given list of classes into a hierarchy of nested lists.

    Where a nested list appears, it contains classes derived from the class
    whose entry immediately precedes the list.  Each entry is a 2-tuple
    containing a class and a tuple of its base classes.  If the 'unique'
    argument is true, exactly one entry appears in the returned structure
    for each class in the given list.  Otherwise, classes using multiple
    inheritance and their descendants will appear multiple times."""
    children = {}
    roots = []
    for c in classes:
        if c.__bases__:
            for parent in c.__bases__:
719
                if not parent in children:
720 721 722 723 724
                    children[parent] = []
                children[parent].append(c)
                if unique and parent in classes: break
        elif c not in roots:
            roots.append(c)
725
    for parent in children:
726 727 728 729 730
        if parent not in classes:
            roots.append(parent)
    return walktree(roots, children, None)

# ------------------------------------------------ argument list extraction
731 732
Arguments = namedtuple('Arguments', 'args, varargs, varkw')

733 734 735
def getargs(co):
    """Get information about the arguments accepted by a code object.

736
    Three things are returned: (args, varargs, varkw), where
737
    'args' is the list of argument names, possibly containing nested
738 739 740
    lists. Keyword-only arguments are appended. 'varargs' and 'varkw'
    are the names of the * and ** arguments or None."""
    args, varargs, kwonlyargs, varkw = _getfullargs(co)
741
    return Arguments(args + kwonlyargs, varargs, varkw)
742 743 744 745 746 747 748 749

def _getfullargs(co):
    """Get information about the arguments accepted by a code object.

    Four things are returned: (args, varargs, kwonlyargs, varkw), where
    'args' and 'kwonlyargs' are lists of argument names (with 'args'
    possibly containing nested lists), and 'varargs' and 'varkw' are the
    names of the * and ** arguments or None."""
750 751 752

    if not iscode(co):
        raise TypeError('arg is not a code object')
753 754 755

    nargs = co.co_argcount
    names = co.co_varnames
756
    nkwargs = co.co_kwonlyargcount
757
    args = list(names[:nargs])
758
    kwonlyargs = list(names[nargs:nargs+nkwargs])
759 760
    step = 0

761
    nargs += nkwargs
762 763 764 765 766 767 768
    varargs = None
    if co.co_flags & CO_VARARGS:
        varargs = co.co_varnames[nargs]
        nargs = nargs + 1
    varkw = None
    if co.co_flags & CO_VARKEYWORDS:
        varkw = co.co_varnames[nargs]
769
    return args, varargs, kwonlyargs, varkw
770

771 772 773

ArgSpec = namedtuple('ArgSpec', 'args varargs keywords defaults')

774 775 776 777 778
def getargspec(func):
    """Get the names and default values of a function's arguments.

    A tuple of four things is returned: (args, varargs, varkw, defaults).
    'args' is a list of the argument names (it may contain nested lists).
779
    'args' will include keyword-only argument names.
780
    'varargs' and 'varkw' are the names of the * and ** arguments or None.
781
    'defaults' is an n-tuple of the default values of the last n arguments.
782

783 784 785 786 787 788 789 790
    Use the getfullargspec() API for Python-3000 code, as annotations
    and keyword arguments are supported. getargspec() will raise ValueError
    if the func has either annotations or keyword arguments.
    """

    args, varargs, varkw, defaults, kwonlyargs, kwonlydefaults, ann = \
        getfullargspec(func)
    if kwonlyargs or ann:
791 792
        raise ValueError("Function has keyword-only arguments or annotations"
                         ", use getfullargspec() API which can support them")
793 794 795
    return ArgSpec(args, varargs, varkw, defaults)

FullArgSpec = namedtuple('FullArgSpec',
796
    'args, varargs, varkw, defaults, kwonlyargs, kwonlydefaults, annotations')
797 798 799 800

def getfullargspec(func):
    """Get the names and default values of a function's arguments.

801 802
    A tuple of seven things is returned:
    (args, varargs, varkw, defaults, kwonlyargs, kwonlydefaults annotations).
803 804 805 806 807 808
    'args' is a list of the argument names (it may contain nested lists).
    'varargs' and 'varkw' are the names of the * and ** arguments or None.
    'defaults' is an n-tuple of the default values of the last n arguments.
    'kwonlyargs' is a list of keyword-only argument names.
    'kwonlydefaults' is a dictionary mapping names from kwonlyargs to defaults.
    'annotations' is a dictionary mapping argument names to annotations.
809

810
    The first four items in the tuple correspond to getargspec().
811 812 813
    """

    if ismethod(func):
814
        func = func.__func__
815 816
    if not isfunction(func):
        raise TypeError('arg is not a Python function')
817
    args, varargs, kwonlyargs, varkw = _getfullargs(func.__code__)
818
    return FullArgSpec(args, varargs, varkw, func.__defaults__,
819
            kwonlyargs, func.__kwdefaults__, func.__annotations__)
820

821 822
ArgInfo = namedtuple('ArgInfo', 'args varargs keywords locals')

823 824 825 826 827 828 829 830
def getargvalues(frame):
    """Get information about arguments passed into a particular frame.

    A tuple of four things is returned: (args, varargs, varkw, locals).
    'args' is a list of the argument names (it may contain nested lists).
    'varargs' and 'varkw' are the names of the * and ** arguments or None.
    'locals' is the locals dictionary of the given frame."""
    args, varargs, varkw = getargs(frame.f_code)
Benjamin Peterson's avatar
Benjamin Peterson committed
831
    return ArgInfo(args, varargs, varkw, frame.f_locals)
832 833 834 835 836

def joinseq(seq):
    if len(seq) == 1:
        return '(' + seq[0] + ',)'
    else:
837
        return '(' + ', '.join(seq) + ')'
838 839 840

def strseq(object, convert, join=joinseq):
    """Recursively walk a sequence, stringifying each element."""
841
    if type(object) in (list, tuple):
842 843 844 845
        return join(map(lambda o, c=convert, j=join: strseq(o, c, j), object))
    else:
        return convert(object)

846 847
def formatannotation(annotation, base_module=None):
    if isinstance(annotation, type):
848
        if annotation.__module__ in ('builtins', base_module):
849 850 851
            return annotation.__name__
        return annotation.__module__+'.'+annotation.__name__
    return repr(annotation)
852

853
def formatannotationrelativeto(object):
854 855 856 857
    module = getattr(object, '__module__', None)
    def _formatannotation(annotation):
        return formatannotation(annotation, module)
    return _formatannotation
858

859
def formatargspec(args, varargs=None, varkw=None, defaults=None,
860
                  kwonlyargs=(), kwonlydefaults={}, annotations={},
861 862 863 864
                  formatarg=str,
                  formatvarargs=lambda name: '*' + name,
                  formatvarkw=lambda name: '**' + name,
                  formatvalue=lambda value: '=' + repr(value),
865 866
                  formatreturns=lambda text: ' -> ' + text,
                  formatannotation=formatannotation,
867
                  join=joinseq):
868
    """Format an argument spec from the values returned by getargspec
869 870 871 872 873 874 875 876 877 878 879 880
    or getfullargspec.

    The first seven arguments are (args, varargs, varkw, defaults,
    kwonlyargs, kwonlydefaults, annotations).  The other five arguments
    are the corresponding optional formatting functions that are called to
    turn names and values into strings.  The last argument is an optional
    function to format the sequence of arguments."""
    def formatargandannotation(arg):
        result = formatarg(arg)
        if arg in annotations:
            result += ': ' + formatannotation(annotations[arg])
        return result
881 882 883
    specs = []
    if defaults:
        firstdefault = len(args) - len(defaults)
884 885
    for i, arg in enumerate(args):
        spec = strseq(arg, formatargandannotation, join)
886 887 888
        if defaults and i >= firstdefault:
            spec = spec + formatvalue(defaults[i - firstdefault])
        specs.append(spec)
889
    if varargs is not None:
890 891 892 893 894 895 896
        specs.append(formatvarargs(formatargandannotation(varargs)))
    else:
        if kwonlyargs:
            specs.append('*')
    if kwonlyargs:
        for kwonlyarg in kwonlyargs:
            spec = formatargandannotation(kwonlyarg)
897
            if kwonlydefaults and kwonlyarg in kwonlydefaults:
898 899
                spec += formatvalue(kwonlydefaults[kwonlyarg])
            specs.append(spec)
900
    if varkw is not None:
901
        specs.append(formatvarkw(formatargandannotation(varkw)))
902
    result = '(' + ', '.join(specs) + ')'
903 904 905
    if 'return' in annotations:
        result += formatreturns(formatannotation(annotations['return']))
    return result
906 907 908 909 910 911 912 913 914 915 916 917 918 919 920 921 922 923 924 925 926 927 928

def formatargvalues(args, varargs, varkw, locals,
                    formatarg=str,
                    formatvarargs=lambda name: '*' + name,
                    formatvarkw=lambda name: '**' + name,
                    formatvalue=lambda value: '=' + repr(value),
                    join=joinseq):
    """Format an argument spec from the 4 values returned by getargvalues.

    The first four arguments are (args, varargs, varkw, locals).  The
    next four arguments are the corresponding optional formatting functions
    that are called to turn names and values into strings.  The ninth
    argument is an optional function to format the sequence of arguments."""
    def convert(name, locals=locals,
                formatarg=formatarg, formatvalue=formatvalue):
        return formatarg(name) + formatvalue(locals[name])
    specs = []
    for i in range(len(args)):
        specs.append(strseq(args[i], convert, join))
    if varargs:
        specs.append(formatvarargs(varargs) + formatvalue(locals[varargs]))
    if varkw:
        specs.append(formatvarkw(varkw) + formatvalue(locals[varkw]))
929
    return '(' + ', '.join(specs) + ')'
930 931

# -------------------------------------------------- stack frame extraction
932 933 934

Traceback = namedtuple('Traceback', 'filename lineno function code_context index')

935 936 937 938 939 940 941 942 943
def getframeinfo(frame, context=1):
    """Get information about a frame or traceback object.

    A tuple of five things is returned: the filename, the line number of
    the current line, the function name, a list of lines of context from
    the source code, and the index of the current line within that list.
    The optional second argument specifies the number of lines of context
    to return, which are centered around the current line."""
    if istraceback(frame):
944
        lineno = frame.tb_lineno
945
        frame = frame.tb_frame
946 947
    else:
        lineno = frame.f_lineno
948
    if not isframe(frame):
949
        raise TypeError('arg is not a frame or traceback object')
950

951
    filename = getsourcefile(frame) or getfile(frame)
952
    if context > 0:
953
        start = lineno - 1 - context//2
954 955
        try:
            lines, lnum = findsource(frame)
956 957 958
        except IOError:
            lines = index = None
        else:
959
            start = max(start, 1)
960
            start = max(0, min(start, len(lines) - context))
961
            lines = lines[start:start+context]
962
            index = lineno - 1 - start
963 964 965
    else:
        lines = index = None

966
    return Traceback(filename, lineno, frame.f_code.co_name, lines, index)
967 968 969

def getlineno(frame):
    """Get the line number from a frame object, allowing for optimization."""
Michael W. Hudson's avatar
Michael W. Hudson committed
970 971
    # FrameType.f_lineno is now a descriptor that grovels co_lnotab
    return frame.f_lineno
972 973 974 975 976 977 978 979 980 981 982 983 984 985 986 987 988 989 990 991 992 993 994

def getouterframes(frame, context=1):
    """Get a list of records for a frame and all higher (calling) frames.

    Each record contains a frame object, filename, line number, function
    name, a list of lines of context, and index within the context."""
    framelist = []
    while frame:
        framelist.append((frame,) + getframeinfo(frame, context))
        frame = frame.f_back
    return framelist

def getinnerframes(tb, context=1):
    """Get a list of records for a traceback's frame and all lower frames.

    Each record contains a frame object, filename, line number, function
    name, a list of lines of context, and index within the context."""
    framelist = []
    while tb:
        framelist.append((tb.tb_frame,) + getframeinfo(tb, context))
        tb = tb.tb_next
    return framelist

995
currentframe = sys._getframe
996 997 998

def stack(context=1):
    """Return a list of records for the stack above the caller's frame."""
999
    return getouterframes(sys._getframe(1), context)
1000 1001

def trace(context=1):
Tim Peters's avatar
Tim Peters committed
1002
    """Return a list of records for the stack below the current exception."""
1003
    return getinnerframes(sys.exc_info()[2], context)