1
# -*- coding: iso-8859-1 -*-
2
"""Get useful information from live Python objects.
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.
8
Here are some of the useful functions provided by this module:
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
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
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
26
# This module is in the public domain. No warranties.
28
__author__ = 'Ka-Ping Yee <ping@lfw.org>'
29
__date__ = '1 Jan 2001'
31
import sys, os, types, string, re, dis, imp, tokenize, linecache
33
# ----------------------------------------------------------- type-checking
35
"""Return true if the object is a module.
37
Module objects provide these attributes:
38
__doc__ documentation string
39
__file__ filename (missing for built-in modules)"""
40
return isinstance(object, types.ModuleType)
43
"""Return true if the object is a class.
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__')
51
"""Return true if the object is an instance method.
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)
61
def ismethoddescriptor(object):
62
"""Return true if the object is a method descriptor.
64
But not if ismethod() or isclass() or isfunction() are true.
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.
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))
81
def isdatadescriptor(object):
82
"""Return true if the object is a data descriptor.
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
89
return (hasattr(object, "__set__") and hasattr(object, "__get__"))
91
def isfunction(object):
92
"""Return true if the object is a user-defined function.
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)
104
def istraceback(object):
105
"""Return true if the object is a traceback.
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)
115
"""Return true if the object is a frame object.
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)
133
"""Return true if the object is a code object.
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)
150
def isbuiltin(object):
151
"""Return true if the object is a built-in function or method.
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)
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)
164
or ismethoddescriptor(object))
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."""
170
for key in dir(object):
171
value = getattr(object, key)
172
if not predicate or predicate(value):
173
results.append((key, value))
177
def classify_class_attrs(cls):
178
"""Return list of attribute-descriptor tuples.
180
For each name in dir(cls), the return list contains a 4-tuple
183
0. The name (a string).
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
192
2. The class which defined this attribute (a class).
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.
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]
211
obj = getattr(cls, name)
213
# Figure out where it was defined.
214
homecls = getattr(obj, "__objclass__", None)
218
if name in base.__dict__:
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]
227
# Also get the object via getattr.
228
obj_via_getattr = getattr(cls, name)
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):
237
elif (ismethod(obj_via_getattr) or
238
ismethoddescriptor(obj_via_getattr)):
243
result.append((name, kind, homecls, obj))
247
# ----------------------------------------------------------- class helpers
248
def _searchbases(cls, accum):
249
# Simulate the "classic class" search order.
253
for base in cls.__bases__:
254
_searchbases(base, accum)
257
"Return tuple of base classes (including cls) in method resolution order."
258
if hasattr(cls, "__mro__"):
262
_searchbases(cls, result)
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))
272
"""Get the documentation string for an object.
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."""
279
except AttributeError:
281
if not isinstance(doc, types.StringTypes):
284
lines = string.split(string.expandtabs(doc), '\n')
288
# Find minimum indentation of any non-blank lines after first line.
290
for line in lines[1:]:
291
content = len(string.lstrip(line))
293
indent = len(line) - content
294
margin = min(margin, indent)
295
# Remove indentation.
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]:
303
while lines and not lines[0]:
305
return string.join(lines, '\n')
308
"""Work out which source or compiled file an object was defined in."""
310
if hasattr(object, '__file__'):
311
return object.__file__
312
raise TypeError('arg is a built-in module')
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')
319
object = object.im_func
320
if isfunction(object):
321
object = object.func_code
322
if istraceback(object):
323
object = object.tb_frame
325
object = object.f_code
327
return object.co_filename
328
raise TypeError('arg is not a module, class, method, '
329
'function, traceback, frame, or code object')
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
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]
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.
355
if os.path.exists(filename):
358
def getabsfile(object):
359
"""Return an absolute path to the source or compiled file for an object.
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)))
368
def getmodule(object):
369
"""Return the module an object was defined in, or None if not found."""
372
if hasattr(object, '__module__'):
373
return sys.modules.get(object.__module__)
375
file = getabsfile(object)
378
if file in modulesbyfile:
379
return sys.modules.get(modulesbyfile[file])
380
for module in sys.modules.values():
381
if hasattr(module, '__file__'):
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__'):
390
if hasattr(main, object.__name__):
391
mainobject = getattr(main, object.__name__)
392
if mainobject is object:
394
builtin = sys.modules['__builtin__']
395
if hasattr(builtin, object.__name__):
396
builtinobject = getattr(builtin, object.__name__)
397
if builtinobject is object:
400
def findsource(object):
401
"""Return the entire source file and starting line number for an object.
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)
410
raise IOError('could not get source code')
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
421
raise IOError('could not find class definition')
424
object = object.im_func
425
if isfunction(object):
426
object = object.func_code
427
if istraceback(object):
428
object = object.tb_frame
430
object = object.f_code
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*@)')
437
if pat.match(lines[lnum]): break
440
raise IOError('could not find code object')
442
def getcomments(object):
443
"""Get lines of comments immediately preceding an object's source code.
445
Returns None when source can't be found.
448
lines, lnum = findsource(object)
449
except (IOError, TypeError):
453
# Look for a comment block at the top of the file.
455
if lines and lines[0][:2] == '#!': start = 1
456
while start < len(lines) and string.strip(lines[start]) in ['', '#']:
458
if start < len(lines) and lines[start][:1] == '#':
461
while end < len(lines) and lines[end][:1] == '#':
462
comments.append(string.expandtabs(lines[end]))
464
return string.join(comments, '')
466
# Look for a preceding block of comments at the same indentation.
468
indent = indentsize(lines[lnum])
470
if end >= 0 and string.lstrip(lines[end])[:1] == '#' and \
471
indentsize(lines[end]) == indent:
472
comments = [string.lstrip(string.expandtabs(lines[end]))]
475
comment = string.lstrip(string.expandtabs(lines[end]))
476
while comment[:1] == '#' and indentsize(lines[end]) == indent:
477
comments[:0] = [comment]
480
comment = string.lstrip(string.expandtabs(lines[end]))
481
while comments and string.strip(comments[0]) == '#':
483
while comments and string.strip(comments[-1]) == '#':
485
return string.join(comments, '')
488
"""Provide a readline() method to return lines from a list of strings."""
489
def __init__(self, lines):
495
if i < len(self.lines):
500
class EndOfBlock(Exception): pass
503
"""Provide a tokeneater() method to detect the end of a code block."""
506
self.islambda = False
508
self.passline = False
511
def tokeneater(self, type, token, (srow, scol), (erow, ecol), line):
513
if token in ("def", "class", "lambda"):
514
if token == "lambda":
518
elif type == tokenize.NEWLINE:
519
self.passline = False
524
raise EndOfBlock, self.last
525
elif type == tokenize.INDENT:
526
self.indent = self.indent + 1
528
elif type == tokenize.DEDENT:
529
self.indent = self.indent - 1
531
raise EndOfBlock, self.last
532
elif type == tokenize.NAME and scol == 0:
533
raise EndOfBlock, self.last
536
"""Extract the block of code at the top of the given list of lines."""
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
544
def getsourcelines(object):
545
"""Return a list of source lines and starting line number for an object.
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)
554
if ismodule(object): return lines, 0
555
else: return getblock(lines[lnum:]), lnum + 1
557
def getsource(object):
558
"""Return the text of the source code for an object.
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, '')
566
# --------------------------------------------------- class tree extraction
567
def walktree(classes, children, parent):
568
"""Recursive helper function for getclasstree()."""
570
classes.sort(key=lambda c: (c.__module__, c.__name__))
572
results.append((c, c.__bases__))
574
results.append(walktree(children[c], children, c))
577
def getclasstree(classes, unique=0):
578
"""Arrange the given list of classes into a hierarchy of nested lists.
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."""
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
597
for parent in children:
598
if parent not in classes:
600
return walktree(roots, children, None)
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
607
"""Get information about the arguments accepted by a code object.
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."""
614
raise TypeError('arg is not a code object')
617
nargs = co.co_argcount
618
names = co.co_varnames
619
args = list(names[:nargs])
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):
629
if op >= dis.HAVE_ARGUMENT:
630
opname = dis.opname[op]
631
value = ord(code[step]) + ord(code[step+1])*256
633
if opname in ['UNPACK_TUPLE', 'UNPACK_SEQUENCE']:
636
elif opname == 'STORE_FAST':
637
stack.append(names[value])
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.
643
stack[0] = [stack[0]]
646
remain[-1] = remain[-1] - 1
647
while remain[-1] == 0:
650
stack[-size:] = [stack[-size:]]
652
remain[-1] = remain[-1] - 1
657
if co.co_flags & CO_VARARGS:
658
varargs = co.co_varnames[nargs]
661
if co.co_flags & CO_VARKEYWORDS:
662
varkw = co.co_varnames[nargs]
663
return args, varargs, varkw
665
def getargspec(func):
666
"""Get the names and default values of a function's arguments.
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.
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
681
def getargvalues(frame):
682
"""Get information about arguments passed into a particular frame.
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
693
return '(' + seq[0] + ',)'
695
return '(' + string.join(seq, ', ') + ')'
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))
702
return convert(object)
704
def formatargspec(args, varargs=None, varkw=None, defaults=None,
706
formatvarargs=lambda name: '*' + name,
707
formatvarkw=lambda name: '**' + name,
708
formatvalue=lambda value: '=' + repr(value),
710
"""Format an argument spec from the 4 values returned by getargspec.
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."""
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])
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, ', ') + ')'
730
def formatargvalues(args, varargs, varkw, locals,
732
formatvarargs=lambda name: '*' + name,
733
formatvarkw=lambda name: '**' + name,
734
formatvalue=lambda value: '=' + repr(value),
736
"""Format an argument spec from the 4 values returned by getargvalues.
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])
746
for i in range(len(args)):
747
specs.append(strseq(args[i], convert, join))
749
specs.append(formatvarargs(varargs) + formatvalue(locals[varargs]))
751
specs.append(formatvarkw(varkw) + formatvalue(locals[varkw]))
752
return '(' + string.join(specs, ', ') + ')'
754
# -------------------------------------------------- stack frame extraction
755
def getframeinfo(frame, context=1):
756
"""Get information about a frame or traceback object.
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
767
lineno = frame.f_lineno
768
if not isframe(frame):
769
raise TypeError('arg is not a frame or traceback object')
771
filename = getsourcefile(frame) or getfile(frame)
773
start = lineno - 1 - context//2
775
lines, lnum = findsource(frame)
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
786
return (filename, lineno, frame.f_code.co_name, lines, index)
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
793
def getouterframes(frame, context=1):
794
"""Get a list of records for a frame and all higher (calling) frames.
796
Each record contains a frame object, filename, line number, function
797
name, a list of lines of context, and index within the context."""
800
framelist.append((frame,) + getframeinfo(frame, context))
804
def getinnerframes(tb, context=1):
805
"""Get a list of records for a traceback's frame and all lower frames.
807
Each record contains a frame object, filename, line number, function
808
name, a list of lines of context, and index within the context."""
811
framelist.append((tb.tb_frame,) + getframeinfo(tb, context))
815
currentframe = sys._getframe
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)
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)