<commit_before>import re
from yota.exceptions import NotCallableException


class MinLengthValidator(object):
    """ Checks to see if data is at least length long.

    :param length: The minimum length of the data.
    :type length: integer

    :param message: The message to present to the user upon failure.
    :type message: string
    """
    __slots__ = ["message", "min_length"]

    def __init__(self, length, message=None):
        self.min_length = length
        self.message = message if message else "Minimum allowed length {0}" \
            .format(length)
        super(MinLengthValidator, self).__init__()

    def __call__(self, target):
        if len(target.data) < self.min_length:
            target.add_error({'message': self.message})


class MaxLengthValidator(object):
    """ Checks to see if data is at most length long.

    :param length: The maximum length of the data.
    :type length: integer

    :param message: The message to present to the user upon failure.
    :type message: string
    """
    __slots__ = ["message", "max_length"]

    def __init__(self, length, message=None):
        self.max_length = length
        self.message = message if message else "Maximum allowed length {0}" \
            .format(length)
        super(MaxLengthValidator, self).__init__()

    def __call__(self, target):
        if len(target.data) > self.max_length:
            target.add_error({'message': self.message})


class NonBlockingDummyValidator(object):
    """ A dummy class for testing non-blocking validators
    """

    def __call__(self, target):
        target.add_error({'message': "I'm not blocking!", 'block': False})


class MatchingValidator(object):
    """ Checks if two nodes values match eachother. The error is delivered to
    the first node.

    :param message: (optional) The message to present to the user upon failure.
    :type message: string
    """
    __slots__ = ["message"]

    def __init__(self, message=None):
        self.message = message if message else "Fields must match"
        super(MatchingValidator, self).__init__()

    def __call__(self, target1, target2):
        if target1.data != target2.data:
            target1.add_error({'message': self.message})


class IntegerValidator(object):
    """ Checks if the value is an integer and converts it to one if it is

    :param message: (optional) The message to present to the user upon failure.
    :type message: string
    """
    __slots__ = ["message"]

    def __init__(self, message=None):
        self.message = message if message else "Value must only contain numbers"
        super(IntegerValidator, self).__init__()

    def __call__(self, target):
        try:
            target.data = int(target.data)
        except ValueError:
            target.add_error({'message': self.message})


class MinMaxValidator(object):
    """ Checks if the value is between the min and max values given

    :param message: (optional) The message to present to the user upon failure.
    :type message: string

    :param min: The minimum length of the data.
    :type length: integer

    :param max: The maximum length of the data.
    :type length: integer
    """
    __slots__ = ["message", "max", "min"]

    def __init__(self, min, max, message=None):
        if message:
            self.message = message
        else:
            self.message = "Length must be between {0} and {1} characters.". \
                            format(min, max)
        self.min = min
        self.max = max
        super(MinMaxValidator, self).__init__()

    def __call__(self, target):
        if len(target.data) < self.min or len(target.data) > self.max:
            target.add_error({'message': self.message})




class RequiredValidator(object):
    """ Checks to make sure the user entered something.

    :param message: (optional) The message to present to the user upon failure.
    :type message: string
    """
    __slots__ = ["message"]
<commit_msg>added regex, password, username, and strong password validators started a matched fields set validator, mostly incomplete<commit_after>import re
from yota.exceptions import NotCallableException


class MinLengthValidator(object):
    """ Checks to see if data is at least length long.

    :param length: The minimum length of the data.
    :type length: integer

    :param message: The message to present to the user upon failure.
    :type message: string
    """
    __slots__ = ["message", "min_length"]

    def __init__(self, length, message=None):
        self.min_length = length
        self.message = message if message else "Minimum allowed length {0}" \
            .format(length)
        super(MinLengthValidator, self).__init__()

    def __call__(self, target):
        if len(target.data) < self.min_length:
            target.add_error({'message': self.message})


class MaxLengthValidator(object):
    """ Checks to see if data is at most length long.

    :param length: The maximum length of the data.
    :type length: integer

    :param message: The message to present to the user upon failure.
    :type message: string
    """
    __slots__ = ["message", "max_length"]

    def __init__(self, length, message=None):
        self.max_length = length
        self.message = message if message else "Maximum allowed length {0}" \
            .format(length)
        super(MaxLengthValidator, self).__init__()

    def __call__(self, target):
        if len(target.data) > self.max_length:
            target.add_error({'message': self.message})


class NonBlockingDummyValidator(object):
    """ A dummy class for testing non-blocking validators
    """

    def __call__(self, target):
        target.add_error({'message': "I'm not blocking!", 'block': False})


class MatchingValidator(object):
    """ Checks if two nodes values match eachother. The error is delivered to
    the first node.

    :param message: (optional) The message to present to the user upon failure.
    :type message: string
    """
    __slots__ = ["message"]

    def __init__(self, message=None):
        self.message = message if message else "Fields must match"
        super(MatchingValidator, self).__init__()

    def __call__(self, target1, target2):
        if target1.data != target2.data:
            target1.add_error({'message': self.message})


class IntegerValidator(object):
    """ Checks if the value is an integer and converts it to one if it is

    :param message: (optional) The message to present to the user upon failure.
    :type message: string
    """
    __slots__ = ["message"]

    def __init__(self, message=None):
        self.message = message if message else "Value must only contain numbers"
        super(IntegerValidator, self).__init__()

    def __call__(self, target):
        try:
            target.data = int(target.data)
        except ValueError:
            target.add_error({'message': self.message})


class MinMaxValidator(object):
    """ Checks if the value is between the min and max values given

    :param message: (optional) The message to present to the user upon failure.
    :type message: string

    :param min: The minimum length of the data.
    :type length: integer

    :param max: The maximum length of the data.
    :type length: integer
    """
    __slots__ = ["message", "max", "min"]

    def __init__(self, min, max, message=None):
        if message:
            self.message = message
        else:
            self.message = "Length must be between {0} and {1} characters.". \
                            format(min, max)
        self.min = min
        self.max = max
        super(MinMaxValidator, self).__init__()

    def __call__(self, target):
        if len(target.data) < self.min or len(target.data) > self.max:
            target.add_error({'message': self.message})


class RegexValidator(object):
    """ Quick and easy check to see if the input
    matches the given regex.

    :param regex: (optional) The regex to run against the input.
    :type regeg: string
    :param message: (optional) The message to present to the user upon failure.
    :type message: string
    """
    __slots__ = ["message", "regex"]

    def __init__(self, regex=None, message=None):
        self.message = message if message else "Input does not match regex"
        self.regex = regex
        super(RegexValidator, self).__init__()

    def __call__(self, target=None):
        if re.match(self.regex, target.data) == None:
            target.add_error({'message': self.message})

class PasswordValidator(RegexValidator):
    """ Quick and easy check to see if a field
    matches a stamdard password regex. This regex
    matches a string at least 7 characters long which
    contains an upper and lowercase letter, a special
    character, a number, and no blanks/returns.

    :param message: (optional) The message to present to the user upon failure.
    :type message: string
    """
    __slots__ = ["message"]

    def __init__(self, message=None):
        self.message = message if message else "Must be 7 characters or longer, contain at least one upper and lower case letter, a number and a special character"
        self.regex = '^(?=.*[0-9])(?=.*[a-z])(?=.*[A-Z])(?=.*[@#$%^&+=])(?=\S+$).{,}$'

class UsernameValidator(RegexValidator):
    """ Quick and easy check to see if a field
    matches a stamdard username regex. This regex
    matches a string from 3-20 characters long and
    composed only of numbers, letters, hyphens, and
    underscores.

    :param message: (optional) The message to present to the user upon failure.
    :type message: string
    """
    __slots__ = ["message"]

    def __init__(self, message=None):
        self.message = message if message else "Must be 3-20 characters and only contain letters, numbers, hyphens and underscores"
        self.regex = '^[a-zA-Z0-9-_]{3,20}$'


class StrongPasswordValidator(object):
    """ A validator to check the password strength.

    :param regex: (optional) The regex to run against the input.
    :type regex: list or tuple
    :param message: (optional) The message to present to the user upon failure.
    :type message: string

    """
    __slots__ = ["message", "regex"]

    def __init__(self, regex=None, message=None):
        self.message = message
        if not isinstance(regex, tuple) and\
           not isinstance(regex, list):
            self.regex = [
                 "(?=.*[A-Z].*[A-Z])", # Matches 2 uppercase letters
                 "(?=.*[!@#$&*])", # Matches 1 Special character
                 "(?=.*[0-9].*[0-9])", # Matches 2 numbers
                 ".{7}" # Has at least 7 characters
             ]
        else:
            self.regex = regex
        super(StrongPasswordValidator, self).__init__()

    def __call__(self, target=None):
        strength = 0

        # Loop through the regex and increment
        # strength for each successful match
        for regex in self.regex:
            if re.match(regex, target.data):
                strength += 1
        target.add_error({'message': "Password strength is " + str(strength),
                          'block': False})


class MatchingFieldsValidator(object):
    """ Checks this field against another to make sure
    that they match

    :param match: (required) The name of the field to match against
    :type match: string
    :param message: (optional) The message to present to the user upon failure.
    :type message: string
    """
    __slots__ = ["message", "field"]

    def __init__(self, field, message=None):
        self.message = message if message else "Fields do no match!"
        super(MatchingFieldsValidator, self).__init__()

    def __call__(self, target=None):
        if target.data == field.data:
            target.add_error({'message': self.message})



class RequiredValidator(object):
    """ Checks to make sure the user entered something.

    :param message: (optional) The message to present to the user upon failure.
    :type message: string
    """
    __slots__ = ["message"]

{'fraction_non_alphanumeric': 0.10505804311774461, 'fraction_numerical': 0.003648424543946932, 'mean_word_length': 2.7317450495049505, 'pattern_counts': {'":': 0, '<': 7, '<?xml version=': 0, '>': 7, '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': '4702489', 'n_tokens_mistral': 3385, 'n_tokens_neox': 3276, 'n_words': 1213}