o
    g>                     @   s   d Z ddlZ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
 ddlmZmZ dd	d
dddddZh dZdddZG dd dejZdd Zdd Zdd ZdS )z"checker for use of Python logging
    N)Set)nodes)checkers
interfaces)utils)check_messages	infer_all)&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E1206>   infowarndebugerrorfatalwarningcritical	exception c                 C   s@   t | tjot | jtjo|r| jj|v ndo|r| j|v S dS )a  Determines if a BoundMethod node represents a method call.

    Args:
      func (astroid.BoundMethod): The BoundMethod AST node to check.
      types (Optional[String]): Optional sequence of caller type names to restrict check.
      methods (Optional[String]): Optional sequence of method names to restrict check.

    Returns:
      bool: 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methodsr    r    U/home/ubuntu/cloudmapper/venv/lib/python3.10/site-packages/pylint/checkers/logging.pyis_method_callr   s   r+   c                   @   s   e Zd ZdZej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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e dejddfddZdd Zdd Zed d! Zdejfd"d#Zd$d% ZdS )&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/   r0   r1   choicesr2   _returnNc                 C   sb   t  | _| jj}| jj| _t || _i | _|D ]}|dd}t	|dkr.|d | j|d < qdS )z?Clears any state left in this checker from last module checked..   r   N)
set_logging_namesconfiglogging_moduleslogging_format_style_format_style_logging_modules_from_importsrsplitlen)selfr7   logging_modslogging_modpartsr    r    r*   visit_module   s   

zLoggingChecker.visit_modulenodec                 C   sP   z| j |j }|jD ]\}}||kr| j|p| q
W dS  ty'   Y dS w )z;Checks to see if a module uses a non-Python logging module.N)rB   modnamenamesr<   addKeyError)rE   rJ   logging_namemoduleas_namer    r    r*   visit_importfrom   s   zLoggingChecker.visit_importfromc                 C   s.   |j D ]\}}|| jv r| j|p| qdS )z<Checks to see if this module uses Python's built-in logging.N)rL   rA   r<   rM   )rE   rJ   rP   rQ   r    r    r*   visit_import   s
   
zLoggingChecker.visit_importc                    sL    fdd} fdd}| r j j}n	| \}}|sdS  | dS )z Checks calls to logging methods.c                      s.   t  jtjot  jjtjo jjjjv S )N)r!   r'   r   	AttributeexprNamer&   r<   r    rJ   rE   r    r*   is_logging_name   s
   z2LoggingChecker.visit_call.<locals>.is_logging_namec                     sf   t  jD ]+} t| tjr0| jj}t|tjr0|	 dks(t
dd | D r0d| jjf  S qdS )Nlogging.Loggerc                 s   s    | ]	}|  d kV  qdS )rY   N)qname).0ancestorr    r    r*   	<genexpr>   s
    

zELoggingChecker.visit_call.<locals>.is_logger_class.<locals>.<genexpr>T)FN)r   r'   r!   r"   r#   _proxiedparentr   ClassDefrZ   any	ancestorsr&   )inferredr_   rJ   r    r*   is_logger_class   s   z2LoggingChecker.visit_call.<locals>.is_logger_classN)r'   attrname_check_log_method)rE   rJ   rX   re   r&   resultr    rW   r*   
visit_call   s   

zLoggingChecker.visit_callc                    sH  |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 t|j| tjrg|j| }|jdk}|jdkrUt	 fdd	|j
|jfD }|dk}|re jd
| |fd dS dS t|j| tjrz |j|  dS t|j| tjr || dS t|j| tjr jd| |fd dS dS )z9Checks calls to logging.log(level, format, *format_args).log   Nr:   r   %+c                 3   s$    | ]}  t|rd V  qdS r:   N)_is_operand_literal_strr   
safe_infer)r[   operandrE   r    r*   r]      s    
z3LoggingChecker._check_log_method.<locals>.<genexpr>r
   rJ   argsr   )starargskwargsrD   rt   CHECKED_CONVENIENCE_FUNCTIONSr!   r   BinOpopsumleftrightadd_message_helper_stringCall_check_call_funcConst_check_format_string	JoinedStr)rE   rJ   r&   
format_posbinopemittotal_number_of_stringsr    rr   r*   rg      sF   







z LoggingChecker._check_log_methodc                 C   s^   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
   rl   z or )linteris_message_enabled
fromlinenoappendjoin)rE   rJ   valid_typesr    r    r*   r~     s   



zLoggingChecker._helper_stringc                 C   s   t | tjo
| jdkS )zL
        Return True if the operand in argument is a literal string
        str)r!   r   r   r&   )rq   r    r    r*   ro   $  s   z&LoggingChecker._is_operand_literal_strc                 C   s^   t |j}d}d}t|tjr)t|||r+t|js-| j	d|| 
|fd dS dS dS dS )z8Checks that function call is not format_string.format().)r   unicode)formatr   rs   N)r   rp   r'   r!   r"   r#   r+   is_complex_format_strr$   r}   r~   )rE   rJ   r'   r(   r)   r    r    r*   r   +  s   



zLoggingChecker._check_call_funcc              
   C   sX  t |j|d d }|sdS |j| j}d}t|tr | }t|trz2| jdkr:t	|\}}}}|r9W dS n| jdkrVt
|\}}	}
tdd |D }||	 |
 }W n8 tjy~ } z||j }| jd||t||jfd	 W Y d}~dS d}~w tjy   | jd
|d Y dS w ||kr| jd|d dS ||k r| jd|d dS dS )zChecks that format string tokens match the supplied arguments.

        Args:
          node (nodes.NodeNG): AST node to be checked.
          format_arg (int): Index of the format string in the node arguments.
        r:   Nr   r3   r5   c                 S   s   h | ]\}}t |ts|qS r    )r!   int)r[   klr    r    r*   	<setcomp>^  s    z6LoggingChecker._check_format_string.<locals>.<setcomp>r   rs   r   rd   r   r   )_count_supplied_tokensrt   valuer!   bytesdecoder   r@   r   parse_format_stringparse_format_method_stringrD   UnsupportedFormatCharacterindexr}   ordIncompleteFormatString)rE   rJ   
format_argnum_argsformat_stringrequired_num_argskeyword_argsr7   keyword_argumentsimplicit_pos_argsexplicit_pos_argskeyword_args_cntexcharr    r    r*   r   ;  s\   





z#LoggingChecker._check_format_string)__name__
__module____qualname____doc__r   IAstroidChecker__implements__r&   MSGSmsgsoptionsr   ModulerI   
ImportFromrR   ImportrS   r   r   ri   rg   r~   staticmethodro   r   r   r    r    r    r*   r,      s@    
 ,
r,   c                 C   s|   t | }|du st|tjrt|jtsdS ztt	 
|j}W n
 ty-   Y dS w |D ]\}}}}|r; dS q0dS )zChecks if node represents a string with complex formatting specs.

    Args:
        node (nodes.NodeNG): AST node to check
    Returns:
        bool: True if inferred string uses complex formatting, False otherwise
    NTF)r   rp   r!   r   r   r   r   liststring	Formatterparse
ValueError)rJ   rc   parsedr7   format_specr    r    r*   r   t  s"   


r   c                 C   s   t dd | D S )a|  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 (list): AST nodes that are arguments for a log format string.

    Returns:
      int: Number of AST nodes that aren't keywords.
    c                 s   s     | ]}t |tjsd V  qdS rn   )r!   r   Keyword)r[   argr    r    r*   r]     s    z)_count_supplied_tokens.<locals>.<genexpr>)rz   )rt   r    r    r*   r     s   r   c                 C   s   |  t|  dS )z.Required method to auto-register this checker.N)register_checkerr,   )r   r    r    r*   register  s   r   )r    r    )r   r   typingr   r"   r   pylintr   r   pylint.checkersr   pylint.checkers.utilsr   r   r   rw   r+   BaseCheckerr,   r   r   r   r    r    r    r*   <module>   s.   A
 o