
    eD@                    N   d Z ddlmZ ddlZddlZddlmZ ddlmZmZ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lZdd
lmZmZmZmZmZmZ dZd.dZ	 	 	 	 d/dZ	 	 	 	 	 	 d0dZ e       Z G d de      Z  G d de      Z! G d d e      Z" G d! d"e"      Z# G d# d$e"      Z$ G d% d&e      Z% ejL                  d'      Z'd1d(Z( G d) d*e      Z)d2d+Z*y# e$ rH dZdZ G d d      Z G d d      Z G d d      Z G d d      Z G d d      Z	 	 	 d,	 	 	 	 	 	 	 d-dZY w xY w)3z7Checker for spelling errors in comments and docstrings.    )annotationsN)Pattern)TYPE_CHECKINGAnyLiteral)nodes)BaseTokenChecker)only_required_for_messages)PyLinter)ChunkerEmailFilterFilter	URLFilterWikiWordFilterget_tokenizerTFc                      e Zd Zy)r   N__name__
__module____qualname__     :/usr/lib/python3/dist-packages/pylint/checkers/spelling.pyr   r   &       r   r   c                      e Zd Zy)r   Nr   r   r   r   r   r   )   r   r   r   c                      e Zd Zy)r   Nr   r   r   r   r   r   ,   r   r   r   c                      e Zd ZddZy)r   c                    t         N)NotImplementedErrorselfwords     r   _skipzFilter._skip0   s    %%r   Nr#   strreturnbool)r   r   r   r$   r   r   r   r   r   /   s    	&r   r   c                      e Zd Zy)r   Nr   r   r   r   r   r   3   s    r   r   c                    t               S r   )r   )tagchunkersfilterss      r   r   r   6   s    
 xr   c                 V    t         r"t        j                         j                         S g S r   )PYENCHANT_AVAILABLEenchantBroker
list_dictsr   r   r   _get_enchant_dictsr3   >   s    ,?7>>&&(GRGr   c                :    dg| D cg c]  }|d   	 c}z   S c c}w )N r   r   )inner_enchant_dictsds     r   _get_enchant_dict_choicesr8   C   s$     4!45A1Q45555s   c                    | r:| D cg c]  }|d    d|d   j                    d }}ddj                  |       }nd}|s|dz  }|d	z  }d
| dS c c}w )Nr   z (   )zAvailable dictionaries: z, z0No available dictionaries : You need to install zboth the python package and z)the system dependency for enchant to workzSpelling dictionary name. .)namejoin)r6   pyenchant_availabler7   dict_as_strenchant_helps        r   _get_enchant_dict_helprB   I   s|     8KL1!A$r!A$))A.LL1$))K2H1IJI"::LCC'~Q77 Ms   Ac                      e Zd ZdZddZy)WordsWithDigitsFilterzSkips words with digits.c                &    t        d |D              S )Nc              3  <   K   | ]  }|j                           y wr   )isdigit).0chars     r   	<genexpr>z.WordsWithDigitsFilter._skip.<locals>.<genexpr>_   s     3d4<<>3s   )anyr!   s     r   r$   zWordsWithDigitsFilter._skip^   s    3d333r   Nr%   r   r   r   __doc__r$   r   r   r   rD   rD   [   s
    "4r   rD   c                      e Zd ZdZddZy)WordsWithUnderscoreszSSkips words with underscores.

    They are probably function parameter names.
    c                
    d|v S )N_r   r!   s     r   r$   zWordsWithUnderscores._skiph   s    d{r   Nr%   rL   r   r   r   rO   rO   b   s    
r   rO   c                  $    e Zd ZU dZded<   ddZy)RegExFilterzParent class for filters using regular expressions.

    This filter skips any words the match the expression
    assigned to the class attribute ``_pattern``.
    zPattern[str]_patternc                J    t        | j                  j                  |            S r   )r(   rT   matchr!   s     r   r$   zRegExFilter._skipu   s    DMM''-..r   Nr%   )r   r   r   rM   __annotations__r$   r   r   r   rS   rS   l   s     /r   rS   c                  4    e Zd ZdZ ej
                  d      Zy)CamelCasedWordzFilter skipping over camelCasedWords.
    This filter skips any words matching the following regular expression:

           ^([a-z]\w+[A-Z]+\w+)

    That is, any words that are camelCasedWords.
    z^([a-z]+(\d|[A-Z])(?:\w+)?)Nr   r   r   rM   recompilerT   r   r   r   rY   rY   y   s     rzz89Hr   rY   c                  4    e Zd ZdZ ej
                  d      Zy)SphinxDirectiveszFilter skipping over Sphinx Directives.
    This filter skips any words matching the following regular expression:

           ^(:([a-z]+)){1,2}:`([^`]+)(`)?

    That is, for example, :class:`BaseQuery`
    z^(:([a-z]+)){1,2}:`([^`]+)(`)?NrZ   r   r   r   r^   r^      s     rzz;<Hr   r^   c                  ,    e Zd ZU dZded<   ddZddZy)	ForwardSlashChunkerz[This chunker allows splitting words like 'before/after' into 'before' and
    'after'.
    r&   _textc                l   	 | j                   s
t               d| j                   vr| j                   }d| _        d| _         |dfS | j                   j                  dd      \  }}|| _         d| _        |r(|r&|d   j	                         r|d   j	                         sd| _         d| _        | d| dfS |dfS )N/r   r5   r:   )ra   StopIteration_offsetsplitisalpha)r"   textpre_text	post_texts       r   nextzForwardSlashChunker.next   s    ::#o%$**$zz 
Qw"&**"2"23":Hi"DJDL |++- |++-
 "1YK0!33Q;r   c                   	 d| j                   vr| j                   dfS | j                   j                  dd      \  }}|r|s	 t               |d   j                         r|d   j                         s
t               |dz   |z   | _         )Nrc   r   r:   rd    )ra   rg   rh   re   )r"   rj   rk   s      r   _nextzForwardSlashChunker._next   s    $**$zz1}$"&**"2"23":Hi9 o B<'')11E1E1G#o%!C)3DJ r   N)r'   ztuple[str, int])r'   ztuple[str, Literal[0]])r   r   r   rM   rW   rl   ro   r   r   r   r`   r`      s     J.
r   r`   z!(\s|^)(`{1,2})([^`]+)(\2)([^`]|$)c                6    dd}t         j                  ||       S )zAlter line so code flanked in back-ticks is ignored.

    Pyenchant automatically strips back-ticks when parsing tokens,
    so this cannot be done at the individual filter level.
    c                H    | j                  d      | j                  d      z   S )Nr:      )group)	match_objs    r   -replace_code_but_leave_surrounding_characterszW_strip_code_flanked_in_backticks.<locals>.replace_code_but_leave_surrounding_characters   s    q!IOOA$666r   )rt   zre.Match[str]r'   r&   )CODE_FLANKED_IN_BACKTICK_REGEXsub)lineru   s     r    _strip_code_flanked_in_backticksry      s!    7 *--5t r   c                  .   e Zd ZdZdZddddZddd	d
 ee       eee	      dfddddddfddddddfddddddfddddddfdd ddd!dffZ
d+d"Zd,d#Zd-d$Z ed%      d.d&       Z ed%      d/d'       Z ed%      	 	 	 	 d0d(       ZeZ	 	 	 	 d1d)Zy*)2SpellingCheckerz*Check spelling in comments and docstrings.spelling)zEWrong spelling of a word '%s' in a comment:
%s
%s
Did you mean: '%s'?wrong-spelling-in-commentz5Used when a word in comment is not spelled correctly.)zGWrong spelling of a word '%s' in a docstring:
%s
%s
Did you mean: '%s'?wrong-spelling-in-docstringz7Used when a word in docstring is not spelled correctly.)z$Invalid characters %r in a docstringinvalid-characters-in-docstringz;Used when a word in docstring cannot be checked by enchant.)C0401C0402C0403zspelling-dictr5   choicez<dict name>)defaulttypemetavarchoiceshelpzspelling-ignore-wordsstringz<comma separated words>z9List of comma separated words that should not be checked.)r   r   r   r   zspelling-private-dict-filepathz<path to file>zIA path to a file that contains the private dictionary; one word per line.zspelling-store-unknown-wordsnynz<y or n>zTells whether to store unknown words to the private dictionary (see the --spelling-private-dict-file option) instead of raising a message.zmax-spelling-suggestions   intNz:Limits count of emitted suggestions for spelling mistakes.z"spelling-ignore-comment-directivesz2fmt: on,fmt: off,noqa:,noqa,nosec,isort:skip,mypy:zList of comma separated words that should be considered directives if they appear at the beginning of a comment and should not be checked.c                   d| _         t        sy | j                  j                  j                  }|sy | j                  j                  j
                  j                  d      D cg c]  }|j                          c}| _        | j                  j                  ddg       | j                  j                  j                  j                  d      D cg c]  }|j                          c}| _        | j                  j                  j                  r:t        j                  || j                  j                  j                        | _        nt        j                  |      | _        | j                  j                  j                   rt#               | _        t'        |t(        gt*        t,        t.        t0        t2        t4        t6        g      | _        d| _         y c c}w c c}w )NF,parampylint)r,   r-   T)initializedr/   linterconfigspelling_dictspelling_ignore_wordsrg   stripignore_listextend"spelling_ignore_comment_directivesignore_comment_directive_listspelling_private_dict_filer0   DictWithPWLDictspelling_store_unknown_wordssetunknown_wordsr   r`   r   r   r   rD   rO   rY   r^   	tokenizer)r"   	dict_namews      r   openzSpellingChecker.open$  sq    "KK&&44	  ${{11GGMMcR
AGGI

 	( 34 [[''JJPPQTU.
 GGI.
*
 ;;88!(!4!44;;--HH"D ")i!8D;;::+.5D&)*%$ 
  G
.
s   #GGc                X   |}	 t        j                  d|      j                  d   d   }|j                         j                  d      rRd|vrN|j                         dd  }| j                  D ])  }|j                  d|z         s|t        |      dz   d  } n d}nd}t        |      }| j                  |j                               D ]  \  }}	|	|z  }	|j                         }
|| j                  v s|
| j                  v r9|j                  d	      rt        |      d
kD  r
|d
d  }|
d
d  }
	 | j                  j                  |
      r| j                  j                  |      r	 | j&                  j(                  j*                  ru|
| j,                  vst/        | j&                  j(                  j0                  dd      5 }|j3                  |
 d       d d d        | j,                  j5                  |
       1| j                  j7                  |      }|| j&                  j(                  j8                  d = ||	d  }t        j                  d| d|      }|r|j                  d
   d   }n|j;                  |      }||	z  }|r|dz  }d|z  dt        |      z  z   }dj=                  |      }|||d| df}| j%                  |||        y # t        t        f$ r d}Y w xY w# t        j                   j"                  $ r | j%                  d||f       Y Tw xY w# 1 sw Y   NxY w)Nz^\s+r   r:   #	docstringrn   TF)zu'zu"zr'zr"   r   )rx   argsazutf-8)encoding
z(\W|^)(z)(\W|$)^z' or '')r[   searchregs
IndexErrorAttributeErrorr   
startswithr   lenry   r   casefoldr   r   checkr0   errorsErroradd_messager   r   r   r   r   r   writeaddsuggestmax_spelling_suggestionsindexr>   )r"   msgidrx   line_numoriginal_lineinitial_spaceiter_directivestarts_with_commentr#   word_start_atlower_cased_wordfsuggestionsline_segmentrV   col	indicatorall_suggestionr   s                      r   _check_spellingzSpellingChecker._check_spellingR  sC   	IIgt499!<Q?M ::<""3'Ku,D::<#D #'"D"D ??3#78^!4q!8 ;<D #'"'/5#'>>$**,#? 9	BD-]*M#}} t'''+;t?O?O+O 78SY]ABx#3AB#7 %%++,<=
 %%++D1 2 {{!!>>#4+=+==**EE!( 9 #3"4B 789 &&**+;< #0088> 2 2 K K MN#MN3		WTF'":LI**Q-*C&,,T2C}$&1HC 3Y3T?;	!){!;mY!N;K18MN  XD As9	B# N+ 	M	R >>''   5HD7 !  	9 9s5   &K *K&K&>LK#"K#&2LLL)	c                   | j                   sy |D ]m  \  }}\  }}}}|t        j                  k(  s |dk(  r|j                  d      r7|j                  d      rI|j                  d      r[| j	                  d||       o y )Nr:   z#!/z	# pylint:z# type: r}   )r   tokenizeCOMMENTr   r   )r"   tokenstok_typetoken	start_rowrQ   s         r   process_tokenszSpellingChecker.process_tokens  s     6< 	T1He^iQ8+++>e&6&6u&=##K0##J/ $$%@%S	Tr   r~   c                &    | j                  |       y r   _check_docstringr"   nodes     r   visit_modulezSpellingChecker.visit_module      d#r   c                &    | j                  |       y r   r   r   s     r   visit_classdefzSpellingChecker.visit_classdef  r   r   c                &    | j                  |       y r   r   r   s     r   visit_functiondefz!SpellingChecker.visit_functiondef  s     	d#r   c                    | j                   sy|j                  sy|j                  dz   }t        |j                  j                  j                               D ]  \  }}| j                  d|||z           y)z*Check if the node has any spelling errors.Nr:   r~   )r   doc_nodelineno	enumeratevalue
splitlinesr   )r"   r   
start_lineidxrx   s        r   r   z SpellingChecker._check_docstring  sm     }}[[1_
"4==#6#6#A#A#CD 	XIC  !>jSVFVW	Xr   N)r'   None)r   r&   rx   r&   r   r   r'   r   )r   zlist[tokenize.TokenInfo]r'   r   )r   znodes.Moduler'   r   )r   znodes.ClassDefr'   r   )r   z*nodes.FunctionDef | nodes.AsyncFunctionDefr'   r   )r   zJnodes.FunctionDef | nodes.AsyncFunctionDef | nodes.ClassDef | nodes.Moduler'   r   )r   r   r   rM   r=   msgsr8   enchant_dictsrB   r/   optionsr   r   r   r
   r   r   r   visit_asyncfunctiondefr   r   r   r   r{   r{      sw   4D


D*  (4]C.}>QR		
 $ 4S		
 )+1			
 +%%		
 'T		
 1O 4-	
	
g>G@+ \OBbT&   =>$ ?$   =>$ ?$   =>$>$	$ ?$
 /XX 
Xr   r{   c                8    | j                  t        |              y r   )register_checkerr{   )r   s    r   registerr     s    
OF34r   )NNN)r+   z
str | Noner,   zlist[Chunker] | Noner-   zlist[Filter] | Noner'   r   )r'   &list[tuple[Any, enchant.ProviderDesc]])r6   r   r'   z	list[str])r6   r   r?   r(   r'   r&   )rx   r&   r'   r&   )r   r   r'   r   )+rM   
__future__r   r[   r   r   typingr   r   r   astroidr   pylint.checkersr	   pylint.checkers.utilsr
   pylint.lintr   r0   enchant.tokenizer   r   r   r   r   r   r/   ImportErrorr3   r8   rB   r   rD   rO   rS   rY   r^   r`   r\   rv   ry   r{   r   r   r   r   <module>r      s  
 > " 	   . .  , <$%  :H
6?668?88 	8 #$4F 46 
/& 
/:[ :	={ 	=(' (V ",,P!Q HX& HXV5m  G   & &  )-'+& % 
	)s   C A
D$#D$