def from_string(cls, action_str):
        args = {}
        try:
            mod_obj = ast.parse(action_str)
        except (SyntaxError, ValueError) as e:
            raise e
        else:
            call_obj = mod_obj.body[0].value
            if isinstance(call_obj, ast.Attribute):
                module = call_obj.value.id
                func = call_obj.attr
            elif isinstance(call_obj, ast.Call):
                try:
                    module = call_obj.func.value.id
                    func = call_obj.func.attr
                except AttributeError:
                    raise UnsupportedActionError(action_str)
                else:
                    for kwarg in call_obj.keywords:
                        if isinstance(kwarg.value, ast.Num):
                            args.update({kwarg.arg: kwarg.value.n})
                        elif isinstance(kwarg.value, ast.Str):
                            args.update({kwarg.arg: kwarg.value.s})
                        else:
                            raise UnsupportedActionArgumentError(action_str,
                                                                 kwarg)
            else:
                raise UnsupportedActionError(action_str)
        return cls(module, func, args)