
    eH                    v    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y)	    )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y)$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``.)z6Formatting a regular string which could be an f-stringconsider-using-f-stringzUsed when we detect a string that is being formatted with format() or % which could potentially be an f-string. The use of f-strings is preferred. Requires Python 3.6 and ``py-version >= 3.6``.)C0200C0201C0206C0207C0208C0209c                X    | j                   j                  j                  }|dk\  | _        y )N)      )linterconfig
py_version
_py36_plus)selfr   s     T/usr/lib/python3/dist-packages/pylint/checkers/refactoring/recommendation_checker.pyopenzRecommendationChecker.openA   s#    [[''22
$.    c                ~    t        j                  |       }|syt        j                  |      xr |j                  |k(  S )NF)r   
safe_inferis_builtin_objectname)nodefunctioninferreds      r    _is_builtinz!RecommendationChecker._is_builtinE   s7    ##D)&&x0NX]]h5NNr"   r   r   c                H    | j                  |       | j                  |       y N)$_check_consider_iterating_dictionary_check_use_maxsplit_argr   r'   s     r    
visit_callz RecommendationChecker.visit_callL   s      	11$7$$T*r"   c                   t        j                  t        j                        sy j                  j                  dk7  ry t        j
                  t        j                        rj
                  j                  dv ry t        j                  t        j                        }t        j
                  t        j                  t        j                  f      s |rt        fd|j                  D              rwt        j                  j                        }t        |t         j"                        r$t        |j$                  t        j&                        sy | j)                  dt*               y y y )Nkeys>   &^|c              3  \   K   | ]#  \  }}|d v r|j                         v s|u r| % yw)>   not ininN)node_ancestors).0op
comparatorr'   s      r    	<genexpr>zMRecommendationChecker._check_consider_iterating_dictionary.<locals>.<genexpr>`   s>      "B
))4#6#6#88J$<N s   ),r   r'   
confidence)
isinstancefuncr   	AttributeattrnameparentBinOpr;   r   get_node_first_ancestor_of_typeCompareForComprehensionanyopsr$   astroidBoundMethodboundDictadd_messager   )r   r'   comp_ancestorr)   s    `  r    r-   z:RecommendationChecker._check_consider_iterating_dictionaryS   s   $))U__599'dkk5;;/DKKNNo4U==dEMMRt{{UYY0C0C$DE &3&7&7  ''		2Hh(;(;<J

E /dy   r"   c                   t        |j                  t        j                        rO|j                  j                  dv r7t        t        j                  |j                        t        j                        syt        j                  |j                  j                        }t        |t        j                        r)t        |j                  t        j                              ryt        }	 t        j                  |dd      }	 t        j                  |dd       y# t
        j                   $ r$ t        j"                  |d      }t$        }|sY yY Ow xY w# t
        j                   $ r t        j"                  |d      rY yY nw xY wt        |j&                  t        j(                        r	 t        j*                  |j&                        j,                  }n# t
        j.                  $ r Y yw xY wt        |j&                  j0                  t        j2                        r%|j5                         }|j                  t        j6                  t        j8                  f      D ]  }|j;                  |      s|j                  t        j<                        D ]<  }|j&                  j0                  j>                  |j@                  j>                  k(  s;  y |j                  t        jB                        D ]O  }|j&                  j0                  j>                  |jD                  D 	cg c]  }	|	j>                   nc c}	w c}	v sN  y  |dv r|j                  j                  }
|d	k(  rd
nd}|j                  jG                         jI                  |
d      d   |z   d|jG                          d| dz   }| jK                  d||f|       yyy)zdAdd message when accessing first or last elements of a str.split() or
        str.rsplit().
        >   splitrsplitNr   sep)keyword   maxsplit)r   rY   rT   rS   )rX   (z, maxsplit=1)[]r   )r'   argsr?   )&r@   rA   r   rB   rC   r   r$   rL   rM   exprInstancerJ   nodes_of_classClassDefr   get_argument_from_callNoSuchArgumentErrorinfer_kwarg_from_callr   rD   	Subscriptget_subscript_const_valuevalueInferredTypeErrorsliceNamescoperH   While	parent_of	AugAssignr&   targetAssigntargets	as_stringrT   rP   )r   r'   inferred_exprr?   rU   subscript_valuerj   	loop_nodeassignment_nodenfn_namenew_fnnew_names                r    r.   z-RecommendationChecker._check_use_maxsplit_argp   s%    tyy%//2		""&995++DII68K8KL((8mW%5%563((8<
 
	..tQ>C	((q*= (( 	--dEBC"J 	 (( 	**4D E	 dkk5??3"'"A"A$++"N"T"T**  $++++UZZ8

!&!5!5uyy%++6N!O #I$..t4  ,5+C+CEOO+T #;;,,11_5K5K5P5PP"# ,5+C+CELL+Q #;;,,11,;,C,C6'(AFF6 6  #	## '))),,%4%:II'')0010EaH#--/*.8IKL 
   &")	 !  *1 4s<   (D  E 2EE*F F*)G G*)G*L1
r   r   r   c                j    | j                  |       | j                  |       | j                  |       y r,   )_check_consider_using_enumerate _check_consider_using_dict_items!_check_use_sequence_for_iterationr/   s     r    	visit_forzRecommendationChecker.visit_for   s.     	,,T2--d3..t4r"   c                f   t        |j                  t        j                        sy| j	                  |j                  j
                  d      sy|j                  j                  syt        |j                  j                  d   t        j                        xr& |j                  j                  d   j                  dk(  }t        |j                  j                        dk(  r|syt        |j                  j                        dkD  ryt        |j                  j                  d   t        j                        sy|j                  j                  d   j
                  }| j	                  |d      sy|j                  j                  d   j                  }|rt        |      dk7  ry|d   }t        |t        j                        rt        j                  }n,t        |t        j                        rt        j                  }ny|j                         }t        |t        j                        r|j                  dk(  r|j                  d	k(  ry|j                  D ]\  }|j                  t        j                         D ]6  }	t        |	j                  |      s|	j"                  }
t        |
t        j                        sB|	j                  j                         |j                         k7  rn|
j                  |j$                  j                  k(  st        |	j                  t        j                        r#|j                  |	j                  j                  k(  sJt        |	j                  t        j                        s|j&                  |	j                  j&                  k(  s#| j)                  d
|         y _ y)z?Emit a convention whenever range and len are used for indexing.Nranger      rY   lenrW   r   __iter__r   r'   )r@   iterr   Callr*   rA   r\   Constrf   r   ri   rB   rj   r&   bodyr_   rd   rh   rn   rC   rP   )r   r'   is_constant_zerosecond_funclen_argsiterating_objectexpected_subscript_val_typerj   child	subscriptrf   s              r    r{   z5RecommendationChecker._check_consider_using_enumerate   s    $))UZZ0		8yy~~tyy~~a(%++6W499>>!;L;R;RVW;W 	 tyy~~!#,<tyy~~" $))..,ejj9iinnR(--U399>>"%**3x=A-#A;&

3*/**'(%//:*///'

'4 %%/

j( YY 	E"11%//B 	!)//3NO!!%4??((*djjl:
 ::!1!11y

;(--1E1EE!)//5??C(11Y__5M5MM$$%?d$K)	r"   c                t   t        j                  |      }|y|j                  D ]  }|j                  t        j
                        D ]j  }t        |j                  t        j                  t        j                  f      s9|j                  }t        |t        j                        r@|j                  |j                  j                  k7  s||j                  j                         k7  r|j                  |j                        d   d   j                  }||j                  kD  rt        |j                   t        j"                        r||j                   j$                  v s=t        |j                   t        j&                        r||j                   j                  k(  r  y| j)                  d|         y  y)7Add message when accessing dict values by index lookup.NrW   rY   r   r   )r   get_iterating_dictionary_namer   r_   r   rd   r@   rf   ri   rB   rh   r&   rn   rq   lookuplinenorD   ro   rp   rm   rP   )r   r'   iterating_object_namer   r   rf   last_definition_linenos          r    r|   z6RecommendationChecker._check_consider_using_dict_items  sT    !& C CD I ( YY 	E"11%//B 	!)//EJJ3PQ!"5%**5zzT[[%5%55,	0I0I0KK).ejj)A!)DR)H)O)O&)DKK7
 y//>!Y%5%5%=%==!)"2"2EOOD!Y%5%5%<%<<   !<4 H;	r"   c                H    | j                  |       | j                  |       y r,   )._check_consider_using_dict_items_comprehensionr}   r/   s     r    visit_comprehensionz)RecommendationChecker.visit_comprehension;  s     
 	;;DA..t4r"   c                   t        j                  |      }|y|j                  j                         D ]  }|j	                  t
        j                        D ]  }t        |j                  t
        j                  t
        j                  f      s8|j                  }t        |t
        j                        r@|j                  |j                  j                  k7  s||j                  j                         k7  r| j                  d|         y  y)r   Nr   r   )r   r   rD   get_childrenr_   r   rd   r@   rf   ri   rB   rh   r&   rn   rq   rP   )r   r'   r   r   r   rf   s         r    r   zDRecommendationChecker._check_consider_using_dict_items_comprehensionC  s     !& C CD I ([[--/ 	E"11%//B 	!)//EJJ3PQ!"5%**5zzT[[%5%55,	0I0I0KK  !<4 H	r"   c                    t        |j                  t        j                        rBt	        t        j                  |            s#| j                  d|j                  t               yyy)zrCheck if code iterates over an in-place defined set.

        Sets using `*` are not considered in-place.
        r   r>   N)	r@   r   r   SetrJ   r   has_starred_node_recursiverP   r   r/   s     r    r}   z7RecommendationChecker._check_use_sequence_for_iteration[  sS     dii+C,,T25
 ,499  5
+r"   r   c                    | j                   rK|j                         dk(  r7t        |j                  t        j
                        s| j                  |       y y y y )Nzbuiltins.str)r   pytyper@   rD   r   	JoinedStr_detect_replacable_format_callr/   s     r    visit_constz!RecommendationChecker.visit_consti  sH    ??{{}.zU__8 33D98. r"   c                (   t        |j                  t        j                        r4|j                  j                  dk(  rt        |j                  j                  t        j
                        sy|j                  j                  j                  r|j                  j                  j                  D ]  }t        |t        j                        rSt        j                  |j                        }t        |t        j                        rt        |j                        dkD  r yd|j                         v s y n|j                  j                  j                   rt        j"                  |j                        d   D cg c]  }|d   	 }}|j                  j                  j                   D ]  }|j%                  |j&                        dkD  r yt        j                  |j                        }t        |t        j(                        s]t        |j*                        dkD  svt        |      dkD  s y | j-                  d||j.                  |j0                         yt        |j                  t        j2                        r|j                  j4                  dk(  rtd|j                  j6                  j                         v ryt9        |j                  j:                  d	      r.t        |j                  j:                  j                  t<              syd
|j                  j:                  j                  v s"d|j                  j:                  j                  v ryt        j                  |j                  j6                        }t        |t        j(                        rt        |j*                        dkD  r4yt        |t        j                        rt        |j                        dkD  ry| j-                  d||j.                  |j0                         yyyc c}w )z{Check whether a string is used in a call to format() or '%' and whether it
        can be replaced by an f-string.
        formatNrW   \r   r   )r'   line
col_offset%rf   {})r@   rD   r   rB   rC   r   r\   Starredr   r$   rf   rL   Listr   eltsrq   keywordsparse_format_method_stringcountargrO   itemsrP   r   r   rE   r;   righthasattrleftstr)r   r'   r   r)   ikeyword_argsrV   inferred_rights           r    r   z4RecommendationChecker._detect_replacable_format_callr  s   
 t{{EOO4$$0 dkk00%**={{!!&&;;--22 C!#u}}5#(#3#3CII#>&x> #HMM 2Q 6"s}}. ##,,"'"B"B4::"Nq"Q AaD     ${{11:: 
#G#))'++6:#..w}}=G "'5::6w}}-1c,6G!6K"
# )[[??	   U[[1dkknn6Kt{{((2244 4;;++W5Z  &&>  dkk&&,,,t{{7G7G7M7M0M"--dkk.?.?@N .%**5~++,q0NEJJ7~**+a/ )[[??	  5 7L1/ s   :PN)returnNone)r'   znodes.NodeNGr(   r   r   bool)r'   z
nodes.Callr   r   )r'   z	nodes.Forr   r   )r'   znodes.Comprehensionr   r   )r'   znodes.For | nodes.Comprehensionr   r   )r'   znodes.Constr   r   )__name__
__module____qualname__r&   msgsr!   staticmethodr*   r   only_required_for_messagesr0   r-   r.   r~   r{   r|   r   r   r}   r   r    r"   r    r
   r
      s-   D





O.D`/ O O &U%%');++:HT &U%%"#$
5
5
GR,\ &U%%#$5	5'	03	 &U%%&?@: A:Qr"   r
   )
__future__r   rL   r   pylintr   pylint.checkersr   pylint.interfacesr   r   BaseCheckerr
   r   r"   r    <module>r      s-   
 #    ! -tH00 tr"   