a
    ¥Q•hºM  ã                   @   s  d dl Z d dlZd dlZd dlmZ d dlmZmZ d dlZd dlm	Z	 ej
ZddddœZG dd	„ d	ejƒZd
d„ Zddd„ZG dd„ deƒZG dd„ dejƒZG dd„ dejƒZG dd„ deƒZefdd„Zefdd„Zedk�rd dlZe  ejejd�j ¡ dS )é    N©Úwraps)ÚMappingÚCallable)ÚPercentStylez%(levelname)s: %(message)sz%(message)s)Ú*ÚINFOÚDEBUGc                       s.   e Zd ZdZd‡ fdd„	Z‡ fdd„Z‡  ZS )	ÚLevelFormatteraí  Log formatter with level-specific formatting.

    Formatter class which optionally takes a dict of logging levels to
    format strings, allowing to customise the log records appearance for
    specific levels.


    Attributes:
            fmt: A dictionary mapping logging levels to format strings.
                    The ``*`` key identifies the default format string.
            datefmt: As per py:class:`logging.Formatter`
            style: As per py:class:`logging.Formatter`

    >>> import sys
    >>> handler = logging.StreamHandler(sys.stdout)
    >>> formatter = LevelFormatter(
    ...     fmt={
    ...         '*':     '[%(levelname)s] %(message)s',
    ...         'DEBUG': '%(name)s [%(levelname)s] %(message)s',
    ...         'INFO':  '%(message)s',
    ...     })
    >>> handler.setFormatter(formatter)
    >>> log = logging.getLogger('test')
    >>> log.setLevel(logging.DEBUG)
    >>> log.addHandler(handler)
    >>> log.debug('this uses a custom format string')
    test [DEBUG] this uses a custom format string
    >>> log.info('this also uses a custom format string')
    this also uses a custom format string
    >>> log.warning("this one uses the default format string")
    [WARNING] this one uses the default format string
    Nú%c                    s¦   |dkrt dƒ‚|d u rt}t|tƒr0|}i }n,t|tƒrPt|ƒ}| dd ¡}ntd| ƒ‚tt	| ƒ 
||¡ | j| _i | _| ¡ D ]\}}t |¡}|| j|< q„d S )Nr   z:only '%' percent style is supported in both python 2 and 3r   z&fmt must be a str or a dict of str: %r)Ú
ValueErrorÚDEFAULT_FORMATSÚ
isinstanceÚstrr   ÚdictÚpopÚ	TypeErrorÚsuperr
   Ú__init__Ú_fmtÚdefault_formatÚcustom_formatsÚitemsÚloggingÚ_checkLevel)ÚselfÚfmtÚdatefmtÚstyler   r   Úlevel©Ú	__class__© úT/var/www/sistema_ama/venv/lib/python3.9/site-packages/fontTools/misc/loggingTools.pyr   8   s&    ÿ


zLevelFormatter.__init__c                    sF   | j r6| j  |j| j¡}| j|kr6|| _tr6t|ƒ| _tt| ƒ 	|¡S ©N)
r   ÚgetÚlevelnor   r   r   Ú_styler   r
   Úformat)r   Úrecordr   r    r"   r#   r(   N   s    

zLevelFormatter.format)NNr   )Ú__name__Ú
__module__Ú__qualname__Ú__doc__r   r(   Ú__classcell__r"   r"   r    r#   r
      s   !r
   c                  K   s¨  |   dd¡}|du r.d| v rFd| v rFtdƒ‚nd| v s>d| v rFtdƒ‚|du r”|   dd¡}|   dd¡}|rxt ||¡}n|   dd¡}t |¡}|g}|   d	d
¡}|r®t|tƒr¸t |¡}t|j	d� |   dd¡}|   dd¡}|   dd¡}	t
|||	ƒ}
|   dg ¡}|D ]D}|jdu �r| |
¡ |j�s<|D ]}| |¡ �q*| |¡ �q|j	dk�rd|   dd¡|_|   dd¡}|du�r„| |¡ | �r¤d |  ¡ ¡}td| ƒ‚dS )a–
  A more sophisticated logging system configuation manager.

    This is more or less the same as :py:func:`logging.basicConfig`,
    with some additional options and defaults.

    The default behaviour is to create a ``StreamHandler`` which writes to
    sys.stderr, set a formatter using the ``DEFAULT_FORMATS`` strings, and add
    the handler to the top-level library logger ("fontTools").

    A number of optional keyword arguments may be specified, which can alter
    the default behaviour.

    Args:

            logger: Specifies the logger name or a Logger instance to be
                    configured. (Defaults to "fontTools" logger). Unlike ``basicConfig``,
                    this function can be called multiple times to reconfigure a logger.
                    If the logger or any of its children already exists before the call is
                    made, they will be reset before the new configuration is applied.
            filename: Specifies that a ``FileHandler`` be created, using the
                    specified filename, rather than a ``StreamHandler``.
            filemode: Specifies the mode to open the file, if filename is
                    specified. (If filemode is unspecified, it defaults to ``a``).
            format: Use the specified format string for the handler. This
                    argument also accepts a dictionary of format strings keyed by
                    level name, to allow customising the records appearance for
                    specific levels. The special ``'*'`` key is for 'any other' level.
            datefmt: Use the specified date/time format.
            level: Set the logger level to the specified level.
            stream: Use the specified stream to initialize the StreamHandler. Note
                    that this argument is incompatible with ``filename`` - if both
                    are present, ``stream`` is ignored.
            handlers: If specified, this should be an iterable of already created
                    handlers, which will be added to the logger. Any handler in the
                    list which does not have a formatter assigned will be assigned the
                    formatter created in this function.
            filters: If specified, this should be an iterable of already created
                    filters. If the ``handlers`` do not already have filters assigned,
                    these filters will be added to them.
            propagate: All loggers have a ``propagate`` attribute which determines
                    whether to continue searching for handlers up the logging hierarchy.
                    If not provided, the "propagate" attribute will be set to ``False``.
    ÚhandlersNÚstreamÚfilenamez8'stream' and 'filename' should not be specified togetherzG'stream' or 'filename' should not be specified together with 'handlers'ÚfilemodeÚaÚloggerZ	fontTools)Úparentr(   r   r   r   ÚfiltersÚrootÚ	propagateFr   z, zUnrecognised argument(s): %s)r   r   r   ÚFileHandlerÚStreamHandlerr   r   Ú	getLoggerÚ_resetExistingLoggersÚnamer
   Ú	formatterÚsetFormatterr6   Ú	addFilterÚ
addHandlerr8   ÚsetLevelÚjoinÚkeys)Úkwargsr/   r1   ÚmodeÚhr0   r4   ÚfsÚdfsr   r   r6   Úfr   rD   r"   r"   r#   ÚconfigLoggerY   sT    -ÿÿ




rK   r7   c                 C   s2  t j}t|jj ¡ ƒ}| dkr*| g| }nt| |vr6dS | |v rž| g}| | ¡d }| d }t|ƒ}t|ƒ}||k rž|| d|… |kr”| || ¡ |d7 }qj|D ]Š}|dk�r | 	t j
¡ |jdd… D ]}	| |	¡ qÊ|jdd… D ]}
| |
¡ qèd|_q¢|jj| }t j|_g |_g |_d|_d|_q¢dS )z‰Reset the logger named 'parent' and all its children to their initial
    state, if they already exist in the current configuration.
    r7   Né   Ú.FT)r   r7   ÚsortedÚmanagerÚ
loggerDictrD   ÚindexÚlenÚappendrB   ÚWARNINGr/   ÚremoveHandlerr6   ZremoveFiltersÚdisabledÚNOTSETr   r8   )r5   r7   ÚexistingZloggers_to_resetÚiÚprefixedÚpflenÚnum_existingr=   rG   rJ   r4   r"   r"   r#   r<   ¼   s<    

r<   c                   @   s|   e Zd ZdZejZdZdZddd„Z	ddd„Z
d	d
„ Zdd„ Zdd„ Zdd„ Zdd„ Zddd„Zdd„ Zdd„ Zdd„ ZdS )ÚTimeraY  Keeps track of overall time and split/lap times.

    >>> import time
    >>> timer = Timer()
    >>> time.sleep(0.01)
    >>> print("First lap:", timer.split())
    First lap: ...
    >>> time.sleep(0.02)
    >>> print("Second lap:", timer.split())
    Second lap: ...
    >>> print("Overall time:", timer.time())
    Overall time: ...

    Can be used as a context manager inside with-statements.

    >>> with Timer() as t:
    ...     time.sleep(0.01)
    >>> print("%0.3f seconds" % t.elapsed)
    0... seconds

    If initialised with a logger, it can log the elapsed time automatically
    upon exiting the with-statement.

    >>> import logging
    >>> log = logging.getLogger("my-fancy-timer-logger")
    >>> configLogger(logger=log, level="DEBUG", format="%(message)s", stream=sys.stdout)
    >>> with Timer(log, 'do something'):
    ...     time.sleep(0.01)
    Took ... to do something

    The same Timer instance, holding a reference to a logger, can be reused
    in multiple with-statements, optionally with different messages or levels.

    >>> timer = Timer(log)
    >>> with timer():
    ...     time.sleep(0.01)
    elapsed time: ...s
    >>> with timer('redo it', level=logging.INFO):
    ...     time.sleep(0.02)
    Took ... to redo it

    It can also be used as a function decorator to log the time elapsed to run
    the decorated function.

    >>> @timer()
    ... def test1():
    ...    time.sleep(0.01)
    >>> @timer('run test 2', level=logging.INFO)
    ... def test2():
    ...    time.sleep(0.02)
    >>> test1()
    Took ... to run 'test1'
    >>> test2()
    Took ... to run test 2
    zelapsed time: %(time).3fszTook %(time).3fs to %(msg)sNc                 C   sZ   |   |¡ |d u r8dD ] }tƒ  |¡d urtd| ƒ‚q|| _|d urJ|nt| _|| _d S )N)Úmsgr   z*'%s' can't be specified without a 'logger')ÚresetÚlocalsr%   r   r4   Ú
TIME_LEVELr   r^   )r   r4   r^   r   ÚstartÚargr"   r"   r#   r   #  s    
zTimer.__init__c                 C   s,   |du r|   ¡ | _n|| _| j| _d| _dS )z0Reset timer to 'start_time' or the current time.Nç        )Ú_timerb   ÚlastÚelapsed)r   rb   r"   r"   r#   r_   -  s
    zTimer.resetc                 C   s   |   ¡ | j S )z=Return the overall time (in seconds) since the timer started.)re   rb   ©r   r"   r"   r#   Útime6  s    z
Timer.timec                 C   s    |   ¡ }|| j | _|| _| jS )z=Split and return the lap time (in seconds) in between splits.©re   rf   rg   )r   Úcurrentr"   r"   r#   Úsplit:  s    zTimer.splitc              	   C   sV   |s
| j }| d¡dk r*| j||dœ }n(z|d|i }W n ttfyP   Y n0 |S )zÿFormat 'time' value in 'msg' and return formatted string.
        If 'msg' contains a '%(time)' format string, try to use that.
        Otherwise, use the predefined 'default_format'.
        If 'msg' is empty or None, fall back to 'default_msg'.
        z%(time)r   ©r^   ri   ri   )Údefault_msgÚfindr   ÚKeyErrorr   )r   r^   ri   r"   r"   r#   Ú
formatTimeA  s    zTimer.formatTimec                 C   s   |   ¡ | _d| _| S )zStart a new laprd   rj   rh   r"   r"   r#   Ú	__enter__R  s    
zTimer.__enter__c                 C   sJ   |   ¡ }| jdu s|rdS |  | j|¡}| j|dœ}| j | j||¡ dS )zŒEnd the current lap. If timer has a logger, log the time elapsed,
        using the format string in self.msg (or the default one).
        Nrm   )rl   r4   rq   r^   Úlogr   )r   Úexc_typeÚ	exc_valueÚ	tracebackri   ÚmessageZ	msg_partsr"   r"   r#   Ú__exit__X  s    zTimer.__exit__c                    sj   t |tƒr:|‰ ˆjs dˆ j ˆ_tˆ ƒ‡ ‡fdd„ƒ}|S |pF| d¡}| dˆj¡}ˆ ˆj||¡S dS )aV  If the first argument is a function, return a decorator which runs
        the wrapped function inside Timer's context manager.
        Otherwise, treat the first argument as a 'msg' string and return an updated
        Timer instance, referencing the same logger.
        A 'level' keyword can also be passed to override self.level.
        zrun '%s'c                     s6   ˆ� ˆ | i |¤ŽW  d   ƒ S 1 s(0    Y  d S r$   r"   )ÚargsÚkwds©Úfuncr   r"   r#   Úwrappert  s    zTimer.__call__.<locals>.wrapperr^   r   N)	r   r   r^   r*   r   r%   r   r!   r4   )r   Zfunc_or_msgrE   r}   r^   r   r"   r{   r#   Ú__call__g  s    
zTimer.__call__c                 C   s   | j S r$   ©rg   rh   r"   r"   r#   Ú	__float__  s    zTimer.__float__c                 C   s
   t | jƒS r$   )Úintrg   rh   r"   r"   r#   Ú__int__‚  s    zTimer.__int__c                 C   s
   d| j  S )Nz%.3fr   rh   r"   r"   r#   Ú__str__…  s    zTimer.__str__)NNNN)N)N)r*   r+   r,   r-   ÚtimeitZdefault_timerre   rn   r   r   r_   ri   rl   rq   rr   rx   r~   r€   r‚   rƒ   r"   r"   r"   r#   r]   å   s   9


	
r]   c                   @   s    e Zd ZdZdd„ Zdd„ ZdS )ÚChannelsFilteraQ  Provides a hierarchical filter for log entries based on channel names.

    Filters out records emitted from a list of enabled channel names,
    including their children. It works the same as the ``logging.Filter``
    class, but allows the user to specify multiple channel names.

    >>> import sys
    >>> handler = logging.StreamHandler(sys.stdout)
    >>> handler.setFormatter(logging.Formatter("%(message)s"))
    >>> filter = ChannelsFilter("A.B", "C.D")
    >>> handler.addFilter(filter)
    >>> root = logging.getLogger()
    >>> root.addHandler(handler)
    >>> root.setLevel(level=logging.DEBUG)
    >>> logging.getLogger('A.B').debug('this record passes through')
    this record passes through
    >>> logging.getLogger('A.B.C').debug('records from children also pass')
    records from children also pass
    >>> logging.getLogger('C.D').debug('this one as well')
    this one as well
    >>> logging.getLogger('A.B.').debug('also this one')
    also this one
    >>> logging.getLogger('A.F').debug('but this one does not!')
    >>> logging.getLogger('C.DE').debug('neither this one!')
    c                 G   s$   || _ t|ƒ| _dd„ |D ƒ| _d S )Nc                 S   s   i | ]}|t |ƒ“qS r"   )rR   )Ú.0Únr"   r"   r#   Ú
<dictcomp>§  ó    z+ChannelsFilter.__init__.<locals>.<dictcomp>)ÚnamesrR   ÚnumÚlengths)r   rŠ   r"   r"   r#   r   ¤  s    
zChannelsFilter.__init__c                 C   s`   | j dkrdS | jD ]F}| j| }||jkr2 dS |j |d|¡dkr|j| dkr dS qdS )Nr   TrM   F)r‹   rŠ   rŒ   r=   ro   )r   r)   r=   Únlenr"   r"   r#   Úfilter©  s    



"zChannelsFilter.filterN)r*   r+   r,   r-   r   rŽ   r"   r"   r"   r#   r…   ‰  s   r…   c                       s>   e Zd Z‡ fdd„Zdd„ Zdd„ Zdd„ Zdd
d„Z‡  ZS )ÚCapturingLogHandlerc                    s:   t t| ƒj|d� g | _t|tƒr0t |¡| _n|| _d S )N)r   )	r   r�   r   Úrecordsr   r   r   r;   r4   )r   r4   r   r    r"   r#   r   ¶  s
    
zCapturingLogHandler.__init__c                 C   sL   | j j| _| j j| _| j j| _| j  | ¡ | j  | j¡ d| j _d| j _| S )NF)	r4   rV   Úoriginal_disabledr   Úoriginal_levelr8   Úoriginal_propagaterA   rB   rh   r"   r"   r#   rr   ¾  s    


zCapturingLogHandler.__enter__c                 C   s2   | j  | ¡ | j  | j¡ | j| j _| j| j _| S r$   )r4   rU   rB   r’   r‘   rV   r“   r8   )r   ÚtypeÚvaluerv   r"   r"   r#   rx   Ê  s
    

zCapturingLogHandler.__exit__c                 C   s   | j  |¡ d S r$   )r�   rS   )r   r)   r"   r"   r#   ÚemitÒ  s    zCapturingLogHandler.emitNc                 C   sR   dd l }| |¡}| jD ]}| | ¡ ¡r dS q|d u rBd| }dsNJ |ƒ‚d S )Nr   Tz(Pattern '%s' not found in logger records)ÚreÚcompiler�   ÚsearchÚ
getMessage)r   Úregexpr^   r—   ÚpatternÚrr"   r"   r#   ÚassertRegexÕ  s    

zCapturingLogHandler.assertRegex)N)	r*   r+   r,   r   rr   rx   r–   rž   r.   r"   r"   r    r#   r�   µ  s
   r�   c                   @   s   e Zd ZdZedd„ ƒZdS )ÚLogMixina2  Mixin class that adds logging functionality to another class.

    You can define a new class that subclasses from ``LogMixin`` as well as
    other base classes through multiple inheritance.
    All instances of that class will have a ``log`` property that returns
    a ``logging.Logger`` named after their respective ``<module>.<class>``.

    For example:

    >>> class BaseClass(object):
    ...     pass
    >>> class MyClass(LogMixin, BaseClass):
    ...     pass
    >>> a = MyClass()
    >>> isinstance(a.log, logging.Logger)
    True
    >>> print(a.log.name)
    fontTools.misc.loggingTools.MyClass
    >>> class AnotherClass(MyClass):
    ...     pass
    >>> b = AnotherClass()
    >>> isinstance(b.log, logging.Logger)
    True
    >>> print(b.log.name)
    fontTools.misc.loggingTools.AnotherClass
    c                 C   s2   t | dƒs,d | jj| jjf¡}t |¡| _| jS )NÚ_logrM   )ÚhasattrrC   r!   r+   r*   r   r;   r    )r   r=   r"   r"   r#   rs   ý  s    
zLogMixin.logN)r*   r+   r,   r-   Úpropertyrs   r"   r"   r"   r#   rŸ   á  s   rŸ   c                 C   s   t jd| |f |dd� dS )z:Raise a warning about deprecated function argument 'name'.ú%r is deprecated; %sé   ©ÚcategoryÚ
stacklevelN)ÚwarningsÚwarn)r=   r^   r¦   r"   r"   r#   ÚdeprecateArgument  s    rª   c                    s   ‡ ‡fdd„}|S )zBDecorator to raise a warning when a deprecated function is called.c                    s   t ˆ ƒ‡‡ ‡fdd„ƒ}|S )Nc                     s(   t jdˆjˆf ˆ dd� ˆ| i |¤ŽS )Nr£   é   r¥   )r¨   r©   r*   )ry   rE   )r¦   r|   r^   r"   r#   r}     s    ýz5deprecateFunction.<locals>.decorator.<locals>.wrapperr   )r|   r}   ©r¦   r^   )r|   r#   Ú	decorator  s    z$deprecateFunction.<locals>.decoratorr"   )r^   r¦   r­   r"   r¬   r#   ÚdeprecateFunction
  s    r®   Ú__main__)Zoptionflags)r7   )!Úsysr   r„   Ú	functoolsr   Úcollections.abcr   r   r¨   r   r	   ra   r   Ú	Formatterr
   rK   r<   Úobjectr]   ÚFilterr…   ÚHandlerr�   rŸ   ÚUserWarningrª   r®   r*   ÚdoctestÚexitÚtestmodÚELLIPSISÚfailedr"   r"   r"   r#   Ú<module>   s0   ýCc
) %,,$
