~ubuntu-branches/ubuntu/karmic/pypy/karmic

« back to all changes in this revision

Viewing changes to lib-python/2.4.1/inspect.py

  • Committer: Bazaar Package Importer
  • Author(s): Alexandre Fayolle
  • Date: 2007-04-13 09:33:09 UTC
  • Revision ID: james.westby@ubuntu.com-20070413093309-yoojh4jcoocu2krz
Tags: upstream-1.0.0
ImportĀ upstreamĀ versionĀ 1.0.0

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
# -*- coding: iso-8859-1 -*-
 
2
"""Get useful information from live Python objects.
 
3
 
 
4
This module encapsulates the interface provided by the internal special
 
5
attributes (func_*, co_*, im_*, tb_*, etc.) in a friendlier fashion.
 
6
It also provides some help for examining source code and class layout.
 
7
 
 
8
Here are some of the useful functions provided by this module:
 
9
 
 
10
    ismodule(), isclass(), ismethod(), isfunction(), istraceback(),
 
11
        isframe(), iscode(), isbuiltin(), isroutine() - check object types
 
12
    getmembers() - get members of an object that satisfy a given condition
 
13
 
 
14
    getfile(), getsourcefile(), getsource() - find an object's source code
 
15
    getdoc(), getcomments() - get documentation on an object
 
16
    getmodule() - determine the module that an object came from
 
17
    getclasstree() - arrange classes so as to represent their hierarchy
 
18
 
 
19
    getargspec(), getargvalues() - get info about function arguments
 
20
    formatargspec(), formatargvalues() - format an argument spec
 
21
    getouterframes(), getinnerframes() - get info about frames
 
22
    currentframe() - get the current stack frame
 
23
    stack(), trace() - get info about frames on the stack or in a traceback
 
24
"""
 
25
 
 
26
# This module is in the public domain.  No warranties.
 
27
 
 
28
__author__ = 'Ka-Ping Yee <ping@lfw.org>'
 
29
__date__ = '1 Jan 2001'
 
30
 
 
31
import sys, os, types, string, re, dis, imp, tokenize, linecache
 
32
 
 
33
# ----------------------------------------------------------- type-checking
 
34
def ismodule(object):
 
35
    """Return true if the object is a module.
 
36
 
 
37
    Module objects provide these attributes:
 
38
        __doc__         documentation string
 
39
        __file__        filename (missing for built-in modules)"""
 
40
    return isinstance(object, types.ModuleType)
 
41
 
 
42
def isclass(object):
 
43
    """Return true if the object is a class.
 
44
 
 
45
    Class objects provide these attributes:
 
46
        __doc__         documentation string
 
47
        __module__      name of module in which this class was defined"""
 
48
    return isinstance(object, types.ClassType) or hasattr(object, '__bases__')
 
49
 
 
50
def ismethod(object):
 
51
    """Return true if the object is an instance method.
 
52
 
 
53
    Instance method objects provide these attributes:
 
54
        __doc__         documentation string
 
55
        __name__        name with which this method was defined
 
56
        im_class        class object in which this method belongs
 
57
        im_func         function object containing implementation of method
 
58
        im_self         instance to which this method is bound, or None"""
 
59
    return isinstance(object, types.MethodType)
 
60
 
 
61
def ismethoddescriptor(object):
 
62
    """Return true if the object is a method descriptor.
 
63
 
 
64
    But not if ismethod() or isclass() or isfunction() are true.
 
65
 
 
66
    This is new in Python 2.2, and, for example, is true of int.__add__.
 
67
    An object passing this test has a __get__ attribute but not a __set__
 
68
    attribute, but beyond that the set of attributes varies.  __name__ is
 
69
    usually sensible, and __doc__ often is.
 
70
 
 
71
    Methods implemented via descriptors that also pass one of the other
 
72
    tests return false from the ismethoddescriptor() test, simply because
 
73
    the other tests promise more -- you can, e.g., count on having the
 
74
    im_func attribute (etc) when an object passes ismethod()."""
 
75
    return (hasattr(object, "__get__")
 
76
            and not hasattr(object, "__set__") # else it's a data descriptor
 
77
            and not ismethod(object)           # mutual exclusion
 
78
            and not isfunction(object)
 
79
            and not isclass(object))
 
80
 
 
81
def isdatadescriptor(object):
 
82
    """Return true if the object is a data descriptor.
 
83
 
 
84
    Data descriptors have both a __get__ and a __set__ attribute.  Examples are
 
85
    properties (defined in Python) and getsets and members (defined in C).
 
86
    Typically, data descriptors will also have __name__ and __doc__ attributes
 
87
    (properties, getsets, and members have both of these attributes), but this
 
88
    is not guaranteed."""
 
89
    return (hasattr(object, "__set__") and hasattr(object, "__get__"))
 
90
 
 
91
def isfunction(object):
 
92
    """Return true if the object is a user-defined function.
 
93
 
 
94
    Function objects provide these attributes:
 
95
        __doc__         documentation string
 
96
        __name__        name with which this function was defined
 
97
        func_code       code object containing compiled function bytecode
 
98
        func_defaults   tuple of any default values for arguments
 
99
        func_doc        (same as __doc__)
 
100
        func_globals    global namespace in which this function was defined
 
101
        func_name       (same as __name__)"""
 
102
    return isinstance(object, types.FunctionType)
 
103
 
 
104
def istraceback(object):
 
105
    """Return true if the object is a traceback.
 
106
 
 
107
    Traceback objects provide these attributes:
 
108
        tb_frame        frame object at this level
 
109
        tb_lasti        index of last attempted instruction in bytecode
 
110
        tb_lineno       current line number in Python source code
 
111
        tb_next         next inner traceback object (called by this level)"""
 
112
    return isinstance(object, types.TracebackType)
 
113
 
 
114
def isframe(object):
 
115
    """Return true if the object is a frame object.
 
116
 
 
117
    Frame objects provide these attributes:
 
118
        f_back          next outer frame object (this frame's caller)
 
119
        f_builtins      built-in namespace seen by this frame
 
120
        f_code          code object being executed in this frame
 
121
        f_exc_traceback traceback if raised in this frame, or None
 
122
        f_exc_type      exception type if raised in this frame, or None
 
123
        f_exc_value     exception value if raised in this frame, or None
 
124
        f_globals       global namespace seen by this frame
 
125
        f_lasti         index of last attempted instruction in bytecode
 
126
        f_lineno        current line number in Python source code
 
127
        f_locals        local namespace seen by this frame
 
128
        f_restricted    0 or 1 if frame is in restricted execution mode
 
129
        f_trace         tracing function for this frame, or None"""
 
130
    return isinstance(object, types.FrameType)
 
131
 
 
132
def iscode(object):
 
133
    """Return true if the object is a code object.
 
134
 
 
135
    Code objects provide these attributes:
 
136
        co_argcount     number of arguments (not including * or ** args)
 
137
        co_code         string of raw compiled bytecode
 
138
        co_consts       tuple of constants used in the bytecode
 
139
        co_filename     name of file in which this code object was created
 
140
        co_firstlineno  number of first line in Python source code
 
141
        co_flags        bitmap: 1=optimized | 2=newlocals | 4=*arg | 8=**arg
 
142
        co_lnotab       encoded mapping of line numbers to bytecode indices
 
143
        co_name         name with which this code object was defined
 
144
        co_names        tuple of names of local variables
 
145
        co_nlocals      number of local variables
 
146
        co_stacksize    virtual machine stack space required
 
147
        co_varnames     tuple of names of arguments and local variables"""
 
148
    return isinstance(object, types.CodeType)
 
149
 
 
150
def isbuiltin(object):
 
151
    """Return true if the object is a built-in function or method.
 
152
 
 
153
    Built-in functions and methods provide these attributes:
 
154
        __doc__         documentation string
 
155
        __name__        original name of this function or method
 
156
        __self__        instance to which a method is bound, or None"""
 
157
    return isinstance(object, types.BuiltinFunctionType)
 
158
 
 
159
def isroutine(object):
 
160
    """Return true if the object is any kind of function or method."""
 
161
    return (isbuiltin(object)
 
162
            or isfunction(object)
 
163
            or ismethod(object)
 
164
            or ismethoddescriptor(object))
 
165
 
 
166
def getmembers(object, predicate=None):
 
167
    """Return all members of an object as (name, value) pairs sorted by name.
 
168
    Optionally, only return members that satisfy a given predicate."""
 
169
    results = []
 
170
    for key in dir(object):
 
171
        value = getattr(object, key)
 
172
        if not predicate or predicate(value):
 
173
            results.append((key, value))
 
174
    results.sort()
 
175
    return results
 
176
 
 
177
def classify_class_attrs(cls):
 
178
    """Return list of attribute-descriptor tuples.
 
179
 
 
180
    For each name in dir(cls), the return list contains a 4-tuple
 
181
    with these elements:
 
182
 
 
183
        0. The name (a string).
 
184
 
 
185
        1. The kind of attribute this is, one of these strings:
 
186
               'class method'    created via classmethod()
 
187
               'static method'   created via staticmethod()
 
188
               'property'        created via property()
 
189
               'method'          any other flavor of method
 
190
               'data'            not a method
 
191
 
 
192
        2. The class which defined this attribute (a class).
 
193
 
 
194
        3. The object as obtained directly from the defining class's
 
195
           __dict__, not via getattr.  This is especially important for
 
196
           data attributes:  C.data is just a data object, but
 
197
           C.__dict__['data'] may be a data descriptor with additional
 
198
           info, like a __doc__ string.
 
199
    """
 
200
 
 
201
    mro = getmro(cls)
 
202
    names = dir(cls)
 
203
    result = []
 
204
    for name in names:
 
205
        # Get the object associated with the name.
 
206
        # Getting an obj from the __dict__ sometimes reveals more than
 
207
        # using getattr.  Static and class methods are dramatic examples.
 
208
        if name in cls.__dict__:
 
209
            obj = cls.__dict__[name]
 
210
        else:
 
211
            obj = getattr(cls, name)
 
212
 
 
213
        # Figure out where it was defined.
 
214
        homecls = getattr(obj, "__objclass__", None)
 
215
        if homecls is None:
 
216
            # search the dicts.
 
217
            for base in mro:
 
218
                if name in base.__dict__:
 
219
                    homecls = base
 
220
                    break
 
221
 
 
222
        # Get the object again, in order to get it from the defining
 
223
        # __dict__ instead of via getattr (if possible).
 
224
        if homecls is not None and name in homecls.__dict__:
 
225
            obj = homecls.__dict__[name]
 
226
 
 
227
        # Also get the object via getattr.
 
228
        obj_via_getattr = getattr(cls, name)
 
229
 
 
230
        # Classify the object.
 
231
        if isinstance(obj, staticmethod):
 
232
            kind = "static method"
 
233
        elif isinstance(obj, classmethod):
 
234
            kind = "class method"
 
235
        elif isinstance(obj, property):
 
236
            kind = "property"
 
237
        elif (ismethod(obj_via_getattr) or
 
238
              ismethoddescriptor(obj_via_getattr)):
 
239
            kind = "method"
 
240
        else:
 
241
            kind = "data"
 
242
 
 
243
        result.append((name, kind, homecls, obj))
 
244
 
 
245
    return result
 
246
 
 
247
# ----------------------------------------------------------- class helpers
 
248
def _searchbases(cls, accum):
 
249
    # Simulate the "classic class" search order.
 
250
    if cls in accum:
 
251
        return
 
252
    accum.append(cls)
 
253
    for base in cls.__bases__:
 
254
        _searchbases(base, accum)
 
255
 
 
256
def getmro(cls):
 
257
    "Return tuple of base classes (including cls) in method resolution order."
 
258
    if hasattr(cls, "__mro__"):
 
259
        return cls.__mro__
 
260
    else:
 
261
        result = []
 
262
        _searchbases(cls, result)
 
263
        return tuple(result)
 
264
 
 
265
# -------------------------------------------------- source code extraction
 
266
def indentsize(line):
 
267
    """Return the indent size, in spaces, at the start of a line of text."""
 
268
    expline = string.expandtabs(line)
 
269
    return len(expline) - len(string.lstrip(expline))
 
270
 
 
271
def getdoc(object):
 
272
    """Get the documentation string for an object.
 
273
 
 
274
    All tabs are expanded to spaces.  To clean up docstrings that are
 
275
    indented to line up with blocks of code, any whitespace than can be
 
276
    uniformly removed from the second line onwards is removed."""
 
277
    try:
 
278
        doc = object.__doc__
 
279
    except AttributeError:
 
280
        return None
 
281
    if not isinstance(doc, types.StringTypes):
 
282
        return None
 
283
    try:
 
284
        lines = string.split(string.expandtabs(doc), '\n')
 
285
    except UnicodeError:
 
286
        return None
 
287
    else:
 
288
        # Find minimum indentation of any non-blank lines after first line.
 
289
        margin = sys.maxint
 
290
        for line in lines[1:]:
 
291
            content = len(string.lstrip(line))
 
292
            if content:
 
293
                indent = len(line) - content
 
294
                margin = min(margin, indent)
 
295
        # Remove indentation.
 
296
        if lines:
 
297
            lines[0] = lines[0].lstrip()
 
298
        if margin < sys.maxint:
 
299
            for i in range(1, len(lines)): lines[i] = lines[i][margin:]
 
300
        # Remove any trailing or leading blank lines.
 
301
        while lines and not lines[-1]:
 
302
            lines.pop()
 
303
        while lines and not lines[0]:
 
304
            lines.pop(0)
 
305
        return string.join(lines, '\n')
 
306
 
 
307
def getfile(object):
 
308
    """Work out which source or compiled file an object was defined in."""
 
309
    if ismodule(object):
 
310
        if hasattr(object, '__file__'):
 
311
            return object.__file__
 
312
        raise TypeError('arg is a built-in module')
 
313
    if isclass(object):
 
314
        object = sys.modules.get(object.__module__)
 
315
        if hasattr(object, '__file__'):
 
316
            return object.__file__
 
317
        raise TypeError('arg is a built-in class')
 
318
    if ismethod(object):
 
319
        object = object.im_func
 
320
    if isfunction(object):
 
321
        object = object.func_code
 
322
    if istraceback(object):
 
323
        object = object.tb_frame
 
324
    if isframe(object):
 
325
        object = object.f_code
 
326
    if iscode(object):
 
327
        return object.co_filename
 
328
    raise TypeError('arg is not a module, class, method, '
 
329
                    'function, traceback, frame, or code object')
 
330
 
 
331
def getmoduleinfo(path):
 
332
    """Get the module name, suffix, mode, and module type for a given file."""
 
333
    filename = os.path.basename(path)
 
334
    suffixes = map(lambda (suffix, mode, mtype):
 
335
                   (-len(suffix), suffix, mode, mtype), imp.get_suffixes())
 
336
    suffixes.sort() # try longest suffixes first, in case they overlap
 
337
    for neglen, suffix, mode, mtype in suffixes:
 
338
        if filename[neglen:] == suffix:
 
339
            return filename[:neglen], suffix, mode, mtype
 
340
 
 
341
def getmodulename(path):
 
342
    """Return the module name for a given file, or None."""
 
343
    info = getmoduleinfo(path)
 
344
    if info: return info[0]
 
345
 
 
346
def getsourcefile(object):
 
347
    """Return the Python source file an object was defined in, if it exists."""
 
348
    filename = getfile(object)
 
349
    if string.lower(filename[-4:]) in ['.pyc', '.pyo']:
 
350
        filename = filename[:-4] + '.py'
 
351
    for suffix, mode, kind in imp.get_suffixes():
 
352
        if 'b' in mode and string.lower(filename[-len(suffix):]) == suffix:
 
353
            # Looks like a binary file.  We want to only return a text file.
 
354
            return None
 
355
    if os.path.exists(filename):
 
356
        return filename
 
357
 
 
358
def getabsfile(object):
 
359
    """Return an absolute path to the source or compiled file for an object.
 
360
 
 
361
    The idea is for each object to have a unique origin, so this routine
 
362
    normalizes the result as much as possible."""
 
363
    return os.path.normcase(
 
364
        os.path.abspath(getsourcefile(object) or getfile(object)))
 
365
 
 
366
modulesbyfile = {}
 
367
 
 
368
def getmodule(object):
 
369
    """Return the module an object was defined in, or None if not found."""
 
370
    if ismodule(object):
 
371
        return object
 
372
    if hasattr(object, '__module__'):
 
373
        return sys.modules.get(object.__module__)
 
374
    try:
 
375
        file = getabsfile(object)
 
376
    except TypeError:
 
377
        return None
 
378
    if file in modulesbyfile:
 
379
        return sys.modules.get(modulesbyfile[file])
 
380
    for module in sys.modules.values():
 
381
        if hasattr(module, '__file__'):
 
382
            modulesbyfile[
 
383
                os.path.realpath(
 
384
                        getabsfile(module))] = module.__name__
 
385
    if file in modulesbyfile:
 
386
        return sys.modules.get(modulesbyfile[file])
 
387
    main = sys.modules['__main__']
 
388
    if not hasattr(object, '__name__'):
 
389
        return None
 
390
    if hasattr(main, object.__name__):
 
391
        mainobject = getattr(main, object.__name__)
 
392
        if mainobject is object:
 
393
            return main
 
394
    builtin = sys.modules['__builtin__']
 
395
    if hasattr(builtin, object.__name__):
 
396
        builtinobject = getattr(builtin, object.__name__)
 
397
        if builtinobject is object:
 
398
            return builtin
 
399
 
 
400
def findsource(object):
 
401
    """Return the entire source file and starting line number for an object.
 
402
 
 
403
    The argument may be a module, class, method, function, traceback, frame,
 
404
    or code object.  The source code is returned as a list of all the lines
 
405
    in the file and the line number indexes a line in that list.  An IOError
 
406
    is raised if the source code cannot be retrieved."""
 
407
    file = getsourcefile(object) or getfile(object)
 
408
    lines = linecache.getlines(file)
 
409
    if not lines:
 
410
        raise IOError('could not get source code')
 
411
 
 
412
    if ismodule(object):
 
413
        return lines, 0
 
414
 
 
415
    if isclass(object):
 
416
        name = object.__name__
 
417
        pat = re.compile(r'^\s*class\s*' + name + r'\b')
 
418
        for i in range(len(lines)):
 
419
            if pat.match(lines[i]): return lines, i
 
420
        else:
 
421
            raise IOError('could not find class definition')
 
422
 
 
423
    if ismethod(object):
 
424
        object = object.im_func
 
425
    if isfunction(object):
 
426
        object = object.func_code
 
427
    if istraceback(object):
 
428
        object = object.tb_frame
 
429
    if isframe(object):
 
430
        object = object.f_code
 
431
    if iscode(object):
 
432
        if not hasattr(object, 'co_firstlineno'):
 
433
            raise IOError('could not find function definition')
 
434
        lnum = object.co_firstlineno - 1
 
435
        pat = re.compile(r'^(\s*def\s)|(.*(?<!\w)lambda(:|\s))|^(\s*@)')
 
436
        while lnum > 0:
 
437
            if pat.match(lines[lnum]): break
 
438
            lnum = lnum - 1
 
439
        return lines, lnum
 
440
    raise IOError('could not find code object')
 
441
 
 
442
def getcomments(object):
 
443
    """Get lines of comments immediately preceding an object's source code.
 
444
 
 
445
    Returns None when source can't be found.
 
446
    """
 
447
    try:
 
448
        lines, lnum = findsource(object)
 
449
    except (IOError, TypeError):
 
450
        return None
 
451
 
 
452
    if ismodule(object):
 
453
        # Look for a comment block at the top of the file.
 
454
        start = 0
 
455
        if lines and lines[0][:2] == '#!': start = 1
 
456
        while start < len(lines) and string.strip(lines[start]) in ['', '#']:
 
457
            start = start + 1
 
458
        if start < len(lines) and lines[start][:1] == '#':
 
459
            comments = []
 
460
            end = start
 
461
            while end < len(lines) and lines[end][:1] == '#':
 
462
                comments.append(string.expandtabs(lines[end]))
 
463
                end = end + 1
 
464
            return string.join(comments, '')
 
465
 
 
466
    # Look for a preceding block of comments at the same indentation.
 
467
    elif lnum > 0:
 
468
        indent = indentsize(lines[lnum])
 
469
        end = lnum - 1
 
470
        if end >= 0 and string.lstrip(lines[end])[:1] == '#' and \
 
471
            indentsize(lines[end]) == indent:
 
472
            comments = [string.lstrip(string.expandtabs(lines[end]))]
 
473
            if end > 0:
 
474
                end = end - 1
 
475
                comment = string.lstrip(string.expandtabs(lines[end]))
 
476
                while comment[:1] == '#' and indentsize(lines[end]) == indent:
 
477
                    comments[:0] = [comment]
 
478
                    end = end - 1
 
479
                    if end < 0: break
 
480
                    comment = string.lstrip(string.expandtabs(lines[end]))
 
481
            while comments and string.strip(comments[0]) == '#':
 
482
                comments[:1] = []
 
483
            while comments and string.strip(comments[-1]) == '#':
 
484
                comments[-1:] = []
 
485
            return string.join(comments, '')
 
486
 
 
487
class ListReader:
 
488
    """Provide a readline() method to return lines from a list of strings."""
 
489
    def __init__(self, lines):
 
490
        self.lines = lines
 
491
        self.index = 0
 
492
 
 
493
    def readline(self):
 
494
        i = self.index
 
495
        if i < len(self.lines):
 
496
            self.index = i + 1
 
497
            return self.lines[i]
 
498
        else: return ''
 
499
 
 
500
class EndOfBlock(Exception): pass
 
501
 
 
502
class BlockFinder:
 
503
    """Provide a tokeneater() method to detect the end of a code block."""
 
504
    def __init__(self):
 
505
        self.indent = 0
 
506
        self.islambda = False
 
507
        self.started = False
 
508
        self.passline = False
 
509
        self.last = 0
 
510
 
 
511
    def tokeneater(self, type, token, (srow, scol), (erow, ecol), line):
 
512
        if not self.started:
 
513
            if token in ("def", "class", "lambda"):
 
514
                if token == "lambda":
 
515
                    self.islambda = True
 
516
                self.started = True
 
517
            self.passline = True
 
518
        elif type == tokenize.NEWLINE:
 
519
            self.passline = False
 
520
            self.last = srow
 
521
        elif self.passline:
 
522
            pass
 
523
        elif self.islambda:
 
524
            raise EndOfBlock, self.last
 
525
        elif type == tokenize.INDENT:
 
526
            self.indent = self.indent + 1
 
527
            self.passline = True
 
528
        elif type == tokenize.DEDENT:
 
529
            self.indent = self.indent - 1
 
530
            if self.indent == 0:
 
531
                raise EndOfBlock, self.last
 
532
        elif type == tokenize.NAME and scol == 0:
 
533
            raise EndOfBlock, self.last
 
534
 
 
535
def getblock(lines):
 
536
    """Extract the block of code at the top of the given list of lines."""
 
537
    try:
 
538
        tokenize.tokenize(ListReader(lines).readline, BlockFinder().tokeneater)
 
539
    except EndOfBlock, eob:
 
540
        return lines[:eob.args[0]]
 
541
    # Fooling the indent/dedent logic implies a one-line definition
 
542
    return lines[:1]
 
543
 
 
544
def getsourcelines(object):
 
545
    """Return a list of source lines and starting line number for an object.
 
546
 
 
547
    The argument may be a module, class, method, function, traceback, frame,
 
548
    or code object.  The source code is returned as a list of the lines
 
549
    corresponding to the object and the line number indicates where in the
 
550
    original source file the first line of code was found.  An IOError is
 
551
    raised if the source code cannot be retrieved."""
 
552
    lines, lnum = findsource(object)
 
553
 
 
554
    if ismodule(object): return lines, 0
 
555
    else: return getblock(lines[lnum:]), lnum + 1
 
556
 
 
557
def getsource(object):
 
558
    """Return the text of the source code for an object.
 
559
 
 
560
    The argument may be a module, class, method, function, traceback, frame,
 
561
    or code object.  The source code is returned as a single string.  An
 
562
    IOError is raised if the source code cannot be retrieved."""
 
563
    lines, lnum = getsourcelines(object)
 
564
    return string.join(lines, '')
 
565
 
 
566
# --------------------------------------------------- class tree extraction
 
567
def walktree(classes, children, parent):
 
568
    """Recursive helper function for getclasstree()."""
 
569
    results = []
 
570
    classes.sort(key=lambda c: (c.__module__, c.__name__))
 
571
    for c in classes:
 
572
        results.append((c, c.__bases__))
 
573
        if c in children:
 
574
            results.append(walktree(children[c], children, c))
 
575
    return results
 
576
 
 
577
def getclasstree(classes, unique=0):
 
578
    """Arrange the given list of classes into a hierarchy of nested lists.
 
579
 
 
580
    Where a nested list appears, it contains classes derived from the class
 
581
    whose entry immediately precedes the list.  Each entry is a 2-tuple
 
582
    containing a class and a tuple of its base classes.  If the 'unique'
 
583
    argument is true, exactly one entry appears in the returned structure
 
584
    for each class in the given list.  Otherwise, classes using multiple
 
585
    inheritance and their descendants will appear multiple times."""
 
586
    children = {}
 
587
    roots = []
 
588
    for c in classes:
 
589
        if c.__bases__:
 
590
            for parent in c.__bases__:
 
591
                if not parent in children:
 
592
                    children[parent] = []
 
593
                children[parent].append(c)
 
594
                if unique and parent in classes: break
 
595
        elif c not in roots:
 
596
            roots.append(c)
 
597
    for parent in children:
 
598
        if parent not in classes:
 
599
            roots.append(parent)
 
600
    return walktree(roots, children, None)
 
601
 
 
602
# ------------------------------------------------ argument list extraction
 
603
# These constants are from Python's compile.h.
 
604
CO_OPTIMIZED, CO_NEWLOCALS, CO_VARARGS, CO_VARKEYWORDS = 1, 2, 4, 8
 
605
 
 
606
def getargs(co):
 
607
    """Get information about the arguments accepted by a code object.
 
608
 
 
609
    Three things are returned: (args, varargs, varkw), where 'args' is
 
610
    a list of argument names (possibly containing nested lists), and
 
611
    'varargs' and 'varkw' are the names of the * and ** arguments or None."""
 
612
 
 
613
    if not iscode(co):
 
614
        raise TypeError('arg is not a code object')
 
615
 
 
616
    code = co.co_code
 
617
    nargs = co.co_argcount
 
618
    names = co.co_varnames
 
619
    args = list(names[:nargs])
 
620
    step = 0
 
621
 
 
622
    # The following acrobatics are for anonymous (tuple) arguments.
 
623
    for i in range(nargs):
 
624
        if args[i][:1] in ['', '.']:
 
625
            stack, remain, count = [], [], []
 
626
            while step < len(code):
 
627
                op = ord(code[step])
 
628
                step = step + 1
 
629
                if op >= dis.HAVE_ARGUMENT:
 
630
                    opname = dis.opname[op]
 
631
                    value = ord(code[step]) + ord(code[step+1])*256
 
632
                    step = step + 2
 
633
                    if opname in ['UNPACK_TUPLE', 'UNPACK_SEQUENCE']:
 
634
                        remain.append(value)
 
635
                        count.append(value)
 
636
                    elif opname == 'STORE_FAST':
 
637
                        stack.append(names[value])
 
638
 
 
639
                        # Special case for sublists of length 1: def foo((bar))
 
640
                        # doesn't generate the UNPACK_TUPLE bytecode, so if
 
641
                        # `remain` is empty here, we have such a sublist.
 
642
                        if not remain:
 
643
                            stack[0] = [stack[0]]
 
644
                            break
 
645
                        else:
 
646
                            remain[-1] = remain[-1] - 1
 
647
                            while remain[-1] == 0:
 
648
                                remain.pop()
 
649
                                size = count.pop()
 
650
                                stack[-size:] = [stack[-size:]]
 
651
                                if not remain: break
 
652
                                remain[-1] = remain[-1] - 1
 
653
                            if not remain: break
 
654
            args[i] = stack[0]
 
655
 
 
656
    varargs = None
 
657
    if co.co_flags & CO_VARARGS:
 
658
        varargs = co.co_varnames[nargs]
 
659
        nargs = nargs + 1
 
660
    varkw = None
 
661
    if co.co_flags & CO_VARKEYWORDS:
 
662
        varkw = co.co_varnames[nargs]
 
663
    return args, varargs, varkw
 
664
 
 
665
def getargspec(func):
 
666
    """Get the names and default values of a function's arguments.
 
667
 
 
668
    A tuple of four things is returned: (args, varargs, varkw, defaults).
 
669
    'args' is a list of the argument names (it may contain nested lists).
 
670
    'varargs' and 'varkw' are the names of the * and ** arguments or None.
 
671
    'defaults' is an n-tuple of the default values of the last n arguments.
 
672
    """
 
673
 
 
674
    if ismethod(func):
 
675
        func = func.im_func
 
676
    if not isfunction(func):
 
677
        raise TypeError('arg is not a Python function')
 
678
    args, varargs, varkw = getargs(func.func_code)
 
679
    return args, varargs, varkw, func.func_defaults
 
680
 
 
681
def getargvalues(frame):
 
682
    """Get information about arguments passed into a particular frame.
 
683
 
 
684
    A tuple of four things is returned: (args, varargs, varkw, locals).
 
685
    'args' is a list of the argument names (it may contain nested lists).
 
686
    'varargs' and 'varkw' are the names of the * and ** arguments or None.
 
687
    'locals' is the locals dictionary of the given frame."""
 
688
    args, varargs, varkw = getargs(frame.f_code)
 
689
    return args, varargs, varkw, frame.f_locals
 
690
 
 
691
def joinseq(seq):
 
692
    if len(seq) == 1:
 
693
        return '(' + seq[0] + ',)'
 
694
    else:
 
695
        return '(' + string.join(seq, ', ') + ')'
 
696
 
 
697
def strseq(object, convert, join=joinseq):
 
698
    """Recursively walk a sequence, stringifying each element."""
 
699
    if type(object) in [types.ListType, types.TupleType]:
 
700
        return join(map(lambda o, c=convert, j=join: strseq(o, c, j), object))
 
701
    else:
 
702
        return convert(object)
 
703
 
 
704
def formatargspec(args, varargs=None, varkw=None, defaults=None,
 
705
                  formatarg=str,
 
706
                  formatvarargs=lambda name: '*' + name,
 
707
                  formatvarkw=lambda name: '**' + name,
 
708
                  formatvalue=lambda value: '=' + repr(value),
 
709
                  join=joinseq):
 
710
    """Format an argument spec from the 4 values returned by getargspec.
 
711
 
 
712
    The first four arguments are (args, varargs, varkw, defaults).  The
 
713
    other four arguments are the corresponding optional formatting functions
 
714
    that are called to turn names and values into strings.  The ninth
 
715
    argument is an optional function to format the sequence of arguments."""
 
716
    specs = []
 
717
    if defaults:
 
718
        firstdefault = len(args) - len(defaults)
 
719
    for i in range(len(args)):
 
720
        spec = strseq(args[i], formatarg, join)
 
721
        if defaults and i >= firstdefault:
 
722
            spec = spec + formatvalue(defaults[i - firstdefault])
 
723
        specs.append(spec)
 
724
    if varargs is not None:
 
725
        specs.append(formatvarargs(varargs))
 
726
    if varkw is not None:
 
727
        specs.append(formatvarkw(varkw))
 
728
    return '(' + string.join(specs, ', ') + ')'
 
729
 
 
730
def formatargvalues(args, varargs, varkw, locals,
 
731
                    formatarg=str,
 
732
                    formatvarargs=lambda name: '*' + name,
 
733
                    formatvarkw=lambda name: '**' + name,
 
734
                    formatvalue=lambda value: '=' + repr(value),
 
735
                    join=joinseq):
 
736
    """Format an argument spec from the 4 values returned by getargvalues.
 
737
 
 
738
    The first four arguments are (args, varargs, varkw, locals).  The
 
739
    next four arguments are the corresponding optional formatting functions
 
740
    that are called to turn names and values into strings.  The ninth
 
741
    argument is an optional function to format the sequence of arguments."""
 
742
    def convert(name, locals=locals,
 
743
                formatarg=formatarg, formatvalue=formatvalue):
 
744
        return formatarg(name) + formatvalue(locals[name])
 
745
    specs = []
 
746
    for i in range(len(args)):
 
747
        specs.append(strseq(args[i], convert, join))
 
748
    if varargs:
 
749
        specs.append(formatvarargs(varargs) + formatvalue(locals[varargs]))
 
750
    if varkw:
 
751
        specs.append(formatvarkw(varkw) + formatvalue(locals[varkw]))
 
752
    return '(' + string.join(specs, ', ') + ')'
 
753
 
 
754
# -------------------------------------------------- stack frame extraction
 
755
def getframeinfo(frame, context=1):
 
756
    """Get information about a frame or traceback object.
 
757
 
 
758
    A tuple of five things is returned: the filename, the line number of
 
759
    the current line, the function name, a list of lines of context from
 
760
    the source code, and the index of the current line within that list.
 
761
    The optional second argument specifies the number of lines of context
 
762
    to return, which are centered around the current line."""
 
763
    if istraceback(frame):
 
764
        lineno = frame.tb_lineno
 
765
        frame = frame.tb_frame
 
766
    else:
 
767
        lineno = frame.f_lineno
 
768
    if not isframe(frame):
 
769
        raise TypeError('arg is not a frame or traceback object')
 
770
 
 
771
    filename = getsourcefile(frame) or getfile(frame)
 
772
    if context > 0:
 
773
        start = lineno - 1 - context//2
 
774
        try:
 
775
            lines, lnum = findsource(frame)
 
776
        except IOError:
 
777
            lines = index = None
 
778
        else:
 
779
            start = max(start, 1)
 
780
            start = max(0, min(start, len(lines) - context))
 
781
            lines = lines[start:start+context]
 
782
            index = lineno - 1 - start
 
783
    else:
 
784
        lines = index = None
 
785
 
 
786
    return (filename, lineno, frame.f_code.co_name, lines, index)
 
787
 
 
788
def getlineno(frame):
 
789
    """Get the line number from a frame object, allowing for optimization."""
 
790
    # FrameType.f_lineno is now a descriptor that grovels co_lnotab
 
791
    return frame.f_lineno
 
792
 
 
793
def getouterframes(frame, context=1):
 
794
    """Get a list of records for a frame and all higher (calling) frames.
 
795
 
 
796
    Each record contains a frame object, filename, line number, function
 
797
    name, a list of lines of context, and index within the context."""
 
798
    framelist = []
 
799
    while frame:
 
800
        framelist.append((frame,) + getframeinfo(frame, context))
 
801
        frame = frame.f_back
 
802
    return framelist
 
803
 
 
804
def getinnerframes(tb, context=1):
 
805
    """Get a list of records for a traceback's frame and all lower frames.
 
806
 
 
807
    Each record contains a frame object, filename, line number, function
 
808
    name, a list of lines of context, and index within the context."""
 
809
    framelist = []
 
810
    while tb:
 
811
        framelist.append((tb.tb_frame,) + getframeinfo(tb, context))
 
812
        tb = tb.tb_next
 
813
    return framelist
 
814
 
 
815
currentframe = sys._getframe
 
816
 
 
817
def stack(context=1):
 
818
    """Return a list of records for the stack above the caller's frame."""
 
819
    return getouterframes(sys._getframe(1), context)
 
820
 
 
821
def trace(context=1):
 
822
    """Return a list of records for the stack below the current exception."""
 
823
    return getinnerframes(sys.exc_info()[2], context)