home *** CD-ROM | disk | FTP | other *** search
/ PC World 2005 June / PCWorld_2005-06_cd.bin / software / vyzkuste / firewally / firewally.exe / framework-2.3.exe / codehack.py < prev    next >
Text File  |  2003-12-30  |  2KB  |  82 lines

  1. # A subroutine for extracting a function name from a code object
  2. # (with cache)
  3.  
  4. import sys
  5. from stat import *
  6. import string
  7. import os
  8. import linecache
  9.  
  10. # XXX The functions getcodename() and getfuncname() are now obsolete
  11. # XXX as code and function objects now have a name attribute --
  12. # XXX co.co_name and f.func_name.
  13. # XXX getlineno() is now also obsolete because of the new attribute
  14. # XXX of code objects, co.co_firstlineno.
  15.  
  16. # Extract the function or class name from a code object.
  17. # This is a bit of a hack, since a code object doesn't contain
  18. # the name directly.  So what do we do:
  19. # - get the filename (which *is* in the code object)
  20. # - look in the code string to find the first SET_LINENO instruction
  21. #   (this must be the first instruction)
  22. # - get the line from the file
  23. # - if the line starts with 'class' or 'def' (after possible whitespace),
  24. #   extract the following identifier
  25. #
  26. # This breaks apart when the function was read from <stdin>
  27. # or constructed by exec(), when the file is not accessible,
  28. # and also when the file has been modified or when a line is
  29. # continued with a backslash before the function or class name.
  30. #
  31. # Because this is a pretty expensive hack, a cache is kept.
  32.  
  33. SET_LINENO = 127 # The opcode (see "opcode.h" in the Python source)
  34. identchars = string.ascii_letters + string.digits + '_' # Identifier characters
  35.  
  36. _namecache = {} # The cache
  37.  
  38. def getcodename(co):
  39.     try:
  40.         return co.co_name
  41.     except AttributeError:
  42.         pass
  43.     key = `co` # arbitrary but uniquely identifying string
  44.     if _namecache.has_key(key): return _namecache[key]
  45.     filename = co.co_filename
  46.     code = co.co_code
  47.     name = ''
  48.     if ord(code[0]) == SET_LINENO:
  49.         lineno = ord(code[1]) | ord(code[2]) << 8
  50.         line = linecache.getline(filename, lineno)
  51.         words = line.split()
  52.         if len(words) >= 2 and words[0] in ('def', 'class'):
  53.             name = words[1]
  54.             for i in range(len(name)):
  55.                 if name[i] not in identchars:
  56.                     name = name[:i]
  57.                     break
  58.     _namecache[key] = name
  59.     return name
  60.  
  61. # Use the above routine to find a function's name.
  62.  
  63. def getfuncname(func):
  64.     try:
  65.         return func.func_name
  66.     except AttributeError:
  67.         pass
  68.     return getcodename(func.func_code)
  69.  
  70. # A part of the above code to extract just the line number from a code object.
  71.  
  72. def getlineno(co):
  73.     try:
  74.         return co.co_firstlineno
  75.     except AttributeError:
  76.         pass
  77.     code = co.co_code
  78.     if ord(code[0]) == SET_LINENO:
  79.         return ord(code[1]) | ord(code[2]) << 8
  80.     else:
  81.         return -1
  82.