U
    b^>                     @   sv  d Z ddlmZmZmZ ddlZddlZddlmZ ddl	m
Z
mZ ddlmZmZmZmZ ddlmZ z
ejZW n" ek
r   eed	ZY nX d
ddddddddddddddddgZdd Zdd Zedd Zedddd G d!d" d"eZd#d Zedddd$G d%d& d&eZdCd'dZedddd G d(d) d)eZ d*d Z!edddd G d+d, d,eZ"d-d Z#edddd G d.d/ d/eZ$d0d Z%edddd G d1d2 d2eZ&d3d Z'edddd G d4d5 d5eZ(dDd6dZ)edddd G d7d8 d8eZ*dEd9dZ+edddd$G d:d; d;eZ,d<d Z-d=d Z.d>d Z/d?d Z0edddd$G d@dA dAeZ1dBd Z2dS )Fz
Commonly useful validators.
    )absolute_importdivisionprint_functionN)contextmanager   )get_run_validatorsset_run_validators)_AndValidatorand_attribattrs)NotCallableError r
   deep_iterabledeep_mappingdisabledgeget_disabledgtin_instance_ofis_callablelelt
matches_remax_lenoptionalprovidesset_disabledc                 C   s   t |   dS )a  
    Globally disable or enable running validators.

    By default, they are run.

    :param disabled: If ``True``, disable running all validators.
    :type disabled: bool

    .. warning::

        This function is not thread-safe!

    .. versionadded:: 21.3.0
    Nr   )r    r    3/tmp/pip-unpacked-wheel-9rkxrohn/attr/validators.pyr   .   s    c                   C   s   t   S )z
    Return a bool indicating whether validators are currently disabled or not.

    :return: ``True`` if validators are currently disabled.
    :rtype: bool

    .. versionadded:: 21.3.0
    )r   r    r    r    r!   r   @   s    	c                   c   s"   t d z
dV  W 5 t d X dS )z
    Context manager that disables running validators within its context.

    .. warning::

        This context manager is not thread-safe!

    .. versionadded:: 21.3.0
    FTNr   r    r    r    r!   r   L   s    
FT)reprslotshashc                   @   s"   e Zd Ze Zdd Zdd ZdS )_InstanceOfValidatorc                 C   s4   t || js0tdj|j| j|j|d|| j|dS )P
        We use a callable class to be able to change the ``__repr__``.
        z?'{name}' must be {type!r} (got {value!r} that is a {actual!r}).)nametypeactualvalueN)
isinstancer(   	TypeErrorformatr'   	__class__selfinstattrr*   r    r    r!   __call__b   s    z_InstanceOfValidator.__call__c                 C   s   dj | jdS )Nz)<instance_of validator for type {type!r}>r(   )r-   r(   r0   r    r    r!   __repr__t   s    z_InstanceOfValidator.__repr__N)__name__
__module____qualname__r   r(   r3   r6   r    r    r    r!   r%   ^   s   r%   c                 C   s   t | S )a  
    A validator that raises a `TypeError` if the initializer is called
    with a wrong type for this particular attribute (checks are performed using
    `isinstance` therefore it's also valid to pass a tuple of types).

    :param type: The type to check for.
    :type type: type or tuple of types

    :raises TypeError: With a human readable error message, the attribute
        (of type `attrs.Attribute`), the expected type, and the value it
        got.
    )r%   r4   r    r    r!   r   z   s    )r"   frozenr#   c                   @   s(   e Zd Ze Ze Zdd Zdd ZdS )_MatchesReValidatorc                 C   s0   |  |s,tdj|j| jj|d|| j|dS )r&   z9'{name}' must match regex {pattern!r} ({value!r} doesn't))r'   patternr*   N)
match_func
ValueErrorr-   r'   r<   r/   r    r    r!   r3      s    
  z_MatchesReValidator.__call__c                 C   s   dj | jdS )Nz.<matches_re validator for pattern {pattern!r}>)r<   )r-   r<   r5   r    r    r!   r6      s    z_MatchesReValidator.__repr__N)r7   r8   r9   r   r<   r=   r3   r6   r    r    r    r!   r;      s   r;   c              	   C   s   t tdd}|dtjtjf}||krJtddtdd t|D t	| t
rf|r`td| }nt| |}|tjkr|j}n:|tjkr|j}n(|r|j}ntd|j|j}|j}t||S )	a  
    A validator that raises `ValueError` if the initializer is called
    with a string that doesn't match *regex*.

    :param regex: a regex string or precompiled pattern to match against
    :param int flags: flags that will be passed to the underlying re function
        (default 0)
    :param callable func: which underlying `re` function to call (options
        are `re.fullmatch`, `re.search`, `re.match`, default
        is ``None`` which means either `re.fullmatch` or an emulation of
        it on Python 2). For performance reasons, they won't be used directly
        but on a pre-`re.compile`\ ed pattern.

    .. versionadded:: 19.2.0
    .. versionchanged:: 21.3.0 *regex* can be a pre-compiled pattern.
    	fullmatchNz'func' must be one of {}.z, c                 s   s   | ]}|r|j pd V  qdS )NoneN)r7   ).0er    r    r!   	<genexpr>   s    zmatches_re.<locals>.<genexpr>zR'flags' can only be used with a string pattern; pass flags to re.compile() insteadz(?:{})\Z)getattrresearchmatchr>   r-   joinsortedsetr+   Patternr,   compiler?   r<   flagsr;   )regexrM   funcr?   Zvalid_funcsr<   r=   r    r    r!   r      s>    




 c                   @   s"   e Zd Ze Zdd Zdd ZdS )_ProvidesValidatorc                 C   s0   | j |s,tdj|j| j |d|| j |dS )r&   z<'{name}' must provide {interface!r} which {value!r} doesn't.)r'   	interfacer*   N)rQ   Z
providedByr,   r-   r'   r/   r    r    r!   r3      s      z_ProvidesValidator.__call__c                 C   s   dj | jdS )Nz0<provides validator for interface {interface!r}>rQ   )r-   rQ   r5   r    r    r!   r6      s    z_ProvidesValidator.__repr__N)r7   r8   r9   r   rQ   r3   r6   r    r    r    r!   rP      s   rP   c                 C   s   t | S )a)  
    A validator that raises a `TypeError` if the initializer is called
    with an object that does not provide the requested *interface* (checks are
    performed using ``interface.providedBy(value)`` (see `zope.interface
    <https://zopeinterface.readthedocs.io/en/latest/>`_).

    :param interface: The interface to check for.
    :type interface: ``zope.interface.Interface``

    :raises TypeError: With a human readable error message, the attribute
        (of type `attrs.Attribute`), the expected interface, and the
        value it got.
    )rP   rR   r    r    r!   r      s    c                   @   s"   e Zd Ze Zdd Zdd ZdS )_OptionalValidatorc                 C   s   |d krd S |  ||| d S )N	validatorr/   r    r    r!   r3   	  s    z_OptionalValidator.__call__c                 C   s   dj t| jdS )Nz'<optional validator for {what} or None>)what)r-   r"   rU   r5   r    r    r!   r6     s    z_OptionalValidator.__repr__N)r7   r8   r9   r   rU   r3   r6   r    r    r    r!   rS     s   rS   c                 C   s   t | trtt| S t| S )a  
    A validator that makes an attribute optional.  An optional attribute is one
    which can be set to ``None`` in addition to satisfying the requirements of
    the sub-validator.

    :param validator: A validator (or a list of validators) that is used for
        non-``None`` values.
    :type validator: callable or `list` of callables.

    .. versionadded:: 15.1.0
    .. versionchanged:: 17.1.0 *validator* can be a list of validators.
    )r+   listrS   r	   rT   r    r    r!   r     s    
c                   @   s"   e Zd Ze Zdd Zdd ZdS )_InValidatorc                 C   sH   z|| j k}W n tk
r&   d}Y nX |sDtdj|j| j |dd S )NFz/'{name}' must be in {options!r} (got {value!r}))r'   optionsr*   )rY   r,   r>   r-   r'   )r0   r1   r2   r*   Z
in_optionsr    r    r!   r3   +  s    
  z_InValidator.__call__c                 C   s   dj | jdS )Nz(<in_ validator with options {options!r}>rY   )r-   rY   r5   r    r    r!   r6   8  s    z_InValidator.__repr__N)r7   r8   r9   r   rY   r3   r6   r    r    r    r!   rX   '  s   rX   c                 C   s   t | S )a  
    A validator that raises a `ValueError` if the initializer is called
    with a value that does not belong in the options provided.  The check is
    performed using ``value in options``.

    :param options: Allowed options.
    :type options: list, tuple, `enum.Enum`, ...

    :raises ValueError: With a human readable error message, the attribute (of
       type `attrs.Attribute`), the expected options, and the value it
       got.

    .. versionadded:: 17.1.0
    )rX   rZ   r    r    r!   r   >  s    c                   @   s   e Zd Zdd Zdd ZdS )_IsCallableValidatorc                 C   s,   t |s(d}t|j|j||jd|ddS )r&   z?'{name}' must be callable (got {value!r} that is a {actual!r}).)r'   r*   r)   )msgr*   N)callabler   r-   r'   r.   )r0   r1   r2   r*   messager    r    r!   r3   R  s      z_IsCallableValidator.__call__c                 C   s   dS )Nz<is_callable validator>r    r5   r    r    r!   r6   b  s    z_IsCallableValidator.__repr__N)r7   r8   r9   r3   r6   r    r    r    r!   r[   P  s   r[   c                   C   s   t  S )ax  
    A validator that raises a `attr.exceptions.NotCallableError` if the
    initializer is called with a value for this particular attribute
    that is not callable.

    .. versionadded:: 19.1.0

    :raises `attr.exceptions.NotCallableError`: With a human readable error
        message containing the attribute (`attrs.Attribute`) name,
        and the value it got.
    )r[   r    r    r    r!   r   f  s    c                   @   s:   e Zd Zee dZedee dZdd Zdd Z	dS )_DeepIterablerT   NdefaultrU   c                 C   s4   | j dk	r|  ||| |D ]}| ||| qdS r&   N)iterable_validatormember_validator)r0   r1   r2   r*   memberr    r    r!   r3   |  s    
z_DeepIterable.__call__c                 C   s,   | j d krdndj| j d}dj|| jdS )Nr   z {iterable!r})iterablezJ<deep_iterable validator for{iterable_identifier} iterables of {member!r}>)iterable_identifierre   )rc   r-   rd   )r0   rg   r    r    r!   r6     s    z_DeepIterable.__repr__)
r7   r8   r9   r   r   rd   r   rc   r3   r6   r    r    r    r!   r_   u  s    
r_   c                 C   s
   t | |S )a1  
    A validator that performs deep validation of an iterable.

    :param member_validator: Validator to apply to iterable members
    :param iterable_validator: Validator to apply to iterable itself
        (optional)

    .. versionadded:: 19.1.0

    :raises TypeError: if any sub-validators fail
    )r_   )rd   rc   r    r    r!   r     s    c                   @   sF   e Zd Zee dZee dZedee dZdd Z	dd Z
dS )_DeepMappingrT   Nr`   c                 C   sF   | j dk	r|  ||| |D ]$}| ||| | ||||  qdS rb   )mapping_validatorkey_validatorvalue_validator)r0   r1   r2   r*   keyr    r    r!   r3     s
    
z_DeepMapping.__call__c                 C   s   dj | j| jdS )NzA<deep_mapping validator for objects mapping {key!r} to {value!r}>)rl   r*   )r-   rj   rk   r5   r    r    r!   r6     s
     z_DeepMapping.__repr__)r7   r8   r9   r   r   rj   rk   r   ri   r3   r6   r    r    r    r!   rh     s
   rh   c                 C   s   t | ||S )a}  
    A validator that performs deep validation of a dictionary.

    :param key_validator: Validator to apply to dictionary keys
    :param value_validator: Validator to apply to dictionary values
    :param mapping_validator: Validator to apply to top-level mapping
        attribute (optional)

    .. versionadded:: 19.1.0

    :raises TypeError: if any sub-validators fail
    )rh   )rj   rk   ri   r    r    r!   r     s    c                   @   s.   e Zd Ze Ze Ze Zdd Zdd ZdS )_NumberValidatorc                 C   s.   |  || js*tdj|j| j| j|ddS )r&   z&'{name}' must be {op} {bound}: {value})r'   opboundr*   N)compare_funcro   r>   r-   r'   
compare_opr/   r    r    r!   r3     s    z_NumberValidator.__call__c                 C   s   dj | j| jdS )Nz<Validator for x {op} {bound}>)rn   ro   )r-   rq   ro   r5   r    r    r!   r6     s     z_NumberValidator.__repr__N)	r7   r8   r9   r   ro   rq   rp   r3   r6   r    r    r    r!   rm     s
   rm   c                 C   s   t | dtjS )z
    A validator that raises `ValueError` if the initializer is called
    with a number larger or equal to *val*.

    :param val: Exclusive upper bound for values

    .. versionadded:: 21.3.0
    <)rm   operatorr   valr    r    r!   r     s    	c                 C   s   t | dtjS )z
    A validator that raises `ValueError` if the initializer is called
    with a number greater than *val*.

    :param val: Inclusive upper bound for values

    .. versionadded:: 21.3.0
    z<=)rm   rs   r   rt   r    r    r!   r     s    	c                 C   s   t | dtjS )z
    A validator that raises `ValueError` if the initializer is called
    with a number smaller than *val*.

    :param val: Inclusive lower bound for values

    .. versionadded:: 21.3.0
    z>=)rm   rs   r   rt   r    r    r!   r     s    	c                 C   s   t | dtjS )z
    A validator that raises `ValueError` if the initializer is called
    with a number smaller or equal to *val*.

    :param val: Exclusive lower bound for values

    .. versionadded:: 21.3.0
    >)rm   rs   r   rt   r    r    r!   r   	  s    	c                   @   s"   e Zd Ze Zdd Zdd ZdS )_MaxLengthValidatorc                 C   s.   t || jkr*tdj|j| jt |ddS )r&   z*Length of '{name}' must be <= {max}: {len})r'   maxlenN)ry   
max_lengthr>   r-   r'   r/   r    r    r!   r3     s      z_MaxLengthValidator.__call__c                 C   s   dj | jdS )Nz<max_len validator for {max}>)rx   )r-   rz   r5   r    r    r!   r6   $  s    z_MaxLengthValidator.__repr__N)r7   r8   r9   r   rz   r3   r6   r    r    r    r!   rw     s   rw   c                 C   s   t | S )z
    A validator that raises `ValueError` if the initializer is called
    with a string or iterable that is longer than *length*.

    :param int length: Maximum length of the string or iterable

    .. versionadded:: 21.3.0
    )rw   )lengthr    r    r!   r   (  s    	)r   N)N)N)3__doc__
__future__r   r   r   rs   rE   
contextlibr   _configr   r   _maker	   r
   r   r   
exceptionsr   rK   AttributeErrorr(   rL   __all__r   r   r   objectr%   r   r;   r   rP   r   rS   r   rX   r   r[   r   r_   r   rh   r   rm   r   r   r   r   rw   r   r    r    r    r!   <module>   s   


7

