o
    éT•j#,  ã                   @   sŒ   d Z dZddlZddlZddlZg d¢Zdadadd„ Zdd„ Z	G d	d
„ d
e
ƒZdd„ ZG dd„ dƒZdd„ Zdd„ ZedkrDe	ƒ  dS dS )a–  The Tab Nanny despises ambiguous indentation.  She knows no mercy.

tabnanny -- Detection of ambiguous indentation

For the time being this module is intended to be called as a script.
However it is possible to import it into an IDE and use the function
check() described below.

Warning: The API provided by this module is likely to change in future
releases; such changes may not be backward compatible.
Ú6é    N)ÚcheckÚNannyNagÚprocess_tokensc                  G   s6   d}| D ]}t j |t|ƒ ¡ d}qt j d¡ d S )NÚ ú Ú
)ÚsysÚstderrÚwriteÚstr)ÚargsÚsepÚarg© r   ú/usr/lib/python3.10/tabnanny.pyÚerrprint    s
   r   c               
   C   s¶   dd l } z|   tjdd … d¡\}}W n | jy+ } zt|ƒ W Y d }~d S d }~ww |D ]\}}|dkr:td a|dkrBtd aq.|sPtdtjd dƒ d S |D ]}t|ƒ qRd S )Nr   é   Úqvz-qz-vzUsage:z[-v] file_or_directory ...)Úgetoptr	   ÚargvÚerrorr   Úfilename_onlyÚverboser   )r   Úoptsr   ÚmsgÚoÚar   r   r   r   Úmain'   s(   €þ€
ÿr   c                   @   s0   e Zd ZdZdd„ Zdd„ Zdd„ Zdd	„ Zd
S )r   zk
    Raised by process_tokens() if detecting an ambiguous indent.
    Captured and handled in check().
    c                 C   s   |||| _ | _| _d S ©N)Úlinenor   Úline)Úselfr    r   r!   r   r   r   Ú__init__@   s   zNannyNag.__init__c                 C   ó   | j S r   )r    ©r"   r   r   r   Ú
get_linenoB   ó   zNannyNag.get_linenoc                 C   r$   r   )r   r%   r   r   r   Úget_msgD   r'   zNannyNag.get_msgc                 C   r$   r   )r!   r%   r   r   r   Úget_lineF   r'   zNannyNag.get_lineN)Ú__name__Ú
__module__Ú__qualname__Ú__doc__r#   r&   r(   r)   r   r   r   r   r   ;   s    r   c           	   
   C   sN  t j | ¡rDt j | ¡sDtrtd| f ƒ t  | ¡}|D ]%}t j | |¡}t j |¡r1t j |¡r=t j |dd… ¡dkrAt	|ƒ qdS zt
 | ¡}W n tyf } ztd| |f ƒ W Y d}~dS d}~ww tdkrqtd|  ƒ z¢z
tt
 |j¡ƒ W n‘ t
jy� } ztd| |f ƒ W Y d}~W | ¡  dS d}~w ty¼ } ztd	| |f ƒ W Y d}~W | ¡  dS d}~w t�y } zE| ¡ }| ¡ }trätd
| |f ƒ td|f ƒ t| ¡ ƒ nd| v rîd|  d } trõt| ƒ nt| |t|ƒƒ W Y d}~W | ¡  dS d}~ww W | ¡  n| ¡  w t�r%td| f ƒ dS dS )a~  check(file_or_dir)

    If file_or_dir is a directory and not a symbolic link, then recursively
    descend the directory tree named by file_or_dir, checking all .py files
    along the way. If file_or_dir is an ordinary Python source file, it is
    checked for whitespace related problems. The diagnostic messages are
    written to standard output using the print statement.
    z%r: listing directoryéýÿÿÿNz.pyz%r: I/O Error: %sr   zchecking %r ...z%r: Token Error: %sz%r: Indentation Error: %sz)%r: *** Line %d: trouble in tab city! ***zoffending line: %rr   ú"z%r: Clean bill of health.)ÚosÚpathÚisdirÚislinkr   ÚprintÚlistdirÚjoinÚnormcaser   ÚtokenizeÚopenÚOSErrorr   r   Úgenerate_tokensÚreadlineÚ
TokenErrorÚcloseÚIndentationErrorr   r&   r)   r(   r   Úrepr)	ÚfileÚnamesÚnameÚfullnameÚfr   ÚnagÚbadliner!   r   r   r   r   I   sj   


ÿ€€þ€î€ò€òöÿr   c                   @   sL   e Zd Zd\ZZdd„ Zdd„ Zdd„ Zdd	„ Zd
d„ Z	dd„ Z
dd„ ZdS )Ú
Whitespacez 	c           	      C   sÊ   || _ tjtj}}g }d } }}| j D ]9}||kr$|d }|d }q||krN|d }|d }|t|ƒkrC|dg|t|ƒ d   }|| d ||< d}q || _|| _t|ƒ|f| _t|ƒdk| _	d S )Nr   r   )
ÚrawrH   ÚSÚTÚlenÚnÚntÚtupleÚnormÚ	is_simple)	r"   ÚwsrJ   rK   ÚcountÚbrM   rN   Úchr   r   r   r#   �   s(   

zWhitespace.__init__c                 C   s   | j \}}tt|ƒd |ƒS ©Nr   )rP   ÚmaxrL   )r"   rS   Útrailingr   r   r   Úlongest_run_of_spaces¶   s   
z Whitespace.longest_run_of_spacesc                 C   sH   | j \}}d}t|t|ƒƒD ]}||| ||   }q|||| j   S )Nr   )rP   ÚrangerL   rN   )r"   ÚtabsizerS   rX   ÚilÚir   r   r   Úindent_levelº   s
   
zWhitespace.indent_levelc                 C   s   | j |j kS r   )rP   )r"   Úotherr   r   r   ÚequalÑ   s   zWhitespace.equalc                 C   sb   t |  ¡ | ¡ ƒd }g }td|d ƒD ]}|  |¡| |¡kr.| ||  |¡| |¡f¡ q|S rV   ©rW   rY   rZ   r^   Úappend©r"   r_   rM   r   Útsr   r   r   Únot_equal_witnessØ   ó   ÿÿþ€zWhitespace.not_equal_witnessc                 C   sp   | j |j krdS | jr|jr| j|jkS t|  ¡ | ¡ ƒd }td|d ƒD ]}|  |¡| |¡kr5 dS q&dS )NFr   é   T)rM   rQ   rN   rW   rY   rZ   r^   )r"   r_   rM   rd   r   r   r   Úlessð   s   ÿÿÿzWhitespace.lessc                 C   sb   t |  ¡ | ¡ ƒd }g }td|d ƒD ]}|  |¡| |¡kr.| ||  |¡| |¡f¡ q|S rV   ra   rc   r   r   r   Únot_less_witness  rf   zWhitespace.not_less_witnessN)r*   r+   r,   rJ   rK   r#   rY   r^   r`   re   rh   ri   r   r   r   r   rH   †   s    rH   c                 C   s8   dd„ | D ƒ}d}t | ƒdkr|d }|d d |¡ S )Nc                 s   s   � | ]	}t |d  ƒV  qdS )r   N)r   )Ú.0Útupr   r   r   Ú	<genexpr>  s   € z#format_witnesses.<locals>.<genexpr>zat tab sizer   Úsr   z, )rL   r6   )ÚwÚfirstsÚprefixr   r   r   Úformat_witnesses  s
   rq   c                 C   s  t j}t j}t j}t jt jf}tdƒg}d}| D ]l\}}}	}
}||kr&d}q||krRd}t|ƒ}|d  |¡sL|d  |¡}dt	|ƒ }t
|	d ||ƒ‚| |¡ q||kr\d}|d= q|r„||vr„d}t|ƒ}|d  |¡s„|d  |¡}dt	|ƒ }t
|	d ||ƒ‚qd S )Nr   r   r   éÿÿÿÿzindent not greater e.g. zindent not equal e.g. )r8   ÚINDENTÚDEDENTÚNEWLINEÚCOMMENTÚNLrH   rh   ri   rq   r   rb   r`   re   )Útokensrs   rt   ru   ÚJUNKÚindentsÚcheck_equalÚtypeÚtokenÚstartÚendr!   ÚthisguyÚwitnessr   r   r   r   r     s:   

€Ôr   Ú__main__)r-   Ú__version__r0   r	   r8   Ú__all__r   r   r   r   Ú	Exceptionr   r   rH   rq   r   r*   r   r   r   r   Ú<module>   s&   = 7
ÿ