def _process_user_algorithm(algorithm):
    """Process the user specfied algorithm.

    Args:
        algorithm (str or callable): The user specified algorithm.

    Returns:
        callable: The internal algorithm.
        str: The name of the algorithm.

    """
    if isinstance(algorithm, str):
        algo_name = algorithm
    else:
        algo_name = getattr(algorithm, "name", "your algorithm")

    if isinstance(algorithm, str):
        try:
            algorithm = AVAILABLE_ALGORITHMS[algorithm]
        except KeyError:
            proposed = propose_alternatives(algorithm, list(AVAILABLE_ALGORITHMS))
            raise ValueError(
                f"Invalid algorithm: {algorithm}. Did you mean {proposed}?"
            ) from None

    return algorithm, algo_name
Esempio n. 2
0
def process_user_algorithm(algorithm):
    """Process the user specfied algorithm.

    If the algorithm is a callable, this function just reads out the algorithm_info
    and available options. If algorithm is a string it loads the algorithm function
    from the available algorithms.

    Args:
        algorithm (str or callable): The user specified algorithm.

    Returns:
        callable: the raw internal algorithm
        AlgoInfo: Attributes of the algorithm
        set: The free arguments of the algorithm.

    """
    if isinstance(algorithm, str):
        try:
            # Use ALL_ALGORITHMS and not just AVAILABLE_ALGORITHMS such that the
            # algorithm specific error message with installation instruction will be
            # reached if an optional dependency is not installed.
            algorithm = ALL_ALGORITHMS[algorithm]
        except KeyError:
            proposed = propose_alternatives(algorithm, list(ALL_ALGORITHMS))
            raise ValueError(
                f"Invalid algorithm: {algorithm}. Did you mean {proposed}?"
            ) from None

    algo_info = algorithm._algorithm_info

    return algorithm, algo_info
Esempio n. 3
0
def process_func_of_params(func,
                           kwargs,
                           name="your function",
                           skip_checks=False):
    # fast path
    if skip_checks and kwargs in (None, {}):
        return func

    kept, ignored = filter_kwargs(func, kwargs)

    if ignored:
        possibilities = [
            p for p in inspect.signature(func).parameters if p != "params"
        ]
        proposals = [
            propose_alternatives(arg, possibilities, 1)[0] for arg in ignored
        ]

        msg = (
            "The following user provided keyword arguments are not compatible with "
            f"{name}:\n\n")
        for arg, prop in zip(ignored, proposals):
            msg += f"{arg}: Did you mean {prop}?"

        raise InvalidKwargsError(msg)

    out = partial(func, **kept)

    if not skip_checks:

        unpartialled_args = get_unpartialled_arguments(out)
        no_default_args = get_arguments_without_default(out)

        no_free_argument_left = len(unpartialled_args) < 1

        if no_free_argument_left and kept:
            raise InvalidKwargsError(
                f"Too many keyword arguments for {name}. After applying all keyword "
                "arguments there must be at least one free argument (the params) left."
            )
        elif no_free_argument_left:
            raise InvalidFunctionError(
                f"{name} must have at least one free argument.")

        required_args = unpartialled_args.intersection(no_default_args)
        too_many_required_arguments = len(required_args) > 1

        # Try to discover if we have a jax calculated jacobian that has a weird
        # signature that would not pass this test:
        skip_because_of_jax = required_args == {"args", "kwargs"}

        if too_many_required_arguments and not skip_because_of_jax:
            raise InvalidKwargsError(
                f"Too few keyword arguments for {name}. After applying all keyword "
                "arguments at most one required argument (the params) should remain. "
                "in your case the following required arguments remain: "
                f"{required_args}.")

    return out
Esempio n. 4
0
def _check_only_allowed_subset_provided(subset, allowed, name):
    """Check if all entries of a proposed subset are in a Series.

    Args:
        subset (iterable or None): If None, no checks are performed. Else a ValueError
            is raised listing all entries that are not in the provided Series.
        allowed (iterable): allowed entries.
        name (str): name of the provided entries to use for the ValueError.

    Raises:
        ValueError

    """
    allowed = set(allowed)
    if subset is not None:
        missing = [entry for entry in subset if entry not in allowed]
        if missing:
            missing_msg = ""
            for entry in missing:
                proposed = propose_alternatives(entry, allowed)
                missing_msg += f"Invalid {name}: {entry}. Did you mean {proposed}?\n"
            raise ValueError(missing_msg)