
'![c           @   s   d  Z  d d l Z d d l Z d d l Z d d l m Z d d l m Z d d l m Z d d l	 m
 Z
 i d- d
 6d. d 6d/ d 6d0 d 6d1 d 6d2 d 6Z d d  d! d" d# d$ d% d& h Z d3 d4 d'  Z d( e j f d)     YZ d*   Z d+   Z d,   Z d S(5   s"   checker for use of Python logging
iN(   t   checkers(   t
   interfaces(   t   utils(   t   check_messagess>   Specify string format arguments as logging function parameterss   logging-not-lazys  Used when a logging statement has a call form of "logging.<logging method>(format_string % (format_args...))". Such calls should leave string interpolation to the logging method itself and be written "logging.<logging method>(format_string, format_args...)" so that the program may avoid incurring the cost of the interpolation in those cases in which no message will be logged. For more, see http://www.python.org/dev/peps/pep-0282/.t   W1201sL   Use % formatting in logging functions and pass the % parameters as argumentss   logging-format-interpolations   Used when a logging statement has a call form of "logging.<logging method>(format_string.format(format_args...))". Such calls should use % formatting instead, but leave interpolation to the logging function by passing the parameters as arguments.t   W1202s;   Unsupported logging format character %r (%#02x) at index %ds   logging-unsupported-formatsd   Used when an unsupported format character is used in a logging              statement format string.t   E1200s<   Logging format string ends in middle of conversion specifiers   logging-format-truncatedsm   Used when a logging statement format string terminates before              the end of a conversion specifier.t   E1201s,   Too many arguments for logging format strings   logging-too-many-argss>   Used when a logging format string is given too many arguments.t   E1205s.   Not enough arguments for logging format strings   logging-too-few-argss=   Used when a logging format string is given too few arguments.t   E1206t   criticalt   debugt   errort	   exceptiont   fatalt   infot   warnt   warningc         C   s\   t  |  t j  o[ t  |  j t j  o[ | r? |  j j | k n t o[ | rX |  j | k St S(   s  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
   isinstancet   astroidt   BoundMethodt   boundt   Instancet   namet   True(   t   funct   typest   methods(    (    s6   lib/python2.7/site-packages/pylint/checkers/logging.pyt   is_method_callI   s    t   LoggingCheckerc           B   s   e  Z d  Z e j Z d Z e Z d i d d 6d d 6d d 6d d	 6f f Z	 d
   Z
 d   Z d   Z e e j     d    Z d   Z e d    Z d   Z d   Z RS(   s!   Checks use of the logging module.t   loggings   logging-modulest   defaultt   csvt   types   <comma separated list>t   metavarsb   Logging modules to check that the string format arguments are in logging function parameter formatt   helpc         C   s   t    |  _ |  j j } t  |  |  _ i  |  _ xJ | D]B } | j d d  } t |  d k r7 | d |  j | d <q7 q7 Wd S(   s?   Clears any state left in this checker from last module checked.t   .i   i    N(   t   sett   _logging_namest   configt   logging_modulest   _logging_modulest   _from_importst   rsplitt   len(   t   selft   nodet   logging_modst   logging_modt   parts(    (    s6   lib/python2.7/site-packages/pylint/checkers/logging.pyt   visit_modulek   s    	c         C   sk   yS |  j  | j } x< | j D]1 \ } } | | k r |  j j | pG |  q q WWn t k
 rf n Xd S(   s;   Checks to see if a module uses a non-Python logging module.N(   R*   t   modnamet   namesR&   t   addt   KeyError(   R-   R.   t   logging_namet   modulet   as_name(    (    s6   lib/python2.7/site-packages/pylint/checkers/logging.pyt   visit_importfromz   s    !c         C   sF   x? | j  D]4 \ } } | |  j k r
 |  j j | p7 |  q
 q
 Wd S(   s<   Checks to see if this module uses Python's built-in logging.N(   R4   R)   R&   R5   (   R-   R.   R8   R9   (    (    s6   lib/python2.7/site-packages/pylint/checkers/logging.pyt   visit_import   s    c            sf      f d   }   f d   } |   r9   j  j } n |   \ } } | sR d S j   |  d S(   s    Checks calls to logging methods.c              sC   t    j t j  oB t    j j t j  oB   j j j  j k S(   N(   R   R   R   t	   Attributet   exprt   NameR   R&   (    (   R.   R-   (    s6   lib/python2.7/site-packages/pylint/checkers/logging.pyt   is_logging_name   s    c             s   y x   j  j   D]w }  t |  t j  r |  j j } t | t j  r | j   d k sw t	 d   | j
   D  r t |  j j f Sq q WWn t j j k
 r n Xt d  f S(   Ns   logging.Loggerc         s   s!   |  ] } | j    d  k Vq d S(   s   logging.LoggerN(   t   qname(   t   .0t   ancestor(    (    s6   lib/python2.7/site-packages/pylint/checkers/logging.pys	   <genexpr>   s   (   R   t   inferR   R   R   t   _proxiedt   parentt   ClassDefR@   t   anyt	   ancestorsR   R   t
   exceptionst   InferenceErrort   Falset   None(   t   inferredRE   (   R.   (    s6   lib/python2.7/site-packages/pylint/checkers/logging.pyt   is_logger_class   s    	N(   R   t   attrnamet   _check_log_method(   R-   R.   R?   RN   R   t   result(    (   R.   R-   s6   lib/python2.7/site-packages/pylint/checkers/logging.pyt
   visit_call   s    	c         C   sv  | d k r@ | j  s3 | j s3 t | j  d k  r7 d Sd } n9 | t k ru | j  sh | j sh | j rl d Sd } n d St | j | t j  r| j | } | j d k s | j d k rrt g  | j	 | j
 f D] } |  j |  r | ^ q  d k rr|  j d d	 | qrn\ t | j | t j  rF|  j | j |  n, t | j | t j  rr|  j | |  n  d S(
   s9   Checks calls to logging.log(level, format, *format_args).t   logi   Ni   i    t   %t   +s   logging-not-lazyR.   (   t   starargst   kwargsR,   t   argst   CHECKED_CONVENIENCE_FUNCTIONSR   R   t   BinOpt   opt   leftt   rightt   _is_operand_literal_strt   add_messaget   Callt   _check_call_funct   Constt   _check_format_string(   R-   R.   R   t
   format_post   binopt   _operand(    (    s6   lib/python2.7/site-packages/pylint/checkers/logging.pyRP      s&    '		$c         C   s   t  |  t j  o |  j d k S(   sL   
        Return True if the operand in argument is a literal string
        t   str(   R   R   Rb   R   (   t   operand(    (    s6   lib/python2.7/site-packages/pylint/checkers/logging.pyR^      s    c         C   sZ   t  j | j  } d } d } t | | |  rV t | j  rV |  j d d | n  d S(	   s   Checks that function call is not format_string.format().

        Args:
          node (astroid.node_classes.Call):
            Call AST node to be checked.
        Rg   t   unicodet   formats   logging-format-interpolationR.   N(   Rg   Ri   (   Rj   (   R   t
   safe_inferR   R   t   is_complex_format_strR   R_   (   R-   R.   R   R   R   (    (    s6   lib/python2.7/site-packages/pylint/checkers/logging.pyRa      s
    "c   	      C   s0  t  | j | d  } | s! d S| j | j } t | t j  sL d } n y# t j |  \ } } | rn d SWnv t j k
 r } | | j	 } |  j
 d d | d | t |  | j	 f d St j k
 r |  j
 d d | d SX| | k r
|  j
 d d | n" | | k  r,|  j
 d	 d | n  d S(
   s   Checks that format string tokens match the supplied arguments.

        Args:
          node (astroid.node_classes.NodeNG): AST node to be checked.
          format_arg (int): Index of the format string in the node arguments.
        i   Ni    s   logging-unsupported-formatR.   RX   s   logging-format-truncateds   logging-too-many-argss   logging-too-few-args(   t   _count_supplied_tokensRX   t   valueR   t   sixt   string_typesR   t   parse_format_stringt   UnsupportedFormatCharactert   indexR_   t   ordt   IncompleteFormatString(	   R-   R.   t
   format_argt   num_argst   format_stringt   required_num_argst   keyword_argst   ext   char(    (    s6   lib/python2.7/site-packages/pylint/checkers/logging.pyRc      s,    	(   R   (   t   __name__t
   __module__t   __doc__R   t   IAstroidCheckert   __implements__R   t   MSGSt   msgst   optionsR2   R:   R;   R   t   keysRR   RP   t   staticmethodR^   Ra   Rc   (    (    (    s6   lib/python2.7/site-packages/pylint/checkers/logging.pyR   [   s"   	
		
			c         C   s   t  j |   } | d k s1 t | j t j  r5 t Sy" t t	 j
   j | j   } Wn t k
 rk t SXx$ | D] \ } } } } | rs t Sqs Wt S(   s   Checks if node represents a string with complex formatting specs.

    Args:
        node (astroid.node_classes.NodeNG): AST node to check
    Returns:
        bool: True if inferred string uses complex formatting, False otherwise
    N(   R   Rk   RL   R   Rn   Ro   Rp   R   t   listt   stringt	   Formattert   parset
   ValueErrorRK   (   R.   RM   t   parsedt   _t   format_spec(    (    s6   lib/python2.7/site-packages/pylint/checkers/logging.pyRl      s    ""c         C   s   t  d   |  D  S(   s|  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(   i   N(   R   R   t   Keyword(   RA   t   arg(    (    s6   lib/python2.7/site-packages/pylint/checkers/logging.pys	   <genexpr>"  s    (   t   sum(   RX   (    (    s6   lib/python2.7/site-packages/pylint/checkers/logging.pyRm     s    c         C   s   |  j  t |    d S(   s.   Required method to auto-register this checker.N(   t   register_checkerR   (   t   linter(    (    s6   lib/python2.7/site-packages/pylint/checkers/logging.pyt   register%  s    (   s>   Specify string format arguments as logging function parameterss   logging-not-lazys  Used when a logging statement has a call form of "logging.<logging method>(format_string % (format_args...))". Such calls should leave string interpolation to the logging method itself and be written "logging.<logging method>(format_string, format_args...)" so that the program may avoid incurring the cost of the interpolation in those cases in which no message will be logged. For more, see http://www.python.org/dev/peps/pep-0282/.(   sL   Use % formatting in logging functions and pass the % parameters as argumentss   logging-format-interpolations   Used when a logging statement has a call form of "logging.<logging method>(format_string.format(format_args...))". Such calls should use % formatting instead, but leave interpolation to the logging function by passing the parameters as arguments.(   s;   Unsupported logging format character %r (%#02x) at index %ds   logging-unsupported-formatsd   Used when an unsupported format character is used in a logging              statement format string.(   s<   Logging format string ends in middle of conversion specifiers   logging-format-truncatedsm   Used when a logging statement format string terminates before              the end of a conversion specifier.(   s,   Too many arguments for logging format strings   logging-too-many-argss>   Used when a logging format string is given too many arguments.(   s.   Not enough arguments for logging format strings   logging-too-few-argss=   Used when a logging format string is given too few arguments.(    (    (   R   R   Ro   R   t   pylintR    R   t   pylint.checkersR   t   pylint.checkers.utilsR   R   RY   R   t   BaseCheckerR   Rl   Rm   R   (    (    (    s6   lib/python2.7/site-packages/pylint/checkers/logging.pyt   <module>   s@     	          
		