diff options
Diffstat (limited to 'Lib/linecache.py')
-rw-r--r-- | Lib/linecache.py | 36 |
1 files changed, 30 insertions, 6 deletions
diff --git a/Lib/linecache.py b/Lib/linecache.py index 2ccc6c6..f49695a 100644 --- a/Lib/linecache.py +++ b/Lib/linecache.py @@ -10,8 +10,8 @@ import os __all__ = ["getline", "clearcache", "checkcache"] -def getline(filename, lineno): - lines = getlines(filename) +def getline(filename, lineno, module_globals=None): + lines = getlines(filename, module_globals) if 1 <= lineno <= len(lines): return lines[lineno-1] else: @@ -30,14 +30,14 @@ def clearcache(): cache = {} -def getlines(filename): +def getlines(filename, module_globals=None): """Get the lines for a file from the cache. Update the cache if it doesn't contain an entry for this file already.""" if filename in cache: return cache[filename][2] else: - return updatecache(filename) + return updatecache(filename, module_globals) def checkcache(filename=None): @@ -54,6 +54,8 @@ def checkcache(filename=None): for filename in filenames: size, mtime, lines, fullname = cache[filename] + if mtime is None: + continue # no-op for files loaded via a __loader__ try: stat = os.stat(fullname) except os.error: @@ -63,7 +65,7 @@ def checkcache(filename=None): del cache[filename] -def updatecache(filename): +def updatecache(filename, module_globals=None): """Update a cache entry and return its list of lines. If something's wrong, print a message, discard the cache entry, and return an empty list.""" @@ -72,12 +74,34 @@ def updatecache(filename): del cache[filename] if not filename or filename[0] + filename[-1] == '<>': return [] + fullname = filename try: stat = os.stat(fullname) except os.error, msg: - # Try looking through the module search path. basename = os.path.split(filename)[1] + + # Try for a __loader__, if available + if module_globals and '__loader__' in module_globals: + name = module_globals.get('__name__') + loader = module_globals['__loader__'] + get_source = getattr(loader, 'get_source', None) + + if name and get_source: + if basename.startswith(name.split('.')[-1]+'.'): + try: + data = get_source(name) + except (ImportError, IOError): + pass + else: + cache[filename] = ( + len(data), None, + [line+'\n' for line in data.splitlines()], fullname + ) + return cache[filename][2] + + # Try looking through the module search path. + for dirname in sys.path: # When using imputil, sys.path may contain things other than # strings; ignore them when it happens. |