o
    èÓáaæ%  ã                   @   s’   d dl mZmZmZmZ d dlmZmZmZm	Z	m
Z
mZ d dlmZ dd„ ZG dd„ deƒZeƒ Zdd	„ ZG d
d„ deed�ZG dd„ deƒZdS )é    )ÚInvariantExceptionÚCheckedTypeÚ_restore_pickleÚstore_invariants)Ú
set_fieldsÚ
check_typeÚis_field_ignore_extra_complaintÚPFIELD_NO_INITIALÚ	serializeÚcheck_global_invariants©Ú	transformc                 C   s   t | ƒdko| d tkS )Né   r   )Úlenr   )Úbases© r   ú4/usr/lib/python3/dist-packages/pyrsistent/_pclass.pyÚ
_is_pclass   s   r   c                       s   e Zd Z‡ fdd„Z‡  ZS )Ú
PClassMetac                    sh   t ||dd� t||ddƒ dtdd„ |d D ƒƒ |d< t|ƒr)|d  d	7  < tt| ƒ | |||¡S )
NÚ_pclass_fields)ÚnameÚ_pclass_invariantsÚ__invariant__)Ú_pclass_frozenc                 s   s   � | ]}|V  qd S ©Nr   ©Ú.0Úkeyr   r   r   Ú	<genexpr>   s   € z%PClassMeta.__new__.<locals>.<genexpr>Ú	__slots__)Ú__weakref__)r   r   Útupler   Úsuperr   Ú__new__)Úmcsr   r   Údct©Ú	__class__r   r   r#      s   zPClassMeta.__new__)Ú__name__Ú
__module__Ú__qualname__r#   Ú__classcell__r   r   r&   r   r      s    r   c                 C   s>   t | |||ƒ | |¡\}}|s| |¡ d S t|||ƒ d S r   )r   Ú	invariantÚappendÚsetattr)ÚclsÚfieldr   ÚvalueÚresultÚinvariant_errorsÚis_okÚ
error_coder   r   r   Ú_check_and_set_attr   s
   r6   c                       sœ   e Zd ZdZ‡ fdd„Zdd„ Zed"dd	„ƒZd#d
d„Zdd„ Z	dd„ Z
dd„ Zdd„ Z‡ fdd„Zdd„ Zdd„ Zdd„ Zdd„ Zdd„ Zd d!„ Z‡  ZS )$ÚPClassa­  
    A PClass is a python class with a fixed set of specified fields. PClasses are declared as python classes inheriting
    from PClass. It is defined the same way that PRecords are and behaves like a PRecord in all aspects except that it
    is not a PMap and hence not a collection but rather a plain Python object.


    More documentation and examples of PClass usage is available at https://github.com/tobgu/pyrsistent
    c                    sL  t t| ƒ | ¡}| dd ¡}| dd ¡}g }g }| j ¡ D ]a\}}||v rV|d u s-||v rEtt||ƒr=|j|| |d�}	n| || ¡}	n|| }	t| |||	||ƒ ||= q|j	t
urqt|j	ƒrd| 	¡ n|j	}
t| |||
||ƒ q|jr~| d | j|¡¡ q|sƒ|r�tt|ƒt|ƒdƒ‚|r›td d |¡| j¡ƒ‚t|| jƒ d|_|S )	NÚ_factory_fieldsÚignore_extra)r9   z{0}.{1}zField invariant failedz0'{0}' are not among the specified fields for {1}ú, T)r"   r7   r#   Úpopr   Úitemsr   Úfactoryr6   Úinitialr	   ÚcallableÚ	mandatoryr-   Úformatr(   r   r!   ÚAttributeErrorÚjoinr   r   r   )r/   Úkwargsr2   Úfactory_fieldsr9   Úmissing_fieldsr3   r   r0   r1   r>   r&   r   r   r#   .   s>   
ÿ€ÿzPClass.__new__c                 O   s`   |r
|d ||d < t |ƒ}| jD ]}||vr%t| |tƒ}|tur%|||< q| jdd|i|¤ŽS )a  
        Set a field in the instance. Returns a new instance with the updated value. The original instance remains
        unmodified. Accepts key-value pairs or single string representing the field name and a value.

        >>> from pyrsistent import PClass, field
        >>> class AClass(PClass):
        ...     x = field()
        ...
        >>> a = AClass(x=1)
        >>> a2 = a.set(x=2)
        >>> a3 = a.set('x', 3)
        >>> a
        AClass(x=1)
        >>> a2
        AClass(x=2)
        >>> a3
        AClass(x=3)
        r   r   r8   Nr   )Úsetr   ÚgetattrÚ_MISSING_VALUEr'   )ÚselfÚargsrD   rE   r   r1   r   r   r   rG   R   s   
€z
PClass.setNFc                    s:   t ˆ | ƒrˆ S |r‡ fdd„| jD ƒ‰ | d||dœˆ ¤ŽS )a:  
        Factory method. Will create a new PClass of the current type and assign the values
        specified in kwargs.

        :param ignore_extra: A boolean which when set to True will ignore any keys which appear in kwargs that are not
                             in the set of fields on the PClass.
        c                    s   i | ]}|ˆ v r|ˆ | “qS r   r   )r   Úk©rD   r   r   Ú
<dictcomp>   s    z!PClass.create.<locals>.<dictcomp>)r8   r9   Nr   )Ú
isinstancer   )r/   rD   r8   r9   r   rM   r   Úcreater   s
   
	zPClass.createc                 C   s@   i }| j D ]}t| |tƒ}|turt| j | j||ƒ||< q|S )z‚
        Serialize the current PClass using custom serializer functions for fields where
        such have been supplied.
        )r   rH   rI   r
   Ú
serializer)rJ   rA   r2   r   r1   r   r   r   r
   ƒ   s   
€zPClass.serializec                 G   s
   t | |ƒS )aT  
        Apply transformations to the currency PClass. For more details on transformations see
        the documentation for PMap. Transformations on PClasses do not support key matching
        since the PClass is not a collection. Apart from that the transformations available
        for other persistent types work as expected.
        r   )rJ   Útransformationsr   r   r   r   �   s   
zPClass.transformc                 C   s>   t || jƒr| jD ]}t| |tƒt||tƒkr dS q	dS tS )NFT)rO   r'   r   rH   rI   ÚNotImplemented)rJ   Úotherr   r   r   r   Ú__eq__™   s   
ÿzPClass.__eq__c                 C   s
   | |k S r   r   )rJ   rT   r   r   r   Ú__ne__£   ó   
zPClass.__ne__c                    s   t t‡ fdd„ˆ jD ƒƒƒS )Nc                 3   s    � | ]}|t ˆ |tƒfV  qd S r   )rH   rI   r   ©rJ   r   r   r   ¨   s   € z"PClass.__hash__.<locals>.<genexpr>)Úhashr!   r   rX   r   rX   r   Ú__hash__¦   s   zPClass.__hash__c                    s2   t | ddƒrtd ||¡ƒ‚tt| ƒ ||¡ d S )Nr   Fz'Can't set attribute, key={0}, value={1})rH   rB   rA   r"   r7   Ú__setattr__©rJ   r   r1   r&   r   r   r[   ª   s   zPClass.__setattr__c                 C   s   t d |¡ƒ‚)Nz-Can't delete attribute, key={0}, use remove())rB   rA   )rJ   r   r   r   r   Ú__delattr__°   ó   zPClass.__delattr__c                 C   s0   i }| j D ]}t| |tƒ}|tur|||< q|S r   )r   rH   rI   )rJ   r2   r   r1   r   r   r   Ú_to_dict³   s   
€zPClass._to_dictc                 C   s(   d  | jjd dd„ |  ¡  ¡ D ƒ¡¡S )Nz{0}({1})r:   c                 s   s$   � | ]\}}d   |t|ƒ¡V  qdS )z{0}={1}N)rA   Úrepr)r   rL   Úvr   r   r   r   ¾   s   €" z"PClass.__repr__.<locals>.<genexpr>)rA   r'   r(   rC   r_   r<   rX   r   r   r   Ú__repr__¼   s   
ÿzPClass.__repr__c                    s&   t ‡ fdd„ˆ jD ƒƒ}tˆ j|ffS )Nc                 3   s(   � | ]}t ˆ |ƒr|tˆ |ƒfV  qd S r   )ÚhasattrrH   r   rX   r   r   r   Â   s   €& z$PClass.__reduce__.<locals>.<genexpr>)Údictr   r   r'   )rJ   Údatar   rX   r   Ú
__reduce__À   s   zPClass.__reduce__c                 C   s   t | |  ¡ ƒS )z5
        Returns an evolver for this object.
        )Ú_PClassEvolverr_   rX   r   r   r   ÚevolverÅ   s   zPClass.evolverc                 C   s   |   ¡ }||= | ¡ S )z‰
        Remove attribute given by name from the current instance. Raises AttributeError if the
        attribute doesn't exist.
        )rh   Ú
persistent)rJ   r   rh   r   r   r   ÚremoveË   s   zPClass.remove©NFr   )r(   r)   r*   Ú__doc__r#   rG   ÚclassmethodrP   r
   r   rU   rV   rZ   r[   r]   r_   rb   rf   rh   rj   r+   r   r   r&   r   r7   %   s$    $ 
	
	r7   )Ú	metaclassc                       s`   e Zd ZdZdd„ Zdd„ Zdd„ Zdd	„ Zd
d„ Zdd„ Z	dd„ Z
‡ fdd„Zdd„ Z‡  ZS )rg   )Ú_pclass_evolver_originalÚ_pclass_evolver_dataÚ_pclass_evolver_data_is_dirtyr8   c                 C   s   || _ || _d| _tƒ | _d S rk   )ro   rp   rq   rG   r8   )rJ   ÚoriginalÚinitial_dictr   r   r   Ú__init__Ø   s   z_PClassEvolver.__init__c                 C   s
   | j | S r   )rp   ©rJ   Úitemr   r   r   Ú__getitem__Þ   rW   z_PClassEvolver.__getitem__c                 C   s2   | j  |t¡|ur|| j |< | j |¡ d| _| S ©NT)rp   ÚgetrI   r8   Úaddrq   r\   r   r   r   rG   á   s
   
z_PClassEvolver.setc                 C   s   |   ||¡ d S r   )rG   r\   r   r   r   Ú__setitem__é   s   z_PClassEvolver.__setitem__c                 C   s0   || j v r| j |= | j |¡ d| _| S t|ƒ‚rx   )rp   r8   Údiscardrq   rB   ru   r   r   r   rj   ì   s   
z_PClassEvolver.removec                 C   s   |   |¡ d S r   )rj   ru   r   r   r   Ú__delitem__õ   r^   z_PClassEvolver.__delitem__c                 C   s&   | j r| jjdd| ji| j¤ŽS | jS )Nr8   r   )rq   ro   r'   r8   rp   rX   r   r   r   ri   ø   s
   ÿz_PClassEvolver.persistentc                    s0   || j vr|  ||¡ d S tt| ƒ ||¡ d S r   )r   rG   r"   rg   r[   r\   r&   r   r   r[   ÿ   s   
z_PClassEvolver.__setattr__c                 C   s   | | S r   r   ru   r   r   r   Ú__getattr__  s   z_PClassEvolver.__getattr__)r(   r)   r*   r   rt   rw   rG   r{   rj   r}   ri   r[   r~   r+   r   r   r&   r   rg   Õ   s    	rg   N)Úpyrsistent._checked_typesr   r   r   r   Úpyrsistent._field_commonr   r   r   r	   r
   r   Úpyrsistent._transformationsr   r   Útyper   ÚobjectrI   r6   r7   rg   r   r   r   r   Ú<module>   s     	 1