0001 """Cache lines from files. 0002 0003 This is intended to read lines from modules imported -- hence if a filename 0004 is not found, it will look down the module search path for a file by 0005 that name. 0006 """ 0007 0008 import sys 0009 import os 0010 0011 __all__ = ["getline", "clearcache", "checkcache"] 0012 0013 def getline(filename, lineno): 0014 lines = getlines(filename) 0015 if 1 <= lineno <= len(lines): 0016 return lines[lineno-1] 0017 else: 0018 return '' 0019 0020 0021 # The cache 0022 0023 cache = {} # The cache 0024 0025 0026 def clearcache(): 0027 """Clear the cache entirely.""" 0028 0029 global cache 0030 cache = {} 0031 0032 0033 def getlines(filename): 0034 """Get the lines for a file from the cache. 0035 Update the cache if it doesn't contain an entry for this file already.""" 0036 0037 if filename in cache: 0038 return cache[filename][2] 0039 else: 0040 return updatecache(filename) 0041 0042 0043 def checkcache(filename=None): 0044 """Discard cache entries that are out of date. 0045 (This is not checked upon each call!)""" 0046 0047 if filename is None: 0048 filenames = cache.keys() 0049 else: 0050 if filename in cache: 0051 filenames = [filename] 0052 else: 0053 return 0054 0055 for filename in filenames: 0056 size, mtime, lines, fullname = cache[filename] 0057 try: 0058 stat = os.stat(fullname) 0059 except os.error: 0060 del cache[filename] 0061 continue 0062 if size != stat.st_size or mtime != stat.st_mtime: 0063 del cache[filename] 0064 0065 0066 def updatecache(filename): 0067 """Update a cache entry and return its list of lines. 0068 If something's wrong, print a message, discard the cache entry, 0069 and return an empty list.""" 0070 0071 if filename in cache: 0072 del cache[filename] 0073 if not filename or filename[0] + filename[-1] == '<>': 0074 return [] 0075 fullname = filename 0076 try: 0077 stat = os.stat(fullname) 0078 except os.error, msg: 0079 # Try looking through the module search path. 0080 basename = os.path.split(filename)[1] 0081 for dirname in sys.path: 0082 # When using imputil, sys.path may contain things other than 0083 # strings; ignore them when it happens. 0084 try: 0085 fullname = os.path.join(dirname, basename) 0086 except (TypeError, AttributeError): 0087 # Not sufficiently string-like to do anything useful with. 0088 pass 0089 else: 0090 try: 0091 stat = os.stat(fullname) 0092 break 0093 except os.error: 0094 pass 0095 else: 0096 # No luck 0097 ## print '*** Cannot stat', filename, ':', msg 0098 return [] 0099 try: 0100 fp = open(fullname, 'rU') 0101 lines = fp.readlines() 0102 fp.close() 0103 except IOError, msg: 0104 ## print '*** Cannot open', fullname, ':', msg 0105 return [] 0106 size, mtime = stat.st_size, stat.st_mtime 0107 cache[filename] = size, mtime, lines, fullname 0108 return lines 0109
Generated by PyXR 0.9.4