<commit_before># -*- coding: utf-8 -*-
# Future
from __future__ import absolute_import, division, print_function, \
    unicode_literals, with_statement

# Standard Library
from threading import Timer

# First Party
from metaopt.core.returns.returnspec import ReturnSpec
from metaopt.invoker.multiprocess import MultiProcessInvoker
from metaopt.invoker.pluggable import PluggableInvoker
from metaopt.optimizer.saes import SAESOptimizer
from metaopt.util.stoppable import StoppedError


def custom_optimize(f, invoker, param_spec=None, return_spec=None,
                    timeout=None, optimizer=SAESOptimizer()):
    """
    Optimizes the given objective function using the specified invoker.

    :param f: Objective function
    :param invoker: Invoker
    :param timeout: Available time for optimization (in seconds)
    :param optimizer: Optimizer
    """

    invoker.f = f

    try:
        invoker.param_spec = param_spec or f.param_spec
    except AttributeError:
        raise NoParamSpecError()

    try:
        invoker.return_spec = return_spec or f.return_spec
    except AttributeError:
        invoker.return_spec = ReturnSpec(f)

    if timeout is not None:
        timer = Timer(timeout, invoker.stop)
        timer.start()

    result = optimizer.optimize(invoker=invoker, param_spec=invoker.param_spec,
                                return_spec=invoker.return_spec)

    try:
        invoker.stop()
    except StoppedError:
        pass

    if timeout is not None:
        timer.cancel()

    if result is None:
        return None

    return tuple(result)


def optimize(f, param_spec=None, return_spec=None, timeout=None, plugins=[],
             optimizer=SAESOptimizer()):
    """
    Optimizes the given objective function.

    :param f: Objective function
    :param timeout: Available time for optimization (in seconds)
    :param plugins: List of plugins
    :param optimizer: Optimizer

    """

    invoker = PluggableInvoker(invoker=MultiProcessInvoker(), plugins=plugins)

    return custom_optimize(f, invoker=invoker, param_spec=param_spec,
                           return_spec=return_spec, timeout=timeout,
                           optimizer=optimizer)


class NoParamSpecError(Exception):
    """The error that occurs when no ParamSpec object is provided"""
    def __init__(self):
        super(NoParamSpecError, self).__init__()<commit_msg>Pass GlobalTimeoutErrror to invoker.stop<commit_after># -*- coding: utf-8 -*-
# Future
from __future__ import absolute_import, division, print_function, \
    unicode_literals, with_statement

# Standard Library
from threading import Timer

# First Party
from metaopt.core.returns.returnspec import ReturnSpec
from metaopt.invoker.multiprocess import MultiProcessInvoker
from metaopt.invoker.pluggable import PluggableInvoker
from metaopt.optimizer.saes import SAESOptimizer
from metaopt.util.stoppable import StoppedError


def custom_optimize(f, invoker, param_spec=None, return_spec=None,
                    timeout=None, optimizer=SAESOptimizer()):
    """
    Optimizes the given objective function using the specified invoker.

    :param f: Objective function
    :param invoker: Invoker
    :param timeout: Available time for optimization (in seconds)
    :param optimizer: Optimizer
    """

    invoker.f = f

    try:
        invoker.param_spec = param_spec or f.param_spec
    except AttributeError:
        raise NoParamSpecError()

    try:
        invoker.return_spec = return_spec or f.return_spec
    except AttributeError:
        invoker.return_spec = ReturnSpec(f)

    def stop_optimization():
        error = GlobalTimeoutError(
            "The optimization ran out of time (%s seconds)" % timeout
        )

        invoker.stop(error)

    if timeout is not None:
        timer = Timer(timeout, stop_optimization)
        timer.start()

    result = optimizer.optimize(invoker=invoker, param_spec=invoker.param_spec,
                                return_spec=invoker.return_spec)

    try:
        invoker.stop()
    except StoppedError:
        pass

    if timeout is not None:
        timer.cancel()

    if result is None:
        return None

    return tuple(result)

class GlobalTimeoutError(Exception):
    pass

def optimize(f, param_spec=None, return_spec=None, timeout=None, plugins=[],
             optimizer=SAESOptimizer()):
    """
    Optimizes the given objective function.

    :param f: Objective function
    :param timeout: Available time for optimization (in seconds)
    :param plugins: List of plugins
    :param optimizer: Optimizer

    """

    invoker = PluggableInvoker(invoker=MultiProcessInvoker(), plugins=plugins)

    return custom_optimize(f, invoker=invoker, param_spec=param_spec,
                           return_spec=return_spec, timeout=timeout,
                           optimizer=optimizer)


class NoParamSpecError(Exception):
    """The error that occurs when no ParamSpec object is provided"""
    def __init__(self):
        super(NoParamSpecError, self).__init__()
{'fraction_non_alphanumeric': 0.07675482203221316, 'fraction_numerical': 0.00039769337840524953, 'mean_word_length': 3.0466613032984715, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 3, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '3669063', 'n_tokens_mistral': 1434, 'n_tokens_neox': 1388, 'n_words': 387}