Example #1
0
 def _get_members(p):
     if not p.exists(encoded_group):
         raise coordination.GroupNotCreated(group_id)
     potential_members = set()
     for m in p.hkeys(encoded_group):
         m = self._decode_member_id(m)
         if m != self.GROUP_EXISTS:
             potential_members.add(m)
     if not potential_members:
         return set()
     # Ok now we need to see which members have passed away...
     gone_members = set()
     member_values = p.mget(
         compat_map(self._encode_beat_id, potential_members))
     for (potential_member,
          value) in compat_zip(potential_members, member_values):
         # Always preserve self (just incase we haven't heartbeated
         # while this call/s was being made...), this does *not* prevent
         # another client from removing this though...
         if potential_member == self._member_id:
             continue
         if not value:
             gone_members.add(potential_member)
     # Trash all the members that no longer are with us... RIP...
     if gone_members:
         p.multi()
         encoded_gone_members = list(
             self._encode_member_id(m) for m in gone_members)
         p.hdel(encoded_group, *encoded_gone_members)
         p.execute()
         return set(m for m in potential_members
                    if m not in gone_members)
     return potential_members
Example #2
0
def _build_rebind_dict(req_args, rebind_args):
    """Build a argument remapping/rebinding dictionary.

    This dictionary allows an atom to declare that it will take a needed
    requirement bound to a given name with another name instead (mapping the
    new name onto the required name).
    """
    if rebind_args is None:
        return collections.OrderedDict()
    elif isinstance(rebind_args, (list, tuple)):
        # Attempt to map the rebound argument names position by position to
        # the required argument names (if they are the same length then
        # this determines how to remap the required argument names to the
        # rebound ones).
        rebind = collections.OrderedDict(compat_zip(req_args, rebind_args))
        if len(req_args) < len(rebind_args):
            # Extra things were rebound, that may be because of *args
            # or **kwargs (or some other reason); so just keep all of them
            # using 1:1 rebinding...
            rebind.update((a, a) for a in rebind_args[len(req_args):])
        return rebind
    elif isinstance(rebind_args, dict):
        return rebind_args
    else:
        raise TypeError("Invalid rebind value '%s' (%s)" %
                        (rebind_args, type(rebind_args)))
Example #3
0
 def _get_members(p):
     if not p.exists(encoded_group):
         raise coordination.GroupNotCreated(group_id)
     potential_members = []
     for m in p.hkeys(encoded_group):
         m = self._decode_member_id(m)
         if m != self.GROUP_EXISTS:
             potential_members.append(m)
     if not potential_members:
         return []
     # Ok now we need to see which members have passed away...
     gone_members = set()
     member_values = p.mget(compat_map(self._encode_beat_id,
                                       potential_members))
     for (potential_member, value) in compat_zip(potential_members,
                                                 member_values):
         # Always preserve self (just incase we haven't heartbeated
         # while this call/s was being made...), this does *not* prevent
         # another client from removing this though...
         if potential_member == self._member_id:
             continue
         if not value:
             gone_members.add(potential_member)
     # Trash all the members that no longer are with us... RIP...
     if gone_members:
         p.multi()
         encoded_gone_members = list(self._encode_member_id(m)
                                     for m in gone_members)
         p.hdel(encoded_group, *encoded_gone_members)
         p.execute()
         return list(m for m in potential_members
                     if m not in gone_members)
     else:
         return potential_members
Example #4
0
def checked_commit(txn):
    """Commits a kazoo transcation and validates the result.

    NOTE(harlowja): Until https://github.com/python-zk/kazoo/pull/224 is fixed
    or a similar pull request is merged we have to workaround the transaction
    failing silently.
    """
    if not txn.operations:
        return []
    results = txn.commit()
    failures = []
    for op, result in compat_zip(txn.operations, results):
        if isinstance(result, k_exc.KazooException):
            failures.append((op, result))
    if len(results) < len(txn.operations):
        raise KazooTransactionException(
            "Transaction returned %s results, this is less than"
            " the number of expected transaction operations %s" %
            (len(results), len(txn.operations)), failures)
    if len(results) > len(txn.operations):
        raise KazooTransactionException(
            "Transaction returned %s results, this is greater than"
            " the number of expected transaction operations %s" %
            (len(results), len(txn.operations)), failures)
    if failures:
        raise KazooTransactionException(
            "Transaction with %s operations failed: %s" %
            (len(txn.operations), prettify_failures(failures, limit=1)),
            failures)
    return results
Example #5
0
def checked_commit(txn):
    """Commits a kazoo transcation and validates the result.

    NOTE(harlowja): Until https://github.com/python-zk/kazoo/pull/224 is fixed
    or a similar pull request is merged we have to workaround the transaction
    failing silently.
    """
    if not txn.operations:
        return []
    results = txn.commit()
    failures = []
    for op, result in compat_zip(txn.operations, results):
        if isinstance(result, k_exc.KazooException):
            failures.append((op, result))
    if len(results) < len(txn.operations):
        raise KazooTransactionException(
            "Transaction returned %s results, this is less than"
            " the number of expected transaction operations %s"
            % (len(results), len(txn.operations)), failures)
    if len(results) > len(txn.operations):
        raise KazooTransactionException(
            "Transaction returned %s results, this is greater than"
            " the number of expected transaction operations %s"
            % (len(results), len(txn.operations)), failures)
    if failures:
        raise KazooTransactionException(
            "Transaction with %s operations failed: %s"
            % (len(txn.operations),
               prettify_failures(failures, limit=1)), failures)
    return results
Example #6
0
def _build_rebind_dict(req_args, rebind_args):
    """Build a argument remapping/rebinding dictionary.

    This dictionary allows an atom to declare that it will take a needed
    requirement bound to a given name with another name instead (mapping the
    new name onto the required name).
    """
    if rebind_args is None:
        return collections.OrderedDict()
    elif isinstance(rebind_args, (list, tuple)):
        # Attempt to map the rebound argument names position by position to
        # the required argument names (if they are the same length then
        # this determines how to remap the required argument names to the
        # rebound ones).
        rebind = collections.OrderedDict(compat_zip(req_args, rebind_args))
        if len(req_args) < len(rebind_args):
            # Extra things were rebound, that may be because of *args
            # or **kwargs (or some other reason); so just keep all of them
            # using 1:1 rebinding...
            rebind.update((a, a) for a in rebind_args[len(req_args):])
        return rebind
    elif isinstance(rebind_args, dict):
        return rebind_args
    else:
        raise TypeError("Invalid rebind value '%s' (%s)"
                        % (rebind_args, type(rebind_args)))
Example #7
0
 def handles(cls, message, channel, config):
     channel_matcher = cls.handles_what['channel_matcher']
     if not channel_matcher(channel):
         return None
     message_matcher = cls.handles_what['message_matcher']
     if (not message_matcher(message, cls, only_to_me=False) or
             # Skip threaded entries...
             message.body.thread_ts):
         return None
     projects, projects_matchers = cls.cache
     if not projects:
         return None
     unfurl_projects = config.get("unfurl_projects")
     matches = {}
     for p, p_matcher in compat_zip(projects, projects_matchers):
         if (not p_matcher or (unfurl_projects is not None
                               and p.key not in unfurl_projects)):
             continue
         p_matches = p_matcher.findall(message.body.text_no_links)
         if p_matches:
             matches[p.key] = set(p_matches)
     if not matches:
         return None
     else:
         return handler.ExplicitHandlerMatch({'matches': matches})
Example #8
0
def _build_rebind_dict(args, rebind_args):
    """Build a argument remapping/rebinding dictionary.

    This dictionary allows an atom to declare that it will take a needed
    requirement bound to a given name with another name instead (mapping the
    new name onto the required name).
    """
    if rebind_args is None:
        return OrderedDict()
    elif isinstance(rebind_args, (list, tuple)):
        rebind = OrderedDict(compat_zip(args, rebind_args))
        if len(args) < len(rebind_args):
            rebind.update((a, a) for a in rebind_args[len(args):])
        return rebind
    elif isinstance(rebind_args, dict):
        return rebind_args
    else:
        raise TypeError("Invalid rebind value '%s' (%s)" %
                        (rebind_args, type(rebind_args)))
Example #9
0
def _build_rebind_dict(args, rebind_args):
    """Build a argument remapping/rebinding dictionary.

    This dictionary allows an atom to declare that it will take a needed
    requirement bound to a given name with another name instead (mapping the
    new name onto the required name).
    """
    if rebind_args is None:
        return collections.OrderedDict()
    elif isinstance(rebind_args, (list, tuple)):
        rebind = collections.OrderedDict(compat_zip(args, rebind_args))
        if len(args) < len(rebind_args):
            rebind.update((a, a) for a in rebind_args[len(args):])
        return rebind
    elif isinstance(rebind_args, dict):
        return rebind_args
    else:
        raise TypeError("Invalid rebind value '%s' (%s)"
                        % (rebind_args, type(rebind_args)))
Example #10
0
def extract_args(args,
                 args_order,
                 args_converters=None,
                 args_defaults=None,
                 allow_extras=False,
                 args_accumulate=None):
    if isinstance(args, (six.string_types)):
        # Because OSX can do this, and it will bust shlex splitting.
        for c in NAUGHTY_DOUBLE_QUOTES:
            args = args.replace(c, '"')
        for c in NAUGHTY_SINGLE_QUOTES:
            args = args.replace(c, "'")
        arg_pieces = shlex.split(args)
    elif isinstance(args, (list, tuple)):
        arg_pieces = []
        for a in args:
            if not isinstance(a, (six.string_types)):
                a = str(a)
            arg_pieces.append(a)
    else:
        raise TypeError("Expected string or"
                        " list/tuple, not %s" % type(args))

    if args_converters is None:
        args_converters = {}
    if args_defaults is None:
        args_defaults = {}
    if args_accumulate is None:
        args_accumulate = set()

    maybe_args = []
    maybe_kwargs = []
    for i, arg in enumerate(arg_pieces):
        if is_likely_kwarg(arg):
            maybe_kwargs.append(i)
        else:
            maybe_args.append(i)

    if maybe_args and maybe_kwargs:
        # It's easier to just not allow intermixing then trying to
        # determine and especially *reason* about the order of
        # intermixed positional arguments and keyword arguments...
        #
        # So ya, just die if they are likely intermixed...
        min_kwarg_idx = min(maybe_kwargs)
        max_arg_idx = max(maybe_args)
        min_arg_idx = min(maybe_args)
        if min_kwarg_idx < min_arg_idx or max_arg_idx > min_kwarg_idx:
            raise excp.ArgumentError("Keyword arguments must always follow"
                                     " positional arguments (and not be"
                                     " intermixed)")

    in_kwargs = collections.defaultdict(list)
    in_kwargs_order = []
    in_pos_args = []
    for i in maybe_args:
        in_pos_args.append(arg_pieces[i])
    for i in maybe_kwargs:
        arg, arg_val = arg_pieces[i].split("=", 1)
        in_kwargs[arg].append(arg_val)
        in_kwargs_order.append(arg)

    if len(in_pos_args) > len(args_order):
        if not allow_extras:
            num_extra_args = len(in_pos_args) - len(args_order)
            raise excp.ArgumentError("%s extra (and unexpected)"
                                     " positional arguments were provided" %
                                     num_extra_args)

    out_args = collections.OrderedDict()
    for arg_name, arg_value in compat_zip(args_order, in_pos_args):
        if arg_name in args_accumulate:
            out_args[arg_name] = [arg_value]
        else:
            out_args[arg_name] = arg_value

    for arg_name in in_kwargs_order:
        if arg_name not in args_order:
            if not allow_extras:
                raise excp.ArgumentError(
                    "Unknown keyword argument '%s' provided" % (arg_name))
        arg_values = in_kwargs[arg_name]
        if arg_name in args_accumulate:
            if arg_name in out_args:
                existing_arg_values = out_args[arg_name]
                existing_arg_values.extend(arg_values)
            else:
                out_args[arg_name] = list(arg_values)
        else:
            out_args[arg_name] = arg_values[-1]

    for arg_name in args_order:
        try:
            arg_value = out_args[arg_name]
        except KeyError:
            if arg_name in args_defaults:
                if arg_name in args_accumulate:
                    out_args[arg_name] = [args_defaults[arg_name]]
                else:
                    out_args[arg_name] = args_defaults[arg_name]

    for arg_name in list(six.iterkeys(out_args)):
        arg_value = out_args[arg_name]
        arg_converter = args_converters.get(arg_name)
        if arg_converter is not None:
            if arg_name in args_accumulate:
                for i, i_arg_value in enumerate(arg_value):
                    arg_value[i] = arg_converter(i_arg_value)
            else:
                out_args[arg_name] = arg_converter(arg_value)

    return out_args