
    e                       d Z ddlmZ ddlZddlmZ ddlmZmZ ddl	m
Z
 ddlmZ ddlmZmZ dd	lmZ dd
lmZ erddlmZ ej,                  ej.                  ej0                  ej2                  j4                  fZ G d de      ZddZy)z*Check for use of nested min/max functions.    )annotationsN)TYPE_CHECKING)nodesobjects)Context)BaseChecker)only_required_for_messages
safe_infer)	PY39_PLUS)	INFERENCE)PyLinterc                  j    e Zd ZdZdZdZddiZedd       Zedd       Z	 e
d      dd	       Zdd
Zy)NestedMinMaxCheckerzMultiple nested min/max calls on the same line will raise multiple messages.

    This behaviour is intended as it would slow down the checker to check
    for nested call with minimal benefits.
    )zbuiltins.minzbuiltins.maxnested_min_maxW3301)z@Do not use nested call of '%s'; it's possible to do '%s' insteadnested-min-maxzHNested calls ``min(1, min(2, 3))`` can be rewritten as ``min(1, 2, 3)``.c                    t        |t        j                        syt        |j                        }t        |t        j
                        xr |j                         | j                  v S )NF)
isinstancer   Callr
   funcFunctionDefqname
FUNC_NAMES)clsnodeinferreds      @/usr/lib/python3/dist-packages/pylint/checkers/nested_min_max.pyis_min_max_callz#NestedMinMaxChecker.is_min_max_call1   sN    $

+dii(x!2!23 3 CNN2	
    c                    |j                   D cg c]B  }| j                  |      r/|j                  j                  |j                  j                  k(  r|D c}S c c}w N)argsr   r   name)r   r   args      r   get_redundant_callsz'NestedMinMaxChecker.get_redundant_calls<   sM     yy
""3'CHHMMTYY^^,K 
 	
 
s   AAr   c                   | j                  |      sy | j                  |      }|sy t        j                  |      }t        |      dkD  rt	        |j
                        D ]w  \  }}t        |t        j                        rt        d |j
                  D              r y ||v sC|j
                  d | |j
                  z   |j
                  |dz   d  z   |_         n | j                  |      }t        |      dkD  rt	        |j
                        D ]  \  }}t        |t        j                        r!| j                  |      s3t        j                  t        j                  |j                  dt        j                   d d d d d       dd      }||_        |j
                  d | |gz   |j
                  |dz   | z   |_         | j%                  d||j&                  j(                  |j+                         ft,               y )Nr   c              3  P   K   | ]  }t        |t        j                           y wr!   )r   r   GeneratorExp).0as     r   	<genexpr>z1NestedMinMaxChecker.visit_call.<locals>.<genexpr>R   s"      7:;Jq%"4"457s   $&   )lineno
col_offset
end_linenoend_col_offsetparent)ctxr-   r.   r1   r/   r0   r   )r   r"   
confidence)r   r%   copylen	enumerater"   r   r   r   anyConst_is_splattable_expressionStarredr   Loadr-   NodeNGvalueadd_messager   r#   	as_stringr   )selfr   redundant_calls
fixed_nodeir$   idx
splat_nodes           r   
visit_callzNestedMinMaxChecker.visit_callD   s   ##D)2248YYt_
/"Q&#JOO4 3 c5::.3 7?Bxx7 4 /)"+chh6Q9QQ O  #66zBO /"Q&" "*//2 	HCc5;;/11#6!&#LL"zz#$$||#''+'++/#'  $%'("J (+J$"-%,'$//#'C89 O%	0 	))..*"6"6"89 	 	 	
r   c                   t        |t        j                        rG|j                  dk(  r8| j	                  |j
                        xr | j	                  |j                        S t        |t        j                        rM|j                  dk(  r>t        r8| j	                  |j
                        xr | j	                  |j                        S t        |      }|r|j                         dv ryt        |xs |t        j                  t        j                  t        j                  t        j                  t        j                  gt              ryy)zaReturns true if expression under min/max could be converted to splat
        expression.
        +|>   builtins.listbuiltins.tupleTF)r   r   BinOpopr9   leftrightr   r
   pytypeListTupleSetListCompDictComp
DICT_TYPES)r@   r$   r   s      r   r9   z-NestedMinMaxChecker._is_splattable_expression~   s   
 c5;;'CFFcM11 <00;< c5;;'CFFcMi11 <00;< c?)-PPO

		 

 r   N)r   nodes.NodeNGreturnbool)r   
nodes.CallrX   zlist[nodes.Call])r   rZ   rX   None)r$   rW   rX   rY   )__name__
__module____qualname____doc__r   r#   msgsclassmethodr   r%   r	   rF   r9    r   r   r   r      sj     2JD 
D 
 
 
 
   017
 27
rr   r   c                8    | j                  t        |              y r!   )register_checkerr   )linters    r   registerrf      s    
/78r   )re   r   rX   r[   )r_   
__future__r   r4   typingr   astroidr   r   astroid.constr   pylint.checkersr   pylint.checkers.utilsr	   r
   pylint.constantsr   pylint.interfacesr   pylint.lintr   
DictValuesDictKeys	DictItemsnode_classesDictrV   r   rf   rb   r   r   <module>ru      sr   
 1 "    " ! ' H & '$ 		
~+ ~B9r   