State Design Pattern in Python I'm trying to find the best - read: readable, maintainable, robust, threadsafe, usable - solution for a State Machine in python.
For this I've been looking at the State Design Pattern. However I want a pythonic and lean solution (saying not implementing functions in subclasses that are not needed).

Long story short, here's what I came up with. What do you think?

#!/bin/env python
# -*- utf-8 -*-
"""Boiler Plate code for implementing a state machine according to
state design pattern

"""

class State(object):
    """Base class for a state in a statemachine

    No statemachine class is needed. State transitions have to be
    defined in self.transitions.

    The object is callable and by calling it input is handled and
    the next state is returned.

    Example usage:

    def handle(self, msg):
        self._state = self._state(msg)

    """
    transitions = [(None, None, None)]

    def __init__(self, state_context):
        self._context = state_context

    def __call__(self, inp):
        new_state = self

        state_action_list = [(state, action) for cls, state,
                     action in self.transitions if
                     isinstance(inp, cls)]
        if 1 == len(state_action_list):
            state, action = state_action_list[0]
            if action is not None:
                try:
                    action(inp)
                except TypeError:
                    action(self, inp)
            new_state = state(self._context)

        elif 1 &lt; len(state_action_list):
            raise AmbiguousTransitionError(inp, self)

        print ("[DEBUG] %s -- %s --&gt; %s" %
               (self.__class__.__name__,
            inp.__class__.__name__,
            new_state.__class__.__name__ ))

        return new_state

class AmbiguousTransitionError(Exception):
    """Raised if more than one state transition was found for a
    given input

    """
    pass

################################################## Example

class MsgA(object): pass
class MsgB(object): pass
class MsgC(object): pass

class StateA(State): pass

class StateB(State):
    @staticmethod
    def print_msg(inp):
        print "Inp: ", inp

class StateC(State):
    def print_context(self, unused_inp):
        print "Context: ", self._context

StateA.transitions = [(MsgA, StateB, None)]
StateB.transitions = [(MsgB, StateC, StateB.print_msg)]
StateC.transitions = [(MsgB, StateB, None),
              (MsgC, StateA, StateC.print_context)]

class Context(object):
    def __init__(self):
        self._state = StateA(self)

    def handle(self, msg):
        self._state = self._state(msg)

if __name__ == "__main__":
    CONTEXT = Context()
    CONTEXT.handle(MsgA())
    CONTEXT.handle(MsgB())
    CONTEXT.handle(MsgC())
    CONTEXT.handle(MsgB())


The output looks like this:

python State.py

[DEBUG] StateA -- MsgA --&gt; StateB
Inp:  &lt;__main__.MsgB object at 0x1eb6250&gt;
[DEBUG] StateB -- MsgB --&gt; StateC
Context:  &lt;__main__.Context object at 0x1eb6150&gt;
[DEBUG] StateC -- MsgC --&gt; StateA
[DEBUG] StateA -- MsgB --&gt; StateA
Not a proper code review as per se but I was wondering if things couldn't be done in a more straight-forward way like this :

#!/usr/bin/python

class Machine(object):
    def __init__(self, state, transitions):
        self.transitions = transitions
        self.state = state

    def __call__(self, input):
        old_state = self.state
        self.state = self.transitions.get((self.state, input), self.state)
        print("DEBUG %s -- %s --&gt; %s" % (old_state, input, self.state))

machine = Machine(
    "a",
    {
        ("a","msgA"):"b",
        ("b","msgB"):"c",
        ("c","msgB"):"b",
        ("c","msgC"):"a",
    }
    )

machine("msgA")
machine("msgB")
machine("msgC")
machine("msgB")


Using functions to have actual side effects, this could look like this :

#!/usr/bin/python


# examples of helper functions
def goto(s):
    return lambda state,input: s

def no_move():
    return lambda state,input: state

def verbose_no_move():
    def func(state,input):
        print('Cannot find a transition for %s from %s' % (input, state))
        return state
    return func

def print_input_and_goto(s):
    def func(state,input):
        print(input)
        return s
    return func

def print_old_state_and_goto(s):
    def func(state,input):
        print(state)
        return s
    return func

def raise_exception():
    def func(state,input):
        raise ValueError('Cannot find a transition for %s from %s' % (input, state))

class Machine(object):
    def __init__(self, initial_state, transitions):
        self.transitions = transitions
        self.state = initial_state
        self.default = verbose_no_move() # pick a default behavior

    def __call__(self, input):
        old_state = self.state
        func = self.transitions.get((self.state, input), self.default)
        self.state = func(self.state,input)
        print("DEBUG %s -- %s --&gt; %s" % (old_state, input, self.state))


machine = Machine(
    "a",
    {
        ("a","msgA"):goto("b"),
        ("b","msgB"):print_input_and_goto("c"),
        ("c","msgB"):goto("b"),
        ("c","msgC"):print_old_state_and_goto("a"),
    }
    )

machine("msgA")
machine("msgB")
machine("msgC")
machine("msgB")