
    e>                    0   U d Z ddlmZ ddlZddlmZ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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	 d	 	 	 	 	 	 	 d dZ G d dej8                        Zd!dZd"dZd#dZ d$dZ!y)%z"Checker for use of Python logging.    )annotationsN)TYPE_CHECKINGLiteral)basesnodes)InferenceResult)checkers)utils)	infer_all)MessageDefinitionTuple)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%rc                    t        | t        j                        xrV t        | j                  t        j                        xr0 |r| j                  j
                  |v ndxr |r| j
                  |v S 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)functypesmethodss      9/usr/lib/python3/dist-packages/pylint/checkers/logging.pyis_method_callr1   i   sj     	4,,- 	8tzz7#3#34	8).TZZ__%D	8 &-TYY'!	 37	    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ed"d       ZddZd#dZy)$LoggingCheckerz!Checks use of the logging module.loggingzlogging-modules)r5   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.)r7   r8   r9   choicesr:   c                T   t               | _        | j                  j                  j                  }| j                  j                  j
                  | _        t        |      | _        i | _        |D ]8  }|j                  dd      }t        |      dkD  s$|d   | j                  |d   <   : y)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)self_logging_modslogging_modpartss        r0   visit_modulezLoggingChecker.visit_module   s    
 ),{{))99![[//DD #L 1' 	8K&&sA.E5zA~/4Qx""58,	8r2   c                    	 | j                   |j                     }|j                  D ]*  \  }}||k(  s| j                  j	                  |xs |       , y# t
        $ r Y yw xY w)z;Checks to see if a module uses a non-Python logging module.N)rJ   modnamenamesrC   addKeyError)rM   nodelogging_namemoduleas_names        r0   visit_importfromzLoggingChecker.visit_importfrom   sg    	--dll;L#':: ?\)''++G,=v>?  		s   0A !A 	A! A!c                    |j                   D ]3  \  }}|| j                  v s| j                  j                  |xs |       5 y)z<Checks to see if this module uses Python's built-in logging.N)rU   rI   rC   rV   )rM   rX   rZ   r[   s       r0   visit_importzLoggingChecker.visit_import   s@    #zz 	;OFG...##''(96:	;r2   c                     d fd}dfd} |       rj                   j                  }n |       \  }}|sy j                  |       y)z Checks calls to logging methods.c                    t         j                  t        j                        xr\ t         j                  j                  t        j
                        xr,  j                  j                  j                  j                  v S N)r'   r-   r   	AttributeexprNamer,   rC   )rX   rM   s   r0   is_logging_namez2LoggingChecker.visit_call.<locals>.is_logging_name   sV    499eoo6 ?tyy~~uzz:?IINN''4+>+>>r2   c                 l   t        j                        D ]  } t        | t        j                        s| j
                  j                  }t        |t        j                        sO|j                         dk(  s!t        d |j                         D              sd| j
                  j                  fc S  y)Nlogging.Loggerc              3  B   K   | ]  }|j                         d k(    yw)rg   N)qname).0ancestors     r0   	<genexpr>zELoggingChecker.visit_call.<locals>.is_logger_class.<locals>.<genexpr>   s%       ( %NN,0@@s   T)FN)r   r-   r'   r(   r)   _proxiedparentr   ClassDefri   any	ancestorsr,   )inferredrn   rX   s     r0   is_logger_classz2LoggingChecker.visit_call.<locals>.is_logger_class   s    %dii0 
<h(;(;<%..55F!&%..9*:: ,2,<,<,> 
  $X%6%6%;%;;;
< r2   N)returnbool)rt   ztuple[bool, str | None])r-   attrname_check_log_method)rM   rX   re   rs   r,   results   ``    r0   
visit_callzLoggingChecker.visit_call   sF    		 99%%D*,LFDtT*r2   c                    |dk(  r4|j                   s$|j                  st        |j                        dk  ryd}n1|t        v r(|j                   s|j                  s|j                  syd}ny|j                  |   }t        |t        j                        r|}|j                  dk(  }|j                  dk(  r@ j                  |      s/t         fd|j                  |j                  fD              }|dkD  }|r% j                  d	| j                  |      f
       yyt        |t        j                        r j!                  |       yt        |t        j"                        r j%                  ||       yt        |t        j&                        r1t)        |      ry j                  d| j                  |      f
       yy)z9Checks calls to logging.log(level, format, *format_args).log   NrA   r   %+c              3  j   K   | ]*  }j                  t        j                  |            rd  , ywrA   N)_is_operand_literal_strr
   
safe_infer)rj   operandrM   s     r0   rl   z3LoggingChecker._check_log_method.<locals>.<genexpr>   s2      .33E4D4DW4MN .s   03r   rX   argsr   )starargskwargsrL   r   CHECKED_CONVENIENCE_FUNCTIONSr'   r   BinOpop#_is_node_explicit_str_concatenationsumleftrightadd_message_helper_stringCall_check_call_funcConst_check_format_string	JoinedStrstr_formatting_in_f_string)rM   rX   r,   
format_pos
format_argbinopemittotal_number_of_stringss   `       r0   rw   z LoggingChecker._check_log_method   s   5=}}s499~/A ()J22}}499 JYYz*
j%++.E88s?Dxx3t'O'OPU'V*- .$)JJ#<. +'
 /2  &--d35 !   
EJJ/!!*-
EKK0%%dJ7
EOO4)*5/))$/1   5r2   c                t   dg}| j                   j                  d|j                        s|j                  d       | j                   j                  d|j                        s|j                  d       | j                   j                  d|j                        s|j                  d       dj	                  |      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 )rD   is_message_enabled
fromlinenoappendjoin)rM   rX   valid_typess      r0   r   zLoggingChecker._helper_string  s    j{{--($//
 y){{--*DOO
 {+{{--.@$//Rs#{{;''r2   c                X    t        | t        j                        xr | j                  dk(  S )z;Return True if the operand in argument is a literal string.str)r'   r   r   r,   )r   s    r0   r   z&LoggingChecker._is_operand_literal_str  s#     '5;;/IGLLE4IIr2   c                <   t        | t        j                        syt        j	                  | j
                        xs t        j                  | j
                        xr@ t        j	                  | j                        xs t        j                  | j                        S )zEReturn True if the node represents an explicitly concatenated string.F)r'   r   r   r4   r   r   r   r   rX   s    r0   r   z2LoggingChecker._is_node_explicit_str_concatenation#  su     $,22499= MAA$))L
 224::> NAA$**M	
r2   c                   t        j                  |j                        }d}d}t        |t        j
                        rIt        |||      r;t        |j                        s%| j                  d|| j                  |      f       yyyy)z8Checks that function call is not format_string.format().)r   unicode)formatr   r   N)r
   r   r-   r'   r(   r)   r1   is_complex_format_strr*   r   r   )rM   rX   r-   r.   r/   s        r0   r   zLoggingChecker._check_call_func0  s    		*"tW001tUG4)$**5.))$/1   6 5 2r2   c           
     ^   t        |j                  |dz   d       }|sy|j                  |   j                  }d}t        |t              r|j                         }t        |t              r	 | j                  dk(  rt        j                  |      \  }}}}|r`y| j                  dk(  rPt        j                  |      \  }}	}
t        |D ch c]  \  }}t        |t              r| c}}      }||	z   |
z   }||kD  r| j                  d
|	       y||k  r| j                  d|	       yyc c}}w # t        j                  $ rC}||j                     }| j                  d||t!        |      |j                  f       Y d}~yd}~wt        j"                  $ r | j                  d|	       Y yw xY w)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.
        rA   Nr   r;   r=   r   r   r   r   r   r   )_count_supplied_tokensr   valuer'   bytesdecoder   rH   r
   parse_format_stringparse_format_method_stringrL   intUnsupportedFormatCharacterindexr   ordIncompleteFormatString)rM   rX   r   num_argsformat_stringrequired_num_argskeyword_argsrN   keyword_argumentsimplicit_pos_argsexplicit_pos_argskkeyword_args_cntexchars                  r0   r   z#LoggingChecker._check_format_string@  s    *$))JN4D*EF 		*-33mU+)002MmS) %%.<A<U<U%=9L"3Q $ ''50
 88G	))) (+'8Stq!
1c@RS($ )+<<?PP & ''44@))3$? *% T
 33 $RXX.  0D	2884 ! 
 //   !;$ Gs<   ++D/ 2D/ 	D)
"D)
&D/ )D/ /F,9F  )F,+F,N)rN   znodes.Modulert   None)rX   znodes.ImportFromrt   r   )rX   znodes.Importrt   r   )rX   
nodes.Callrt   r   )rX   r   r,   r   rt   r   )rX   r   rt   r   )r   zInferenceResult | Nonert   ru   rX   znodes.NodeNGrt   ru   )rX   r   r   zLiteral[0, 1]rt   r   )__name__
__module____qualname____doc__r,   r   msgsoptionsrR   r\   r^   ry   rw   r   staticmethodr   r   r   r    r2   r0   r4   r4      s    +DD '3F			
 #  1!5>P
	
G08";+@-^(" J J 

 

 6@r2   r4   c                J   t        j                  |       }|4t        |t        j                        rt        |j
                  t              sy	 t        t        j                         j                  |j
                              }t        d |D              S # t        $ r Y yw xY w)zJReturn whether the node represents a string with complex formatting specs.TFc              3  *   K   | ]  \  }}}}|  y wra   r   )rj   rN   format_specs      r0   rl   z(is_complex_format_str.<locals>.<genexpr>  s     @51k1{@s   )r
   r   r'   r   r   r   r   liststring	Formatterparse
ValueErrorrp   )rX   rr   parseds      r0   r   r   y  s    %H8U[[)j.Mf&&(..x~~>? @@@@  s   6B 	B"!B"c                &    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  V   K   | ]!  }t        |t        j                        rd  # ywr   )r'   r   Keyword)rj   args     r0   rl   z)_count_supplied_tokens.<locals>.<genexpr>  s     GS
3(FqGs   )))r   )r   s    r0   r   r     s     GDGGGr2   c                :    t        d | j                  D              S )znDetermine whether the node represents an f-string with string formatting.

    For example: `f'Hello %s'`
    c              3     K   | ]F  t        t        j                        r*d j                  v xr t	        fdt
        D               H yw)r}   c              3  :   K   | ]  }|j                   v   y wra   )r   )rj   xvals     r0   rl   z7str_formatting_in_f_string.<locals>.<genexpr>.<genexpr>  s      PAcii Ps   N)r'   r   r   r   rp   MOST_COMMON_FORMATTING)rj   r   s    @r0   rl   z-str_formatting_in_f_string.<locals>.<genexpr>  sD      c5;;' 	syyPS P9O PPPs   AA)rp   valuesr   s    r0   r   r     s"      ;;  r2   c                8    | j                  t        |              y ra   )register_checkerr4   )rD   s    r0   registerr     s    
N623r2   )r   r   )r-   zbases.BoundMethodr.   tuple[str, ...]r/   r   rt   ru   r   )r   zlist[nodes.NodeNG]rt   r   )rX   znodes.JoinedStrrt   ru   )rD   r   rt   r   )"r   
__future__r   r   typingr   r   r(   r   r   astroid.typingr   pylintr	   pylint.checkersr
   pylint.checkers.utilsr   pylint.typingr   pylint.lintr   r   __annotations__r   	frozensetr   r1   BaseCheckerr4   r   r   r   r   r   r2   r0   <module>r      s   
 ) "  )    *  ! + 0$

s>   @F	!  ##;<  VX
$3CR	,w@X)) w@tAH 
4r2   