
    cF                    t    d dl mZ d dlZd dlmZ d dlmZ d dlmZ d dlm	Z	m
Z
  G d dej                  ZdS )	    )annotationsN)nodes)checkers)utils)HIGH	INFERENCEc                  T   e Zd ZdZdddddddZd)dZed*d            Z ej	        dd          d+d            Z
d+dZd+dZ ej	        ddd          d,d            Zd,dZd,dZ ej	        dd          d-d             Zd-d!Zd.d#Z ej	        d$          d/d&            Zd/d'Zd(S )0RecommendationCheckerrefactoring)z@Consider using enumerate instead of iterating with range and lenconsider-using-enumeratez~Emitted when code that iterates with range and len is encountered. Such code can be simplified by using the enumerate builtin.)zEConsider iterating the dictionary directly instead of calling .keys()consider-iterating-dictionarya  Emitted when the keys of a dictionary are iterated through the ``.keys()`` method or when ``.keys()`` is used for a membership check. It is enough to iterate through the dictionary itself, ``for key in dictionary``. For membership checks, ``if key in dictionary`` is faster.)z Consider iterating with .items()consider-using-dict-itemszEmitted when iterating over the keys of a dictionary and accessing the value by index lookup. Both the key and value can be accessed by iterating using the .items() method of the dictionary instead.)zUse %s insteaduse-maxsplit-argzEmitted when accessing only the first or last element of str.split(). The first and last element can be accessed by using str.split(sep, maxsplit=1)[0] or str.rsplit(sep, maxsplit=1)[-1] instead.)z.Use a sequence type when iterating over valuesuse-sequence-for-iterationzvWhen iterating over values, sequence types (e.g., ``lists``, ``tuples``, ``ranges``) are more efficient than ``sets``.)z5Formatting a regular string which could be a f-stringconsider-using-f-stringzUsed when we detect a string that is being formatted with format() or % which could potentially be a f-string. The use of f-strings is preferred. Requires Python 3.6 and ``py-version >= 3.6``.)C0200C0201C0206C0207C0208C0209returnNonec                >    | j         j        j        }|dk    | _        d S )N)      )linterconfig
py_version
_py36_plus)selfr   s     Rlib/python3.11/site-packages/pylint/checkers/refactoring/recommendation_checker.pyopenzRecommendationChecker.openA   s    ['2
$.    nodenodes.NodeNGfunctionstrboolc                p    t          j        |           }|sdS t          j        |          o
|j        |k    S )NF)r   
safe_inferis_builtin_objectname)r%   r'   inferreds      r"   _is_builtinz!RecommendationChecker._is_builtinE   s<    #D)) 	5&x00NX]h5NNr$   r   r   
nodes.Callc                Z    |                      |           |                     |           d S N)$_check_consider_iterating_dictionary_check_use_maxsplit_argr!   r%   s     r"   
visit_callz RecommendationChecker.visit_callL   s2     	11$777$$T*****r$   c                   t          j        t          j                  sd S j        j        dk    rd S t          j        t          j                  rj        j        dv rd S t          j	        t          j
                  }t          j        t          j        t          j        f          s"|rt          fd|j        D                       rut          j        j                  }t          |t           j                  rt          |j        t          j                  sd S |                     dt*                     d S d S d S )Nkeys>   &^|c              3  ^   K   | ]'\  }}|d v 	|                                 v s|u #|V  (dS )>   not ininN)node_ancestors).0op
comparatorr%   s      r"   	<genexpr>zMRecommendationChecker._check_consider_iterating_dictionary.<locals>.<genexpr>`   sr        "B
))  4#6#6#8#88	 =G$<N	     r$   r   r%   
confidence)
isinstancefuncr   	AttributeattrnameparentBinOprA   r   get_node_first_ancestor_of_typeCompareForComprehensionanyopsr+   astroidBoundMethodboundDictadd_messager   )r!   r%   comp_ancestorr.   s    `  r"   r3   z:RecommendationChecker._check_consider_iterating_dictionaryS   se   $)U_55 	F9' 	Fdk5;// 	DKNo4U 	F=dEMRRt{UY0C$DEE		     &3&7    	 '	22Hh(;<< J
E E  /dy      	 	 	 	r$   c                   t          |j        t          j                  r?|j        j        dv r1t          t          j        |j                  t          j                  sdS t          j        |j        j	                  }t          |t          j
                  r.t          |                    t          j                            rdS 	 t          j        |dd          }n# t
          j        $ r Y dS w xY w	 t          j        |dd           dS # t
          j        $ r Y nw xY wt          |j        t          j                  r	 t          j        |j                  j        }n# t
          j        $ r Y dS w xY wt          |j        j        t          j                  r|                                }|                    t          j        t          j        f          D ]}|                    |          s|                    t          j                  D ]%}|j        j        j        |j        j        k    r  dS &|                    t          j                  D ](}|j        j        j        d |j        D             v r  dS )|dv r|j        j        }|d	k    rd
nd}	|j                                         !                    |d          d         |	z   d|                                  d| dz   }
| "                    d||
f           dS dS dS )zdAdd message when accessing first or last elements of a str.split() or
        str.rsplit().
        >   splitrsplitNr   sep   maxsplitc                    g | ]	}|j         
S  )r-   )r@   ns     r"   
<listcomp>zARecommendationChecker._check_use_maxsplit_arg.<locals>.<listcomp>   s'     6 6 6'(AF6 6 6r$   )r   rb   rZ   rY   )r]   (z, maxsplit=1)[]r   )r%   args)#rF   rG   r   rH   rI   r   r+   rR   rS   exprInstancerP   nodes_of_classClassDefget_argument_from_callNoSuchArgumentErrorrJ   	Subscriptget_subscript_const_valuevalueInferredTypeErrorsliceNamescoperN   While	parent_of	AugAssignr-   targetAssigntargets	as_stringrZ   rV   )r!   r%   inferred_exprr[   subscript_valuerr   	loop_nodeassignment_nodefn_namenew_fnnew_names              r"   r4   z-RecommendationChecker._check_use_maxsplit_argp   sg    ty%/22		"&99	 5+DI668KLL	
 F(88mW%566 	3((88<
 <
 	 F	.tQ>>CC( 	 	 	FF		(q*===F( 	 	 	D	 dk5?33  	R"'"A$+"N"N"T*    $++UZ88 #

!&!5!5uy%+6N!O!O # #I$..t44 !  ,5+C+CEO+T+T # #;,1_5K5PP #"FFF#+4+C+CEL+Q+Q # #;,1 6 6,;,C6 6 6  # #FFF## ') R),%4%:GI''))0010EEaHK#--//KKKKKL 
   !3$h[ QQQQQA 	R  	R0R Rs6   C C21C26D D D E# #E65E6r   r   r   	nodes.Forc                    |                      |           |                     |           |                     |           d S r2   )_check_consider_using_enumerate _check_consider_using_dict_items!_check_use_sequence_for_iterationr5   s     r"   	visit_forzRecommendationChecker.visit_for   sF     	,,T222--d333..t44444r$   c                `   t          |j        t          j                  sdS |                     |j        j        d          sdS |j        j        sdS t          |j        j        d         t          j                  o|j        j        d         j        dk    }t          |j        j                  dk    r|sdS t          |j        j                  dk    rdS t          |j        j        d         t          j                  sdS |j        j        d         j        }|                     |d          sdS |j        j        d         j        }|rt          |          dk    rdS |d         }t          |t          j
                  rt          j
        }n)t          |t          j                  rt          j        }ndS |                                }t          |t          j
                  r|j        dk    r|j        d	k    rdS |j        D ]'}|                    t          j                  D ]}	t          |	j        |          s|	j        }
t          |
t          j
                  s;|	j                                        |                                k    rk|
j        |j        j        k    rt          |	j        t          j
                  r|j        |	j        j        k    s4t          |	j        t          j                  r0|j        |	j        j        k    r|                     d
|             dS )dS )z?Emit a convention whenever range and len are used for indexing.Nranger      rb   lenr\   r!   __iter__r   r%   )rF   iterr   Callr/   rG   re   Constrn   r   rq   rH   rr   r-   bodyrh   rl   rp   rv   rI   rV   )r!   r%   is_constant_zerosecond_funclen_argsiterating_objectexpected_subscript_val_typerr   child	subscriptrn   s              r"   r   z5RecommendationChecker._check_consider_using_enumerate   s    $)UZ00 	F	88 	Fy~ 	Fty~a(%+66W49>!;L;RVW;W 	 ty~!# 	,< 	Fty~" 	F $).,ej99 	FinR(-U33 	F9>"%* 	3x==A- 	F#A;&
33 	*/*''(%/:: 	*//''F

'44	 %/	 
j(	
 F Y 	 	E"11%/BB  	!)/3NOO !!%44 ?((**djjll: 
 :!11 y
;;(-1EE ")/5?CC )1Y_5MM	 $$%?d$KKKFFF)	 	r$   c                   t          j        |          }|dS |j        D ]W}|                    t          j                  D ]3}t          |j        t          j        t          j	        f          s/|j
        }t          |t          j                  r2|j        |j        j        k    s||j                                        k    r|                    |j                  d         d         j        }||j        k    rt          |j        t          j                  r||j        j        v s/t          |j        t          j                  r||j        j        k    r  dS |                     d|             dS YdS )7Add message when accessing dict values by index lookup.Nr\   rb   r   r   )r   get_iterating_dictionary_namer   rh   r   rl   rF   rn   rq   rH   rp   r-   rv   ry   lookuplinenorJ   rw   rx   ru   rV   )r!   r%   iterating_object_namer   r   rn   last_definition_linenos          r"   r   z6RecommendationChecker._check_consider_using_dict_items  s    !& CD I I  	F Y 	 	E"11%/BB  	!)/EJ3PQQ !"5%*55zT[%55 -	0I0I0K0KK
 ).ej)A)A!)DR)H)O&)DK7 
 y/>>!Y%5%== ")"2EODD "Y%5%<<	 FFF  !<4 HHH;	 	r$   nodes.Comprehensionc                Z    |                      |           |                     |           d S r2   )._check_consider_using_dict_items_comprehensionr   r5   s     r"   visit_comprehensionz)RecommendationChecker.visit_comprehension1  s2    
 	;;DAAA..t44444r$   c                   t          j        |          }|dS |j                                        D ]}|                    t
          j                  D ]}t          |j        t
          j	        t
          j
        f          s.|j        }t          |t
          j	                  r2|j        |j        j        k    s||j                                        k    r|                     d|             dS dS )r   Nr   r   )r   r   rJ   get_childrenrh   r   rl   rF   rn   rq   rH   rp   r-   rv   ry   rV   )r!   r%   r   r   r   rn   s         r"   r   zDRecommendationChecker._check_consider_using_dict_items_comprehension9  s    !& CD I I  	F[--// 	 	E"11%/BB  	!)/EJ3PQQ !"5%*55zT[%55 -	0I0I0K0KK
   !<4 HHH	 	r$   nodes.For | nodes.Comprehensionc                    t          |j        t          j                  rEt	          t          j        |                    s&|                     d|j        t                     dS dS dS )zrCheck if code iterates over an in-place defined set.

        Sets using `*` are not considered in-place.
        r   rD   N)	rF   r   r   SetrP   r   has_starred_node_recursiverV   r   r5   s     r"   r   z7RecommendationChecker._check_use_sequence_for_iterationQ  s     di++ 	C,T225
 5
 	 ,49      	 	 	 	r$   r   nodes.Constc                    | j         rN|                                dk    r8t          |j        t          j                  s|                     |           d S d S d S d S )Nzbuiltins.str)r    pytyperF   rJ   r   	JoinedStr_detect_replacable_format_callr5   s     r"   visit_constz!RecommendationChecker.visit_const_  su    ? 	:{{}}. :zU_8 8 : 33D99999	: 	:: : : :r$   c                n   t          |j        t          j                  r|j        j        dk    rt          |j        j        t          j                  sdS |j        j        j        r|j        j        j        D ]}t          |t          j                  rNt          j	        |j
                  }t          |t          j                  rt          |j                  dk    r dS d|                                v r dS n|j        j        j        rd t          j        |j
                  d         D             }|j        j        j        D ]}|                    |j                  dk    r dS t          j	        |j
                  }t          |t          j                  r.t          |j                  dk    rt          |          dk    r dS |                     d||j        |j                   dS t          |j        t          j                  r|j        j        d	k    rd|j        j                                        v rdS t9          |j        j        d
          r$t          |j        j        j
        t<                    sdS t          j	        |j        j                  }t          |t          j                  rt          |j                  dk    rdS n4t          |t          j                  rt          |j                  dk    rdS |                     d||j        |j                   dS dS dS )z{Check whether a string is used in a call to format() or '%' and whether it
        can be replaced by an f-string.
        formatNr\   \c                    g | ]
}|d          S )r   r_   )r@   is     r"   ra   zHRecommendationChecker._detect_replacable_format_call.<locals>.<listcomp>  s)          AaD     r$   r   r   )r%   line
col_offset%rn   )rF   rJ   r   rH   rI   r   re   Starredr   r+   rn   rR   Listr   eltsry   keywordsparse_format_method_stringcountargrU   itemsrV   r   r   rK   rA   righthasattrleftr(   )r!   r%   r   r.   keyword_argskeywordinferred_rights          r"   r   z4RecommendationChecker._detect_replacable_format_callh  s\   
 t{EO44I	$0I	
 dk0%*== {!& #;-2  C!#u}55 ##(#3CI#>#>&x>># #HM 2 2Q 6# #FFs}}.  #, #   "'"B4:"N"Nq"Q       ${1: 
# 
#G#))'+66: #.w}==G "'5:66 #w}--1 #c,6G6G!6K #"FF )[?	       U[11 	dkn6K 	t{(22444  4;+W55 Z &> >  "-dk.?@@N .%*55 ~+,,q0 FNEJ77 ~*++a/ F )[?	      -	 	 	 	r$   N)r   r   )r%   r&   r'   r(   r   r)   )r%   r0   r   r   )r%   r   r   r   )r%   r   r   r   )r%   r   r   r   )r%   r   r   r   )__name__
__module____qualname__r-   msgsr#   staticmethodr/   r   only_required_for_messagesr6   r3   r4   r   r   r   r   r   r   r   r   r_   r$   r"   r
   r
      s       D





O. .D`/ / / / O O O \O &U%'); + + + +   :>R >R >R >R@ &U%"#$ 
5 5 5 
5
G G G GR, , , ,\ &U%#$ 5 5 5	 5   0    &U%&?@@: : : A@:M M M M M Mr$   r
   )
__future__r   rR   r   pylintr   pylint.checkersr   pylint.interfacesr   r   BaseCheckerr
   r_   r$   r"   <module>r      s   
 # " " " " "              ! ! ! ! ! ! - - - - - - - -f f f f fH0 f f f f fr$   