This file is indexed.

/usr/share/pyshared/axiom/_fincache.py is in python-axiom 0.7.1-2.

This file is owned by root:root, with mode 0o644.

The actual contents of the file can be viewed below.

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 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
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
from weakref import ref
from traceback import print_exc

from twisted.python import log

from axiom import iaxiom

class CacheFault(KeyError):
    """
    An item has fallen out of cache, but the weakref callback has not yet run.
    """



class CacheInconsistency(RuntimeError):
    """
    A key being cached is already present in the cache.
    """



def logErrorNoMatterWhat():
    try:
        log.msg("Exception in finalizer cannot be propagated")
        log.err()
    except:
        try:
            emergLog = file("WEAKREF_EMERGENCY_ERROR.log", 'a')
            print_exc(file=emergLog)
            emergLog.flush()
            emergLog.close()
        except:
            # Nothing can be done.  We can't get an emergency log file to write
            # to.  Don't bother.
            return



def createCacheRemoveCallback(cacheRef, key, finalizer):
    """
    Construct a callable to be used as a weakref callback for cache entries.

    The callable will invoke the provided finalizer, as well as removing the
    cache entry if the cache still exists and contains an entry for the given
    key.

    @type  cacheRef: L{weakref.ref} to L{FinalizingCache}
    @param cacheRef: A weakref to the cache in which the corresponding cache
        item was stored.

    @param key: The key for which this value is cached.

    @type  finalizer: callable taking 0 arguments
    @param finalizer: A user-provided callable that will be called when the
        weakref callback runs.
    """
    def remove(self):
        # Weakref callbacks cannot raise exceptions or DOOM ensues
        try:
            finalizer()
        except:
            logErrorNoMatterWhat()
        try:
            self = cacheRef()
            if self is not None:
                try:
                    del self.data[key]
                except KeyError:
                    # FinalizingCache.get may have already removed the cache
                    # item from the dictionary; see the comment in that method
                    # for an explanation of why.
                    pass
        except:
            logErrorNoMatterWhat()
    return remove



class FinalizingCache:
    """
    A cache that stores values by weakref.

    A finalizer is invoked when the weakref to a cached value is broken.

    @type data: L{dict}
    @ivar data: The cached values.
    """
    def __init__(self):
        self.data = {}


    def cache(self, key, value):
        """
        Add an entry to the cache.

        A weakref to the value is stored, rather than a direct reference. The
        value must have a C{__finalizer__} method that returns a callable which
        will be invoked when the weakref is broken.

        @param key: The key identifying the cache entry.

        @param value: The value for the cache entry.
        """
        fin = value.__finalizer__()
        try:
            # It's okay if there's already a cache entry for this key as long
            # as the weakref has already been broken. See the comment in
            # get() for an explanation of why this might happen.
            if self.data[key]() is not None:
                raise CacheInconsistency(
                    "Duplicate cache key: %r %r %r" % (
                        key, value, self.data[key]))
        except KeyError:
            pass
        self.data[key] = ref(value, createCacheRemoveCallback(
                ref(self), key, fin))
        return value


    def uncache(self, key, value):
        """
        Remove a key from the cache.

        As a sanity check, if the specified key is present in the cache, it
        must have the given value.

        @param key: The key to remove.

        @param value: The expected value for the key.
        """
        try:
            assert self.get(key) is value
            del self.data[key]
        except KeyError:
            # If the entry has already been removed from the cache, this will
            # result in KeyError which we ignore. If the entry is still in the
            # cache, but the weakref has been broken, this will result in
            # CacheFault (a KeyError subclass) which we also ignore. See the
            # comment in get() for an explanation of why this might happen.
            pass


    def get(self, key):
        """
        Get an entry from the cache by key.

        @raise KeyError: if the given key is not present in the cache.

        @raise CacheFault: (a L{KeyError} subclass) if the given key is present
            in the cache, but the value it points to is gone.
        """
        o = self.data[key]()
        if o is None:
            # On CPython, the weakref callback will always(?) run before any
            # other code has a chance to observe that the weakref is broken;
            # and since the callback removes the item from the dict, this
            # branch of code should never run. However, on PyPy (and possibly
            # other Python implementations), the weakref callback does not run
            # immediately, thus we may be able to observe this intermediate
            # state. Should this occur, we remove the dict item ourselves,
            # and raise CacheFault (which is a KeyError subclass).
            del self.data[key]
            raise CacheFault(
                "FinalizingCache has %r but its value is no more." % (key,))
        log.msg(interface=iaxiom.IStatEvent, stat_cache_hits=1, key=key)
        return o