B
    S\VJ              
   @   s8  d Z ddlZddlZddlZddlmZ ddlmZ ddlmZ e	dZ
e	dZejZe	dZe Zejd	krd
ZdZndZdZed dhZddddddddddh
Z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)
exceptions)utilzinterpreter.objectmodelhelpersmanager)   r   builtins__bool__Z__builtin__Z__nonzero__z	.propertyzabc.abstractpropertyZcached_propertyZcachedpropertyZlazypropertyZlazy_propertyZreifyZlazyattributeZlazy_attributeZLazyPropertyZlazyZcache_readonlyc                s   t |  rdS dd |  D  t fddtD r>dS | jsHdS x| jjpTdD ]t}t|}|d ksV|t	j
krxqV|jjdkrVxD|jD ]:}|jjd	krq||j\}}|jtkr|jd
krdS qW qVW dS )NTc             S   s$   h | ]}|t jk	r|d d qS ).)r   Uninferablesplit).0name r   ,lib/python3.7/site-packages/astroid/bases.py	<setcomp>D   s   z_is_property.<locals>.<setcomp>c             3   s   | ]}| kV  qd S )Nr   )r   r   )strippedr   r   	<genexpr>I   s    z_is_property.<locals>.<genexpr>Fr   ClassDefNameproperty)
PROPERTIESintersectionZdecoratornamesanyPOSSIBLE_PROPERTIES
decoratorsZnodesr   Z
safe_inferr   r   	__class____name__baseslookupr   BUILTINS)methZ	decoratorinferredZ
base_classmodule_r   )r   r   _is_propertyA   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__i   s    zProxy.__init__c             C   s4   |dkrt | jdS || jkr(| j| S t | j|S )Nr(   )getattrr   __dict__r(   )r)   r   r   r   r   __getattr__m   s
    

zProxy.__getattr__c             c   s
   | V  d S )Nr   )r)   r   r   r   r   infert   s    zProxy.infer)N)N)r   
__module____qualname____doc__r(   r*   r-   r.   r   r   r   r   r'   ^   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j	k
r   w.Y q. tj
k
r   tjV  d}Y q.X q.W |stj
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   )Z
lookupnameZclone
contextmodInferenceContextr   r   Z_infer_namer.   r   ZNameInferenceErrorInferenceError)r2   r   r3   r#   r   Zstmtr   r   r   _infer_stmtsx   s6    


r7   c             C   s   t | j||dd }|rt|dr| s0tjS y@x:|j| |dD ](}|tjkrT|S t |j|d}| S W W n t	j
k
r   Y nX tjS )N)r   infer_call_result)nextigetattrhasattrcallabler   r   r8   r.   
bool_valuer   r6   )instanceZmethod_namer   r"   valuer#   r   r   r   _infer_method_result_truth   s    
r@   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 nj tjk
r| } zJ| jrD|| jkrD| j|gS |rZ| j j||ddS tj| ||d|W d d }~X Y nX |ry|| j j||dd S  tjk
r   Y nX |S )NF)class_context)targetZ	attributer   )r(   Zinstance_attrr   AttributeInferenceErrorspecial_attributesr    r+   )r)   r   r   lookupclassvaluesexcr   r   r   r+      s"    
zBaseInstance.getattrc             c   s   |st  }yD|| j|fr"dS | j||dd}t| |||| dE dH  W n tjk
r } zyH| jj	j
dkrtjf t||| jj||dd}| ||E dH  W n6 tjk
r } ztjf t||W dd}~X Y nX W dd}~X Y nX dS )zinferred getattrNF)rG   )r3   r   )rC   )r4   r5   pushr(   r+   r7   
_wrap_attrr   rE   r   r   r6   varsr:   )r)   r   r   Zget_attrerrorattrsr   r   r   r:      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	kr|j
j
r|j
j
d jdkrt|| V  q|V  q|V  qW dS )z7wrap bound methods of attrs in a InstanceMethod proxiesNr   z<lambda>r   r)   )
isinstanceUnboundMethodr&   r8   BoundMethodr;   r   Z	statementZscoper(   args)r)   rN   r   attrr   r   r   rK      s    

zBaseInstance._wrap_attrc             c   st   t || }d}xJ| jd|D ]8}|tjks | s8q x|||D ]}d}|V  qFW q W |sptj	| ||ddS )z4infer what a class instance is returning when calledF__call__T)nodecallerr   N)
r4   bind_context_to_noder(   r:   r   r   r<   r8   r   r6   )r)   rV   r   r#   rU   Zresr   r   r   r8      s    zBaseInstance.infer_call_result)NT)N)N)N)
r   r/   r0   r1   rF   rB   r+   r:   rK   r8   r   r   r   r   rA      s   


rA   c               @   sX   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 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>  s    zInstance.<lambda>c             C   s   d| j  j| j jt| f S )Nz<Instance of %s.%s at 0x%s>)r(   rootr   id)r)   r   r   r   __repr__  s    
zInstance.__repr__c             C   s   d| j  j| j jf S )NzInstance of %s.%s)r(   r[   r   )r)   r   r   r   __str__  s    zInstance.__str__c             C   s0   y| j jddd dS  tjk
r*   dS X d S )NrT   F)rC   T)r(   r+   r   rE   )r)   r   r   r   r<     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   rB   '  s    zInstance.display_typec             C   s|   t  }t jg d|_| |_yt| t|}W nJ tjtj	fk
rv   yt| d|}W n tj	tjfk
rp   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.
        )rR   __len__T)
r4   r5   ZCallContextZcallcontextZ	boundnoder@   BOOL_SPECIAL_METHODr   r6   rE   )r)   r   resultr   r   r   r=   *  s    zInstance.bool_valueNc             C   s   d S )Nr   )r)   indexr   r   r   r   getitemF  s    zInstance.getitem)N)r   r/   r0   r1   r   lazy_descriptorrF   r]   r^   r<   r`   rB   r=   re   r   r   r   r   rX     s   rX   c               @   sZ   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 Zd
S )rP   z=a special node representing a method not bound to an instancec               C   s   t  S )N)rY   ZUnboundMethodModelr   r   r   r   rZ   N  s    zUnboundMethod.<lambda>c             C   s,   | j j }d| jj| j j| t| f S )Nz<%s %s of %s at 0x%s)r(   parentr3   r   r   r   r_   r\   )r)   r3   r   r   r   r]   P  s    zUnboundMethod.__repr__c             C   s   dS )Nr   r   )r)   r   r   r   implicit_parametersY  s    z!UnboundMethod.implicit_parametersc             C   s   dS )NFr   )r)   r   r   r   is_bound\  s    zUnboundMethod.is_boundNc             C   s&   || j kr| j |gS | j||S )N)rF   r    r(   r+   )r)   r   r   r   r   r   r+   _  s    
zUnboundMethod.getattrc             C   s*   || j krt| j |fS | j||S )N)rF   iterr    r(   r:   )r)   r   r   r   r   r   r:   d  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   rX   )r   xr   r   r   r     s    z2UnboundMethod.infer_call_result.<locals>.<genexpr>)r(   r   rg   r3   r_   r!   rR   Zextra_contextgetr.   r8   )r)   rV   r   Znode_contextr.   r   r   r   r8   i  s    zUnboundMethod.infer_call_resultc             C   s   dS )NTr   )r)   r   r   r   r=     s    zUnboundMethod.bool_value)N)N)r   r/   r0   r1   r   rf   rF   r]   rh   ri   r+   r:   r8   r=   r   r   r   r   rP   J  s   	

rP   c                   sX   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 Z  ZS )rQ   z9a special node representing a method bound to an instancec               C   s   t  S )N)rY   ZBoundMethodModelr   r   r   r   rZ     s    zBoundMethod.<lambda>c             C   s   t | | || _d S )N)rP   r*   bound)r)   proxyrn   r   r   r   r*     s    zBoundMethod.__init__c             C   s   dS )N   r   )r)   r   r   r   rh     s    zBoundMethod.implicit_parametersc             C   s   dS )NTr   )r)   r   r   r   ri     s    zBoundMethod.is_boundc                s  ddl m} t|jd j d}|jjdkr2dS |dt sDdS t|jd j d}|jjdkrjdS t	|j
tszdS t|jd	 j d}|jjd
krdS  fdd|jD }tdd |D rdS t|jd j d}|jjdkrdS tt}	x`|jD ]V\}
}t|
j d}
t|j d}|
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   r   Nz%s.typerp   ZConst   ZTuplec                s   g | ]}t |j d qS ))r   )r9   r.   )r   Z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>r   ZDict)r   lineno
col_offsetrg   T)r   Zbodyr   Znewstyle	metaclasskeywords)astroidrq   r9   rR   r.   r   r   Zis_subtype_ofr!   rO   r?   strZeltsr   collectionsdefaultdictlistitemsappendru   rv   ZPassZpostinitlocals)r)   rV   r   rq   Zmcsr   r   Zinferred_basesrN   Z
cls_localskeyr?   clsemptyr   )r   r   _infer_type_new_call  sR    
z BoundMethod._infer_type_new_callNc                sl   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
t| ||S )Nr   typerk      )r4   rW   rn   r   r   r   lenrR   r   rj   superrQ   r8   )r)   rV   r   Znew_cls)r   r   r   r8     s    

zBoundMethod.infer_call_resultc             C   s   dS )NTr   )r)   r   r   r   r=     s    zBoundMethod.bool_value)N)r   r/   r0   r1   r   rf   rF   r*   rh   ri   r   r8   r=   __classcell__r   r   )r   r   rQ     s   ErQ   c               @   sX   e Zd ZdZedd ZdddZdd Zd	d
 Z	dd Z
dd Zdd Zdd ZdS )	Generatorzea special node representing a generator.

    Proxied class is set once for all in raw_building.
    c               C   s   t  S )N)rY   ZGeneratorModelr   r   r   r   rZ     s    zGenerator.<lambda>Nc             C   s
   || _ d S )N)rg   )r)   rg   r   r   r   r*     s    zGenerator.__init__c             C   s   dS )NFr   )r)   r   r   r   r<     s    zGenerator.callablec             C   s   dt  S )Nz%s.generator)r!   )r)   r   r   r   r`     s    zGenerator.pytypec             C   s   dS )Nr   r   )r)   r   r   r   rB     s    zGenerator.display_typec             C   s   dS )NTr   )r)   r   r   r   r=     s    zGenerator.bool_valuec             C   s   d| j j| jt| f S )Nz<Generator(%s) l.%s at 0x%s>)r(   r   ru   r\   )r)   r   r   r   r]     s    zGenerator.__repr__c             C   s   d| j j S )NzGenerator(%s))r(   r   )r)   r   r   r   r^     s    zGenerator.__str__)N)r   r/   r0   r1   r   rf   rF   r*   r<   r`   rB   r=   r]   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   r`     s    zAsyncGenerator.pytypec             C   s   dS )Nr   r   )r)   r   r   r   rB     s    zAsyncGenerator.display_typec             C   s   d| j j| jt| f S )Nz!<AsyncGenerator(%s) l.%s at 0x%s>)r(   r   ru   r\   )r)   r   r   r   r]     s    zAsyncGenerator.__repr__c             C   s   d| j j S )NzAsyncGenerator(%s))r(   r   )r)   r   r   r   r^   "  s    zAsyncGenerator.__str__N)r   r/   r0   r1   r`   rB   r]   r^   r   r   r   r   r     s
   r   )N)r1   r   r{   sysry   r   r4   r   r   Zlazy_importrY   r   r   r!   r   ZAstroidManagerZMANAGERversion_inforb   r   r   r&   r'   r7   r@   rA   rX   rP   rQ   r   r   r   r   r   r   <module>   sJ   





"`=<h$