a
    E
al                     @   s  d Z ddl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	m
Z
mZmZmZ ddl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 ed	ZdZd
dZeej_eej _eej!_eej"_eej#_d[ddZ$e	j%d\ddZ&e&ej'_e&ej(_e&ej)_d]ddZ*dd Z+dd Z,e*ej-_dd Z.d^ddZ/e	%e	0e/ej1_e/ej2_3e	j%e	j0d_ddZ4e4ej5_e	j%e	j0d`ddZ6e6ej7_e	j%e	j0dadd Z8e8ej9_dbd!d"Z:e	%e	0e:ej;_e	%e:ej<_3e	j%e	j0dcd#d$Z=e=ej>_e? Z@ddd%d&ZAe	%e	0eAejB_e	%eAejB_3e	j%e	j0ded'd(ZCeCejD_d)d* ZEdfd+d,ZFe	j%e	j0dgd-d.ZGeFejH_FeGejH_d/d0 ZId1d2 ZJdhd4d5ZKdid6d7ZLd8d9 ZMd:d; ZNd<d= ZOd>d? ZPd@dA ZQdBdC ZRe	jSe	j0djdDdEZTeRejU_ReTejU_dkdFdGZVe	j%e	j0dldHdIZWeVejX_VeWejX_e	j%dmdJdKZYeYejZ_e	j%e	j0dndLdMZ[e[ej2_e[ej<_e	j%e	j0dodNdOZ\e\ej]_e	j%dpdPdQZ^e^ej__dRdS Z`e	j%dqdTdUZaeaejb_ejci fdVdWZdeddrdXdYZeeeejf_dS )szMthis module contains a set of functions to handle inference on astroid trees
    N)basescontext)
decoratorshelpersnodes	protocolsutil)AstroidBuildingErrorAstroidErrorAstroidIndexErrorAstroidTypeErrorAttributeInferenceErrorInferenceErrorNameInferenceError_NonDeducibleTypeHierarchy)dunder_lookup)AstroidManagerobjectsc                 c   s
   | V  dS )zInference's end for nodes that yield themselves on inference

    These are objects for which inference does not have any semantic,
    such as Module or Consts.
    N selfr   r   r   0lib/python3.9/site-packages/astroid/inference.py	infer_end:   s    r   c                 C   s   g }| j D ]}t|tjr^t|j|}|s8t| |dt|dsNt| |d|	t
| q
t|tjrt|j|}|st| |d|| q
|| q
|S )z-Infer all values based on _BaseContainer.eltsnoder   elts)r   
isinstancer   Starredr   
safe_infervaluer   hasattrextend_infer_sequence_helper	NamedExprappend)r   r   valueseltZstarredr    r   r   r   r#   J   s     

r#   c                 c   sV   t dd | jD }|rLt| |}t| | j| j| jd}|| |V  n| V  d S )Nc                 s   s    | ]}t |tjtjfV  qd S N)r   r   r   r$   ).0er   r   r   	<genexpr>b   s   z!infer_sequence.<locals>.<genexpr>)lineno
col_offsetparent)anyr   r#   typer,   r-   r.   postinit)r   r   Zhas_starred_named_exprr&   new_seqr   r   r   infer_sequence`   s    

r3   c                 c   sX   t dd | jD s| V  n8t| |}t| | j| j| j}|t|  |V  d S )Nc                 s   s   | ]\}}t |tjV  qd S r(   )r   r   
DictUnpack)r)   k_r   r   r   r+   w       zinfer_map.<locals>.<genexpr>)	r/   items
_infer_mapr0   r,   r-   r.   r1   list)r   r   r8   r2   r   r   r   	infer_mapv   s    
r;   c                 C   s.   t |  | }dd |D }t| S )ab  Delete nodes that equate to duplicate keys

    Since an astroid node doesn't 'equal' another node with the same value,
    this function uses the as_string method to make sure duplicate keys
    don't get through

    Note that both the key and the value are astroid nodes

    Fixes issue with DictUnpack causing duplicte keys
    in inferred Dict items

    :param dict(nodes.NodeNG, nodes.NodeNG) lhs_dict: Dictionary to 'merge' nodes into
    :param dict(nodes.NodeNG, nodes.NodeNG) rhs_dict: Dictionary with nodes to pull from
    :return dict(nodes.NodeNG, nodes.NodeNG): merged dictionary of nodes
    c                 S   s   i | ]\}}|  ||fqS r   )Z	as_string)r)   keyr    r   r   r   
<dictcomp>   r7   z,_update_with_replacement.<locals>.<dictcomp>)	itertoolschainr8   dictr&   )Zlhs_dictZrhs_dictZcombined_dictZ
string_mapr   r   r   _update_with_replacement   s    rA   c                 C   s   i }| j D ]\}}t|tjr`t||}|s2tt|tjsJt| |dt||}t	||}q
tj||d}tj||d}t
dd ||fD rt| |dt	|||i}q
|S )z$Infer all values based on Dict.itemsr   r   c                 s   s   | ]}| V  qd S r(   r   )r)   elemr   r   r   r+      r7   z_infer_map.<locals>.<genexpr>)r8   r   r   r4   r   r   r   Dictr9   rA   r/   )r   r   r&   namer    Zdouble_starredZunpack_itemsr<   r   r   r   r9      s     
r9   c                 C   s4   | }|j r t|j tjs |j }q|r0|j r0|j S dS )a  Search for the first function which encloses the given
    scope. This can be used for looking up in that function's
    scope, in case looking up in a lower scope for a particular
    name fails.

    :param node: A scope node.
    :returns:
        ``None``, if no parent function scope was found,
        otherwise an instance of :class:`astroid.scoped_nodes.Function`,
        which encloses the given node.
    N)r.   r   r   FunctionDef)r   Zcurrentr   r   r   _higher_function_scope   s    
rF   c                 C   sl   |  | j\}}|sLt|  }|r4| | j\}}|sLt| j|  |dt|}| j|_t	|||S )z#infer a Name: use name lookup rules)rD   scoper   )
lookuprD   rF   rG   r   
contextmodcopy_context
lookupnamer   _infer_stmts)r   r   framestmtsZparent_functionr6   r   r   r   
infer_name   s    
rO   c              	   c   s   t |}t j| j| jd|_d|_|dur<t| | |_	| j
|D ]P}|tju r^|V  qHz"t|dr~|j| |dE dH  W qH ty   Y qHY qH0 qHt| |dS )z>infer a Call node by trying to guess what the function returns)argskeywordsNinfer_call_result)Zcallerr   r   )rI   rJ   CallContextrP   rQ   callcontext	boundnode_populate_context_lookupcloneZextra_contextfuncinferr	   Uninferabler!   rR   r   r@   )r   r   rT   Zcalleer   r   r   
infer_call   s"    


r[   Tc              
   c   sz   |j }|du rt| |dz(|r4| | |V  n| |V  W n2 tyt } zt| |d|W Y d}~n
d}~0 0 dS )z7infer an Import node: return the imported module/objectNr   )rK   r   do_import_module	real_namer
   )r   r   asnamerD   excr   r   r   infer_import   s    r`   c              
   C   s  |j }|du rt| |d|r`z| |}W n2 ty^ } zt| |d|W Y d}~n
d}~0 0 z|  }W n2 ty } zt| |d|W Y d}~n
d}~0 0 z4t|}||_ |j||| 	 u d}t
||W S  ty } z"tt|| ||d|W Y d}~n
d}~0 0 dS )z:infer a ImportFrom node: return the imported module/objectNr   )Zignore_localstargetZ	attributer   )rK   r   r]   r   r\   r
   rI   rJ   getattrrootr   rL   str)r   r   r^   rD   r_   modulerN   errorr   r   r   infer_import_from  s.    $$
rh   c                 c   s   | j |D ]}|tju r"|V  q|r|jrt|tjrt|jtjrz$t	t
|jt
|rh|j}W q ty|   Y q0 n|st }|j}zBz||_|| j|E dH  W n tttfy   Y n0 W ||_q||_0 qt| |dS )zAinfer an Attribute node by using getattr on the associated objectNr   )exprrY   r	   rZ   rU   r   r   Instancer   
is_subtypeobject_typer   rI   InferenceContextZigetattrattrnamer   r   AttributeErrorr@   )r   r   ownerZold_boundnoder   r   r   infer_attribute,  s<    




rq   c              
   C   sr   |j d u rt| |dzt|  |j |W S  tyl } z$tt|| |j |d|W Y d }~n
d }~0 0 d S )Nr   ra   )rK   r   r   rL   rd   rc   r   re   )r   r   rg   r   r   r   infer_global\  s    
rr   c           	      c   sF  d}| j |D ]}|tju r.tjV   dS | j|D ]}|tju rXtjV    dS t}|jtjkrn|}n$|jtjkrt	
|}|r|}n|}|tu rt| |dz|||}W n: ttttfy } zt| |d|W Y d}~n
d}~0 0 | |u s|tju rtjV    dS ||E dH  d}q:q|rBt| |dS dS )zInference for subscripts

    We're understanding if the index is a Const
    or a slice, passing the result of inference
    to the value's `getitem` method, which should
    handle each supported index type accordingly.
    FNr   T)r    rY   r	   rZ   slice_SUBSCRIPT_SENTINEL	__class__r   rj   r   Zclass_instance_as_indexr   getitemr   r   r   ro   r@   )	r   r   Z	found_oner    indexZindex_valueZinstance_as_indexassignedr_   r   r   r   infer_subscripto  sH    	


$ry   c                 #   s   | j }| jdkrtj}ntj}z fdd|D }W n tyP   tjV  Y dS 0 tj	| D ]|}t
dd |D r|tjV  q\dd |D }t
dd |D rtjV  q\tj}t||D ]\}}||r|V   q\q|V  q\t|  d	S )
zInfer a boolean operation (and / or / not).

    The function will calculate the boolean operation
    for all pairs generated through inference for each component
    node.
    orc                    s   g | ]}|j  d qS )r   )rY   r)   r    r   r   r   
<listcomp>  r7   z!_infer_boolop.<locals>.<listcomp>Nc                 s   s   | ]}|t ju V  qd S r(   r	   rZ   r)   itemr   r   r   r+     r7   z _infer_boolop.<locals>.<genexpr>c                 S   s   g | ]}|  qS r   )
bool_valuer~   r   r   r   r|     r7   c                 s   s   | ]}|t ju V  qd S r(   r}   r~   r   r   r   r+     r7   r   )r&   opoperatortruthnot_r   r	   rZ   r>   productr/   zipr@   )r   r   r&   Z	predicateZpairZbool_valuesr    r   r   r   r   _infer_boolop  s0    	
r   c                 c   s.   || |D ]}t ||r"tjV  q
|V  q
d S r(   )r   r	   rZ   )r   Zinfer_callabler   rg   resultr   r   r   _filter_operation_errors  s    

r   c           
      c   s"  | j |D ]}z|| jV  W q tyZ } zt|| j|V  W Y d}~qd}~0  ty } ztj	| j }|du r|
 }|tjurt| V  ntjV  nXt|tjtjfst|| j|V  W Y d}~qzzt||}W n6 ty&   t|| j|V  Y W W Y d}~qY n0 |d }t|j|dd}|tju sX| sfW W Y d}~qt|}tj|gd|_|j| |d}t|d}	|	du r|V  n|	V  W nR ty } zt|| j|V  W Y d}~n$d}~0  ty   tjV  Y n0 W Y d}~qd}~0 0 qdS )3Infer what an UnaryOp should return when evaluated.Nr   r   rP   )operandrY   Zinfer_unary_opr   	TypeErrorr	   BadUnaryOperationMessagero   r   ZUNARY_OP_METHODr   rZ   r   Zconst_factoryr   r   rj   ClassDefr   rH   r   nextcallablerI   rJ   rS   rT   rR   r   )
r   r   r   r_   methr   methodsinferredZcall_resultsr   r   r   r   _infer_unaryop  sH    &




&r   c                 c   s"   t | t|tjE dH  t| |dS )r   Nr   )r   r   r	   r   r@   r   r   r   r   infer_unaryop)  s    

r   c                 C   s   t | tjo| jtu S )z0Check if the given const node is NotImplemented.)r   r   Constr    NotImplemented)Zconstr   r   r   _is_not_implemented7  s    r   c           
   
   C   s   t | |}t|| }|d }zt|j|d}W n2 tyf }	 zt||d|	W Y d}	~	n
d}	~	0 0 |tj	u rvt| 
|||||S )z8Invoke binary operation inference on the given instance.r   r   r   N)r   rH   rI   Zbind_context_to_noder   rY   StopIterationr   r	   rZ   Zinfer_binary_op)
instanceopnoder   otherr   method_namer   methodr   r*   r   r   r   _invoke_binop_inference<  s    $
r   Fc              	   C   s"   t j| }tjt| |||||dS )z<Get an inference callable for an augmented binary operation.r   r   r   r   r   r   )r   ZAUGMENTED_OP_METHOD	functoolspartialr   r   r   r   r   r   reverser   r   r   r   _aug_opJ  s    
r   c              	   C   s2   |rt j| }n
t j| }tjt| |||||dS )zGet an inference callable for a normal binary operation.

    If *reverse* is True, then the reflected method will be used instead.
    r   )r   ZREFLECTED_BIN_OP_METHODZBIN_OP_METHODr   r   r   r   r   r   r   _bin_opX  s    
r   c                 c   s6   ||fD ](}|   }tj|gd|_d|_|V  qdS )zGet contexts for binary operations.

    This will return two inference contexts, the first one
    for x.__op__(y), the other one for y.__rop__(x), where
    only the arguments are inversed.
    r   N)rW   rI   rS   rT   rU   )r   leftrightargZnew_contextr   r   r   _get_binop_contextsl  s
    	r   c                 C   s   |   |  kS )z$Check if type1 is the same as type2.)Zqname)Ztype1Ztype2r   r   r   
_same_type|  s    r   c           	   	   C   s   |j }t||r$t| ||||g}nvt||rDt| ||||g}nVt||rvt|||| |ddt| ||||g}n$t| ||||t|||| |ddg}|S )aV  Get the flow for binary operations.

    The rules are a bit messy:

        * if left and right have the same type, then only one
          method will be called, left.__op__(right)
        * if left and right are unrelated typewise, then first
          left.__op__(right) is tried and if this does not exist
          or returns NotImplemented, then right.__rop__(left) is tried.
        * if left is a subtype of right, then only left.__op__(right)
          is tried.
        * if left is a supertype of right, then right.__rop__(left)
          is first tried and then left.__op__(right)
    Tr   )r   r   r   r   rk   is_supertype)	r   	left_typebinary_opnoder   
right_typer   reverse_contextr   r   r   r   r   _get_binop_flow  s    
r   c           
   
   C   s   |j d}|j }t||r>t| ||||t| ||||g}	nt||rlt| ||||t| ||||g}	nrt||rt| ||||t|||| |ddt| ||||g}	n2t| ||||t| ||||t|||| |ddg}	|	S )a  Get the flow for augmented binary operations.

    The rules are a bit messy:

        * if left and right have the same type, then left.__augop__(right)
          is first tried and then left.__op__(right).
        * if left and right are unrelated typewise, then
          left.__augop__(right) is tried, then left.__op__(right)
          is tried and then right.__rop__(left) is tried.
        * if left is a subtype of right, then left.__augop__(right)
          is tried and then left.__op__(right).
        * if left is a supertype of right, then left.__augop__(right)
          is tried, then right.__rop__(left) and then
          left.__op__(right)
    =Tr   )r   stripr   r   r   r   rk   r   )
r   r   Z
aug_opnoder   r   r   r   Zbin_opZaug_opr   r   r   r   _get_aug_flow  s(    
r   c              	   c   s  t || |\}}t| }t|}|| ||||||}|D ]}	zt|	 }
W nF tyd   Y q<Y q< tyx   Y q<Y q< ty   tjV  Y  dS 0 t	dd |
D rtjV   dS t
tt|
rq<tdd |
D }|r|t|
krtjV   dS |
E dH   dS q<t||j|V  dS )zInfer a binary operation between a left operand and a right operand

    This is used by both normal binary operations and augmented binary
    operations, the only difference is the flow factory used.
    Nc                 s   s   | ]}|t ju V  qd S r(   r}   r)   r   r   r   r   r+     r7   z*_infer_binary_operation.<locals>.<genexpr>c                 s   s   | ]}t |rd V  qdS )   N)r   r   r   r   r   r+     s   )r   r   rl   r:   ro   r   r   r	   rZ   r/   allmapr   sumlenBadBinaryOperationMessager   )r   r   r   r   flow_factoryr   r   r   r   r   ZresultsZnot_implementedr   r   r   _infer_binary_operation  s<    



r   c           
   	   c   s   | j }| j}|pt }t|}t|}|j|d}|j|d}t||D ]b\}}	tdd |	|fD r|t	j
V   dS zt||	| |tE dH  W qP ty   t	j
V  Y qP0 qPdS )z!Binary operation inference logic.r   c                 s   s   | ]}|t ju V  qd S r(   r}   r{   r   r   r   r+     r7   z_infer_binop.<locals>.<genexpr>N)r   r   rI   rm   rJ   rY   r>   r   r/   r	   rZ   r   r   r   )
r   r   r   r   lhs_contextrhs_contextlhs_iterrhs_iterlhsrhsr   r   r   _infer_binop  s    

r   c                 C   s   t | t|tjS r(   )r   r   r	   r   r   r   r   r   infer_binop  s    
r   c              	   c   s   |du rt  }| }| jj|d}| jj|d}t||D ]d\}}t	dd ||fD rlt
jV   dS zt||| |tdE dH  W q@ ty   t
jV  Y q@0 q@dS )z0Inference logic for augmented binary operations.Nr   c                 s   s   | ]}|t ju V  qd S r(   r}   r{   r   r   r   r+   ,  r7   z#_infer_augassign.<locals>.<genexpr>)r   r   r   r   r   )rI   rm   rW   rb   	infer_lhsr    rY   r>   r   r/   r	   rZ   r   r   r   )r   r   r   r   r   r   r   r   r   r   _infer_augassign"  s&    r   c                 C   s   t | t|tjS r(   )r   r   r	   r   r   r   r   r   infer_augassign=  s    
r   c                 C   s(   |j }|d u rt| |dt| ||S )Nr   )rK   r   r   Z_arguments_infer_argname)r   r   rD   r   r   r   infer_argumentsK  s    r   c                 C   s6   t | jtjr| j|S t| j|d}t||S )zWinfer a AssignName/AssignAttr: need to inspect the RHS part of the
    assign node
    r   )	r   r.   r   	AugAssignrY   r:   Zassigned_stmtsr   rL   )r   r   rN   r   r   r   infer_assignV  s    r   c                 c   sN   |   stjV  n8zt j| j|dE d H  W n tyH   tjV  Y n0 d S )Nr   )Zhas_underlying_objectr	   rZ   r   Zinfer_ast_from_somethingobjectr   r   r   r   r   infer_empty_nodeg  s    
r   c                 C   s   | j |S r(   )r    rY   r   r   r   r   infer_indexx  s    r   c                 C   sh   i }|d u r|S | j D ]$}t|tjr2|||j< q|||< q| jd urL| jng }|D ]}|||j< qT|S r(   )rP   r   r   r   r    rQ   )Zcallr   Zcontext_lookupr   rQ   keywordr   r   r   rV     s    

rV   c              	   c   s   d}|pt  }t |}t |}zt| jj| d}W n ttfyX   d}Y nD0 |t	j
ur| r| jj|dE dH  q| jj|dE dH  nd}|r| jj|dE dH  | jj|dE dH  dS )zSupport IfExp inference

    If we can't infer the truthiness of the condition, we default
    to inferring both branches. Otherwise, we infer either branch
    depending on the condition.
    Fr   TN)rI   rm   rJ   r   testrY   rW   r   r   r	   rZ   r   bodyorelse)r   r   Zboth_branchesr   r   r   r   r   r   infer_ifexp  s     



r   c           	      C   sj   |d }zt || t|f W S  tyd   | |i |}t|\}}t||| t|f< | Y S 0 d S )Nr   )iteridKeyErrorr>   teer:   )	rX   r   rP   kwargs_cacher   r   Zoriginalcopyr   r   r   _cached_generator  s    r   c                 c   sd   | j rt| s"| V  t| |dS tj| | j| j| j| j	| j
d}|jg | jd |V  t| |dS )Nr   )ZfunctionrD   docr,   r.   r-   )r   rP   )r   r   Z_is_propertyr@   r   ZPropertyrD   r   r,   r.   r-   r1   rP   )r   r   Z	prop_funcr   r   r   infer_functiondef  s    r   )N)N)N)N)N)N)NT)NT)N)N)N)N)N)N)F)F)N)N)N)N)N)N)N)N)N)g__doc__r   r>   r   ZwraptZastroidr   r   rI   r   r   r   r   r	   Zastroid.exceptionsr
   r   r   r   r   r   r   r   Zastroid.interpreterr   Zastroid.managerr   Zlazy_importr   r   ZModuleZ_inferr   ZLambdar   ZSlicer#   Zraise_if_nothing_inferredr3   ListTupleSetr;   rA   r9   rC   rF   rO   Zpath_wrapperNameZ
AssignNamer   r[   ZCallr`   ZImportrh   Z
ImportFromrq   Z	AttributeZ
AssignAttrrr   ZGlobalr   rt   ry   Z	Subscriptr   ZBoolOpr   r   r   ZUnaryOpr   r   r   r   r   r   r   r   r   r   Zyes_if_nothing_inferredr   ZBinOpr   r   r   r   Z	Argumentsr   r   Z	EmptyNoder   ZIndexrV   r   ZIfExp	decoratorr   r   rE   r   r   r   r   <module>   s   (


	




)
83
6

#-,
 