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