o
    g.                     @   s   d dl Z d dlmZmZmZmZmZmZmZ d dl	m
Z
 d dl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 jd	krJd d
lmZ nd d
lmZ G dd deZdeddfddZdS )    N)ListOptionalSetTupleTypeUnioncast)nodes)BaseCheckerutils)check_messages
safe_infer)IAstroidChecker)PyLinter)get_global_option)   
   )	TypeGuardc                
       sL  e Zd ZdZefZdZdZddddZdd	d
ddffZ	de
ddf fddZd*ddZeddejddfddZeddejddfddZeddej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ejddfd"d#Zed$eej d%ee deeejej f  fd&d'Z!edejd%ee de"fd(d)Z#  Z$S )+CodeStyleCheckeran  Checkers that can improve code consistency.

    As such they don't necessarily provide a performance benefit and
    are often times opinionated.

    Before adding another checker here, consider this:
    1. Does the checker provide a clear benefit,
       i.e. detect a common issue or improve performance
       => it should probably be part of the core checker classes
    2. Is it something that would improve code consistency,
       maybe because it's slightly better with regards to performance
       and therefore preferred => this is the right place
    3. Everything else should go into another extension
    
code_style)z<Consider using namedtuple or dataclass for dictionary values&consider-using-namedtuple-or-dataclasszUEmitted when dictionary values can be replaced by namedtuples or dataclass instances.)z0Consider using an in-place tuple instead of listconsider-using-tuplezOnly for style consistency! Emitted where an in-place defined ``list`` can be replaced by a ``tuple``. Due to optimizations by CPython, there is no performance benefit from it.)zUse '%s' insteadconsider-using-assignment-exprzEmitted when an if assignment is directly followed by an if statement and both can be combined by using an assignment expression ``:=``. Requires Python 3.8)R6101R6102R6103zmax-line-length-suggestionsintz<int>zMax line length for which to sill emit suggestions. Used to prevent optional suggestions which would get split by a code formatter (e.g., black). Will default to the setting for ``max-line-length``.)typemetavarhelplinterreturnNc                    s   t  j|d dS )zInitialize checker instance.r!   N)super__init__)selfr!   	__class__ Z/home/ubuntu/cloudmapper/venv/lib/python3.10/site-packages/pylint/extensions/code_style.pyr%   K   s   zCodeStyleChecker.__init__c                 C   s,   t | d}|dk| _| jjpt | d| _d S )Nz
py-version)r      zmax-line-length)r   
_py38_plusconfigmax_line_length_suggestions_max_length)r&   
py_versionr)   r)   r*   openO   s
   

zCodeStyleChecker.openr   nodec                 C   s   |  | d S N))_check_dict_consider_namedtuple_dataclassr&   r2   r)   r)   r*   
visit_dictW   s   zCodeStyleChecker.visit_dictr   c                 C   &   t |jtjr| jd|jd d S d S Nr   r2   
isinstanceiterr	   r   add_messager5   r)   r)   r*   	visit_for[      zCodeStyleChecker.visit_forc                 C   r7   r8   r:   r5   r)   r)   r*   visit_comprehension`   r?   z$CodeStyleChecker.visit_comprehensionr   c                 C   s   | j r
| | d S d S r3   )r,   %_check_consider_using_assignment_exprr5   r)   r)   r*   visit_ife   s   zCodeStyleChecker.visit_ifc                 C   sl  t |jtjtjfrt |jjtjs+t |jtjr)t |jjtjr)t	|jjds+dS t
|jdkrtdd |jD rtttj tf }t }|jD ]8\}}ttj|}|jD ]*\}}t|| f}||v riqXt|}t |tjry| dks}  dS || qXqKg }	|jD ]\}}ttj|}|	tdd |jD  qt|	d }
|	dd D ]}|
| q|
sdS | jd	|d
 dS t
|jdkr2tdd |jD r4t
|jd d j}|dkrdS |jdd D ]\}}tttj tjf |}t
|j|kr dS q|jD ]\}}tttj tjf |}tdd |jD r' dS q
| jd	|d
 dS dS dS )zFCheck if dictionary values can be replaced by Namedtuple or Dataclass.FinalN   c                 s   s     | ]\}}t |tjV  qd S r3   r;   r	   Dict.0_
dict_valuer)   r)   r*   	<genexpr>x   s    
zMCodeStyleChecker._check_dict_consider_namedtuple_dataclass.<locals>.<genexpr>zbuiltins.strc                 s   s$    | ]\}}t || fV  qd S r3   )r   	as_string)rH   keyrI   r)   r)   r*   rK      s   " r   r   r9   c                 s   s&    | ]\}}t |tjtjfV  qd S r3   )r;   r	   r   r   rG   r)   r)   r*   rK      s
    
c                 s   s    | ]	}t |tjV  qd S r3   rE   )rH   entryr)   r)   r*   rK      s    )!r;   parentr	   Assign	AnnAssignModuletarget
AssignNamer   is_assign_name_annotated_withlenitemsallr   r   NodeNGstrsetr   rF   r   rL   r   Constpytypeaddappendtupleintersection_updater=   eltsr   r   )r&   r2   	KeyTupleTkeys_checkedrI   rJ   rM   	key_tupleinferred
key_tupleskeys_intersectionsub_key_tupleslist_lengthr)   r)   r*   r4   j   sz   	

z:CodeStyleChecker._check_dict_consider_namedtuple_dataclassc                 C   s4  d}t |jtjr|j}n8t |jtjr'|jjdkr't |jjtjr'|jj}nt |jtjrCt |jjtjrCt	|jj
dkrC|jj}ndS | }t||jrt||jrYdS |j |jd|j d|j  dd}d| d}|jdurt	||j | jkst	|| jkrdS | jd	||fd
 dS dS )aX  Check if an assignment expression (walrus operator) can be used.

        For example if an assignment is directly followed by an if statment:
        >>> x = 2
        >>> if x:
        >>>     ...

        Can be replaced by:
        >>> if (x := 2):
        >>>     ...

        Note: Assignment expressions were added in Python 3.8
        NnotrD   (z := )zif :r   )r2   args)r;   testr	   NameUnaryOpopoperandCompareleftrV   opsprevious_siblingr   _check_prev_sibling_to_if_stmtname(_check_ignore_assignment_expr_suggestionrL   replacevalue
col_offsetr/   r=   )r&   r2   	node_nameprev_siblingtest_str
suggestionr)   r)   r*   rA      sP   




z6CodeStyleChecker._check_consider_using_assignment_exprr   rz   c                 C   s   | du s| j | j dkrdS t| tjr.t| jdkr.t| jd tjr.| jd j|kr.dS t| tj	rCt| j
tjrC| j
j|krCdS dS )z|Check if previous sibling is an assignment with the same name.
        Ignore statements which span multiple lines.
        Nr   FrD   T)tolineno
fromlinenor;   r	   rP   rV   targetsrT   rz   rQ   rS   )r   rz   r)   r)   r*   ry      s    

z/CodeStyleChecker._check_prev_sibling_to_if_stmtc                 C   s   t | jtjrTd}|  }t| jdkr#t | jd tjr#| jd }nt |tjr+|}|durTt |jtjrEt |jjtj	rE|jjj
|ksRt |jtj	rT|jj
|krTdS dS )zReturn True if suggestion for assignment expr should be ignore.

        E.g., in cases where a match statement would be a better fit
        (multiple conditions).
        NrD   r   TF)r;   rp   r	   ru   next_siblingrV   orelseIfrv   rq   rz   )r2   rz   next_if_noder   r)   r)   r*   r{     s$   	 z9CodeStyleChecker._check_ignore_assignment_expr_suggestion)r"   N)%__name__
__module____qualname____doc__r   __implements__rz   prioritymsgsoptionsr   r%   r1   r   r	   rF   r6   Forr>   Comprehensionr@   r   rB   r4   rA   staticmethodr   rY   rZ   r   r   rP   rQ   ry   boolr{   __classcell__r)   r)   r'   r*   r      sX    
JDr   r!   r"   c                 C   s   |  t|  d S r3   )register_checkerr   r#   r)   r)   r*   register2  s   r   )systypingr   r   r   r   r   r   r   astroidr	   pylint.checkersr
   r   pylint.checkers.utilsr   r   pylint.interfacesr   pylint.lintr   pylint.utils.utilsr   version_infor   typing_extensionsr   r   r)   r)   r)   r*   <module>   s    $
  "