This file is indexed.

/usr/share/pyshared/enthought/util/equivalence.py is in python-enthoughtbase 3.1.0-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
from copy import copy

from enthought.traits.api import HasTraits, Instance, List, Property
from enthought.util.sequence import union

# Our representation of equivalence classes can be optimized. It looks like all
# of our methods are linear in the number of classes; liberal use of hashes
# should be able to make some of them sub-linear -- at least 'get_class'.

# TODO Fire more events? e.g. 'classes_items_changed'

class Equivalence(HasTraits):
    ''' An equivalence relation.

        An equivalence relation is a binary relation ~ on a set A with the
        following properties:

        * Reflexivity:  a ~ a
        * Symmetry:     a ~ b iff b ~ a
        * Transitivity: a ~ b and b ~ c implies a ~ c

        For our purposes, the set A is the set of all hashable python objects.

        Examples::

            >>> e = Equivalence(list('foo'), list('bar'), list('baz'))
            >>> e.equivalent('f', 'o')
            True
            >>> e.equivalent('f', 'b')
            False
            >>> e.equivalent('b', 'a', 'r', 'z')
            True
            >>> assert e.get_class('f') == set('fo')
            >>> assert e.get_class('b') == set('barz')

            >>> e.remove('f')
            >>> assert e.get_class('f') == set('f')
            >>> assert e.get_class('o') == set('o')
            >>> assert e.get_class('b') == set('barz')

            >>> e.remove('r', 'z')
            >>> assert e.classes == [set('ba')]
            >>> assert set(e.classes) == set(e) == set([frozenset('ba')])

            >>> e = Equivalence()
            >>> e.equate(1, 3)
            >>> e.equate(2, 4)
            >>> e.equate(5, 6, 7, 8, 9)
            >>> e.equate(10)
            >>> assert len(e.classes) == 3
            >>> assert e.get_class(1) == set([1, 3])
            >>> assert e.get_class(4) == set([2, 4])
            >>> e.equate(2, 3)
            >>> assert e.get_class(1) == e.get_class(4) == set([1, 2, 3, 4])
            >>> e.remove(2, 3)
            >>> assert e.get_class(1) == e.get_class(4) == set([1, 4])
            >>> e.remove(4)
            >>> assert not e.equivalent(1, 4)

            >>> e = Equivalence()
            >>> assert set(e) == set()
            >>> e.equate(1,2)
            >>> e.remove(1,2)
            >>> assert set(e) == set()
    '''

    # Our equivalence classes
    classes = Property(List(Instance(set)))
    _classes = List(Instance(set))

    ### Properties ############################################################

    def _get_classes(self):
        return map(frozenset, self._classes)

    ### object interface ######################################################

    def __init__(self, *classes):
        super(Equivalence, self).__init__()
        for c in classes:
            self.equate(*c)

    def __iter__(self):
        return iter(self.classes)

    def __repr__(self):
        return repr(self._classes)

    ### Equivalence interface #################################################

    def equivalent(self, *args):
        'Whether all given elements are equivalent'
        # If the given elements are all the same element, then they are
        # equivalent whether we've seen them before or not. Otherwise, if we
        # haven't seen all of them, then they aren't equivalent.
        if args:
            return (len(set(args)) == 1 or
                    set(args[1:]).issubset(self.get_class(args[0])))
        else:
            return True # Vacuously

    def get_class(self, a):
        "'a's equivalence class (the set of elements equivalent to 'a')."
        for c in self._classes:
            if a in c:
                return c
        return set([a])

    def equate(self, *args):
        'Declare that the given elements are equivalent to each other.'
        args = set(args)

        # Singleton classes are implicit
        if len(args) == 1:
            return

        unaffected, to_merge = [], []
        for c in self._classes:
            if args & c:
                to_merge.append(c)
            else:
                unaffected.append(c)

        self._classes = unaffected + [args | union(to_merge)]

    def remove(self, *args):
        ''' Declare that each given element is only equivalent to itself.

            Unknown elements are assumed to be equivalent only to themselves,
            so using 'remove' is only necessary to undo effects of previous
            calls to 'equate'.
        '''
        args = set(args)
        for c in copy(self._classes):

            # Remove 'args' from each class
            c -= args

            # Singleton classes are implicit; remove them.
            # Empty classes are cruft; remove them too.
            if len(c) <= 1:
                self._classes.remove(c)