
    c<                    Z   U d Z ddlmZ ddlZddlZddlmZ ddlZddlmZm	Z	 ddl
mZ ddlmZ ddlmZ dd	lmZ dd
lmZ ej        dk    rddlmZ nddlmZ erddlmZ ddddddddZded<   h dZ eg d          Z	 d2d3d"Z G d# d$ej                  Z d4d'Z!d5d+Z"d6d-Z#d7d1Z$dS )8z"Checker for use of Python logging.    )annotationsN)TYPE_CHECKING)basesnodes)InferenceResult)checkers)utils)	infer_all)MessageDefinitionTuple)      )Literal)PyLinter)&Use %s formatting in logging functionslogging-not-lazya  Used when a logging statement has a call form of "logging.<logging method>(format_string % (format_args...))". Use another type of string formatting instead. You can use % formatting but leave interpolation to the logging function by passing the parameters as arguments. If logging-fstring-interpolation is disabled then you can use fstring formatting. If logging-format-interpolation is disabled then you can use str.format.)r   logging-format-interpolationa  Used when a logging statement has a call form of "logging.<logging method>(format_string.format(format_args...))". Use another type of string formatting instead. You can use % formatting but leave interpolation to the logging function by passing the parameters as arguments. If logging-fstring-interpolation is disabled then you can use fstring formatting. If logging-not-lazy is disabled then you can use % formatting as normal.)r   logging-fstring-interpolationa  Used when a logging statement has a call form of "logging.<logging method>(f"...")".Use another type of string formatting instead. You can use % formatting but leave interpolation to the logging function by passing the parameters as arguments. If logging-format-interpolation is disabled then you can use str.format. If logging-not-lazy is disabled then you can use % formatting as normal.)z;Unsupported logging format character %r (%#02x) at index %dlogging-unsupported-formatzWUsed when an unsupported format character is used in a logging statement format string.)z<Logging format string ends in middle of conversion specifierlogging-format-truncatedz`Used when a logging statement format string terminates before the end of a conversion specifier.)z,Too many arguments for logging format stringlogging-too-many-argsz>Used when a logging format string is given too many arguments.)z.Not enough arguments for logging format stringlogging-too-few-argsz=Used when a logging format string is given too few arguments.)W1201W1202W1203E1200E1201E1205E1206z!dict[str, MessageDefinitionTuple]MSGS>   infowarndebugerrorfatalwarningcritical	exception)z%sz%dz%fz%r funcbases.BoundMethodtypestuple[str, ...]methodsreturnboolc                    t          | t          j                  o=t          | j        t          j                  o|r| j        j        |v ndo|r	| j        |v ndS )a~  Determines if a BoundMethod node represents a method call.

    Args:
      func: The BoundMethod AST node to check.
      types: Optional sequence of caller type names to restrict check.
      methods: Optional sequence of method names to restrict check.

    Returns:
      true if the node represents a method call for the given type and
      method names, False otherwise.
    T)
isinstanceastroidBoundMethodboundInstancename)r)   r+   r-   s      7lib/python3.11/site-packages/pylint/checkers/logging.pyis_method_callr8   o   sf     	4,-- 	8tz7#344	8).8TZ_%%D	8 &-6TY'!!$	    c                      e Zd ZdZdZeZddddddfd	d
ddd
dgddffZd)dZd*dZ	d+dZ
d,dZd-dZd.dZed/d#            Zd,d$Zd0d'Zd(S )1LoggingCheckerz!Checks use of the logging module.loggingzlogging-modules)r<   csvz<comma separated list>zcLogging modules to check that the string format arguments are in logging function parameter format.)defaulttypemetavarhelpzlogging-format-styleoldchoicez<old (%) or new ({)>newztThe type of string formatting that logging methods do. `old` means using % formatting, `new` is for `{}` formatting.)r>   r?   r@   choicesrA   _nodes.Moduler.   Nonec                8   t                      | _        | j        j        j        }| j        j        j        | _        t          |          | _        i | _        |D ]A}|	                    dd          }t          |          dk    r|d         | j        |d         <   BdS )z?Clears any state left in this checker from last module checked..   r   N)set_logging_nameslinterconfiglogging_moduleslogging_format_style_format_style_logging_modules_from_importsrsplitlen)selfrF   logging_modslogging_modpartss        r7   visit_modulezLoggingChecker.visit_module   s    
 ),{)9![/D #L 1 1' 	8 	8K&&sA..E5zzA~ 8/4Qx"58,	8 	8r9   nodenodes.ImportFromc                    	 | j         |j                 }|j        D ]'\  }}||k    r| j                            |p|           (dS # t
          $ r Y dS w xY w)z;Checks to see if a module uses a non-Python logging module.N)rT   modnamenamesrM   addKeyError)rW   r\   logging_namemoduleas_names        r7   visit_importfromzLoggingChecker.visit_importfrom   s    	-dl;L#': ? ?\) ?'++G,=v>>>? ?  	 	 	DD	s   AA 
AAnodes.Importc                j    |j         D ]*\  }}|| j        v r| j                            |p|           +dS )z<Checks to see if this module uses Python's built-in logging.N)r`   rS   rM   ra   )rW   r\   rd   re   s       r7   visit_importzLoggingChecker.visit_import   sN    #z 	; 	;OFG.. ;#''(96:::	; 	;r9   
nodes.Callc                     d fd}dfd} |            rj         j        }n |            \  }}|sdS                      |           dS )	z Checks calls to logging methods.r.   r/   c                     t           j        t          j                  o;t           j        j        t          j                  o j        j        j        j        v S N)r1   r)   r   	AttributeexprNamer6   rM   )r\   rW   s   r7   is_logging_namez2LoggingChecker.visit_call.<locals>.is_logging_name   sH    49eo66 ?ty~uz::?IN'4+>>r9   tuple[bool, str | None]c                 \   t          j                  D ]} t          | t          j                  ry| j        j        }t          |t          j                  rS|	                                dk    s+t          d |                                D                       rd| j        j        fc S dS )Nlogging.Loggerc              3  F   K   | ]}|                                 d k    V  dS )rt   N)qname).0ancestors     r7   	<genexpr>zELoggingChecker.visit_call.<locals>.is_logger_class.<locals>.<genexpr>   sF         ( %NN,,0@@     r9   T)FN)r
   r)   r1   r2   r3   _proxiedparentr   ClassDefrv   any	ancestorsr6   )inferredr{   r\   s     r7   is_logger_classz2LoggingChecker.visit_call.<locals>.is_logger_class   s    %di00 
< 
<h(;<< 	<%.5F!&%.99 <*::<  ,2,<,<,>,>    <  $X%6%;;;;;;r9   N)r.   r/   )r.   rr   )r)   attrname_check_log_method)rW   r\   rq   r   r6   results   ``    r7   
visit_callzLoggingChecker.visit_call   s    	 	 	 	 	 	 		 	 	 	 	 	 ? 	9%DD*?,,LFD tT*****r9   r6   strc                h    |dk    r+|j         s|j        st          |j                  dk     rdS d}n%|t          v r|j         s|j        s|j        sdS d}ndS |j        |         }t          |t          j                  rw|}|j        dk    }|j        dk    r-t           fd|j
        |j        fD                       }|dk    }|r.                     d	|                     |          f
           dS dS t          |t          j                  r                     |           dS t          |t          j                  r                     ||           dS t          |t          j                  r?t'          |          rdS                      d|                     |          f
           dS dS )z9Checks calls to logging.log(level, format, *format_args).log   NrK   r   %+c              3  j   K   | ]-}                     t          j        |                    )d V  .dS rK   N)_is_operand_literal_strr	   
safe_infer)rw   operandrW   s     r7   ry   z3LoggingChecker._check_log_method.<locals>.<genexpr>   sV       . .33E4DW4M4MNN.. . . . . .r9   r   r\   argsr   )starargskwargsrV   r   CHECKED_CONVENIENCE_FUNCTIONSr1   r   BinOpopsumleftrightadd_message_helper_stringCall_check_call_funcConst_check_format_string	JoinedStrstr_formatting_in_f_string)rW   r\   r6   
format_pos
format_argbinopemittotal_number_of_stringss   `       r7   r   z LoggingChecker._check_log_method   s1   5= 	}  s49~~/A  ()JJ22 	}  49  JJFYz*
j%+.. 	E8s?Dx3 3*- . . . .$)J#<. . . + +'
 /2   &--d335 !       
EJ// 	!!*-----
EK00 		%%dJ77777
EO44 	)*55 /))$//1      	 	r9   c                p   dg}| j                             d|j                  s|                    d           | j                             d|j                  s|                    d           | j                             d|j                  s|                    d           d                    |          S )	zGCreate a string that lists the valid types of formatting for this node.zlazy %zlogging-fstring-formattingfstringr   z	.format()r   r   z or )rN   is_message_enabled
fromlinenoappendjoin)rW   r\   valid_typess      r7   r   zLoggingChecker._helper_string  s    j{--($/
 
 	* y))){--*DO
 
 	, {+++{--.@$/RR 	$s###{{;'''r9   r   InferenceResult | Noner/   c                L    t          | t          j                  o
| j        dk    S )z;Return True if the operand in argument is a literal string.r   )r1   r   r   r6   )r   s    r7   r   z&LoggingChecker._is_operand_literal_str$  s"     '5;//IGLE4IIr9   c                "   t          j        |j                  }d}d}t          |t          j                  rSt          |||          rDt          |j                  s2| 	                    d|| 
                    |          f           dS dS dS dS )z8Checks that function call is not format_string.format().)r   unicode)formatr   r   N)r	   r   r)   r1   r2   r3   r8   is_complex_format_strr4   r   r   )rW   r\   r)   r+   r-   s        r7   r   zLoggingChecker._check_call_func)  s    	**"tW011		tUG44		 *$*55		
 .))$//1      		 		 		 		 		 		r9   r   Literal[0, 1]c           	     H   t          |j        |dz   d                   }|sdS |j        |         j        }d}t          |t                    r|                                }t          |t                    r	 | j        dk    rt          j	        |          \  }}}}|rdS nD| j        dk    r9t          j
        |          \  }}	}
t          d |D                       }||	z   |
z   }n# t          j        $ rE}||j                 }|                     d||t          |          |j        f           Y d}~dS d}~wt          j        $ r |                     d	|
           Y dS w xY w||k    r|                     d|
           dS ||k     r|                     d|
           dS dS )zChecks that format string tokens match the supplied arguments.

        Args:
          node: AST node to be checked.
          format_arg: Index of the format string in the node arguments.
        rK   Nr   rB   rD   c                B    h | ]\  }}t          |t                    |S r(   )r1   int)rw   kls      r7   	<setcomp>z6LoggingChecker._check_format_string.<locals>.<setcomp>\  s+    SSStq!
1c@R@RSSSSr9   r   r   r   r\   r   r   )_count_supplied_tokensr   valuer1   bytesdecoder   rR   r	   parse_format_stringparse_format_method_stringrV   UnsupportedFormatCharacterindexr   ordIncompleteFormatString)rW   r\   r   num_argsformat_stringrequired_num_argskeyword_argsrF   keyword_argumentsimplicit_pos_argsexplicit_pos_argskeyword_args_cntexchars                 r7   r   z#LoggingChecker._check_format_string9  sF    *$)JN4D4D*EFF 	 F	*-3mU++ 	3)0022MmS)) !	 %. <A<U%= =9L"3Q $   '50 
 8GG	))) (+SS'8SSS( ($ )+<<?PP & 3   $RX.  0D		284 !   
 /     !;$ GGG '' 	@44@@@@@)) 	@3$?????	@ 	@s%   7&C% AC% %E!4:D44)E! E!N)rF   rG   r.   rH   )r\   r]   r.   rH   )r\   rg   r.   rH   )r\   rj   r.   rH   )r\   rj   r6   r   r.   rH   )r\   rj   r.   r   )r   r   r.   r/   )r\   rj   r   r   r.   rH   )__name__
__module____qualname____doc__r6   r   msgsoptionsr[   rf   ri   r   r   r   staticmethodr   r   r   r(   r9   r7   r;   r;      sD       ++DD '3F	 		
 #  1!5>P 
	
G08 8 8 8"   ; ; ; ;+ + + +@- - - -^( ( ( (" J J J \J    6@ 6@ 6@ 6@ 6@ 6@r9   r;   r\   nodes.NodeNGc                b   t          j        |           }|4t          |t          j                  rt          |j        t                    sdS 	 t          t          j	                    
                    |j                            }n# t          $ r Y dS w xY wt          d |D                       S )zJReturn whether the node represents a string with complex formatting specs.NTFc              3  $   K   | ]\  }}}}|V  d S rm   r(   )rw   rF   format_specs      r7   ry   z(is_complex_format_str.<locals>.<genexpr>~  s+      @@51k1{@@@@@@r9   )r	   r   r1   r   r   r   r   liststring	Formatterparse
ValueErrorr}   )r\   r   parseds      r7   r   r   r  s    %%H 8U[)).8.M.M tf&((..x~>>??   uu @@@@@@@@s   8B 
BBr   list[nodes.NodeNG]r   c                4    t          d | D                       S )ap  Counts the number of tokens in an args list.

    The Python log functions allow for special keyword arguments: func,
    exc_info and extra. To handle these cases correctly, we only count
    arguments that aren't keywords.

    Args:
      args: AST nodes that are arguments for a log format string.

    Returns:
      Number of AST nodes that aren't keywords.
    c              3  N   K   | ] }t          |t          j                  d V  !dS r   )r1   r   Keyword)rw   args     r7   ry   z)_count_supplied_tokens.<locals>.<genexpr>  s3      GGS
3(F(FGqGGGGGGr9   )r   )r   s    r7   r   r     s!     GGDGGGGGGr9   nodes.JoinedStrc                >    t          d | j        D                       S )znDetermine whether the node represents an f-string with string formatting.

    For example: `f'Hello %s'`
    c              3     K   | ]Gt          t          j                  d j        v ot	          fdt
          D                       V  HdS )r   c              3  *   K   | ]}|j         v V  d S rm   )r   )rw   xvals     r7   ry   z7str_formatting_in_f_string.<locals>.<genexpr>.<genexpr>  s)       P PAci P P P P P Pr9   N)r1   r   r   r   r}   MOST_COMMON_FORMATTING)rw   r   s    @r7   ry   z-str_formatting_in_f_string.<locals>.<genexpr>  ss        c5;''syPS P P P P9O P P PPP     r9   )r}   valuesr   s    r7   r   r     s4       ;     r9   rN   r   rH   c                J    |                      t          |                      d S rm   )register_checkerr;   )rN   s    r7   registerr     s$    
N62233333r9   )r(   r(   )r)   r*   r+   r,   r-   r,   r.   r/   )r\   r   r.   r/   )r   r   r.   r   )r\   r   r.   r/   )rN   r   r.   rH   )%r   
__future__r   r   systypingr   r2   r   r   astroid.typingr   pylintr   pylint.checkersr	   pylint.checkers.utilsr
   pylint.typingr   version_infor   typing_extensionspylint.lintr   r   __annotations__r   	frozensetr   r8   BaseCheckerr;   r   r   r   r   r(   r9   r7   <module>r      sI  
 ) ( ( " " " " " "  



                              * * * * * *       ! ! ! ! ! ! + + + + + + 0 0 0 0 0 0v *)))))) %$$$$$$

s> >  @ @ @ @F	! 	! 	!  ##;#;#;<<  VX    ,j@ j@ j@ j@ j@X) j@ j@ j@ZA A A AH H H H 
 
 
 
4 4 4 4 4 4r9   