inspect.py 38.8 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 abc import ABCMeta
43
from operator import attrgetter
44
from collections import namedtuple
Christian Heimes's avatar
Christian Heimes committed
45 46 47
# 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
48

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

52 53 54 55 56 57 58
# ----------------------------------------------------------- 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)"""
59
    return isinstance(object, types.ModuleType)
60 61 62 63 64 65 66

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"""
67
    return isinstance(object, type) or hasattr(object, '__bases__')
68 69 70 71 72 73 74

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
75 76
        __func__        function object containing implementation of method
        __self__        instance to which this method is bound"""
77
    return isinstance(object, types.MethodType)
78

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

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

    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.

89 90 91
    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
92
    __func__ attribute (etc) when an object passes ismethod()."""
93 94 95
    return (hasattr(object, "__get__")
            and not hasattr(object, "__set__") # else it's a data descriptor
            and not ismethod(object)           # mutual exclusion
96
            and not isfunction(object)
97 98
            and not isclass(object))

99 100 101 102 103 104 105 106 107 108
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__"))

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 142
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

143 144 145 146 147 148
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
149 150 151 152 153
        __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"""
154
    return isinstance(object, types.FunctionType)
155

Christian Heimes's avatar
Christian Heimes committed
156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182
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."""
    if (isfunction(object) or ismethod(object)) and \
        object.__code__.co_flags & CO_GENERATOR:
        return True

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)

183 184 185 186 187 188 189 190
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)"""
191
    return isinstance(object, types.TracebackType)
192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207

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_exc_traceback traceback if raised in this frame, or None
        f_exc_type      exception type if raised in this frame, or None
        f_exc_value     exception value if raised in this frame, or None
        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"""
208
    return isinstance(object, types.FrameType)
209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225

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"""
226
    return isinstance(object, types.CodeType)
227 228 229 230 231 232 233 234

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"""
235
    return isinstance(object, types.BuiltinFunctionType)
236 237 238

def isroutine(object):
    """Return true if the object is any kind of function or method."""
239 240 241 242
    return (isbuiltin(object)
            or isfunction(object)
            or ismethod(object)
            or ismethoddescriptor(object))
243

Christian Heimes's avatar
Christian Heimes committed
244 245 246 247
def isgenerator(object):
    """Return true if the object is a generator object."""
    return isinstance(object, types.GeneratorType)

248 249 250 251
def isabstract(object):
    """Return true if the object is an abstract base class (ABC)."""
    return object.__flags__ & TPFLAGS_IS_ABSTRACT

252 253 254 255 256 257 258 259 260 261 262
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):
        value = getattr(object, key)
        if not predicate or predicate(value):
            results.append((key, value))
    results.sort()
    return results

263 264
Attribute = namedtuple('Attribute', 'name kind defining_class object')

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 302 303
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:
304
            # search the dicts.
305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324
            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"
325
        elif (isfunction(obj_via_getattr) or
326 327 328 329 330
              ismethoddescriptor(obj_via_getattr)):
            kind = "method"
        else:
            kind = "data"

331
        result.append(Attribute(name, kind, homecls, obj))
332 333 334

    return result

335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352
# ----------------------------------------------------------- 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)

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

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."""
365 366 367 368
    try:
        doc = object.__doc__
    except AttributeError:
        return None
369
    if not isinstance(doc, str):
370 371
        return None
    try:
372
        lines = doc.expandtabs().split('\n')
373 374 375
    except UnicodeError:
        return None
    else:
Ka-Ping Yee's avatar
Ka-Ping Yee committed
376
        # Find minimum indentation of any non-blank lines after first line.
377
        margin = sys.maxsize
378
        for line in lines[1:]:
379
            content = len(line.lstrip())
Ka-Ping Yee's avatar
Ka-Ping Yee committed
380 381 382 383 384 385
            if content:
                indent = len(line) - content
                margin = min(margin, indent)
        # Remove indentation.
        if lines:
            lines[0] = lines[0].lstrip()
386
        if margin < sys.maxsize:
387
            for i in range(1, len(lines)): lines[i] = lines[i][margin:]
Ka-Ping Yee's avatar
Ka-Ping Yee committed
388 389 390 391 392
        # Remove any trailing or leading blank lines.
        while lines and not lines[-1]:
            lines.pop()
        while lines and not lines[0]:
            lines.pop(0)
393
        return '\n'.join(lines)
394 395

def getfile(object):
396
    """Work out which source or compiled file an object was defined in."""
397 398 399
    if ismodule(object):
        if hasattr(object, '__file__'):
            return object.__file__
400
        raise TypeError('arg is a built-in module')
401
    if isclass(object):
402
        object = sys.modules.get(object.__module__)
403 404
        if hasattr(object, '__file__'):
            return object.__file__
405
        raise TypeError('arg is a built-in class')
406
    if ismethod(object):
407
        object = object.__func__
408
    if isfunction(object):
409
        object = object.__code__
410 411 412 413 414 415
    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
416
    raise TypeError('arg is not a module, class, method, '
417
                    'function, traceback, frame, or code object')
418

419 420
ModuleInfo = namedtuple('ModuleInfo', 'name suffix mode module_type')

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

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

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

451
def getabsfile(object, _filename=None):
452
    """Return an absolute path to the source or compiled file for an object.
453

454 455
    The idea is for each object to have a unique origin, so this routine
    normalizes the result as much as possible."""
456 457 458
    if _filename is None:
        _filename = getsourcefile(object) or getfile(object)
    return os.path.normcase(os.path.abspath(_filename))
459

460
modulesbyfile = {}
461
_filesbymodname = {}
462

463
def getmodule(object, _filename=None):
464
    """Return the module an object was defined in, or None if not found."""
465 466
    if ismodule(object):
        return object
467
    if hasattr(object, '__module__'):
Ka-Ping Yee's avatar
Ka-Ping Yee committed
468
        return sys.modules.get(object.__module__)
469 470 471 472
    # 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
473
    try:
474
        file = getabsfile(object, _filename)
475 476
    except TypeError:
        return None
477
    if file in modulesbyfile:
478
        return sys.modules.get(modulesbyfile[file])
479 480 481
    # 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():
482
        if ismodule(module) and hasattr(module, '__file__'):
483 484 485 486 487
            f = module.__file__
            if f == _filesbymodname.get(modname, None):
                # Have already mapped this module, so skip it
                continue
            _filesbymodname[modname] = f
488
            f = getabsfile(module)
489
            # Always map to the name the module knows itself by
490 491
            modulesbyfile[f] = modulesbyfile[
                os.path.realpath(f)] = module.__name__
492
    if file in modulesbyfile:
493
        return sys.modules.get(modulesbyfile[file])
494
    # Check the main module
495
    main = sys.modules['__main__']
496 497
    if not hasattr(object, '__name__'):
        return None
498
    if hasattr(main, object.__name__):
499
        mainobject = getattr(main, object.__name__)
500 501
        if mainobject is object:
            return main
502
    # Check builtins
503
    builtin = sys.modules['builtins']
504
    if hasattr(builtin, object.__name__):
505
        builtinobject = getattr(builtin, object.__name__)
506 507
        if builtinobject is object:
            return builtin
508 509 510 511 512 513 514 515

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."""
516
    file = getsourcefile(object) or getfile(object)
517
    module = getmodule(object, file)
518 519 520 521
    if module:
        lines = linecache.getlines(file, module.__dict__)
    else:
        lines = linecache.getlines(file)
522
    if not lines:
523
        raise IOError('could not get source code')
524 525 526 527 528 529

    if ismodule(object):
        return lines, 0

    if isclass(object):
        name = object.__name__
530 531 532 533 534
        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 = []
535
        for i in range(len(lines)):
536 537 538 539 540 541 542 543 544 545 546 547
            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]
548 549
        else:
            raise IOError('could not find class definition')
550 551

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

def getcomments(object):
571 572 573 574 575 576 577 578
    """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
579 580 581 582

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

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

615 616 617 618 619 620
class EndOfBlock(Exception): pass

class BlockFinder:
    """Provide a tokeneater() method to detect the end of a code block."""
    def __init__(self):
        self.indent = 0
621
        self.islambda = False
622 623
        self.started = False
        self.passline = False
624
        self.last = 1
625

626
    def tokeneater(self, type, token, srowcol, erowcol, line):
627
        if not self.started:
628
            # look for the first "def", "class" or "lambda"
629
            if token in ("def", "class", "lambda"):
630 631
                if token == "lambda":
                    self.islambda = True
632
                self.started = True
633
            self.passline = True    # skip to the end of the line
634
        elif type == tokenize.NEWLINE:
635
            self.passline = False   # stop skipping when a NEWLINE is seen
636
            self.last = srowcol[0]
637 638
            if self.islambda:       # lambdas always end at the first NEWLINE
                raise EndOfBlock
639 640
        elif self.passline:
            pass
641
        elif type == tokenize.INDENT:
642
            self.indent = self.indent + 1
643
            self.passline = True
644
        elif type == tokenize.DEDENT:
645
            self.indent = self.indent - 1
646 647 648 649 650 651 652 653 654
            # 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
655 656 657

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

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)
687
    return ''.join(lines)
688 689 690 691 692

# --------------------------------------------------- class tree extraction
def walktree(classes, children, parent):
    """Recursive helper function for getclasstree()."""
    results = []
693
    classes.sort(key=attrgetter('__module__', '__name__'))
694 695
    for c in classes:
        results.append((c, c.__bases__))
696
        if c in children:
697 698 699 700 701 702 703 704 705 706 707 708 709 710 711 712 713
            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__:
714
                if not parent in children:
715 716 717 718 719
                    children[parent] = []
                children[parent].append(c)
                if unique and parent in classes: break
        elif c not in roots:
            roots.append(c)
720
    for parent in children:
721 722 723 724 725
        if parent not in classes:
            roots.append(parent)
    return walktree(roots, children, None)

# ------------------------------------------------ argument list extraction
726 727
Arguments = namedtuple('Arguments', 'args, varargs, varkw')

728 729 730
def getargs(co):
    """Get information about the arguments accepted by a code object.

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

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."""
745 746 747

    if not iscode(co):
        raise TypeError('arg is not a code object')
748 749 750

    nargs = co.co_argcount
    names = co.co_varnames
751
    nkwargs = co.co_kwonlyargcount
752
    args = list(names[:nargs])
753
    kwonlyargs = list(names[nargs:nargs+nkwargs])
754 755
    step = 0

756
    nargs += nkwargs
757 758 759 760 761 762 763
    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]
764
    return args, varargs, kwonlyargs, varkw
765

766 767 768

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

769 770 771 772 773
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).
774
    'args' will include keyword-only argument names.
775
    'varargs' and 'varkw' are the names of the * and ** arguments or None.
776
    'defaults' is an n-tuple of the default values of the last n arguments.
777

778 779 780 781 782 783 784 785
    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:
786 787
        raise ValueError("Function has keyword-only arguments or annotations"
                         ", use getfullargspec() API which can support them")
788 789 790 791
    return ArgSpec(args, varargs, varkw, defaults)

FullArgSpec = namedtuple('FullArgSpec',
    'args, varargs, varkw, defaults, kwonlyargs, kwdefaults, annotations')
792 793 794 795

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

796 797
    A tuple of seven things is returned:
    (args, varargs, varkw, defaults, kwonlyargs, kwonlydefaults annotations).
798 799 800 801 802 803
    '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.
804

805
    The first four items in the tuple correspond to getargspec().
806 807 808
    """

    if ismethod(func):
809
        func = func.__func__
810 811
    if not isfunction(func):
        raise TypeError('arg is not a Python function')
812
    args, varargs, kwonlyargs, varkw = _getfullargs(func.__code__)
813
    return FullArgSpec(args, varargs, varkw, func.__defaults__,
814
            kwonlyargs, func.__kwdefaults__, func.__annotations__)
815

816 817
ArgInfo = namedtuple('ArgInfo', 'args varargs keywords locals')

818 819 820 821 822 823 824 825 826 827 828 829 830 831
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)
    return args, varargs, varkw, frame.f_locals

def joinseq(seq):
    if len(seq) == 1:
        return '(' + seq[0] + ',)'
    else:
832
        return '(' + ', '.join(seq) + ')'
833 834 835

def strseq(object, convert, join=joinseq):
    """Recursively walk a sequence, stringifying each element."""
836
    if type(object) in (list, tuple):
837 838 839 840
        return join(map(lambda o, c=convert, j=join: strseq(o, c, j), object))
    else:
        return convert(object)

841 842
def formatannotation(annotation, base_module=None):
    if isinstance(annotation, type):
843
        if annotation.__module__ in ('builtins', base_module):
844 845 846
            return annotation.__name__
        return annotation.__module__+'.'+annotation.__name__
    return repr(annotation)
847

848
def formatannotationrelativeto(object):
849 850 851 852
    module = getattr(object, '__module__', None)
    def _formatannotation(annotation):
        return formatannotation(annotation, module)
    return _formatannotation
853

854
def formatargspec(args, varargs=None, varkw=None, defaults=None,
855
                  kwonlyargs=(), kwonlydefaults={}, annotations={},
856 857 858 859
                  formatarg=str,
                  formatvarargs=lambda name: '*' + name,
                  formatvarkw=lambda name: '**' + name,
                  formatvalue=lambda value: '=' + repr(value),
860 861
                  formatreturns=lambda text: ' -> ' + text,
                  formatannotation=formatannotation,
862
                  join=joinseq):
863
    """Format an argument spec from the values returned by getargspec
864 865 866 867 868 869 870 871 872 873 874 875
    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
876 877 878 879
    specs = []
    if defaults:
        firstdefault = len(args) - len(defaults)
    for i in range(len(args)):
880
        spec = strseq(args[i], formatargandannotation, join)
881 882 883
        if defaults and i >= firstdefault:
            spec = spec + formatvalue(defaults[i - firstdefault])
        specs.append(spec)
884
    if varargs is not None:
885 886 887 888 889 890 891 892 893 894
        specs.append(formatvarargs(formatargandannotation(varargs)))
    else:
        if kwonlyargs:
            specs.append('*')
    if kwonlyargs:
        for kwonlyarg in kwonlyargs:
            spec = formatargandannotation(kwonlyarg)
            if kwonlyarg in kwonlydefaults:
                spec += formatvalue(kwonlydefaults[kwonlyarg])
            specs.append(spec)
895
    if varkw is not None:
896
        specs.append(formatvarkw(formatargandannotation(varkw)))
897
    result = '(' + ', '.join(specs) + ')'
898 899 900
    if 'return' in annotations:
        result += formatreturns(formatannotation(annotations['return']))
    return result
901 902 903 904 905 906 907 908 909 910 911 912 913 914 915 916 917 918 919 920 921 922 923

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]))
924
    return '(' + ', '.join(specs) + ')'
925 926

# -------------------------------------------------- stack frame extraction
927 928 929

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

930 931 932 933 934 935 936 937 938
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):
939
        lineno = frame.tb_lineno
940
        frame = frame.tb_frame
941 942
    else:
        lineno = frame.f_lineno
943
    if not isframe(frame):
944
        raise TypeError('arg is not a frame or traceback object')
945

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

961
    return Traceback(filename, lineno, frame.f_code.co_name, lines, index)
962 963 964

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

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

990
currentframe = sys._getframe
991 992 993

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

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