B
    A!p\{                 @   s`  d Z ddlZddlZddlZddlZddlmZ ddlZddlm	Z	 ddl
mZ ddlmZmZmZ ddlmZmZ ddlmZ dd	lmZ d
Zejdd dkZejdd dkZddddddddddddddddddd Zejejejejejejej fZ!ej"d! Z#ej"d" Z$ej"d# Z%d$d% Z&d&d' Z'G d(d) d)eZ(G d*d+ d+eZ)d,d- Z*d.d/ Z+dS )0z*Checker for string formatting operations.
    N)Counter)CallSite)Const)ITokenCheckerIAstroidCheckerIRawChecker)BaseCheckerBaseTokenChecker)utils)check_messages)z__builtin__.unicodez__builtin__.strzbuiltins.str   )   r   )r      )z3Unsupported format character %r (%#02x) at index %dzbad-format-characterzEUsed when an unsupported format character is used in a format string.)z4Format string ends in middle of conversion specifierztruncated-format-stringzNUsed when a format string terminates before the end of a conversion specifier.)z?Mixing named and unnamed conversion specifiers in format stringzmixed-format-stringzUsed when a format string contains both named (e.g. '%(foo)d') and unnamed (e.g. '%d') conversion specifiers.  This is also used when a named conversion specifier contains * for the minimum field width and/or precision.)z*Expected mapping for format string, not %szformat-needs-mappingzoUsed when a format string that uses named conversion specifiers is used with an argument that is not a mapping.)z7Format string dictionary key should be a string, not %szbad-format-string-keyzyUsed when a format string that uses named conversion specifiers is used with a dictionary whose keys are not all strings.)z)Unused key %r in format string dictionaryzunused-format-string-keyzUsed when a format string that uses named conversion specifiers is used with a dictionary that contains keys not required by the format string.)z*Missing key %r in format string dictionaryzmissing-format-string-keyzUsed when a format string that uses named conversion specifiers is used with a dictionary that doesn't contain all the keys required by the format string.)z$Too many arguments for format stringztoo-many-format-argsz^Used when a format string that uses unnamed conversion specifiers is given too many arguments.)z&Not enough arguments for format stringztoo-few-format-argsz\Used when a format string that uses unnamed conversion specifiers is given too few arguments)z)Argument %r does not match format type %rzbad-string-format-typezSUsed when a type required by format string is not suitable for actual argument type)z!Suspicious argument in %s.%s callzbad-str-strip-callzGThe argument to a str.{l,r,}strip call contains a duplicate character, )zInvalid format stringzbad-format-stringz.Used when a PEP 3101 format string is invalid.)z-Missing keyword argument %r for format stringzmissing-format-argument-keyzhUsed when a PEP 3101 format string that uses named fields doesn't receive one or more required keywords.)zUnused format argument %rzunused-format-string-argumentz}Used when a PEP 3101 format string that uses named fields is used with an argument that is not required by the format string.)zTFormat string contains both automatic field numbering and manual field specificationzformat-combined-specificationzUsed when a PEP 3101 format string contains both automatic field numbering (e.g. '{}') and manual field specification (e.g. '{0}').)z2Missing format attribute %r in format specifier %rzmissing-format-attributezUsed when a PEP 3101 format string uses an attribute specifier ({0.length}), but the argument passed for formatting doesn't have that attribute.)z2Using invalid lookup key %r in format specifier %rzinvalid-format-indexzUsed when a PEP 3101 format string uses a lookup specifier ({a[1]}), but the argument passed for formatting doesn't contain or doesn't have that key as an attribute.)zKDuplicate string formatting argument %r, consider passing as named argumentz$duplicate-string-formatting-argumentzmUsed when we detect that a string formatting is repeating an argument instead of using named string arguments)ZE1300ZE1301ZE1302ZE1303ZW1300ZW1301ZE1304ZE1305ZE1306ZE1307ZE1310ZW1302ZW1303ZW1304ZW1305ZW1306ZW1307ZW1308z.strz.floatz.intc             C   sN   g }x6|D ].\}}|r(| d| q
| d| q
W t| d| S )z^ Given a list of format specifiers, returns
    the final access path (e.g. a.b.c[0][1]).
    z.{}z[{!r}] )appendformatstrjoin)keypartspathis_attribute	specifier r   6lib/python3.7/site-packages/pylint/checkers/strings.pyget_access_path   s    r   c             C   sT   |dkrdS t | tjrP|  } | tkr0|dkS | tkr@|dkS | tkrLdS dS dS )NsrTcz	deEfFgGn%F)
isinstanceastroidInstancepytypeBUILTINS_STRBUILTINS_FLOATBUILTINS_INT)arg_typeformat_typer   r   r   arg_matches_format_type   s    r'   c               @   sV   e Zd ZdZefZdZeZe	e dd Z
e	e dd Zdd Zd	d
 Zdd ZdS )StringFormatCheckerzChecks string formatting operations to ensure that the format string
    is valid and the arguments match the format string.
    stringc          
   C   s`  |j dkrd S |j}|j}t|tjr2t|jts6d S |j}yt	|\}}}}W nl tj
k
r }	 z*||	j }
| jd||
t|
|	jfd d S d }	~	X Y n$ tjk
r   | jd|d d S X |r|r| jd|d n|rZt|tjr*t }d}xV|jD ]L\}}t|tjrF|j}t|tr4|| n| jd||d nd	}q W |sx(|D ] }||kr\| jd
||d q\W x(|D ] }||kr| jd||d qW x|jD ]r\}}t|tjs̐q||jd }t|}|d k	r|d tjfkrt||s| jd|| |fd qW n,t|ttjfr\t|j}| jd||d nd}t|tjrt|}d }t|dr|j}t|}n(t|ttjtjffr|g}d}nd }|d k	r\||kr| jd|d n||k r| jd|d x`t ||D ]R\}}|sqt|}|d tjfkrt||s| jd|| |fd qW d S )N%zbad-format-character)nodeargsztruncated-format-string)r+   zmixed-format-stringFzbad-format-string-keyTzmissing-format-string-keyzunused-format-string-keyzbad-string-format-typezformat-needs-mappingr   elts   ztoo-many-format-argsztoo-few-format-args)!opleftrightr   r   r   valuer   r
   Zparse_format_stringZUnsupportedFormatCharacterindexadd_messageordIncompleteFormatStringZDictsetitemsaddget
safe_inferUninferabler'   r!   OTHER_NODESZTupletype__name__hasattrr-   lenZDictCompzip)selfr+   r0   r,   format_stringZrequired_keysZrequired_num_argsZrequired_key_typesZrequired_arg_typeser   keysZunknown_keysk_r   argr&   r%   Z	type_nameZ	args_eltsZ	rhs_tuplenum_argsr   r   r   visit_binop   s    
















zStringFormatChecker.visit_binopc             C   s   t |j}t|tjrt|jtjr|jjdkr|jdkr|j	rt |j	d }t|tj
rjt|jtsnd S t|jtt|jkr| jd||jj|jfd n|jdkr| || d S )N)r   Zunicodebytes)striplstriprstripr   zbad-str-strip-call)r+   r,   r   )r
   r;   funcr   r   ZBoundMethodboundr    namer,   r   r2   r   rA   r7   r4   _check_new_format)rC   r+   rP   rI   r   r   r   
visit_callR  s    
zStringFormatChecker.visit_callc             C   sH   t dd |D }x0| D ]$\}}|dkr.q| jd||fd qW d S )Nc             s   s    | ]}t |tjr|jV  qd S )N)r   r   NamerR   ).0rI   r   r   r   	<genexpr>i  s    zAStringFormatChecker._detect_vacuous_formatting.<locals>.<genexpr>r.   z$duplicate-string-formatting-argument)r+   r,   )r   r8   r4   )rC   r+   positional_argumentsZcounterrR   countr   r   r   _detect_vacuous_formattingg  s    z.StringFormatChecker._detect_vacuous_formattingc             C   s6  t |jtjr"t |jjtjs"dS |js.|jr2dS yt|j	
 }W n tjk
rZ   dS X t |tjrtt |jtsxdS yt|}W n tjk
r   dS X yt|j\}}}W n$ tjk
r   | jd|d dS X |j}|j}	dd |D }
|r|r| jd|d dS d}|tdd	 |
D 7 }|
rx0|
D ](}|r8||	kr8| jd
||fd q8W x*|	D ]"}||
krj| jd||fd qjW |p|}|s|rtdd	 |
D }|	s|rd}nd}|r|p|}t||kr| jd|d nt||k r| jd|d | || | |||	 dS )z" Check the new string formatting. Nzbad-format-string)r+   c             S   s"   h | ]}t |d  tr|d  qS )r   )r   r   )rV   fieldr   r   r   	<setcomp>  s    z8StringFormatChecker._check_new_format.<locals>.<setcomp>zformat-combined-specificationFc             s   s   | ]}|d krdV  qdS )r   r.   Nr   )rV   r[   r   r   r   rW     s    z8StringFormatChecker._check_new_format.<locals>.<genexpr>zmissing-format-argument-key)r+   r,   zunused-format-string-argumentc             s   s   | ]}|d krdV  qdS )r   TNr   )rV   r[   r   r   r   rW     s    Tztoo-many-format-argsztoo-few-format-args)r   rP   r   Z	Attributeexprr   ZstarargskwargsnextrQ   inferInferenceErrorr2   r   r   Z	from_callr
   Zparse_format_method_stringr6   r4   rX   Zkeyword_argumentssumanyrA   rZ   _check_new_format_specifiers)rC   r+   rP   ZstrnodeZ	call_sitefieldsrJ   Z
manual_posrX   Znamed_argumentsZnamed_fieldsZ
check_argsr[   emptyr   r   r   rS   r  sh    




z%StringFormatChecker._check_new_formatc             C   sh  x`|D ]V\}}|dkrd}t |tjrVyt||}W qh tjk
rR   wY qhX n||kr`q|| }|tjdfkrxqyt|	 }W n tj
k
r   wY nX |r|tjkrq|jrt |jtjrq|}g }	x|D ]\}
}|tjkrP |	|
|f |
rhy||d }W nP tjk
rd   t|dr@| r@P t||	}| jd||f|d P Y nX nd}t|dry|t|}W n> tjtjtjfk
r   d	}Y n tj
k
r   P Y nX |tjkr
P n.y|d
 P W n tjk
r   d	}Y nX |r0t||	}| jd||f|d P yt|	 }W q tj
k
rZ   P Y qX qW qW dS )zg
        Check attribute and index access in the format
        string ("{0.a}" and "{0[a]}").
        r   r   Nhas_dynamic_getattrzmissing-format-attribute)r,   r+   FgetitemT__getitem__zinvalid-format-index)r   numbersNumberr
   Zget_argument_from_callZNoSuchArgumentErrorr   r<   r_   r`   ra   parentZ	Argumentsr   getattrZNotFoundErrorr@   rg   r   r4   rh   r   ZAstroidIndexErrorZAstroidTypeErrorZAttributeInferenceError)rC   r+   re   Znamedr   Z
specifiersargnameZargumentZpreviousZparsedr   r   r   Z
warn_errorr   r   r   rd     s    







z0StringFormatChecker._check_new_format_specifiersN)r?   
__module____qualname____doc__r   __implements__rR   MSGSmsgsr   rK   rT   rZ   rS   rd   r   r   r   r   r(      s   zSr(   c                   s   e Zd ZdZeeefZdZddddZ	ddd	d
ddffZ
dZdZ fddZdd Zdd Zee	  dd Zee	  dd Zee	  dd Zdd Zdd Zdd  Z  ZS )!StringConstantCheckerzCheck string literalsr)   )zRAnomalous backslash in string: '%s'. String constant might be missing an r prefix.zanomalous-backslash-in-stringzBUsed when a backslash is in a literal string but not as an escape.)zaAnomalous Unicode escape in byte string: '%s'. String constant might be missing an r or u prefix.z"anomalous-unicode-escape-in-stringzSUsed when an escape like \u is encountered in a byte string where it has no effect.)z)Implicit string concatenation found in %szimplicit-str-concat-in-sequenceziString literals are implicitly concatenated in a literal iterable definition : maybe a comma is missing ?)ZW1401ZW1402ZW1403z check-str-concat-over-line-jumpsFZynz<y_or_n>zThis flag controls whether the implicit-str-concat-in-sequence should generate a warning on implicit string concatenation in sequences defined over several lines.)defaultr>   metavarhelpzabfnrtvx
	\'"01234567ZuUNc                s   t t| j|| i | _d S )N)superru   __init__string_tokens)rC   r,   r^   )	__class__r   r   rz   [  s    zStringConstantChecker.__init__c             C   s   d|j k| _d S )NZunicode_literals)Zfuture_imports_unicode_literals)rC   moduler   r   r   process_module_  s    z$StringConstantChecker.process_modulec             C   s   d}xt |D ]\}\}}}}}|tjkr0|}q|tjkr| ||d  |d }	x2|	t|k r||	 jtjtjtj	fkr|	d7 }	qTW |	t|k r||	 nd }
|dkr|d t|d |d  
|f}t||
f| j|< qW d S )Nasciir   r.   )	enumeratetokenizeENCODINGSTRINGprocess_string_tokenrA   r>   NEWLINENLCOMMENTencodestr_evalr{   )rC   tokensencodingitok_typetokenstartrH   linej
next_tokenr   r   r   process_tokensb  s     


"z$StringConstantChecker.process_tokensc             C   s   |  |d d S )Nlist)check_for_concatenated_strings)rC   r+   r   r   r   
visit_list{  s    z StringConstantChecker.visit_listc             C   s   |  |d d S )Nr7   )r   )rC   r+   r   r   r   	visit_set  s    zStringConstantChecker.visit_setc             C   s   |  |d d S )Ntuple)r   )rC   r+   r   r   r   visit_tuple  s    z!StringConstantChecker.visit_tuplec             C   s   x|j D ]}t|tr| tkr|jdk r.q|j|jf| jkrBq| j|j|jf \}}||jkr|d k	r|j	t
jkr|jd |jks| jjr| jd|j|fd qW d S )Nr   zimplicit-str-concat-in-sequence)r   r,   )r-   r   r   r!   _AST_NODE_STR_TYPES
col_offsetlinenor{   r2   r>   r   r   r   ZconfigZ check_str_concat_over_line_jumpsr4   )rC   Ziterable_nodeZiterable_typeZeltZmatching_tokenr   r   r   r   r     s     
z4StringConstantChecker.check_for_concatenated_stringsc       	      C   s   d }d }x"t |D ]\}}|dkr|}P qW |d kr8d S |d |  }||d  }|d d |dd    kr|d| krn n|dd }n|dd }d|kr| ||| d S )Nz'"r   r.   r)r   lowerprocess_non_raw_string_token)	rC   r   	start_rowZ
quote_charr3   r   prefixZafter_prefixstring_bodyr   r   r   r     s    ,z*StringConstantChecker.process_string_tokenc             C   s   d}x| d|}|dkrP ||d  }|||d  }|| jkrtd|krLqtsV| jr`d|kr`q| jd||fd	 n|| jkr| jd
||fd	 |d7 }qW dS )a  check for bad escapes in a non-raw string.

        prefix: lowercase string of eg 'ur' string prefix markers.
        string_body: the un-parsed body of the string, not including the quote
        marks.
        start_row: integer line number in the source.
        r   \r   r.   r   ubz"anomalous-unicode-escape-in-string)r   r,   zanomalous-backslash-in-stringN)findUNICODE_ESCAPE_CHARACTERS_PY3Kr}   r4   ESCAPE_CHARACTERS)rC   r   r   r   r   Z	next_charmatchr   r   r   r     s(    

z2StringConstantChecker.process_non_raw_string_token)r?   ro   rp   rq   r   r   r   rr   rR   rt   Zoptionsr   r   rz   r   r   r   rF   r   r   r   r   r   r   __classcell__r   r   )r|   r   ru   &  s,   
	
ru   c             C   s    |  t|  |  t|  dS )z.required method to auto register this checker N)Zregister_checkerr(   ru   )Zlinterr   r   r   register  s    r   c             C   sf   | dd   dkr"| dd } n| d   dkr>| dd } | dd dkrZ| dd	 S | dd
 S )a%  
    Mostly replicate `ast.literal_eval(token)` manually to avoid any performance hit.
    This supports f-strings, contrary to `ast.literal_eval`.
    We have to support all string literal notations:
    https://docs.python.org/3/reference/lexical_analysis.html#string-and-bytes-literals
    r   r   )frZrfN)r   r   fr.   r   )z"""z'''r   r   )r   )r   r   r   r   r     s    r   ),rq   builtinssysr   rj   collectionsr   r   Zastroid.argumentsr   Zastroid.node_classesr   Zpylint.interfacesr   r   r   Zpylint.checkersr   r	   r
   Zpylint.checkers.utilsr   r   version_infor   Z_PY27rs   ZListZLambdaZFunctionDefZListCompZSetCompZGeneratorExpr=   r?   r"   r#   r$   r   r'   r(   ru   r   r   r   r   r   r   <module>   sh   


  Z C