
    e/^                        d Z ddlmZ ddlZddlmZmZ ddl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mZmZ ddlmZ dd	lmZmZmZ dd
lmZmZ ddlm Z  ddl!m"Z" ddl#m$Z$ er?ddl%m&Z& ee$ee$   eejN                  ejP                  f   e$ee$   eege)e
ee$ddf         f   Z* G d de"      Z+ G d de"      Z, G d de"      Z- G d de"      Z. G d de.      Z/ G d de-e,e+      Z0 G d de"      Z1 G d de1      Z2 G d d e"      Z3d4d!Z4d4d"Z5d#d$d%d&d'd(d)d*d+d,d-d.d/d0Z6e6jo                         D  ci c]  \  } }|  e4|       c}} Z8e6jo                         D  ci c]  \  } }| d1z    e5|       c}} Z9 G d2 d3e"      Z:yc c}} w c c}} w )5zThis module contains some base nodes that can be inherited for the different nodes.

Previously these were called Mixin nodes.
    )annotationsN)	GeneratorIterator)cached_property	lru_cachepartial)TYPE_CHECKINGAnyCallableClassVarOptionalUnion)basesnodesutil)
PY310_PLUS)CallContextInferenceContextbind_context_to_node)AttributeInferenceErrorInferenceError)dunder_lookup)NodeNG)InferenceResult)LocalsDictNodeNGc                  "    e Zd ZdZdZ	 d Zd Zy)	StatementzpStatement node adding a few attributes.

    NOTE: This class is part of the public API of 'astroid.nodes'.
    Tc                    | j                   j                  |       }|j                  |       }	 ||dz      S # t        $ r Y yw xY w)z|The next sibling statement node.

        :returns: The next sibling statement node.
        :rtype: NodeNG or None
           N)parentchild_sequenceindex
IndexErrorselfstmtsr"   s      ;/usr/lib/python3/dist-packages/astroid/nodes/_base_nodes.pynext_siblingzStatement.next_sibling:   sL     **40D!	## 		s   6 	AAc                v    | j                   j                  |       }|j                  |       }|dk\  r||dz
     S y)zThe previous sibling statement.

        :returns: The previous sibling statement node.
        :rtype: NodeNG or None
        r   N)r    r!   r"   r$   s      r'   previous_siblingzStatement.previous_siblingG   s?     **40D!A:##    N)__name__
__module____qualname____doc__is_statementr(   r*    r+   r'   r   r   1   s    
 L2
r+   r   c                      e Zd ZdZddZy)NoChildrenNodez1Base nodes for nodes with no children, e.g. Pass.c              #  $   K   dE d {    y 7 w)Nr1   r1   r%   s    r'   get_childrenzNoChildrenNode.get_childrenW   s     s   N)returnzIterator[NodeNG])r,   r-   r.   r/   r6   r1   r+   r'   r3   r3   T   s
    ;r+   r3   c                      e Zd ZdZddZd Zy)FilterStmtsBaseNodez6Base node for statement filtering and assignment type.c                8    | j                         |u r|gdfS |dfS )zAMethod used in _filter_stmts to get statements and trigger break.TF	statement)r%   _node_stmtsmystmts        r'   _get_filtered_stmtsz'FilterStmtsBaseNode._get_filtered_stmts^   s)    >>v% 64<u}r+   c                    | S Nr1   r5   s    r'   assign_typezFilterStmtsBaseNode.assign_typef       r+   Nr@   zStatement | None)r,   r-   r.   r/   rA   rD   r1   r+   r'   r9   r9   [   s    @r+   r9   c                      e Zd ZdZd ZddZy)AssignTypeNodez8Base node for nodes that can 'assign' such as AnnAssign.c                    | S rC   r1   r5   s    r'   rD   zAssignTypeNode.assign_typem   rE   r+   c                H    | |u r|dfS | j                         |u r|gdfS |dfS )zMethod used in filter_stmts.TFr;   )r%   lookup_noder>   r?   r@   s        r'   rA   z"AssignTypeNode._get_filtered_stmtsp   s:    6>4<>>v% 64<u}r+   NrF   )r,   r-   r.   r/   rD   rA   r1   r+   r'   rH   rH   j   s    Br+   rH   c                      e Zd ZdZd Zy)ParentAssignNodezGBase node for nodes whose assign_type is determined by the parent node.c                6    | j                   j                         S rC   )r    rD   r5   s    r'   rD   zParentAssignNode.assign_type~   s    {{&&((r+   N)r,   r-   r.   r/   rD   r1   r+   r'   rM   rM   {   s
    Q)r+   rM   c                  B    e Zd ZU dZded<   	 ded<   	 d Zd
ddZdd	Zy)
ImportNodez$Base node for From and Import Nodes.
str | Nonemodnamezlist[tuple[str, str | None]]namesc                    |S rC   r1   )r%   framenames      r'   _infer_namezImportNode._infer_name   rE   r+   Nc                    | j                         }t        | dd      }|| j                  }|r"|j                  ||      |j                  k(  rd}nd}|j                  ||t        |xr |dk\        |      S )zGReturn the ast for a module whose name is <modname> imported by <self>.levelNFTr   )rY   relative_only	use_cache)rootgetattrrR   relative_to_absolute_namerV   import_modulebool)r%   rR   mymodulerY   r[   s        r'   do_import_modulezImportNode.do_import_module   s    99;#D'48?llG
 227EBhmmSII %%u3!4	 & 
 	
r+   c                    | j                   D ]0  \  }}|dk(  r|c S |s|j                  dd      d   }|}||k(  s.|c S  t        d| |      )zGet name from 'as' name.*.r   r   z:Could not find original name for {attribute} in {target!r})target	attribute)rS   splitr   )r%   asnamerV   _asnames       r'   	real_namezImportNode.real_name   sg    !ZZ 	MD's{zz#q)!, 	 &H
 	
r+   rC   )rR   rQ   r7   znodes.Module)ri   strr7   rl   )r,   r-   r.   r/   __annotations__rW   rb   rk   r1   r+   r'   rP   rP      s,    .
 ('
4
r+   rP   c                  T    e Zd ZU dZdZded<   ed        Zd Zd Z	d Z
edd	       Zy
)MultiLineBlockNodea(  Base node for multi-line blocks, e.g. For and FunctionDef.

    Note that this does not apply to every node with a `body` field.
    For instance, an If node has a multi-line body, but the body of an
    IfExpr is not multi-line, and hence cannot contain Return nodes,
    Assign nodes, etc.
    r1   zClassVar[tuple[str, ...]]_multi_line_block_fieldsc                @     t         fd j                  D              S )Nc              3  6   K   | ]  }t        |        y wrC   )r]   ).0fieldr%   s     r'   	<genexpr>z8MultiLineBlockNode._multi_line_blocks.<locals>.<genexpr>   s     UeWT5)Us   )tuplerp   r5   s   `r'   _multi_line_blocksz%MultiLineBlockNode._multi_line_blocks   s    Ut7T7TUUUr+   c              #     K   | j                   D ].  }|D ]'  }|j                  r|j                         E d {    ) 0 y 7 	wrC   )rw   is_function _get_return_nodes_skip_functionsr%   block
child_nodes      r'   rz   z3MultiLineBlockNode._get_return_nodes_skip_functions   sR     ,, 	IE# I
))%FFHHHI	I I   5AA
Ac              #     K   | j                   D ].  }|D ]'  }|j                  r|j                         E d {    ) 0 y 7 	wrC   )rw   ry   _get_yield_nodes_skip_functionsr{   s      r'   r   z2MultiLineBlockNode._get_yield_nodes_skip_functions   sR     ,, 	HE# H
))%EEGGGH	H Hr~   c              #     K   | j                   D ].  }|D ]'  }|j                  r|j                         E d {    ) 0 y 7 	wrC   )rw   	is_lambda_get_yield_nodes_skip_lambdasr{   s      r'   r   z0MultiLineBlockNode._get_yield_nodes_skip_lambdas   sR     ,, 	FE# F
''%CCEEEF	F Fr~   c                x    d | j                   D        }t        t        j                  j	                  |            S )Nc              3  B   K   | ]  }|D ]  }|j                      y wrC   )_assign_nodes_in_scope)rs   r|   r}   s      r'   ru   z<MultiLineBlockNode._assign_nodes_in_scope.<locals>.<genexpr>   s3      !
#!
  --!
-!
s   )rw   list	itertoolschainfrom_iterable)r%   children_assign_nodess     r'   r   z)MultiLineBlockNode._assign_nodes_in_scope   s5    !
00!

 IOO112GHIIr+   N)r7   zlist[nodes.Assign])r,   r-   r.   r/   rp   rm   r   rw   rz   r   r   r   r1   r+   r'   ro   ro      sQ     ;=7<V VIHF J Jr+   ro   c                  :    e Zd ZdZed        Z	 d	 	 	 	 	 	 	 ddZy)MultiLineWithElseBlockNodez>Base node for multi-line blocks that can have else statements.c                    | j                   S rC   )linenor5   s    r'   blockstart_tolinenoz.MultiLineWithElseBlockNode.blockstart_tolineno   s    {{r+   Nc                    || j                   k(  r||fS |r7||d   j                   k\  r||d   j                  fS ||d   j                   dz
  fS ||xs | j                  fS )z_Handle block line numbers range for try/finally, for, if and while
        statements.
        r   r   )
fromlinenotolineno)r%   r   orelselasts       r'   _elsed_block_rangez-MultiLineWithElseBlockNode._elsed_block_range   sr     T__$6>!---vbz22226!9//!333t,t}},,r+   rC   )r   intr   zlist[nodes.NodeNG]r   z
int | Noner7   ztuple[int, int])r,   r-   r.   r/   r   r   r   r1   r+   r'   r   r      sC    H  KO--#5-=G-	-r+   r   c                  (    e Zd ZdZedd       Zd Zy)LookupMixInz+Mixin to look up a name in the right scope.c                B    | j                         j                  | |      S )a#  Lookup where the given variable is assigned.

        The lookup starts from self's scope. If self is not a frame itself
        and the name is found in the inner frame locals, statements will be
        filtered to remove ignorable statements according to self's location.

        :param name: The name of the variable to find assignments for.

        :returns: The scope node and the list of assignments associated to the
            given name according to the scope where it has been found (locals,
            globals or builtin).
        )scopescope_lookup)r%   rV   s     r'   lookupzLookupMixIn.lookup  s     zz|((t44r+   c                l    | j                  |      \  }}t               }t        j                  |||      S )a
  Lookup the inferred values of the given variable.

        :param name: The variable name to find values for.
        :type name: str

        :returns: The inferred values of the statements returned from
            :meth:`lookup`.
        :rtype: iterable
        )r   r   r   _infer_stmts)r%   rV   rU   r&   contexts        r'   ilookupzLookupMixIn.ilookup  s3     {{4(u"$!!%%88r+   N)rV   rl   r7   z%tuple[LocalsDictNodeNG, list[NodeNG]])r,   r-   r.   r/   r   r   r   r1   r+   r'   r   r     s    55 59r+   r   c                    d| dd  z   S )N__r   r1   rV   s    r'   _reflected_namer   &      48r+   c                    d| dd  z   S )N__ir   r1   r   s    r'   _augmented_namer   *  r   r+   __add____sub____truediv____floordiv____mul____pow____mod____and____or____xor__
__lshift__
__rshift__
__matmul__)+-/z//rd   z**%&|^z<<z>>@=c                     e Zd Ze	 	 	 	 	 	 	 	 dd       Zedd       Ze	 	 	 	 	 	 	 	 dd       Ze	 	 	 	 	 	 	 	 	 	 	 	 	 	 dd       Ze	 d	 	 	 	 	 	 	 	 	 	 	 	 	 dd       Ze	 d	 	 	 	 	 	 	 	 	 	 	 	 	 dd       Z	e	 	 	 	 	 	 dd       Z
ed        Zedd	       Ze	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 dd
       Ze	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 dd       Ze	 	 	 	 	 	 	 	 	 	 	 	 dd       Zy)OperatorNodec              #  l   K    | |      D ]%  }t        ||      rt        j                   "| ' y wrC   )
isinstancer   Uninferable)infer_callabler   errorresults       r'   _filter_operation_errorsz%OperatorNode._filter_operation_errorsG  s9      %W- 	F&%( &&&	s   24c                ^    t        | t        j                        xr | j                  t        u S )z0Check if the given const node is NotImplemented.)r   r   ConstvalueNotImplemented)consts    r'   _is_not_implementedz OperatorNode._is_not_implementedY  s#     %-O%++2OOr+   c                   t        |t        j                        rt        j                  |j
                  v rt        j                  fS |j
                  D cg c]  }t        j                  ||       }}t        d |D              rt        d |D              }nd}nt        |t        j                        ri }|j                  D ]  }t        j                  |d   |      }t        |t        j                        st        j                  fc S t        j                  |d   |      }t        |t        j                        st        j                  fc S |j                  ||j                  <    n8t        |t        j                        r|j                  }nt        j                  fS 	 t        j                  | j                  |z        fS c c}w # t        t        t         f$ r t        j                  fcY S w xY w)zInfer the result of '"string" % ...'.

        TODO: Instead of returning Uninferable we should rely
        on the call to '%' to see if the result is actually uninferable.
        c              3  P   K   | ]  }t        |t        j                           y wrC   )r   r   r   rs   is     r'   ru   zBOperatorNode._infer_old_style_string_formatting.<locals>.<genexpr>k  s     K!:a-K   $&c              3  4   K   | ]  }|j                     y wrC   )r   r   s     r'   ru   zBOperatorNode._infer_old_style_string_formatting.<locals>.<genexpr>l  s     D1qwwDs   Nr   r   )r   r   Tupler   r   elts
safe_inferallrv   Dictitemsr   r   const_factory	TypeErrorKeyError
ValueError)	instanceotherr   r   inferred_positionalvaluespairkeyr   s	            r'   "_infer_old_style_string_formattingz/OperatorNode._infer_old_style_string_formatting^  s    eU[[)5::-((**HM

"S14??1g#>"S"SK7JKKD0CDDuzz*%'F 0ood1gw7!#u{{3 ,,..Q9!%5 ,,..$)KKsyy!0 u{{+[[F$$&&	'''(?@BB+ #T, 8Z0 	'$$&&	's   G+"G %G;:G;c                   t        j                  | |      }t        ||       }|d   }||j                  _        t        | t        j                        r?t        | j                  t              r%|dk(  r t        t        j                  | ||            S 	 t        |j                  |            }t        |t"        j$                        rt         t        | t        j                  t        j&                  t        j(                  t        j*                  t,        j.                  f      st         | j1                  |||||      S # t        $ r}	t!        ||      |	d}	~	ww xY w)z8Invoke binary operation inference on the given instance.r   r   )r   )r>   r   N)r   r   r   callcontextcalleer   r   r   r   rl   iterr   r   nextinferStopIterationr   r   UninferableBaser   ListClassDefr   Instanceinfer_binary_op)
r   opnodeopr   r   method_namemethodsmethodinferredes
             r'   _invoke_binop_inferencez$OperatorNode._invoke_binop_inference  s$     &&x=&w9%+" x-8>>3/c	??eW 	FFLLL9:H h 4 45  [[%++uzz5>>5>>R
 ! ''E7HMM  	F fg>AE	Fs   E   	E	EEc           	     T    t         |   }t        t        j                  | |||||      S )z<Get an inference callable for an augmented binary operation.r   r   r   r   r   r   )AUGMENTED_OP_METHODr   r   r   r   r   r   r   r   reverser   s          r'   _aug_opzOperatorNode._aug_op  s6     *"-00#
 	
r+   c           	     l    |r
t         |   }n	t        |   }t        t        j                  | |||||      S )zGet an inference callable for a normal binary operation.

        If *reverse* is True, then the reflected method will be used instead.
        r   )REFLECTED_BIN_OP_METHODBIN_OP_METHODr   r   r   r   s          r'   _bin_opzOperatorNode._bin_op  sC     1"5K'+K00#
 	
r+   c              #  <   K   t        j                  | |       yw)z>Create a new UnionType instance for binary or, e.g. int | str.N)r   	UnionType)leftrights     r'   _bin_op_or_union_typez"OperatorNode._bin_op_or_union_type  s      oodE**s   c              #  x   K   ||fD ]/  }| j                         }t        |g      |_        d|_        | 1 yw)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.
        )argsN)cloner   r   	boundnode)r   r  r	  argnew_contexts        r'   _get_binop_contextsz OperatorNode._get_binop_contexts  sC      4= 	C!--/K&1u&=K#$(K!		s   8:c                D    | j                         |j                         k(  S )z$Check if type1 is the same as type2.)qname)type1type2s     r'   
_same_typezOperatorNode._same_type  s     {{}--r+   c           
        ddl m} |j                  j                  d      }|j                  }	t        j                  ||      r4t        j                  | ||	||      t        j                  | ||||      g}
|
S |j                  ||      r4t        j                  | ||	||      t        j                  | ||||      g}
|
S |j                  ||      rNt        j                  | ||	||      t        j                  |||| |d      t        j                  | ||||      g}
|
S t        j                  | ||	||      t        j                  | ||||      t        j                  |||| |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)
        r   helpersr   Tr   )
astroidr  r   stripr   r  r  r  
is_subtypeis_supertype)r  	left_type
aug_opnoder	  
right_typer   reverse_contextr  bin_opaug_opr   s              r'   _get_aug_flowzOperatorNode._get_aug_flow  s   2 	$$$S)""9j9$$T:vugN$$T:vugNG2 + 	:6$$T:vugN$$T:vugNG( ! !!)Z8$$T:vugN$$:vt_d %  $$T:vugNG  $$T:vugN$$T:vugN$$:vt_d % G r+   c           	        ddl m} |j                  }t        j	                  ||      rt        j                  | ||||      g}	n|j                  ||      rt        j                  | ||||      g}	n{|j                  ||      r5t        j                  |||| |d      t        j                  | ||||      g}	n4t        j                  | ||||      t        j                  |||| |d      g}	t        r|dk(  rt        | t        j                  t        j                  f      s&t        | t        j                        r| j                  {t        |t        j                  t        j                  f      s&t        |t        j                        r7|j                  +|	j!                  t#        t        j$                  | |      g       |	S )ax  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)
        r   r  Tr  r   )r  r  r   r   r  r  r  r  r   r   r   r  r   r   r   r   extendr   r
  )
r  r  binary_opnoder	  r!  r   r"  r  r   r   s
             r'   _get_binop_flowzOperatorNode._get_binop_flow0  s   0 	$""9j9#++D-UGTUG	:6#++D-UGTUG!!)Z8$$="dOT %  $$T="eWM	G $$T="eWM$$="dOT % G c	4%//5>>!BCdEKK0JJ& 55??ENN"CDeU[[1KK' NNGL$F$FeTUVr+   c           	   #    K   ddl m} t        j                  || |      \  }}|j	                  |       }|j	                  |      } || ||||||      }	|	D ]  }
	 t         |
             }t        d |D              rt        j                    yt        t        t        j                  |            r^t        d |D              }|r"|t        |      k7  rt        j                    y|E d{     y t        j"                  ||j$                  |       y7 +# t        $ r Y t        $ r Y t         $ r t        j                   Y  yw xY ww)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.
        r   r  c              3  P   K   | ]  }t        |t        j                           y wrC   )r   r   r   rs   r   s     r'   ru   z7OperatorNode._infer_binary_operation.<locals>.<genexpr>  s     VFz&$*>*>?Vr   Nc              3  L   K   | ]  }t         j                  |      sd   yw)r   N)r   r   r,  s     r'   ru   z7OperatorNode._infer_binary_operation.<locals>.<genexpr>  s#      & |/O/OPV/WA&s   $$)r  r  r   r  object_typer   anyr   r   r   mapr   sumlenAttributeErrorr   r   BadBinaryOperationMessager   )r  r	  r(  r   flow_factoryr  r"  r  r!  r   r   resultsnot_implementeds                r'   _infer_binary_operationz$OperatorNode._infer_binary_operationo  sS     	$#/#C#CT5$
  ''-	((/
)]E:w
  	Fvx. VgVV***s<;;WEF"% &$+& # ##g,'F***"""5	: ,,Y8H8H*UU	 #- " * ! &&&sO   AED)BE.D/,E	E%E'E/E1EEEEN)r   zfCallable[[InferenceContext | None], Generator[InferenceResult | util.BadOperationMessage, None, None]]r   zInferenceContext | Noner   ztype[util.BadOperationMessage]r7   &Generator[InferenceResult, None, None])r7   r`   )r   znodes.Constr   znodes.NodeNGr   r   r7   z)tuple[util.UninferableBase | nodes.Const])r   r   r   nodes.AugAssign | nodes.BinOpr   rl   r   r   r   r   r   rl   r7   r9  )F)r   r   r   nodes.AugAssignr   rl   r   r   r   r   r   r`   r7   /partial[Generator[InferenceResult, None, None]])r   r   r   r:  r   rl   r   r   r   r   r   r`   r7   r<  )r  .bases.UnionType | nodes.ClassDef | nodes.Constr	  r=  r7   r9  )r  r   r  InferenceResult | Noner   r;  r	  r   r!  r>  r   r   r"  r   r7   5list[partial[Generator[InferenceResult, None, None]]])r  r   r  r>  r(  r:  r	  r   r!  r>  r   r   r"  r   r7   r?  )r  r   r	  r   r(  r:  r   r   r5  GetFlowFactoryr7   zGGenerator[InferenceResult | util.BadBinaryOperationMessage, None, None])r,   r-   r.   staticmethodr   r   r   r   r  r  r
  r  r  r%  r)  r8  r1   r+   r'   r   r   F  s
   

 ) . 
0 " P P "'"'&2"'=M"'	2"' "'H $N!$N-$N $N 	$N
 "$N $N 
0$N $NL  
!

 
 	

 "
 
 
9
 
(  
!
-
 
 	

 "
 
 
9
 
4 +<+=+ 
0+ +   . . 66)6 $6 	6
 +6 "6 *6 
?6 6p <<)< 5< 	<
 +< "< *< 
?< <| 3V3V3V 53V "	3V
 %3V 
Q3V 3Vr+   r   )r7   rl   );r/   
__future__r   r   collections.abcr   r   	functoolsr   r   r   typingr	   r
   r   r   r   r   r  r   r   r   astroid.constr   astroid.contextr   r   r   astroid.exceptionsr   r   astroid.interpreterr   astroid.nodes.node_ngr   astroid.typingr   astroid.nodes.node_classesr   	AugAssignBinOpr   r@  r   r3   r9   rH   rM   rP   ro   r   r   r   r   r  r   r  r   r   )r   r   s   00r'   <module>rO     s  

 #  / 9 9 J J & & $ 
 . ( *;_%%//5;;./_%	
 	WYd:;<=		?N   FV & V ")~ );
$ni ;
|+J +J\-!3 -,9& 9D
 
		
	
				

	" 5B4G4G4I$0S%C	  ;H:M:M:O*63C#Iu%% 
]V6 ]Vs   4FF
