B
    aR                 @   s4  d Z ddlZddlmZ ddlmZmZ ddlmZm	Z	 ddl
mZmZmZmZ edZedZed	Zd
Zed dhZe	red dddddddddddhZd-ddZG dd dZd.ddZdd  ZG d!d" d"eZG d#d$ d$eZG d%d& d&eZG d'd( d(eZG d)d* d*eZG d+d, d,eZ dS )/zXThis module contains base classes and functions for the nodes and some
inference utils.
    N)context)
decoratorsutil)BUILTINS
PY310_PLUS)AstroidTypeErrorAttributeInferenceErrorInferenceErrorNameInferenceErrorzinterpreter.objectmodelhelpersmanager__bool__z	.propertyzabc.abstractpropertyzenum.propertycached_propertyZcachedpropertyZlazypropertyZlazy_propertyZreifyZlazyattributeZlazy_attributeZLazyPropertyZlazyZcache_readonlyDynamicClassAttributec                s   | j |d}t|rdS dd |D  t fddtD rBdS | jsLdS x| jjpXdD ]x}tj||d}|d ksZ|t	j
krqZ|jjd	krZxD|jD ]:}|jjd
krq||j\}}|jtkr|jdkrdS qW qZW dS )N)r   Tc             S   s$   h | ]}|t jk	r|d d qS ).)r   Uninferablesplit).0name r   1/tmp/pip-unpacked-wheel-mm06h1t3/astroid/bases.py	<setcomp>O   s   z_is_property.<locals>.<setcomp>c             3   s   | ]}| kV  qd S )Nr   )r   r   )strippedr   r   	<genexpr>R   s    z_is_property.<locals>.<genexpr>Fr   ClassDefNameproperty)decoratornames
PROPERTIESintersectionanyPOSSIBLE_PROPERTIESr   Znodesr   Z
safe_inferr   r   	__class____name__baseslookupr   r   )methr   r   	decoratorinferredZ
base_classmodule_r   )r   r   _is_propertyK   s*    
r,   c               @   s0   e Zd ZdZdZd	ddZdd Zd
ddZdS )Proxyza simple proxy object

    Note:

    Subclasses of this object will need a custom __getattr__
    if new instance attributes are created. See the Const class
    Nc             C   s   |d k	r|| _ d S )N)_proxied)selfZproxiedr   r   r   __init__r   s    zProxy.__init__c             C   s0   |dkr| j jS || jkr$| j| S t| j|S )Nr.   )r#   r.   __dict__getattr)r/   r   r   r   r   __getattr__v   s
    

zProxy.__getattr__c             c   s
   | V  d S )Nr   )r/   r   r   r   r   infer}   s    zProxy.infer)N)N)r$   
__module____qualname____doc__r.   r0   r3   r4   r   r   r   r   r-   g   s
   
r-   c          	   c   s   d}|dk	r|j }| }nd}t }x| D ]}|tjkrH|V  d}q.||||_ y$x|j|dD ]}|V  d}qfW W q. tk
r   w.Y q. t	k
r   tjV  d}Y q.X q.W |st	d| ||ddS )zGReturn an iterator on statements inferred by each statement in *stmts*.FNT)r   z.Inference failed for all members of {stmts!r}.)stmtsframer   )

lookupnameclone
contextmodInferenceContextr   r   Z_infer_namer4   r
   r	   )r8   r   r9   r)   r   Zstmtr   r   r   _infer_stmts   s6    


r>   c             C   s   t | j||dd }|rt|dr| s0tjS ytxn|j| |dD ]\}|tjkrT|S yt |j|d}W n. tk
r } zt	|d|W d d }~X Y nX |
 S W W n t	k
r   Y nX tjS )N)r   infer_call_result)nextigetattrhasattrcallabler   r   r?   r4   StopIterationr	   
bool_value)instancemethod_namer   r'   valuer)   er   r   r   _infer_method_result_truth   s     
rJ   c               @   sD   e Zd ZdZdZdd ZdddZddd	Zdd
dZdddZ	dS )BaseInstancezNAn instance base class, which provides lookup methods for potential instances.Nc             C   s   dS )NzInstance ofr   )r/   r   r   r   display_type   s    zBaseInstance.display_typeTc          
   C   s   y| j ||}W nf tk
rx } zH| jrB|| jkrB| j|gS |rX| j j||ddS t| ||d|W d d }~X Y nX |ry|| j j||dd S  tk
r   Y nX |S )NF)class_context)target	attributer   )r.   Zinstance_attrr   special_attributesr&   r2   )r/   r   r   lookupclassvaluesexcr   r   r   r2      s"    
zBaseInstance.getattrc             c   s   |st  }yP||_|| jr.td| |d| j||dd}t| |||| dE dH  W n t	k
r   y8| jj
jdkr~ | jj||dd}| ||E dH  W n2 t	k
r } ztf t||W dd}~X Y nX Y nX dS )	zinferred getattrz%Cannot infer the same attribute again)messagenoder   F)rQ   )r9   Nr   )rM   )r<   r=   r:   pushr.   r	   r2   r>   
_wrap_attrr   r#   r$   rA   vars)r/   r   r   Zget_attrattrserrorr   r   r   rA      s(    zBaseInstance.igetattrc             c   s   x|D ]}t |tr>t|r0|| |E dH  qt|| V  qt|dr|jdkr|jjrz|jjd jdkrzt|| V  q|V  q|V  qW dS )z7wrap bound methods of attrs in a InstanceMethod proxiesNr   z<lambda>r   r/   )	
isinstanceUnboundMethodr,   r?   BoundMethodrB   r   args	arguments)r/   rY   r   attrr   r   r   rW      s    

zBaseInstance._wrap_attrc             c   sr   t || }d}xJ| jd|D ]8}|tjks | s8q x|||D ]}d}|V  qFW q W |snt| ||ddS )z4infer what a class instance is returning when calledF__call__T)rU   callerr   N)	r<   bind_context_to_noder.   rA   r   r   rC   r?   r	   )r/   rb   r   r)   rU   resr   r   r   r?   	  s    zBaseInstance.infer_call_result)NT)N)N)N)
r$   r5   r6   r7   rP   rL   r2   rA   rW   r?   r   r   r   r   rK      s   


rK   c               @   sZ   e Zd ZdZedd Zdd Zdd Zdd	 Z	d
d Z
dd ZdddZdddZdS )Instancez-A special node representing a class instance.c               C   s   t  S )N)objectmodelZInstanceModelr   r   r   r   <lambda>      zInstance.<lambda>c             C   s   d | j j| jjt| S )Nz<Instance of {}.{} at 0x{}>)formatr.   rootr   id)r/   r   r   r   __repr__  s    zInstance.__repr__c             C   s   d| j  j d| j j S )NzInstance of r   )r.   rj   r   )r/   r   r   r   __str__"  s    zInstance.__str__c             C   s.   y| j jddd dS  tk
r(   dS X d S )Nra   F)rM   T)r.   r2   r   )r/   r   r   r   rC   %  s
    zInstance.callablec             C   s
   | j  S )N)r.   qname)r/   r   r   r   pytype,  s    zInstance.pytypec             C   s   dS )NzInstance ofr   )r/   r   r   r   rL   /  s    zInstance.display_typeNc             C   sx   |p
t  }t jg d|_| |_yt| t|}W nB ttfk
rr   yt| d|}W n ttfk
rl   dS X Y nX |S )aV  Infer the truth value for an Instance

        The truth value of an instance is determined by these conditions:

           * if it implements __bool__ on Python 3 or __nonzero__
             on Python 2, then its bool value will be determined by
             calling this special method and checking its result.
           * when this method is not defined, __len__() is called, if it
             is defined, and the object is considered true if its result is
             nonzero. If a class defines neither __len__() nor __bool__(),
             all its instances are considered true.
        )r^   __len__T)	r<   r=   CallContextcallcontextZ	boundnoderJ   BOOL_SPECIAL_METHODr	   r   )r/   r   resultr   r   r   rE   2  s    zInstance.bool_valuec             C   s   t || }|s|}t j|gd|_t| jd|dd }t|tsPtd| |dt	|j
jdkrntd| |dt|| |d S )N)r^   __getitem__)r   z(Could not find __getitem__ for {node!r}.)rU   r      z8__getitem__ for {node!r} does not have correct signature)r<   rc   rq   rr   r@   rA   r[   r]   r	   lenr^   r_   r   r?   )r/   indexr   Znew_contextmethodr   r   r   getitemM  s    
zInstance.getitem)N)N)r$   r5   r6   r7   r   lazy_descriptorrP   rl   rm   rC   ro   rL   rE   rz   r   r   r   r   re     s   
re   c               @   s\   e Zd ZdZedd Zdd Zdd Zdd	 Z	dddZ
dddZdd ZdddZd
S )r\   z=a special node representing a method not bound to an instancec               C   s   t  S )N)rf   ZUnboundMethodModelr   r   r   r   rg   f  rh   zUnboundMethod.<lambda>c             C   s,   | j j }d| jj| j j| t| S )Nz<{} {} of {} at 0x{})	r.   parentr9   ri   r#   r$   r   rn   rk   )r/   r9   r   r   r   rl   h  s    zUnboundMethod.__repr__c             C   s   dS )Nr   r   )r/   r   r   r   implicit_parametersn  s    z!UnboundMethod.implicit_parametersc             C   s   dS )NFr   )r/   r   r   r   is_boundq  s    zUnboundMethod.is_boundNc             C   s&   || j kr| j |gS | j||S )N)rP   r&   r.   r2   )r/   r   r   r   r   r   r2   t  s    
zUnboundMethod.getattrc             C   s*   || j krt| j |fS | j||S )N)rP   iterr&   r.   rA   )r/   r   r   r   r   r   rA   y  s    
zUnboundMethod.igetattrc             C   sp   | j jdkrb| j j  dt krb|jrP|j|jd }|jd j	|d}ng }dd |D S | j 
||S )a  
        The boundnode of the regular context with a function called
        on ``object.__new__`` will be of type ``object``,
        which is incorrect for the argument in general.
        If no context is given the ``object.__new__`` call argument will
        correctly inferred except when inside a call that requires
        the additional context (such as a classmethod) of the boundnode
        to determine which class the method was called from
        __new__z	%s.objectr   )r   c             s   s$   | ]}|t jk	rt|n|V  qd S )N)r   r   re   )r   xr   r   r   r     s    z2UnboundMethod.infer_call_result.<locals>.<genexpr>)r.   r   r|   r9   rn   r   r^   Zextra_contextgetr4   r?   )r/   rb   r   Znode_contextr4   r   r   r   r?   ~  s    zUnboundMethod.infer_call_resultc             C   s   dS )NTr   )r/   r   r   r   r   rE     s    zUnboundMethod.bool_value)N)N)N)r$   r5   r6   r7   r   r{   rP   rl   r}   r~   r2   rA   r?   rE   r   r   r   r   r\   b  s   

r\   c                   sZ   e Zd ZdZedd Zdd Zdd Zdd	 Z	d
d Z
d fdd	ZdddZ  ZS )r]   z9a special node representing a method bound to an instancec               C   s   t  S )N)rf   ZBoundMethodModelr   r   r   r   rg     rh   zBoundMethod.<lambda>c             C   s   t | | || _d S )N)r\   r0   bound)r/   proxyr   r   r   r   r0     s    zBoundMethod.__init__c             C   s   | j dkrdS dS )Nr   r      )r   )r/   r   r   r   r}     s    
zBoundMethod.implicit_parametersc             C   s   dS )NTr   )r/   r   r   r   r~     s    zBoundMethod.is_boundc                s  ddl m} yt|jd j d}W n. tk
rT } zt d|W dd}~X Y nX |jjdkrfdS |	dt
 sxdS yt|jd j d}W n. tk
r } zt d|W dd}~X Y nX |jjdkrdS t|jtsdS yt|jd	 j d}W n0 tk
r, } zt d|W dd}~X Y nX |jjd
kr@dS y fdd|jD }W n0 tk
r } zt d|W dd}~X Y nX tdd |D rdS yt|jd j d}	W n0 tk
r } zt d|W dd}~X Y nX |	jjdkr dS tt}
x|	jD ]\}}yt|j d}W n0 tk
r^ } zt d|W dd}~X Y nX yt|j d}W n0 tk
r } zt d|W dd}~X Y nX |jjdkrt|jtr|
|j | qW |j|j|j|j|d}| }|j|j|gg d|g d |
|_|S )zTry to infer what type.__new__(mcs, name, bases, attrs) returns.

        In order for such call to be valid, the metaclass needs to be
        a subtype of ``type``, the name needs to be a string, the bases
        needs to be a tuple of classes
        r   )node_classes)r   Nr   z%s.typer   ZConstrv   Tuplec                s   g | ]}t |j d qS ))r   )r@   r4   )r   elt)r   r   r   
<listcomp>  s    z4BoundMethod._infer_type_new_call.<locals>.<listcomp>c             s   s   | ]}|j jd kV  qdS )r   N)r#   r$   )r   baser   r   r   r     s    z3BoundMethod._infer_type_new_call.<locals>.<genexpr>   Dict)r   lineno
col_offsetr|   T)r%   bodyr   Znewstyle	metaclasskeywords)astroidr   r@   r^   r4   rD   r	   r#   r$   Zis_subtype_ofr   r[   rH   strZeltsr!   collectionsdefaultdictlistitemsappendr   r   ZPassZpostinitlocals)r/   rb   r   r   ZmcsrI   r   r%   Zinferred_basesrY   Z
cls_localskeyrH   clsemptyr   )r   r   _infer_type_new_call  s|    
z BoundMethod._infer_type_new_callNc                sh   t || j}| jjjdkrZ| jjdkrZ| jdkrZt|jdkrZ| ||}|rZt	|fS t
 ||S )Nr   typer      )r<   rc   r   r#   r$   r   rw   r^   r   r   superr?   )r/   rb   r   Znew_cls)r#   r   r   r?   	  s    

zBoundMethod.infer_call_resultc             C   s   dS )NTr   )r/   r   r   r   r   rE     s    zBoundMethod.bool_value)N)N)r$   r5   r6   r7   r   r{   rP   r0   r}   r~   r   r?   rE   __classcell__r   r   )r#   r   r]     s   [r]   c                   sn   e Zd ZdZeejZd fdd	Z	e
jdd Zdd Zd	d
 Zdd ZdddZdd Zdd Z  ZS )	Generatorzea special node representing a generator.

    Proxied class is set once for all in raw_building.
    Nc                s    t    || _t|| _d S )N)r   r0   r|   r<   Zcopy_context_call_context)r/   r|   Zgenerator_initial_context)r#   r   r   r0   $  s    
zGenerator.__init__c             c   s   | j | jE d H  d S )N)r|   Zinfer_yield_resultr   )r/   r   r   r   infer_yield_types)  s    zGenerator.infer_yield_typesc             C   s   dS )NFr   )r/   r   r   r   rC   -  s    zGenerator.callablec             C   s   dt  S )Nz%s.generator)r   )r/   r   r   r   ro   0  s    zGenerator.pytypec             C   s   dS )Nr   r   )r/   r   r   r   rL   3  s    zGenerator.display_typec             C   s   dS )NTr   )r/   r   r   r   r   rE   6  s    zGenerator.bool_valuec             C   s   d | jj| jt| S )Nz<Generator({}) l.{} at 0x{}>)ri   r.   r   r   rk   )r/   r   r   r   rl   9  s    zGenerator.__repr__c             C   s   d| j j S )NzGenerator(%s))r.   r   )r/   r   r   r   rm   >  s    zGenerator.__str__)NN)N)r$   r5   r6   r7   r   r{   rf   ZGeneratorModelrP   r0   r   cachedr   rC   ro   rL   rE   rl   rm   r   r   r   )r#   r   r     s   
r   c               @   s0   e Zd ZdZdd Zdd Zdd Zdd	 Zd
S )AsyncGeneratorz,Special node representing an async generatorc             C   s   dt  S )Nz%s.async_generator)r   )r/   r   r   r   ro   E  s    zAsyncGenerator.pytypec             C   s   dS )Nr   r   )r/   r   r   r   rL   H  s    zAsyncGenerator.display_typec             C   s   d | jj| jt| S )Nz!<AsyncGenerator({}) l.{} at 0x{}>)ri   r.   r   r   rk   )r/   r   r   r   rl   K  s    zAsyncGenerator.__repr__c             C   s   d| j j S )NzAsyncGenerator(%s))r.   r   )r/   r   r   r   rm   P  s    zAsyncGenerator.__str__N)r$   r5   r6   r7   ro   rL   rl   rm   r   r   r   r   r   B  s
   r   )N)N)!r7   r   r   r   r<   r   r   Zastroid.constr   r   Zastroid.exceptionsr   r   r	   r
   Zlazy_importrf   r   r   rs   r   addr"   r,   r-   r>   rJ   rK   re   r\   r]   r   r   r   r   r   r   <module>   sD   





"_K9 &