def __init__(self, workflow):
        super(Step, self).__init__()
        self.workflow = workflow

        cls = self.__class__.__name__
        if not (self.action_class and issubclass(self.action_class, Action)):
            raise AttributeError("You must specify an action for %s." % cls)

        self.slug = self.action_class.slug
        self.name = self.action_class.name
        self.permissions = self.action_class.permissions
        self.has_errors = False
        self._handlers = {}

        if self.connections is None:
            # We want a dict, but don't want to declare a mutable type on the
            # class directly.
            self.connections = {}

        # Gather our connection handlers and make sure they exist.
        for key, handlers in self.connections.items():
            self._handlers[key] = []
            # TODO(gabriel): This is a poor substitute for broader handling
            if not isinstance(handlers, (list, tuple)):
                raise TypeError("The connection handlers for %s must be a "
                                "list or tuple." % cls)
            for possible_handler in handlers:
                if callable(possible_handler):
                    # If it's callable we know the function exists and is valid
                    self._handlers[key].append(possible_handler)
                    continue
                elif not isinstance(possible_handler, basestring):
                    return TypeError("Connection handlers must be either "
                                     "callables or strings.")
                bits = possible_handler.split(".")
                if bits[0] == "self":
                    root = self
                    for bit in bits[1:]:
                        try:
                            root = getattr(root, bit)
                        except AttributeError:
                            raise AttributeError("The connection handler %s "
                                                 "could not be found on %s."
                                                 % (possible_handler, cls))
                    handler = root
                elif len(bits) == 1:
                    # Import by name from local module not supported
                    raise ValueError("Importing a local function as a string "
                                     "is not supported for the connection "
                                     "handler %s on %s."
                                     % (possible_handler, cls))
                else:
                    # Try a general import
                    module_name = ".".join(bits[:-1])
                    try:
                        mod = import_module(module_name)
                        handler = getattr(mod, bits[-1])
                    except __HOLE__:
                        raise ImportError("Could not import %s from the "
                                          "module %s as a connection "
                                             "handler on %s."
                                             % (bits[-1], module_name, cls))
                    except AttributeError:
                        raise AttributeError("Could not import %s from the "
                                             "module %s as a connection "
                                             "handler on %s."
                                             % (bits[-1], module_name, cls))
                self._handlers[key].append(handler)
dataset/ETHPy150Open Havate/havate-openstack/proto-build/gui/horizon/Horizon_GUI/horizon/workflows/base.py/Step.__init__