B
    KÆ\4*                 @   sR  d dl Z d dlmZmZmZmZmZmZmZm	Z	m
Z
 d dlmZ d dlmZ d dlmZ dd Zdd	 Zd
d Zdd ZG dd deZdZdd Zdd Ze Zdd Zdd ZeeedeefddZdd ZG dd deZedediZi Z dd  Z!d!d" Z"d#d$ Z#d%d& Z$d2d'd(Z%d3d)d*Z&d+d Z'i Z(d,d- Z)d.d/ Z*defd0d1Z+dS )4    N)	CheckedPMapCheckedPSetCheckedPVectorCheckedTypeInvariantException_restore_pickleget_typemaybe_parse_user_typemaybe_parse_many_user_types)optional)wrap_invariant)Enumc                sZ   t t fdd|D g |  < x4t|  D ]$\}}t|tr.||   |< | |= q.W d S )Nc                s"   g | ]}t |j i  qS  )list__dict__getitems).0b)namer   7lib/python3.7/site-packages/pyrsistent/_field_common.py
<listcomp>   s    zset_fields.<locals>.<listcomp>)dictsumr   r   
isinstance_PField)Zdctbasesr   kvr   )r   r   
set_fields   s
     
r   c                s4   t dd  fdd|D D }|r0t|ddd S )Nc             s   s   | ]\}}|s|V  qd S )Nr   )r   Zis_okZ
error_coder   r   r   	<genexpr>   s    z*check_global_invariants.<locals>.<genexpr>c             3   s   | ]}| V  qd S )Nr   )r   	invariant)subjectr   r   r       s    r   zGlobal invariant failed)tupler   )r"   Z
invariantsZerror_codesr   )r"   r   check_global_invariants   s    r$   c             C   s&   t |tr| tkr||S | ||S )N)r   r   PFIELD_NO_SERIALIZER	serialize)
serializerformatvaluer   r   r   r&   #   s    
r&   c                sN   |j rJt fdd|j D sJt  }d| j||j}t| ||j ||d S )Nc             3   s   | ]}t  t|V  qd S )N)r   r   )r   t)r)   r   r   r    +   s    zcheck_type.<locals>.<genexpr>z'Invalid type for field {0}.{1}, was {2})typeanyr(   __name__
PTypeError)Zdestination_clsfieldr   r)   actual_typemessager   )r)   r   
check_type*   s    r2   c               @   s$   e Zd ZdZdd Zedd ZdS )r   )r+   r!   initial	mandatory_factoryr'   c             C   s(   || _ || _|| _|| _|| _|| _d S )N)r+   r!   r3   r4   r5   r'   )selfr+   r!   r3   r4   factoryr'   r   r   r   __init__4   s    z_PField.__init__c             C   s@   | j tkr:t| jdkr:tt| jd }t|tr:|jS | j S )N   r   )	r5   PFIELD_NO_FACTORYlenr+   r   r#   
issubclassr   create)r6   typr   r   r   r7   <   s
    
z_PField.factoryN)r-   
__module____qualname__	__slots__r8   propertyr7   r   r   r   r   r   1   s   r   r   c             C   s   dS )N)TNr   )_r   r   r   <lambda>G   s    rD   c             C   s   | S )Nr   )xr   r   r   rD   H   s    c             C   s   |S )Nr   )rC   r)   r   r   r   rD   J   s    c             C   s   |S )Nr   )rC   r)   r   r   r   rD   K   s    Fc       	      C   sf   t | tttfrtt| }ntt| }|tkrBt|rBt|n|}t	||||||d}t
| |S )a  
    Field specification factory for :py:class:`PRecord`.

    :param type: a type or iterable with types that are allowed for this field
    :param invariant: a function specifying an invariant that must hold for the field
    :param initial: value of field if not specified when instantiating the record
    :param mandatory: boolean specifying if the field is mandatory or not
    :param factory: function called when field is set.
    :param serializer: function that returns a serialized version of the field
    )r+   r!   r3   r4   r7   r'   )r   r   setr#   r
   r	   PFIELD_NO_INVARIANTcallabler   r   _check_field_parameters)	r+   r!   r3   r4   r7   r'   typesZinvariant_functionr/   r   r   r   r/   M   s    r/   c                s   x6 j D ],}t|t st|tjstdt |qW  jtk	r~t js~ j r~t	 fdd j D s~tdt  jt j
stdt jstdt jstdd S )Nz Type parameter expected, not {0}c             3   s   | ]}t  j|V  qd S )N)r   r3   )r   r*   )r/   r   r   r    x   s    z*_check_field_parameters.<locals>.<genexpr>zInitial has invalid type {0}zInvariant must be callablezFactory must be callablezSerializer must be callable)r+   r   sixZstring_types	TypeErrorr(   r3   PFIELD_NO_INITIALrH   r,   r!   r7   r'   )r/   r*   r   )r/   r   rI   q   s    




rI   c                   s    e Zd ZdZ fddZ  ZS )r.   a  
    Raised when trying to assign a value with a type that doesn't match the declared type.

    Attributes:
    source_class -- The class of the record
    field -- Field name
    expected_types  -- Types allowed for the field
    actual_type -- The non matching type
    c                s.   t t| j|| || _|| _|| _|| _d S )N)superr.   r8   source_classr/   expected_typesr0   )r6   rO   r/   rP   r0   argskwargs)	__class__r   r   r8      s
    zPTypeError.__init__)r-   r?   r@   __doc__r8   __classcell__r   r   )rS   r   r.      s   	r.   ZPVectorZPSetc             C   s   t | |f }t||S )z=Unpickling function for auto-generated PVec/PSet field types.)_seq_field_typesr   )checked_class	item_typedatatype_r   r   r   _restore_seq_field_pickle   s    r[   c             C   s   d dd | D S )z4Convert a tuple of types to a human-readable string. c             s   s   | ]}t |j V  qd S )N)r   r-   
capitalize)r   r>   r   r   r   r       s    z"_types_to_names.<locals>.<genexpr>)join)rJ   r   r   r   _types_to_names   s    r_   c                sX   t  f}|dk	r|S G  fddd }t  }t|j| |_|t  f< |S )zFCreate a subclass of the given checked class with the given item type.Nc                   s   e Zd ZZ fddZdS )z%_make_seq_field_type.<locals>.TheTypec                s   t  t| ffS )N)r[   r   )r6   )rW   rX   r   r   
__reduce__   s    z0_make_seq_field_type.<locals>.TheType.__reduce__N)r-   r?   r@   Z__type__r`   r   )rW   rX   r   r   TheType   s   ra   )rV   r   SEQ_FIELD_TYPE_SUFFIXESr_   Z_checked_typesr-   )rW   rX   rZ   ra   suffixr   )rW   rX   r   _make_seq_field_type   s    rd   c                sB   t | | |r fdd}n j}t|r0t n |d||dS )a  
    Create checked field for either ``PSet`` or ``PVector``.

    :param checked_class: ``CheckedPSet`` or ``CheckedPVector``.
    :param item_type: The required type for the items in the set.
    :param optional: If true, ``None`` can be used as a value for
        this field.
    :param initial: Initial value to pass to factory.

    :return: A ``field`` containing a checked class.
    c                s   | d krd S   | S d S )N)r=   )argument)ra   r   r   r7      s    z _sequence_field.<locals>.factoryT)r+   r7   r4   r3   )rd   r=   r/   optional_type)rW   rX   r   r3   r7   r   )ra   r   _sequence_field   s    
rg   c             C   s   t t| ||S )al  
    Create checked ``PSet`` field.

    :param item_type: The required type for the items in the set.
    :param optional: If true, ``None`` can be used as a value for
        this field.
    :param initial: Initial value to pass to factory if no value is given
        for the field.

    :return: A ``field`` containing a ``CheckedPSet`` of the given type.
    )rg   r   )rX   r   r3   r   r   r   
pset_field   s    rh   c             C   s   t t| ||S )au  
    Create checked ``PVector`` field.

    :param item_type: The required type for the items in the vector.
    :param optional: If true, ``None`` can be used as a value for
        this field.
    :param initial: Initial value to pass to factory if no value is given
        for the field.

    :return: A ``field`` containing a ``CheckedPVector`` of the given type.
    )rg   r   )rX   r   r3   r   r   r   pvector_field   s    ri   c             C   s   dS )N)Tr\   r   )itemr   r   r   rD      s    c             C   s   t | |f }t||S )z8Unpickling function for auto-generated PMap field types.)_pmap_field_typesr   )key_type
value_typerY   rZ   r   r   r   _restore_pmap_field_pickle   s    rn   c                sZ   t  f}|dk	r|S G  fdddt}dt|jt|j|_|t  f< |S )zDCreate a subclass of CheckedPMap with the given key and value types.Nc                   s   e Zd Z ZZdd ZdS )z%_make_pmap_field_type.<locals>.TheMapc             S   s   t | j| jt| ffS )N)rn   __key_type____value_type__r   )r6   r   r   r   r`     s    z0_make_pmap_field_type.<locals>.TheMap.__reduce__N)r-   r?   r@   ro   rp   r`   r   )rl   rm   r   r   TheMap  s   rq   z{0}To{1}PMap)rk   r   r   r(   r_   Z_checked_key_typesZ_checked_value_typesr-   )rl   rm   rZ   rq   r   )rl   rm   r   _make_pmap_field_type  s    rr   c                sB   t | | |r fdd}n j}td  |r6t n ||dS )ad  
    Create a checked ``PMap`` field.

    :param key: The required type for the keys of the map.
    :param value: The required type for the values of the map.
    :param optional: If true, ``None`` can be used as a value for
        this field.
    :param invariant: Pass-through to ``field``.

    :return: A ``field`` containing a ``CheckedPMap``.
    c                s   | d krd S   | S d S )N)r=   )re   )rq   r   r   r7   %  s    zpmap_field.<locals>.factoryT)r4   r3   r+   r7   r!   )rr   r=   r/   rf   )rl   rm   r   r!   r7   r   )rq   r   
pmap_field  s    
rs   )Fr   )Fr   ),rK   Zpyrsistent._checked_typesr   r   r   r   r   r   r   r	   r
   r   rf   r   Zpyrsistent._compatr   r   r$   r&   r2   objectr   ZPFIELD_NO_TYPErG   r:   rM   r%   r/   rI   rL   r.   rb   rV   r[   r_   rd   rg   rh   ri   Z_validrk   rn   rr   rs   r   r   r   r   <module>   sB   ,	#

