o
    g'@                     @   sR   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 G dd dej	Z
dS )    )UnionN)nodes)checkers
interfaces)utilsc                   @   sL  e Zd ZejfZdZdddddddZed	d
 Z	e
dddejddfddZdejddfddZdejddfddZe
ddddejddfddZdejddfddZdejddfddZe
dddejddfdd Zdejddfd!d"Zdeejejf ddfd#d$Ze
d%dejddfd&d'Zdejddfd(d)ZdS )*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.)C0200C0201C0206C0207C0208C0209c                 C   s&   t | }|s	dS t |o|j|kS )NF)r   
safe_inferis_builtin_objectname)nodefunctioninferred r   p/home/ubuntu/cloudmapper/venv/lib/python3.10/site-packages/pylint/checkers/refactoring/recommendation_checker.py_is_builtin?   s   
z!RecommendationChecker._is_builtinr
   r   r   returnNc                 C      |  | | | d S N)$_check_consider_iterating_dictionary_check_use_maxsplit_argselfr   r   r   r   
visit_callF   s   
z RecommendationChecker.visit_callc                    s   t  jtjs	d S  jjdkrd S t  jtjtjfs/t  jtjrMt	 fdd jj
D rOt j}t |tjrBt |jtjsDd S | jd d d S d S d S )Nkeysc                 3   s(    | ]\}}|d kr| u r|V  qdS )inNr   ).0op
comparatorr   r   r   	<genexpr>S   s    zMRecommendationChecker._check_consider_iterating_dictionary.<locals>.<genexpr>r
   r+   )
isinstancefuncr   	AttributeattrnameparentForComprehensionCompareanyopsr   r   astroidBoundMethodboundDictadd_message)r$   r   r   r   r+   r   r!   K   s&   	z:RecommendationChecker._check_consider_iterating_dictionaryc           	      C   s  t |jtjr|jjdv rt t|jtjsdS z	t	|dd W n tj
y-   Y dS w z
t	|dd W dS  tj
yB   Y nw t |jtjrz	t|jj}W n tjy^   Y dS w t |jjtjr| }|tjtjfD ]8}||s|qt|tjD ]}|jjj|jjkr  dS q|tjD ]}|jjjdd |jD v r  dS qqt|d	v r|jj}|d
krdnd}|j j|ddd | d|jd   d| d }| jd||fd dS dS dS )zSAdd message when accessing first or last elements of a str.split() or str.rsplit().)splitrsplitNr   sep   maxsplitc                 S   s   g | ]}|j qS r   )r   )r(   nr   r   r   
<listcomp>   s    zARecommendationChecker._check_use_maxsplit_arg.<locals>.<listcomp>)r   rC   r=   r<   )r@   (z, maxsplit=1)[]r   )r   args) r-   r.   r   r/   r0   r   r   r7   r8   get_argument_from_callNoSuchArgumentErrorr1   	Subscriptget_subscript_const_valuevalueInferredTypeErrorsliceNamescopenodes_of_classr2   While	parent_of	AugAssignr   targetAssigntargets	as_stringr=   rF   r;   )	r$   r   subscript_valuerO   	loop_nodeassignment_nodefn_namenew_fnnew_namer   r   r   r"   a   sf   
z-RecommendationChecker._check_use_maxsplit_argr	   r   r   c                 C   s"   |  | | | | | d S r    )_check_consider_using_enumerate _check_consider_using_dict_items!_check_use_sequence_for_iterationr#   r   r   r   	visit_for   s   

zRecommendationChecker.visit_forc                 C   s  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r8|s8dS t	|jjdkrBdS t |jjd tjsNdS |jjd j}| |ds]dS |jjd j}|rlt	|dkrndS |d }t |tj
r|tj
}nt |tjrtj}ndS | }t |tj
r|jdkr|jd	krdS |jD ]T}|tjD ]K}	t |	j|sq|	j}
t |
tj
sq|	j | krq|
j|jjkrt |	jtj
r|j|	jjkst |	jtjr|j|	jjkr| jd
|d   dS qqdS )z?Emit a convention whenever range and len are used for indexing.Nranger      rC   lenr?   r$   __iter__r	   r+   )r-   iterr   Callr   r.   rF   ConstrK   rd   rN   r/   rO   r   bodyrP   rI   rM   rT   r0   r;   )r$   r   is_constant_zerosecond_funclen_argsiterating_objectexpected_subscript_val_typerO   child	subscriptrK   r   r   r   r^      sj   $



z5RecommendationChecker._check_consider_using_enumeratec                 C   s   t |}|du rdS |jD ]g}|tjD ]^}t|jtjtj	fs#q|j
}t|tjr:|j|jjks:||j kr;q||jd d j}||jkrLqt|jtjrY||jjv sft|jtjrj||jjkrj  dS | jd|d   dS qdS )7Add message when accessing dict values by index lookup.Nr?   rC   r   r+   )r   get_iterating_dictionary_nameri   rP   r   rI   r-   rK   rN   r/   rM   r   rT   rW   lookuplinenor1   rU   rV   rS   r;   )r$   r   iterating_object_namero   rp   rK   last_definition_linenor   r   r   r_      s6   



z6RecommendationChecker._check_consider_using_dict_itemsc                 C   r   r    )._check_consider_using_dict_items_comprehensionr`   r#   r   r   r   visit_comprehension  s   
z)RecommendationChecker.visit_comprehensionc                 C   s   t |}|du rdS |j D ]8}|tjD ]/}t|jtj	tj
fs%q|j}t|tj	r<|j|jjks<||j kr=q| jd|d   dS qdS )rq   Nr   r+   )r   rr   r1   get_childrenrP   r   rI   r-   rK   rN   r/   rM   r   rT   rW   r;   )r$   r   ru   ro   rp   rK   r   r   r   rw   #  s"   

zDRecommendationChecker._check_consider_using_dict_items_comprehensionc                 C   s&   t |jtjr| jd|jd dS dS )z4Check if code iterates over an in-place defined set.r   r+   N)r-   rf   r   Setr;   r#   r   r   r   r`   ;  s   z7RecommendationChecker._check_use_sequence_for_iterationr   c                 C   s0   |  dkrt|jtjs| | d S d S d S )Nzbuiltins.str)pytyper-   r1   r   	JoinedStr_detect_replacable_format_callr#   r   r   r   visit_constB  s
   z!RecommendationChecker.visit_constc                 C   s  t |jtjr|jjdkrt |jjtjrdS |jjjrA|jjjD ]}t |tjr?t	|j
}t |tjr?t|jdkr? dS q!nA|jjjrdd t|j
d D }|jjjD ])}||jdkre dS t	|j
}t |tjrt|jdkrt|dkr dS qX| jd||j|jd dS t |jtjr|jjd	krt	|jj}t |tjrt|jdkrdS nt |tjrt|jdkrdS | jd||j|jd dS dS dS )
zpCheck whether a string is used in a call to format() or '%' and whether it
        can be replaced by a f-stringformatNr?   c                 S   s   g | ]}|d  qS )r   r   )r(   ir   r   r   rB   `  s    zHRecommendationChecker._detect_replacable_format_call.<locals>.<listcomp>r   r   )r   line
col_offset%)r-   r1   r   r/   r0   rU   rF   Starredr   r   rK   r7   Listrd   eltskeywordsparse_format_method_stringcountargr:   itemsr;   rt   r   BinOpr)   right)r$   r   r   r   keyword_argskeywordinferred_rightr   r   r   r}   I  sb   





z4RecommendationChecker._detect_replacable_format_call)__name__
__module____qualname__r   IAstroidChecker__implements__r   msgsstaticmethodr   r   check_messagesr   rg   r%   r!   r"   r2   ra   r^   r_   r3   rx   rw   r   r`   rh   r~   r}   r   r   r   r   r      sT    	/

9I.

r   )typingr   r7   r   pylintr   r   pylint.checkersr   BaseCheckerr   r   r   r   r   <module>   s   