<commit_before>from functools import partial
from collections import defaultdict

def listify(obj):
    return obj if isinstance(obj, list) or obj is None else [obj]

class State(object):

    def __init__(self, name, on_enter=None, on_exit=None):

        self.name = name
        self.on_enter = listify(on_enter) if on_enter else []
        self.on_exit = listify(on_exit) if on_exit else []

    def enter(self, event):
        for oe in self.on_enter: getattr(event.model, oe)()

    def exit(self, event):
        for oe in self.on_exit: getattr(event.model, oe)()


class Transition(object):

    def __init__(self, source, dest, conditions=None, before=None, after=None):

        self.source = source
        self.dest = dest
        before, after, conditions = (listify(x) for x in [before, after, conditions])
        self.before = [] if before is None else before
        self.after = [] if after is None else after
        self.conditions = [] if conditions is None else conditions

    def execute(self, event):

        machine = event.machine
        for c in self.conditions:
            if not getattr(event.model, c)(): return False

        for trigger in self.before: getattr(event.model, trigger)()
        machine.get_state(self.source).exit(event)
        machine.update_state(self.dest)
        machine.get_state(self.source).enter(event)
        for trigger in self.after: getattr(event.model, trigger)()
        return True


class Event(object):

    def __init__(self, state, trigger, machine, model, *args, **kwargs):

        self.state = state
        self.trigger = trigger
        self.machine = machine
        self.model = model
        self.args = args
        self.kwargs = kwargs


class Trigger(object):

    def __init__(self, name, machine):

        self.name = name
        self.machine = machine
        self.transitions = defaultdict(list)

    def add_transition(self, transition):
        source = transition.source
        self.transitions[transition.source].append(transition)

    def trigger(self, *args, **kwargs):
        """ Serially execute all transitions that match the current state, 
        halting as soon as one successfully completes. """
        state_name = self.machine.current_state.name
        if state_name not in self.transitions:
            raise MachineError("Can't trigger event %s from state %s!" % (self.name, state_name))
        event = Event(self.machine.current_state, self, self.machine, self.machine.model, *args, **kwargs)
        for t in self.transitions[state_name]:
            if t.execute(event): return True
        return False
<commit_msg>update event state before entrance/after callbacks<commit_after>from functools import partial
from collections import defaultdict

def listify(obj):
    return obj if isinstance(obj, list) or obj is None else [obj]

class State(object):

    def __init__(self, name, on_enter=None, on_exit=None):

        self.name = name
        self.on_enter = listify(on_enter) if on_enter else []
        self.on_exit = listify(on_exit) if on_exit else []

    def enter(self, event):
        for oe in self.on_enter: getattr(event.model, oe)()

    def exit(self, event):
        for oe in self.on_exit: getattr(event.model, oe)()


class Transition(object):

    def __init__(self, source, dest, conditions=None, before=None, after=None):

        self.source = source
        self.dest = dest
        before, after, conditions = (listify(x) for x in [before, after, conditions])
        self.before = [] if before is None else before
        self.after = [] if after is None else after
        self.conditions = [] if conditions is None else conditions

    def execute(self, event):

        machine = event.machine
        for c in self.conditions:
            if not getattr(event.model, c)(): return False

        for trigger in self.before: getattr(event.model, trigger)()
        machine.get_state(self.source).exit(event)
        machine.update_state(self.dest)
        event.update()
        machine.get_state(self.source).enter(event)
        for trigger in self.after: getattr(event.model, trigger)()
        return True


class Event(object):

    def __init__(self, state, trigger, machine, model, *args, **kwargs):

        self.state = state
        self.trigger = trigger
        self.machine = machine
        self.model = model
        self.args = args
        self.kwargs = kwargs

    def update(self):
        self.state = self.machine.current_state


class Trigger(object):

    def __init__(self, name, machine):

        self.name = name
        self.machine = machine
        self.transitions = defaultdict(list)

    def add_transition(self, transition):
        source = transition.source
        self.transitions[transition.source].append(transition)

    def trigger(self, *args, **kwargs):
        """ Serially execute all transitions that match the current state, 
        halting as soon as one successfully completes. """
        state_name = self.machine.current_state.name
        if state_name not in self.transitions:
            raise MachineError("Can't trigger event %s from state %s!" % (self.name, state_name))
        event = Event(self.machine.current_state, self, self.machine, self.machine.model, *args, **kwargs)
        for t in self.transitions[state_name]:
            if t.execute(event): return True
        return False

{'fraction_non_alphanumeric': 0.10024087455994071, 'fraction_numerical': 0.0, 'mean_word_length': 2.7176308539944904, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 3, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '6570695', 'n_tokens_mistral': 1540, 'n_tokens_neox': 1496, 'n_words': 466}