
    c2                        d dl mZ d dlZd dl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 erd dlmZ ej        d	k    rd d
lmZ nd d
lmZ  G d de          ZddZdS )    )annotationsN)TYPE_CHECKINGTupleTypecast)nodes)BaseCheckerutils)only_required_for_messages
safe_infer)	INFERENCE)PyLinter)   
   )	TypeGuardc                  ^   e Zd ZdZdZddddddd	d
ifdZddddddffZd.dZ ed          d/d            Z	 ed          d0d            Z
 ed          d1d            Z ed          d2d             Zd/d!Zd2d"Zed3d(            Zed4d*            Z ed          d5d,            Zd-S )6CodeStyleCheckeram  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 regard 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 and ``py-version >= 3.8``.z+Use '%s' to do an augmented assign directlyconsider-using-augmented-assignzEmitted when an assignment is referring to the object that it is assigning to. This can be changed to be an augmented assign.
Disabled by default!default_enabledF)R6101R6102R6103R6104zmax-line-length-suggestionsintr   z<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defaultmetavarhelpreturnNonec                    | j         j        j        }|dk    | _        | j         j        j        p| j         j        j        | _        d S )N)r      )linterconfig
py_version
_py38_plusmax_line_length_suggestionsmax_line_length_max_length)selfr)   s     <lib/python3.11/site-packages/pylint/extensions/code_style.pyopenzCodeStyleChecker.openZ   sD    ['2
$.K: 2{!1 	    r   node
nodes.Dictc                0    |                      |           d S N))_check_dict_consider_namedtuple_dataclassr.   r2   s     r/   
visit_dictzCodeStyleChecker.visit_dictb   s    66t<<<<<r1   r   	nodes.Forc                    t          |j        t          j                  r|                     d|j                   d S d S Nr   r2   
isinstanceiterr   Listadd_messager7   s     r/   	visit_forzCodeStyleChecker.visit_forf   G    di,, 	E3$)DDDDD	E 	Er1   nodes.Comprehensionc                    t          |j        t          j                  r|                     d|j                   d S d S r;   r=   r7   s     r/   visit_comprehensionz$CodeStyleChecker.visit_comprehensionk   rC   r1   r   nodes.Ifc                B    | j         r|                     |           d S d S r5   )r*   %_check_consider_using_assignment_exprr7   s     r/   visit_ifzCodeStyleChecker.visit_ifp   s0    ? 	=66t<<<<<	= 	=r1   c                   t          |j        t          j        t          j        f          r$t          |j        j        t          j                  sdt          |j        t          j                  rCt          |j        j        t          j                  rt          j	        |j        j        d          sdS t          |j                  dk    rt          d |j        D                       rt          t          t          j                 t           f         }t#                      }|j        D ]\  }}t%          t          j        |          }|j        D ]\  }}t)          |          |                                f}||v r-t-          |          }t          |t          j                  r|                                dk    s  dS |                    |           g }	|j        D ]P\  }}t%          t          j        |          }|	                    t7          d |j        D                                  Qt#          |	d                   }
|	dd         D ]}|
                    |           |
sdS |                     d|	           dS t          |j                  dk    rt          d
 |j        D                       rt          |j        d         d         j                  }|dk    rdS |j        dd         D ] \  }}t          |j                  |k    r dS !|j        D ]&\  }}t          d |j        D                       r dS '|                     d|	           dS dS dS )zFCheck if dictionary values can be replaced by Namedtuple or Dataclass.FinalN   c              3  P   K   | ]!\  }}t          |t          j                  V  "d S r5   r>   r   Dict.0_
dict_values      r/   	<genexpr>zMCodeStyleChecker._check_dict_consider_namedtuple_dataclass.<locals>.<genexpr>   sC       '
 '
3@1jJz5:..'
 '
 '
 '
 '
 '
r1   zbuiltins.strc              3  b   K   | ]*\  }}t          |          |                                fV  +d S r5   )r   	as_string)rR   keyrS   s      r/   rU   zMCodeStyleChecker._check_dict_consider_namedtuple_dataclass.<locals>.<genexpr>   s9      VV63499cmmoo6VVVVVVr1   r   r   r<   c              3  h   K   | ]-\  }}t          |t          j        t          j        f          V  .d S r5   )r>   r   r@   r   rQ   s      r/   rU   zMCodeStyleChecker._check_dict_consider_namedtuple_dataclass.<locals>.<genexpr>   sM       '
 '
: zEJ#<=='
 '
 '
 '
 '
 '
r1   c              3  J   K   | ]}t          |t          j                  V  d S r5   rO   )rR   entrys     r/   rU   zMCodeStyleChecker._check_dict_consider_namedtuple_dataclass.<locals>.<genexpr>   s.      RRz%44RRRRRRr1   )r>   parentr   Assign	AnnAssignModuletarget
AssignNamer
   is_assign_name_annotated_withlenitemsallr   r   NodeNGstrsetr   rP   r   rW   r   Constpytypeaddappendtupleintersection_updaterA   elts)r.   r2   	KeyTupleTkeys_checkedrS   rT   rX   	key_tupleinferred
key_tupleskeys_intersectionsub_key_tupleslist_lengths                r/   r6   z:CodeStyleChecker._check_dict_consider_namedtuple_dataclassu   s    t{U\5?$CDD		4;-u|<<		 $+u77		 4;-u/?@@			
 3DK4FPP		 F tz??Q #	3 '
 '
DHJ'
 '
 '
 $
 $
 #	 d5<0#56I ,/55L!% 0 0:!%*j99
(. 
0 
0FC!%cCMMOO <I L0 ! )#H"8U[99$OO--?  $$Y////
0 79J!%  :!%*j99
!!VVZEUVVVVV    14JqM0B0B",QRR. F F!55nEEEE$ EDQQQF tz??Q 	3 '
 '
!%'
 '
 '
 $
 $
 	
 djmA.344Ka !%ABB  :z'';6 FF "&  :RR*/RRRRR FF EDQQQF%	 	 	 	r1   c                   d}t          |j        t          j                  r|j        }nt          |j        t          j                  rA|j        j        dk    r1t          |j        j        t          j                  r|j        j        }not          |j        t          j                  rNt          |j        j        t          j                  r*t          |j        j
                  dk    r|j        j        }ndS |                                }t                              ||j                  rt                              ||j                  rdS |j                                                            |j        d|j         d|j                                         dd          }d| d}|j         t          |          |j        z   | j        k    st          |          | j        k    rdS |                     d	||f
           dS dS )aY  Check if an assignment expression (walrus operator) can be used.

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

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

        Note: Assignment expressions were added in Python 3.8
        NnotrM   (z := )zif :r   )r2   args)r>   testr   NameUnaryOpopoperandCompareleftrc   opsprevious_siblingr   _check_prev_sibling_to_if_stmtname(_check_ignore_assignment_expr_suggestionrW   replacevalue
col_offsetr-   rA   )r.   r2   	node_nameprev_siblingtest_str
suggestions         r/   rI   z6CodeStyleChecker._check_consider_using_assignment_expr   s    (,	di,, 		IIty%-00		%	 49,ej99	
 	)IIty%-00	49>5:66	 DIM""a'	
 	IIF ,,..::).
 
 	
  HHin    y**,,44IINII(:(D(D(F(FIII H
 +x***J
OOdo58HH z??T%55
 0 ]      3	 	r1   r   nodes.NodeNG | Noner   
str | None)TypeGuard[nodes.Assign | nodes.AnnAssign]c                   | | j         | j        z
  dk    rdS t          | t          j                  rUt          | j                  dk    r=t          | j        d         t          j                  r| j        d         j        |k    rdS t          | t          j	                  r1t          | j
        t          j                  r| j
        j        |k    rdS dS )z}Check if previous sibling is an assignment with the same name.

        Ignore statements which span multiple lines.
        Nr   FrM   T)tolineno
fromlinenor>   r   r]   rc   targetsra   r   r^   r`   )r   r   s     r/   r   z/CodeStyleChecker._check_prev_sibling_to_if_stmt   s      	<#8<;R#RVW#W 	5 |U\22	L())Q.	 </2E4DEE	 $Q',4		 4|U_55	<.0@AA	 #(D0	
 4ur1   boolc                V   t          | j        t          j                  rd}|                                 }t          | j                  dk    r3t          | j        d         t          j                  r| j        d         }nt          |t          j                  r|}|t          |j        t          j                  r9t          |j        j        t          j	                  r|j        j        j
        |k    s/t          |j        t          j	                  r|j        j
        |k    rdS dS )zReturn True if suggestion for assignment expr should be ignored.

        E.g., in cases where a match statement would be a better fit
        (multiple conditions).
        NrM   r   TF)r>   r~   r   r   next_siblingrc   orelseIfr   r   r   )r2   r   next_if_noder   s       r/   r   z9CodeStyleChecker._check_ignore_assignment_expr_suggestion  s    di// 	,0L,,..L4;1$ ,DKNEH)M)M ,#{1~L%(33 ,+ 
 |0%-@@
 #<#4#95:FF	

 %).3t;
 ","3UZ@@
 %).$6
 tur1   nodes.Assignc                    t          j        |          \  }}|r/|                     d| d||j        |j        t
                     d S d S )Nr   =)r}   r2   liner   
confidence)r
   is_augmented_assignrA   linenor   r   )r.   r2   is_augr   s       r/   visit_assignzCodeStyleChecker.visit_assign:  sk    .t44
 	1XXX[?$      	 	r1   N)r#   r$   )r2   r3   r#   r$   )r2   r9   r#   r$   )r2   rD   r#   r$   )r2   rG   r#   r$   )r   r   r   r   r#   r   )r2   rG   r   r   r#   r   )r2   r   r#   r$   )__name__
__module____qualname____doc__r   msgsoptionsr0   r   r8   rB   rF   rJ   r6   rI   staticmethodr   r   r    r1   r/   r   r      s         D



 :-# "5	
) DB *"K
 
	
G"
 
 
 
   HII= = = JI=   677E E E 87E   677E E E 87E   @AA= = = BA=F F F FPA A A AF    \2    \>   ABB
 
 
 CB
 
 
r1   r   r'   r   r#   r$   c                J    |                      t          |                      d S r5   )register_checkerr   )r'   s    r/   registerr   H  s%    
,V4455555r1   )r'   r   r#   r$   )
__future__r   systypingr   r   r   r   astroidr   pylint.checkersr	   r
   pylint.checkers.utilsr   r   pylint.interfacesr   pylint.lintr   version_infor   typing_extensionsr   r   r   r1   r/   <module>r      s<  
 # " " " " " 



 3 3 3 3 3 3 3 3 3 3 3 3       . . . . . . . . H H H H H H H H ' ' ' ' ' ' %$$$$$$w ,       ++++++l l l l l{ l l l^	6 6 6 6 6 6r1   