linecache.py 2.35 KB
Newer Older
1 2 3 4 5 6
"""Cache lines from files.

This is intended to read lines from modules imported -- hence if a filename
is not found, it will look down the module search path for a file by
that name.
"""
Guido van Rossum's avatar
Guido van Rossum committed
7

8
import sys
Guido van Rossum's avatar
Guido van Rossum committed
9 10 11
import os
from stat import *

12 13
__all__ = ["getline","clearcache","checkcache"]

Guido van Rossum's avatar
Guido van Rossum committed
14
def getline(filename, lineno):
15 16 17 18 19
    lines = getlines(filename)
    if 1 <= lineno <= len(lines):
        return lines[lineno-1]
    else:
        return ''
Guido van Rossum's avatar
Guido van Rossum committed
20 21 22 23 24 25 26 27


# The cache

cache = {} # The cache


def clearcache():
28
    """Clear the cache entirely."""
Guido van Rossum's avatar
Guido van Rossum committed
29

30 31
    global cache
    cache = {}
Guido van Rossum's avatar
Guido van Rossum committed
32 33 34


def getlines(filename):
35 36
    """Get the lines for a file from the cache.
    Update the cache if it doesn't contain an entry for this file already."""
Guido van Rossum's avatar
Guido van Rossum committed
37

38 39 40 41
    if cache.has_key(filename):
        return cache[filename][2]
    else:
        return updatecache(filename)
Guido van Rossum's avatar
Guido van Rossum committed
42 43 44


def checkcache():
45 46
    """Discard cache entries that are out of date.
    (This is not checked upon each call!)"""
Guido van Rossum's avatar
Guido van Rossum committed
47

48 49 50 51 52 53 54
    for filename in cache.keys():
        size, mtime, lines, fullname = cache[filename]
        try:
            stat = os.stat(fullname)
        except os.error:
            del cache[filename]
            continue
55
        if size != stat[ST_SIZE] or mtime != stat[ST_MTIME]:
56
            del cache[filename]
Guido van Rossum's avatar
Guido van Rossum committed
57 58 59


def updatecache(filename):
60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94
    """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."""

    if cache.has_key(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]
        for dirname in sys.path:
            fullname = os.path.join(dirname, basename)
            try:
                stat = os.stat(fullname)
                break
            except os.error:
                pass
        else:
            # No luck
##          print '*** Cannot stat', filename, ':', msg
            return []
    try:
        fp = open(fullname, 'r')
        lines = fp.readlines()
        fp.close()
    except IOError, msg:
##      print '*** Cannot open', fullname, ':', msg
        return []
    size, mtime = stat[ST_SIZE], stat[ST_MTIME]
    cache[filename] = size, mtime, lines, fullname
    return lines