This file is indexed.

/usr/lib/python3/dist-packages/invoke/vendor/fluidity/machine.py is in python3-invoke 0.11.1+dfsg1-1.

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
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
import re
import inspect
from .backwardscompat import callable

# metaclass implementation idea from
# http://blog.ianbicking.org/more-on-python-metaprogramming-comment-14.html
_transition_gatherer = []

def transition(event, from_, to, action=None, guard=None):
    _transition_gatherer.append([event, from_, to, action, guard])

_state_gatherer = []

def state(name, enter=None, exit=None):
    _state_gatherer.append([name, enter, exit])


class MetaStateMachine(type):

    def __new__(cls, name, bases, dictionary):
        global _transition_gatherer, _state_gatherer
        Machine = super(MetaStateMachine, cls).__new__(cls, name, bases, dictionary)
        Machine._class_transitions = []
        Machine._class_states = {}
        for s in _state_gatherer:
            Machine._add_class_state(*s)
        for i in _transition_gatherer:
            Machine._add_class_transition(*i)
        _transition_gatherer = []
        _state_gatherer = []
        return Machine


StateMachineBase = MetaStateMachine('StateMachineBase', (object, ), {})


class StateMachine(StateMachineBase):

    def __init__(self):
        self._bring_definitions_to_object_level()
        self._inject_into_parts()
        self._validate_machine_definitions()
        if callable(self.initial_state):
            self.initial_state = self.initial_state()
        self._current_state_object = self._state_by_name(self.initial_state)
        self._current_state_object.run_enter(self)
        self._create_state_getters()

    def __new__(cls, *args, **kwargs):
        obj = super(StateMachine, cls).__new__(cls)
        obj._states = {}
        obj._transitions = []
        return obj

    def _bring_definitions_to_object_level(self):
        self._states.update(self.__class__._class_states)
        self._transitions.extend(self.__class__._class_transitions)

    def _inject_into_parts(self):
        for collection in [self._states.values(), self._transitions]:
            for component in collection:
                component.machine = self

    def _validate_machine_definitions(self):
        if len(self._states) < 2:
            raise InvalidConfiguration('There must be at least two states')
        if not getattr(self, 'initial_state', None):
            raise InvalidConfiguration('There must exist an initial state')

    @classmethod
    def _add_class_state(cls, name, enter, exit):
        cls._class_states[name] = _State(name, enter, exit)

    def add_state(self, name, enter=None, exit=None):
        state = _State(name, enter, exit)
        setattr(self, state.getter_name(), state.getter_method().__get__(self, self.__class__))
        self._states[name] = state

    def _current_state_name(self):
        return self._current_state_object.name

    current_state = property(_current_state_name)

    def changing_state(self, from_, to):
        """
        This method is called whenever a state change is executed
        """
        pass

    def _new_state(self, state):
        self.changing_state(self._current_state_object.name, state.name)
        self._current_state_object = state

    def _state_objects(self):
        return list(self._states.values())

    def states(self):
        return [s.name for s in self._state_objects()]

    @classmethod
    def _add_class_transition(cls, event, from_, to, action, guard):
        transition = _Transition(event, [cls._class_states[s] for s in _listize(from_)],
            cls._class_states[to], action, guard)
        cls._class_transitions.append(transition)
        setattr(cls, event, transition.event_method())

    def add_transition(self, event, from_, to, action=None, guard=None):
        transition = _Transition(event, [self._state_by_name(s) for s in _listize(from_)],
            self._state_by_name(to), action, guard)
        self._transitions.append(transition)
        setattr(self, event, transition.event_method().__get__(self, self.__class__))

    def _process_transitions(self, event_name, *args, **kwargs):
        transitions = self._transitions_by_name(event_name)
        transitions = self._ensure_from_validity(transitions)
        this_transition = self._check_guards(transitions)
        this_transition.run(self, *args, **kwargs)

    def _create_state_getters(self):
        for state in self._state_objects():
            setattr(self, state.getter_name(), state.getter_method().__get__(self, self.__class__))

    def _state_by_name(self, name):
        for state in self._state_objects():
            if state.name == name:
                return state

    def _transitions_by_name(self, name):
        return list(filter(lambda transition: transition.event == name, self._transitions))

    def _ensure_from_validity(self, transitions):
        valid_transitions = list(filter(
          lambda transition: transition.is_valid_from(self._current_state_object),
          transitions))
        if len(valid_transitions) == 0:
            raise InvalidTransition("Cannot %s from %s" % (
                transitions[0].event, self.current_state))
        return valid_transitions

    def _check_guards(self, transitions):
        allowed_transitions = []
        for transition in transitions:
            if transition.check_guard(self):
                allowed_transitions.append(transition)
        if len(allowed_transitions) == 0:
            raise GuardNotSatisfied("Guard is not satisfied for this transition")
        elif len(allowed_transitions) > 1:
            raise ForkedTransition("More than one transition was allowed for this event")
        return allowed_transitions[0]


class _Transition(object):

    def __init__(self, event, from_, to, action, guard):
        self.event = event
        self.from_ = from_
        self.to = to
        self.action = action
        self.guard = _Guard(guard)

    def event_method(self):
        def generated_event(machine, *args, **kwargs):
            these_transitions = machine._process_transitions(self.event, *args, **kwargs)
        generated_event.__doc__ = 'event %s' % self.event
        generated_event.__name__ = self.event
        return generated_event

    def is_valid_from(self, from_):
        return from_ in _listize(self.from_)

    def check_guard(self, machine):
        return self.guard.check(machine)

    def run(self, machine, *args, **kwargs):
        machine._current_state_object.run_exit(machine)
        machine._new_state(self.to)
        self.to.run_enter(machine)
        _ActionRunner(machine).run(self.action, *args, **kwargs)


class _Guard(object):

    def __init__(self, action):
        self.action = action

    def check(self, machine):
        if self.action is None:
            return True
        items = _listize(self.action)
        result = True
        for item in items:
            result = result and self._evaluate(machine, item)
        return result

    def _evaluate(self, machine, item):
        if callable(item):
            return item(machine)
        else:
            guard = getattr(machine, item)
            if callable(guard):
                guard = guard()
            return guard


class _State(object):

    def __init__(self, name, enter, exit):
        self.name = name
        self.enter = enter
        self.exit = exit

    def getter_name(self):
        return 'is_%s' % self.name

    def getter_method(self):
        def state_getter(self_machine):
            return self_machine.current_state == self.name
        return state_getter

    def run_enter(self, machine):
        _ActionRunner(machine).run(self.enter)

    def run_exit(self, machine):
        _ActionRunner(machine).run(self.exit)


class _ActionRunner(object):

    def __init__(self, machine):
        self.machine = machine

    def run(self, action_param, *args, **kwargs):
        if not action_param:
            return
        action_items = _listize(action_param)
        for action_item in action_items:
            self._run_action(action_item, *args, **kwargs)

    def _run_action(self, action, *args, **kwargs):
        if callable(action):
            self._try_to_run_with_args(action, self.machine, *args, **kwargs)
        else:
            self._try_to_run_with_args(getattr(self.machine, action), *args, **kwargs)

    def _try_to_run_with_args(self, action, *args, **kwargs):
        try:
            action(*args, **kwargs)
        except TypeError:
            action()


class InvalidConfiguration(Exception):
    pass


class InvalidTransition(Exception):
    pass


class GuardNotSatisfied(Exception):
    pass


class ForkedTransition(Exception):
    pass


def _listize(value):
    return type(value) in [list, tuple] and value or [value]