B
    *U\%                 @   s   d dl mZmZmZ d dlZddlmZ ddlmZm	Z	m
Z
 ddlmZ ddedfd	d
Zdd ZddedfddZdd Zdd Zdd ZdS )    )absolute_importdivisionprint_functionN   )	iteritems)NOTHING_obj_setattrfields)AttrsAttributeNotFoundErrorTFc       
         s   t | j} }x|D ]}t| |j}dk	r:||s:q|dkrt|jrdt|d||j< qt|ttt	frdkr|jnt}	|	fdd|D ||j< qt|t
r܈   fddt|D ||j< q|||j< q|||j< qW |S )a  
    Return the ``attrs`` attribute values of *inst* as a dict.

    Optionally recurse into other ``attrs``-decorated classes.

    :param inst: Instance of an ``attrs``-decorated class.
    :param bool recurse: Recurse into classes that are also
        ``attrs``-decorated.
    :param callable filter: A callable whose return code determines whether an
        attribute or element is included (``True``) or dropped (``False``).  Is
        called with the :class:`attr.Attribute` as the first argument and the
        value as the second argument.
    :param callable dict_factory: A callable to produce dictionaries from.  For
        example, to produce ordered dictionaries instead of normal Python
        dictionaries, pass in ``collections.OrderedDict``.
    :param bool retain_collection_types: Do not convert to ``list`` when
        encountering an attribute whose type is ``tuple`` or ``set``.  Only
        meaningful if ``recurse`` is ``True``.

    :rtype: return type of *dict_factory*

    :raise attr.exceptions.NotAnAttrsClassError: If *cls* is not an ``attrs``
        class.

    ..  versionadded:: 16.0.0 *dict_factory*
    ..  versionadded:: 16.1.0 *retain_collection_types*
    NTc                s   g | ]}t | qS  )_asdict_anything).0i)dict_factoryfilterretain_collection_typesr   *lib/python3.7/site-packages/attr/_funcs.py
<listcomp>;   s   zasdict.<locals>.<listcomp>c             3   s.   | ]&\}}t | t | fV  qd S )N)r   )r   kkvv)dfr   r   r   r   	<genexpr>D   s   zasdict.<locals>.<genexpr>)r	   	__class__getattrnamehasasdict
isinstancetuplelistsetdictr   )
instrecurser   r   r   attrsrvavcfr   )r   r   r   r   r   r   
   s.    "



r   c                s   t | jdddk	r$t| d}npt| tttfrbdkrB| jnt}|fdd| D }n2t| tr   fddt| D }n| }|S )zK
    ``asdict`` only works on attrs instances, this works on anything.
    __attrs_attrs__NTc                s   g | ]}t | qS r   )r   )r   r   )r   r   r   r   r   r   `   s   z$_asdict_anything.<locals>.<listcomp>c             3   s.   | ]&\}}t | t | fV  qd S )N)r   )r   r   r   )r   r   r   r   r   r   i   s   z#_asdict_anything.<locals>.<genexpr>)	r   r   r   r   r   r   r    r!   r   )valr   r   r   r%   r(   r   )r   r   r   r   r   r   U   s    
r   c          
      s  t | j}g }|x|D ]}t| |j} dk	r< ||s<q|dkrt|jrh|t|d d nt|tt	t
frdkr|jnt	}	||	 fdd|D  nJt|trdkr|jnt}
||
fddt|D  n
|| q|| qW t	kr|S |S )a8  
    Return the ``attrs`` attribute values of *inst* as a tuple.

    Optionally recurse into other ``attrs``-decorated classes.

    :param inst: Instance of an ``attrs``-decorated class.
    :param bool recurse: Recurse into classes that are also
        ``attrs``-decorated.
    :param callable filter: A callable whose return code determines whether an
        attribute or element is included (``True``) or dropped (``False``).  Is
        called with the :class:`attr.Attribute` as the first argument and the
        value as the second argument.
    :param callable tuple_factory: A callable to produce tuples from.  For
        example, to produce lists instead of tuples.
    :param bool retain_collection_types: Do not convert to ``list``
        or ``dict`` when encountering an attribute which type is
        ``tuple``, ``dict`` or ``set``.  Only meaningful if ``recurse`` is
        ``True``.

    :rtype: return type of *tuple_factory*

    :raise attr.exceptions.NotAnAttrsClassError: If *cls* is not an ``attrs``
        class.

    ..  versionadded:: 16.2.0
    NT)r#   r   tuple_factoryr   c          	      s,   g | ]$}t |jr$t|d  dn|qS )T)r#   r   r+   r   )r   r   astuple)r   j)r   retainr+   r   r   r      s   	zastuple.<locals>.<listcomp>c             3   sJ   | ]B\}}t |jr"t| d n|t |jr<t| d n|fV  qdS ))r+   r   N)r   r   r,   )r   r   r   )r.   r+   r   r   r      s   zastuple.<locals>.<genexpr>)r	   r   r   r   r   appendr,   r   r   r   r    r!   r   )r"   r#   r   r+   r   r$   r%   r&   r'   r(   r   r   )r   r.   r+   r   r,   t   s>    !


	
r,   c             C   s   t | dddk	S )z
    Check whether *cls* is a class with ``attrs`` attributes.

    :param type cls: Class to introspect.
    :raise TypeError: If *cls* is not a class.

    :rtype: :class:`bool`
    r)   N)r   )clsr   r   r   r      s    	r   c             K   sz   ddl }|jdtdd t| }t| j}xHt|D ]<\}}t||t}|tkrft	dj
||jdt||| q6W |S )a  
    Copy *inst* and apply *changes*.

    :param inst: Instance of a class with ``attrs`` attributes.
    :param changes: Keyword changes in the new copy.

    :return: A copy of inst with *changes* incorporated.

    :raise attr.exceptions.AttrsAttributeNotFoundError: If *attr_name* couldn't
        be found on *cls*.
    :raise attr.exceptions.NotAnAttrsClassError: If *cls* is not an ``attrs``
        class.

    ..  deprecated:: 17.1.0
        Use :func:`evolve` instead.
    r   Nz6assoc is deprecated and will be removed after 2018/01.   )
stacklevelz&{k} is not an attrs attribute on {cl}.)kZcl)warningswarnDeprecationWarningcopyr	   r   r   r   r   r
   formatr   )r"   changesr4   newr$   r3   r'   r&   r   r   r   assoc   s    

r;   c             K   sf   | j }t|}xL|D ]D}|js q|j}|d dkr6|n
|dd }||krt| |||< qW |f |S )a  
    Create a new instance, based on *inst* with *changes* applied.

    :param inst: Instance of a class with ``attrs`` attributes.
    :param changes: Keyword changes in the new copy.

    :return: A copy of inst with *changes* incorporated.

    :raise TypeError: If *attr_name* couldn't be found in the class
        ``__init__``.
    :raise attr.exceptions.NotAnAttrsClassError: If *cls* is not an ``attrs``
        class.

    ..  versionadded:: 17.1.0
    r   _r   N)r   r	   Zinitr   r   )r"   r9   r0   r$   r&   Z	attr_nameZ	init_namer   r   r   evolve	  s    
r=   )Z
__future__r   r   r   r7   Z_compatr   _maker   r   r	   
exceptionsr
   r!   r   r   r   r,   r   r;   r=   r   r   r   r   <module>   s    F!^&