U
    Sh>                     @  s   d Z ddlmZ ddlZddlmZmZmZ dddddd	d
Z	dddddZ
G dd deZd'ddZdddddZdddddZd(ddZdddddZd)dd dd!d"d#Zd*ddd dd$d%d&ZdS )+zUValidators for dataclasses, mirroring those of https://github.com/python-attrs/attrs.    )annotationsN)AnyProtocolSequencer   dc.FieldNone)instfieldvaluereturnc                 C  sR   d|j krdS t|j d tr<|j d D ]}|| || q(n|j d | || dS )zValidate the field of a dataclass,
    according to a `validator` function set in the field.metadata.

    The validator function should take as input (inst, field, value) and
    raise an exception if the value is invalid.
    	validatorN)metadata
isinstancelist)r   r	   r
   r    r   S/root/rtd-docs/venv/lib/python3.8/site-packages/myst_parser/config/dc_validators.pyvalidate_field	   s    
r   )r   r   c                 C  s(   t | D ]}t| |t| |j q
dS )a1  Validate the fields of a dataclass,
    according to `validator` functions set in the field metadata.

    This function should be called in the `__post_init__` of the dataclass.

    The validator function should take as input (inst, field, value) and
    raise an exception if the value is invalid.
    N)dcfieldsr   getattrname)r   r	   r   r   r   validate_fields   s    	r   c                   @  s$   e Zd Zd
ddddddddZd	S )ValidatorType r   r   strr   )r   r	   r
   suffixr   c                 C  s   d S )Nr   )selfr   r	   r
   r   r   r   r   __call__'   s    zValidatorType.__call__N)r   )__name__
__module____qualname__r   r   r   r   r   r   &   s    r   r   c                 C  s   dS )z;
    A validator that does not perform any validation.
    Nr   r   r	   r
   r   r   r   r   any_,   s    r"   z!type[Any] | tuple[type[Any], ...])type_r   c                   s   d fdd	}|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.
    r   c                   s8   t | s4td|j | d d|d|jd
dS )zP
        We use a callable class to be able to change the ``__repr__``.
        'z' must be of type  (got  that is a ).N)r   	TypeErrorr   	__class__r!   r#   r   r   
_validator;   s    
$zinstance_of.<locals>._validator)r   r   )r#   r+   r   r*   r   instance_of2   s    	
r,   )r   r   c                   s   d fdd	}|S )z
    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.
    r   c                   s    |d krd S  | |||d d S )Nr   r   r!   r   r   r   r+   O   s    zoptional.<locals>._validator)r   r   )r   r+   r   r.   r   optionalH   s    r/   c              	   C  s0   t |s,td|j | d|d|jddS )z
    A validator that raises a `TypeError` if the
    initializer is called with a value for this particular attribute
    that is not callable.
    r$   z' must be callable (got r&   r'   N)callabler(   r   r)   r!   r   r   r   is_callableX   s    r1   r   )optionsr   c                   s   d fdd	}|S )z
    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.
    r   c              	     sP   z| k}W n t k
r$   d}Y nX |sLtd|j | d d|dd S )NFr$   z' must be in r%   ))r(   
ValueErrorr   )r   r	   r
   r   Z
in_optionsr2   r   r   r+   n   s    
zin_.<locals>._validator)r   r   )r2   r+   r   r5   r   in_e   s    	r6   zValidatorType | None)member_validatoriterable_validatorr   c                   s   d fdd	}|S )z
    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
    r   c              	     sJ    d k	r | |||d t |D ]$\}}| ||| d| dd q d S )Nr-   [])	enumerate)r   r	   r
   r   idxmemberr8   r7   r   r   r+      s    z!deep_iterable.<locals>._validator)r   r   )r7   r8   r+   r   r>   r   deep_iterable|   s    
r?   )key_validatorvalue_validatormapping_validatorr   c                   s   ddd fdd}|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)
    r   r   )r	   c              	     s^   d k	r| || |D ]@} | ||| d|dd | ||| | d|dd qd S )Nr9   r:   r-   r   )r   r	   r
   r   keyr@   rB   rA   r   r   r+      s
    z deep_mapping.<locals>._validator)r   r   )r@   rA   rB   r+   r   rD   r   deep_mapping   s    rE   )r   )r   )N)N)__doc__
__future__r   dataclassesr   typingr   r   r   r   r   r   r"   r,   r/   r1   r6   r?   rE   r   r   r   r   <module>   s   

  