B
    .KcG              
   @   s  U d Z ddlZddlZddlmZ ddlmZ ddlmZm	Z	m
Z
mZmZmZmZmZmZmZ ddlmZ ddlmZ ddlmZ dd	lmZ dd
lmZ ddlmZ e	rddlmZ dZ dZ!edd Z"ee#e$f e%d< e"&ej'ej'ej(ej)ej*e!ej+d edd Z,ee$e$f e%d< e,&ej*e!ej+d edd ej(dej)dej+diZ-e#ddddZ.eej/ dddd Z0G d!d" d"ej/Z1G d#d$ d$e1Z2G d%d& d&e1Z3G d'd dej4Z5G d(d) d)ej6Z7G d*d+ d+ej6Z8G d,d- d-ej9j:Z;eeej<ddf d.d/d0Z=eee;ddf d.d1d2Z>eee;ddf d.d3d4Z?edae@ed6 d7d8d9ZAee#ed6 d:d;d<ZBG d=d> d>ZCG d?d@ d@ejDZEe#e#ee# e@dAdBdCZFG dDdE dEejDZGG dFdG dGejDZHG dHdI dIejDZIG dJdK dKejDZJG dLdM dMejDZKG dNdO dOejDZLG dPdQ dQeLZMG dRdS dSeLZNeee# dTdUdVZOG dWdX dXejPZQG dYdZ dZZRG d[d\ d\ZSd]eedd^d_d`ZTdS )bz%Logging utility functions for Sphinx.    N)defaultdict)contextmanager)
IOTYPE_CHECKINGAnyDict	GeneratorListOptionalTupleTypeUnion)nodes)Node)get_source_line)SphinxWarning)colorize)abspath)SphinxZsphinx   c               C   s   t jS )N)loggingWARNING r   r   2lib/python3.7/site-packages/sphinx/util/logging.py<lambda>       r   LEVEL_NAMES)CRITICALZSEVEREERRORr   INFOVERBOSEDEBUGc               C   s   dS )Nr   r   r   r   r   r   r   #   r   VERBOSITY_MAP)r         c               C   s   dS )NZbluer   r   r   r   r   r   *   r   ZdarkredZredZdarkgraySphinxLoggerAdapter)namereturnc             C   s"   t td |  }d|_t|i S )a  Get logger wrapped by :class:`sphinx.util.logging.SphinxLoggerAdapter`.

    Sphinx logger always uses ``sphinx.*`` namespace to be independent from
    settings of root logger.  It ensures logging is consistent even if a
    third-party extension or imported application resets logger settings.

    Example usage::

        >>> from sphinx.util import logging
        >>> logger = logging.getLogger(__name__)
        >>> logger.info('Hello, this is an extension!')
        Hello, this is an extension!
    .F)r   	getLogger	NAMESPACEZdisabledr%   )r&   loggerr   r   r   r)   2   s    r)   )recordsr'   c             C   sD   x>| D ]6}|  |_d|_t|dd}t|tjrt||_qW dS )zConvert LogRecord serializable.r   locationN)	
getMessagemsgargsgetattr
isinstancer   r   get_node_locationr-   )r,   rr-   r   r   r   convert_serializableH   s    

r5   c                   s8   e Zd ZU dZdZdZeed< ed fddZ	  Z
S )SphinxLogRecordz$Log record class supporting location Nr-   )r'   c                sD   t   }t| dd }|r,d|| j|f }n| j|kr@| j| }|S )Nr-   z%s: %s%s)superr.   r1   prefix)selfmessager-   )	__class__r   r   r.   Y   s    


zSphinxLogRecord.getMessage)__name__
__module____qualname____doc__r9   r-   r   __annotations__strr.   __classcell__r   r   )r<   r   r6   T   s   
r6   c               @   s   e Zd ZdZdZdS )SphinxInfoLogRecordz)Info log record class supporting locationr7   N)r=   r>   r?   r@   r9   r   r   r   r   rD   d   s   rD   c               @   s"   e Zd ZdZeedddZdS )SphinxWarningLogRecordz,Warning log record class supporting location)r'   c             C   s(   | j tjkrdS | j tjkr dS dS d S )Nz
CRITICAL: zERROR: z	WARNING: )levelnor   r   r   )r:   r   r   r   r9   k   s
    zSphinxWarningLogRecord.prefixN)r=   r>   r?   r@   propertyrB   r9   r   r   r   r   rE   i   s   rE   c                   s   e Zd ZdZddddddgZeeef eeedd	 fd
dZ	eeeddddZ
eeeeef dddZejddddZ  ZS )r%   z9LoggerAdapter allowing ``type`` and ``subtype`` keywords.typesubtyper-   nonlcoloronceN)levelr/   r0   kwargsr'   c                sD   t |tr"t j||f|| nt| }t j||f|| d S )N)r2   intr8   logr   )r:   rM   r/   r0   rN   rF   )r<   r   r   rP   y   s    
zSphinxLoggerAdapter.log)r/   r0   rN   r'   c             O   s   | j t|f|| d S )N)rP   r    )r:   r/   r0   rN   r   r   r   verbose   s    zSphinxLoggerAdapter.verbose)r/   rN   r'   c             C   s:   | di }x$| jD ]}||kr||||< qW ||fS )Nextra)
setdefaultKEYWORDSpop)r:   r/   rN   rR   keywordr   r   r   process   s
    zSphinxLoggerAdapter.process)recordr'   c             C   s   | j | d S )N)r+   handle)r:   rX   r   r   r   rY      s    zSphinxLoggerAdapter.handle)r=   r>   r?   r@   rT   r   rO   rB   r   rP   rQ   r   r   rW   r   	LogRecordrY   rC   r   r   )r<   r   r%   u   s   "c               @   s   e Zd ZdZdS )WarningStreamHandlerzStreamHandler for warnings.N)r=   r>   r?   r@   r   r   r   r   r[      s   r[   c                   s*   e Zd ZdZejdd fddZ  ZS )NewLineStreamHandlerzAStreamHandler which switches line terminator by record.nonl flag.N)rX   r'   c                s@   z*|    t|ddrd| _t | W d d| _|   X d S )NrJ   Fr7   
)acquirer1   
terminatorr8   emitrelease)r:   rX   )r<   r   r   r`      s    zNewLineStreamHandler.emit)r=   r>   r?   r@   r   rZ   r`   rC   r   r   )r<   r   r\      s   r\   c                   s|   e Zd ZU dZeej ed< dd fddZeje	ddd	Z
ddd
dZejddddZeej dddZ  ZS )MemoryHandlerzHandler buffering all logs.bufferN)r'   c                s   t  d d S )N)r8   __init__)r:   )r<   r   r   re      s    zMemoryHandler.__init__)rX   r'   c             C   s   dS )NFr   )r:   rX   r   r   r   shouldFlush   s    zMemoryHandler.shouldFlushc             C   s   d S )Nr   )r:   r   r   r   flush   s    zMemoryHandler.flush)r+   r'   c             C   s<   |    z$x| jD ]}|| qW g | _W d |   X d S )N)r^   rc   rY   ra   )r:   r+   rX   r   r   r   flushTo   s    
zMemoryHandler.flushToc             C   s   | j g  }| _ |S )N)rc   )r:   rc   r   r   r   clear   s    zMemoryHandler.clear)r=   r>   r?   r@   r	   r   rZ   rA   re   boolrf   rg   ZLoggerrh   ri   rC   r   r   )r<   r   rb      s   
	rb   )r'   c           
   c   s   t t} t }|t j zNg }x4| jdd D ]"}t|tr2| 	| |
| q2W | | |V  W d| 	| x|D ]}| | q|W ||  X dS )zgContext manager to postpone logging warnings temporarily.

    Similar to :func:`pending_logging`.
    N)r   r)   r*   rb   setLevelr   handlersr2   r[   removeHandlerappend
addHandlerrh   )r+   
memhandlerrl   handlerr   r   r   pending_warnings   s    






rr   c           
   c   s~   t t} t }zDg }x*| jdd D ]}| | || q&W | | |V  W d| | x|D ]}| | qfW X dS )zContext manager to suppress logging all logs temporarily.

    For example::

        >>> with suppress_logging():
        >>>     logger.warning('Warning message!')  # suppressed
        >>>     some_long_process()
        >>>
    N)r   r)   r*   rb   rl   rm   rn   ro   )r+   rp   rl   rq   r   r   r   suppress_logging   s    





rs   c           	   c   s8   t t} zt }|V  W dQ R X W d||  X dS )a$  Context manager to postpone logging all logs temporarily.

    For example::

        >>> with pending_logging():
        >>>     logger.warning('Warning message!')  # not flushed yet
        >>>     some_long_process()
        >>>
        Warning message!  # the warning is flushed here
    N)r   r)   r*   rs   rh   )r+   rp   r   r   r   pending_logging   s
    
rt   T)NNN)skipr'   c          
   c   sj   t t}| dkrdV  nLz.t }x|jD ]}|jd| q*W dV  W dx|jD ]}|| qRW X dS )z9Context manager to skip WarningIsErrorFilter temporarily.FNr   )r   r)   r*   DisableWarningIsErrorFilterrl   filtersinsertremoveFilter)ru   r+   Zdisablerrq   r   r   r   skip_warningiserror  s    

rz   )r9   r'   c          	   c   s   t t}d}x(|jD ]}t|tr|}P qW dV  dS d}x|jD ]}t|trD|}P qDW |rz|j}| |_dV  W d||_X n*t| }z|	| dV  W d|
| X dS )zContext manager to prepend prefix to all warning log records temporarily.

    For example::

        >>> with prefixed_warnings("prefix:"):
        >>>     logger.warning('Warning message!')  # => prefix: Warning message!

    .. versionadded:: 2.0
    N)r   r)   r*   rl   r2   r[   rw   MessagePrefixFilterr9   	addFilterry   )r9   r+   warning_handlerrq   Zprefix_filterZ_filterZpreviousr   r   r   prefixed_warnings"  s0    






r~   c               @   s0   e Zd ZddddZeed dddZdS )LogCollectorN)r'   c             C   s
   g | _ d S )N)logs)r:   r   r   r   re   Q  s    zLogCollector.__init__)NNNc          	   c   s&   t  }d V  | | _W d Q R X d S )N)rt   ri   r   )r:   rp   r   r   r   collectT  s    zLogCollector.collect)r=   r>   r?   re   r   r   r   r   r   r   r   r   P  s   r   c               @   s"   e Zd ZdZejedddZdS )
InfoFilterz"Filter error and warning messages.)rX   r'   c             C   s   |j tjk rdS dS d S )NTF)rF   r   r   )r:   rX   r   r   r   filter_  s    zInfoFilter.filterN)r=   r>   r?   r@   r   rZ   rj   r   r   r   r   r   r   \  s   r   )rH   rI   suppress_warningsr'   c             C   s\   | dkrdS xJ|D ]B}d|kr0| dd\}}n
|d }}|| kr|d|dfkrdS qW dS )z/Check whether the warning is suppressed or not.NFr(   r#   *T)split)rH   rI   r   Zwarning_typetargetZ	subtargetr   r   r   is_suppressed_warningf  s    

r   c                   s:   e Zd ZdZddd fddZejeddd	Z  Z	S )
WarningSuppressorz#Filter logs by `suppress_warnings`.r   N)appr'   c                s   || _ t   d S )N)r   r8   re   )r:   r   )r<   r   r   re   |  s    zWarningSuppressor.__init__)rX   r'   c             C   sh   t |dd}t |dd}y| jjj}W n tk
r>   g }Y nX t|||rPdS | j jd7  _dS d S )NrH   r7   rI   Fr#   T)r1   r   Zconfigr   AttributeErrorr   Z
_warncount)r:   rX   rH   rI   r   r   r   r   r     s    
zWarningSuppressor.filter)
r=   r>   r?   r@   re   r   rZ   rj   r   rC   r   r   )r<   r   r   y  s   r   c                   s:   e Zd ZdZddd fddZejeddd	Z  Z	S )
WarningIsErrorFilterz#Raise exception if warning emitted.r   N)r   r'   c                s   || _ t   d S )N)r   r8   re   )r:   r   )r<   r   r   re     s    zWarningIsErrorFilter.__init__)rX   r'   c          	   C   s   t |ddrdS | jjrt |dd}y|j|j }W n ttfk
rR   |j}Y nX |rnt|d t| }nt|}|j	d k	r||j	d q|ndS d S )Nskip_warningsiserrorFTr-   r7   :r#   )
r1   r   Zwarningiserrorr/   r0   	TypeError
ValueErrorr   rB   exc_info)r:   rX   r-   r;   excr   r   r   r     s    
zWarningIsErrorFilter.filter)
r=   r>   r?   r@   re   r   rZ   rj   r   rC   r   r   )r<   r   r     s   r   c               @   s"   e Zd ZdZejedddZdS )rv   z6Disable WarningIsErrorFilter if this filter installed.)rX   r'   c             C   s
   d|_ dS )NT)r   )r:   rX   r   r   r   r     s    z"DisableWarningIsErrorFilter.filterN)r=   r>   r?   r@   r   rZ   rj   r   r   r   r   r   rv     s   rv   c                   s:   e Zd ZdZedd fddZejedddZ	  Z
S )	r{   z"Prepend prefix to all log records.N)r9   r'   c                s   || _ t   d S )N)r9   r8   re   )r:   r9   )r<   r   r   re     s    zMessagePrefixFilter.__init__)rX   r'   c             C   s   | j r| j d |j |_dS )N T)r9   r/   )r:   rX   r   r   r   r     s    zMessagePrefixFilter.filter)r=   r>   r?   r@   rB   re   r   rZ   rj   r   rC   r   r   )r<   r   r{     s   r{   c                   s<   e Zd ZdZd
edd fddZejeddd	Z	  Z
S )
OnceFilterzShow the message only once.r7   N)r&   r'   c                s   t  | i | _d S )N)r8   re   messages)r:   r&   )r<   r   r   re     s    zOnceFilter.__init__)rX   r'   c             C   sF   t |dd}|sdS | j|jg }|j|kr2dS ||j dS d S )NrL   r7   TF)r1   r   rS   r/   r0   rn   )r:   rX   rL   paramsr   r   r   r     s    
zOnceFilter.filter)r7   )r=   r>   r?   r@   rB   re   r   rZ   rj   r   rC   r   r   )r<   r   r     s   r   c                   sH   e Zd ZU dZeej ed< ddd fddZe	e
dd	d
Z  ZS )SphinxLogRecordTranslatorzConverts a log record to one Sphinx expects

    * Make a instance of SphinxLogRecord
    * docname to path if location given
    LogRecordClassr   N)r   r'   c                s   || _ t   d S )N)r   r8   re   )r:   r   )r<   r   r   re     s    z"SphinxLogRecordTranslator.__init__)rX   r'   c             C   s   t |tjr| j|_t|dd }t |trv|\}}|rT|rTd| jj	||f |_
q|rnd| jj	| |_
qd |_
n8t |tjrt||_
n |rd|krd| jj	| |_
dS )Nr-   z%s:%sz%sr   T)r2   r   rZ   r   r<   r1   tupler   envZdoc2pathr-   r   r   r3   )r:   rX   r-   Zdocnamelinenor   r   r   r     s    
z SphinxLogRecordTranslator.filter)r=   r>   r?   r@   r   r   rZ   rA   re   rE   rj   r   rC   r   r   )r<   r   r     s   
r   c               @   s   e Zd ZdZeZdS )InfoLogRecordTranslatorz/LogRecordTranslator for INFO level log records.N)r=   r>   r?   r@   rD   r   r   r   r   r   r     s   r   c               @   s   e Zd ZdZeZdS )WarningLogRecordTranslatorz2LogRecordTranslator for WARNING level log records.N)r=   r>   r?   r@   rE   r   r   r   r   r   r     s   r   )noder'   c             C   sL   t | \}}|rt|}|r,|r,d||f S |r8d| S |rDd| S d S d S )Nz%s:%sz%s:z<unknown>:%s)r   r   )r   sourceliner   r   r   r3     s    r3   c                   s&   e Zd Zejed fddZ  ZS )ColorizeFormatter)rX   r'   c                sB   t  |}t|dd }|d kr,t|j}|r:t||S |S d S )NrK   )r8   formatr1   	COLOR_MAPgetrF   r   )r:   rX   r;   rK   )r<   r   r   r     s    
zColorizeFormatter.format)r=   r>   r?   r   rZ   rB   r   rC   r   r   )r<   r   r     s   r   c               @   s>   e Zd ZdZeddddZeddddZdd	d
dZdS )SafeEncodingWriterz7Stream writer which ignores UnicodeEncodeError silentlyN)streamr'   c             C   s   || _ t|ddpd| _d S )Nencodingascii)r   r1   r   )r:   r   r   r   r   re   !  s    zSafeEncodingWriter.__init__)datar'   c          	   C   sH   y| j | W n2 tk
rB   | j || jd| j Y nX d S )Nreplace)r   writeUnicodeEncodeErrorencoder   decode)r:   r   r   r   r   r   %  s    zSafeEncodingWriter.write)r'   c             C   s   t | jdr| j  d S )Nrg   )hasattrr   rg   )r:   r   r   r   rg   -  s    zSafeEncodingWriter.flush)	r=   r>   r?   r@   r   re   rB   r   rg   r   r   r   r   r     s   r   c               @   s2   e Zd ZdZdeddddZedddd	ZdS )
LastMessagesWriterzBStream writer storing last 10 messages in memory to save trackbackr   N)r   r   r'   c             C   s
   || _ d S )N)r   )r:   r   r   r   r   r   re   4  s    zLastMessagesWriter.__init__)r   r'   c             C   s   | j j| d S )N)r   Z
messagelogrn   )r:   r   r   r   r   r   7  s    zLastMessagesWriter.write)r=   r>   r?   r@   r   re   rB   r   r   r   r   r   r   2  s   r   r   )r   statuswarningr'   c             C   s4  t t}|t j d|_x |jdd D ]}|| q,W tt	|}|
t  |
t|  |t| j  |t  tt	|}|
t|  |
t|  |
t|  |
t  |t j |t  t t| |}|
t  |t| j  |t  || || || dS )zSetup root logger for SphinxFN)r   r)   r*   rk   r!   Z	propagaterl   rm   r\   r   r|   r   r   r"   	verbosityZsetFormatterr   r[   r   r   r   r   r   StreamHandlerr   ro   )r   r   r   r+   rq   Zinfo_handlerr}   Zmessagelog_handlerr   r   r   setup;  s0    


r   )T)Ur@   r   Zlogging.handlerscollectionsr   
contextlibr   typingr   r   r   r   r   r	   r
   r   r   r   Zdocutilsr   Zdocutils.nodesr   Zdocutils.utilsr   Zsphinx.errorsr   Zsphinx.util.consoler   Zsphinx.util.osutilr   Zsphinx.applicationr   r*   r    r   rB   rO   rA   updater   r   r   r   r!   r"   r   r)   rZ   r5   r6   rD   rE   ZLoggerAdapterr%   r   r[   r\   rl   ZBufferingHandlerrb   ZHandlerrr   rs   rt   rj   rz   r~   r   ZFilterr   r   r   r   rv   r{   r   r   r   r   r3   Z	Formatterr   r   r   r   r   r   r   r   <module>   s   0-
"	