<commit_before>import collections
import logging
import itertools

from .pluggable import Pluggable

logger = logging.getLogger(__name__)


class Check(Pluggable):
    """
    Base class for service check plugins.

    Subclasses are expected to define a name for the check, plus methods for
    validating that any dependencies are present, the given config is valid,
    and of course performing the check itself.
    """

    entry_point = "lighthouse.checks"

    def __init__(self):
        self.results = deque()
        self.passing = False

    @classmethod
    def validate_check_config(cls, config):
        """
        This method should return True if the given config is valid for the
        health check subclass, False otherwise.
        """
        raise NotImplementedError

    def apply_check_config(self, config):
        """
        This method takes an already-validated configuration dictionary as its
        only argument.

        The method should set any attributes or state in the instance needed
        for performing the health check.
        """
        raise NotImplementedError

    def perform(self):
        """
        This `perform()` is at the heart of the check.  Subclasses must define
        this method to actually perform their check.  If the check passes, the
        method should return True, otherwise False.

        Note that this method takes no arguments.  Any sort of context required
        for performing a check should be handled by the config.
        """
        raise NotImplementedError

    def run(self):
        """
        Calls the `perform()` method defined by subclasses and stores the
        result in a `results` deque.

        After the result is determined the `results` deque is analyzed to see
        if the `passing` flag should be updated.  If the check was considered
        passing and the previous `self.fall` number of checks failed, the check
        is updated to not be passing.  If the check was not passing and the
        previous `self.rise` number of checks passed, the check is updated to
        be considered passing.
        """
        logger.debug("Running %s check", self.name)

        try:
            result = self.perform()
        except Exception:
            logger.exception("Error while performing %s check", self.name)
            result = False

        logger.debug("Result: %s", result)

        self.results.append(result)
        if self.passing and not any(self.last_n_results(self.fall)):
            logger.info(
                "%s check failed %d time(s), no longer passing.",
                self.name, self.fall,
            )
            self.passing = False
        if not self.passing and all(self.last_n_results(self.rise)):
            logger.info(
                "%s check passed %d time(s), is now passing.",
                self.name, self.rise
            )
            self.passing = True

    def last_n_results(self, n):
        """
        Helper method for returning a set number of the previous check results.
        """
        return list(
            itertools.islice(
                self.results, len(self.results) - n, len(self.results)
            )
        )

    def apply_config(self, config):
        """
        Sets attributes based on the given config.

        Also adjusts the `results` deque to either expand (padding itself with
        False results) or contract (by removing the oldest results) until it
        matches the required length.
        """
        self.host = config["host"]
        self.port = int(config["port"])
        self.rise = config["rise"]
        self.fall = config["fall"]

        self.apply_check_config(config)

        if self.results.maxlen == max(self.rise, self.fall):
            return

        results = list(self.results)
        while len(results) > max(self.rise, self.fall):
            results.pop(0)
        while len(results) < max(self.rise, self.fall):
            results.insert(0, False)

        self.results = deque(
            results,
            maxlen=max(self.rise, self.fall)
        )

    @classmethod
    def validate_config(cls, config):
        """
        Validates that required config entries are present.

        Each check requires a `host`, `port`, `rise` and `fall` to be
        configured.

        The rise and fall variables are integers denoting how many times a
        check must pass before being considered passing and how many times a
        check must fail before being considered failing.
        """
        if "host" not in config:
            raise ValueError("No host configured")
        if "port" not in config:
            raise ValueError("No port configured")
        if "rise" not in config:
            raise ValueError("No 'rise' configured")
        if "fall" not in config:
            raise ValueError("No 'fall' configured")

        try:
            int(config["port"])
        except Exception:
            raise ValueError("Invalid value for 'port'")

        cls.validate_check_config(config)

    @classmethod
    def from_config(cls, name, host, port, config):
        """
        Behaves like the base Configurable class's `from_config()` except this
        method transfers the given service's host and port to the config.
        """
        config["host"] = host
        config["port"] = int(port)

        return super(Check, cls).from_config(name, config)


class deque(collections.deque):
    """
    Custom collections.deque subclass for 2.6 compatibility.

    The python 2.6 version of the deque class doesn't support referring to
    the `maxlen` attribute.
    """

    def __init__(self, iterable=(), maxlen=None):
        self._maxlen = maxlen
        super(deque, self).__init__(iterable=iterable, maxlen=maxlen)

    @property
    def maxlen(self):
        return self._maxlen
<commit_msg>Define Check's attributes in the constructor.<commit_after>import collections
import logging
import itertools

from .pluggable import Pluggable

logger = logging.getLogger(__name__)


class Check(Pluggable):
    """
    Base class for service check plugins.

    Subclasses are expected to define a name for the check, plus methods for
    validating that any dependencies are present, the given config is valid,
    and of course performing the check itself.
    """

    entry_point = "lighthouse.checks"

    def __init__(self):
        self.host = None
        self.port = None

        self.rise = None
        self.fall = None

        self.results = deque()
        self.passing = False

    @classmethod
    def validate_check_config(cls, config):
        """
        This method should return True if the given config is valid for the
        health check subclass, False otherwise.
        """
        raise NotImplementedError

    def apply_check_config(self, config):
        """
        This method takes an already-validated configuration dictionary as its
        only argument.

        The method should set any attributes or state in the instance needed
        for performing the health check.
        """
        raise NotImplementedError

    def perform(self):
        """
        This `perform()` is at the heart of the check.  Subclasses must define
        this method to actually perform their check.  If the check passes, the
        method should return True, otherwise False.

        Note that this method takes no arguments.  Any sort of context required
        for performing a check should be handled by the config.
        """
        raise NotImplementedError

    def run(self):
        """
        Calls the `perform()` method defined by subclasses and stores the
        result in a `results` deque.

        After the result is determined the `results` deque is analyzed to see
        if the `passing` flag should be updated.  If the check was considered
        passing and the previous `self.fall` number of checks failed, the check
        is updated to not be passing.  If the check was not passing and the
        previous `self.rise` number of checks passed, the check is updated to
        be considered passing.
        """
        logger.debug("Running %s check", self.name)

        try:
            result = self.perform()
        except Exception:
            logger.exception("Error while performing %s check", self.name)
            result = False

        logger.debug("Result: %s", result)

        self.results.append(result)
        if self.passing and not any(self.last_n_results(self.fall)):
            logger.info(
                "%s check failed %d time(s), no longer passing.",
                self.name, self.fall,
            )
            self.passing = False
        if not self.passing and all(self.last_n_results(self.rise)):
            logger.info(
                "%s check passed %d time(s), is now passing.",
                self.name, self.rise
            )
            self.passing = True

    def last_n_results(self, n):
        """
        Helper method for returning a set number of the previous check results.
        """
        return list(
            itertools.islice(
                self.results, len(self.results) - n, len(self.results)
            )
        )

    def apply_config(self, config):
        """
        Sets attributes based on the given config.

        Also adjusts the `results` deque to either expand (padding itself with
        False results) or contract (by removing the oldest results) until it
        matches the required length.
        """
        self.host = config["host"]
        self.port = int(config["port"])
        self.rise = config["rise"]
        self.fall = config["fall"]

        self.apply_check_config(config)

        if self.results.maxlen == max(self.rise, self.fall):
            return

        results = list(self.results)
        while len(results) > max(self.rise, self.fall):
            results.pop(0)
        while len(results) < max(self.rise, self.fall):
            results.insert(0, False)

        self.results = deque(
            results,
            maxlen=max(self.rise, self.fall)
        )

    @classmethod
    def validate_config(cls, config):
        """
        Validates that required config entries are present.

        Each check requires a `host`, `port`, `rise` and `fall` to be
        configured.

        The rise and fall variables are integers denoting how many times a
        check must pass before being considered passing and how many times a
        check must fail before being considered failing.
        """
        if "host" not in config:
            raise ValueError("No host configured")
        if "port" not in config:
            raise ValueError("No port configured")
        if "rise" not in config:
            raise ValueError("No 'rise' configured")
        if "fall" not in config:
            raise ValueError("No 'fall' configured")

        try:
            int(config["port"])
        except Exception:
            raise ValueError("Invalid value for 'port'")

        cls.validate_check_config(config)

    @classmethod
    def from_config(cls, name, host, port, config):
        """
        Behaves like the base Configurable class's `from_config()` except this
        method transfers the given service's host and port to the config.
        """
        config["host"] = host
        config["port"] = int(port)

        return super(Check, cls).from_config(name, config)


class deque(collections.deque):
    """
    Custom collections.deque subclass for 2.6 compatibility.

    The python 2.6 version of the deque class doesn't support referring to
    the `maxlen` attribute.
    """

    def __init__(self, iterable=(), maxlen=None):
        self._maxlen = maxlen
        super(deque, self).__init__(iterable=iterable, maxlen=maxlen)

    @property
    def maxlen(self):
        return self._maxlen

{'fraction_non_alphanumeric': 0.08118578406602661, 'fraction_numerical': 0.001010611419909045, 'mean_word_length': 2.101331940454427, 'pattern_counts': {'":': 0, '<': 5, '<?xml version=': 0, '>': 5, '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': '2087082', 'n_tokens_mistral': 3069, 'n_tokens_neox': 2984, 'n_words': 1155}