
    jkeM                        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	ej                        Zd
 ZddZ G d de      Z G d dej&                        Z G d dej*                        Z G d de      ZefdZefdZedk(  r<d dlZ e j:                   ej<                  ej>                        j@                         yy)    Nwraps)MappingCallable)PercentStylez%(levelname)s: %(message)sz%(message)s)*INFODEBUGc                   .     e Zd ZdZd fd	Z fdZ x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
    c                    |dk7  rt        d      |t        }t        |t              r|}i }n<t        |t              rt        |      }|j                  dd       }nt        d|z        t        t        | +  ||       | j                  | _        i | _        |j                         D ])  \  }}t        j                   |      }|| j                  |<   + y )N%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__s          =/usr/lib/python3/dist-packages/fontTools/misc/loggingTools.pyr   zLevelFormatter.__init__8   s    C<L  ;!Cc3 NNW%!#YN+//T:NDsJKKnd,^WE"ii (..0 	-JE3''.E),D&	-    c                     | j                   r\| j                   j                  |j                  | j                        }| j                  |k7  r|| _        t
        rt        |      | _        t        t        | '  |      S N)
r   getlevelnor   r   r   _styler   r   format)r   recordr   r#   s      r$   r+   zLevelFormatter.formatN   sb    %%))&..$:M:MNCyyC	".s"3DK^T1&99r%   )NNr   )__name__
__module____qualname____doc__r   r+   __classcell__r#   s   @r$   r   r      s    B-,: :r%   r   c                  8   | j                  dd      }|d| v r"d| v rt        d      d| v sd| v rt        d      |g| j                  dd      }| j                  dd      }|rt        j                  ||      }n'| j                  dd      }t        j                  |      }|g}| j                  d	d
      }|rt        |t              rt        j                  |      }t        |j                         | j                  dd      }| j                  dd      }| j                  dd      }	t        |||	      }
| j                  dg       }|D ]T  }|j                  |j                  |
       |j                  s|D ]  }|j                  |        |j                  |       V |j                  dk7  r| j                  dd      |_        | j                  dd      }||j#                  |       | r-dj%                  | j'                               }t        d|z        y)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logger	fontTools)parentr+   r    r!   r   filtersroot	propagateFr"   z, zUnrecognised argument(s): %s)r   r   r   FileHandlerStreamHandlerr   r   	getLogger_resetExistingLoggersnamer   	formattersetFormatterr<   	addFilter
addHandlerr>   setLeveljoinkeys)kwargsr4   r6   modehr5   r9   fsdfsr!   r   r<   fr"   rJ   s                  r$   configLoggerrQ   Y   s   Z zz*d+Hv*"6M  vv!55  ::j$/zz*c*##Hd3AZZ$/F%%f-A3ZZ+.FZ,""6*-	Hd	#B
**Y
%CJJw$E
S%
(CjjB'G ;;NN3yy A! {{f!::k59JJw%Eyy'7$>?? r%   c                    t         j                  }t        |j                  j                  j                               }| dk(  r| g|z   }nj| |vry| |v ra| g}|j                  |       dz   }| dz   }t        |      }t        |      }||k  r*||   d| |k(  r|j                  ||          |dz  }||k  r*D ]  }|dk(  rq|j                  t         j                         |j                  dd D ]  }	|j                  |	        |j                  dd D ]  }
|j                  |
        d|_        y|j                  j                  |   }t         j                   |_        g |_        g |_        d|_        d|_         y)zReset the logger named 'parent' and all its children to their initial
    state, if they already exist in the current configuration.
    r=   N   .FT)r   r=   sortedmanager
loggerDictrJ   indexlenappendrH   WARNINGr4   removeHandlerr<   removeFiltersdisabledNOTSETr"   r>   )r;   r=   existingloggers_to_resetiprefixedpflennum_existingrC   rM   rP   r9   s               r$   rB   rB      s~    <<Ddll--2245H"8h.	x		8	"8NN6"Q&C<H8},{6E"h. ''4FA , ! $6>MM'//*]]1% &""1%&\\!_ &""1%&!DM\\,,T2F">>FL FOFN#F#FO$r%   c                   x    e Zd ZdZej
                  ZdZdZddZ	ddZ
d Zd Zd	 Zd
 Zd ZddZd Zd Zd Zy)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                     | j                  |       |.dD ])  }t               j                  |      t        d|z         || _        ||nt
        | _        || _        y )N)msgr"   z*'%s' can't be specified without a 'logger')resetlocalsr(   r   r9   
TIME_LEVELr"   ri   )r   r9   ri   r"   startargs         r$   r   zTimer.__init__#  se    

5>' Y8<<$0$%QTW%WXXY #/UZ
r%   c                 r    || j                         | _        n|| _        | j                  | _        d| _        y)z0Reset timer to 'start_time' or the current time.N        )_timerm   lastelapsed)r   rm   s     r$   rj   zTimer.reset-  s-    =DJDJJJ	r%   c                 <    | j                         | j                  z
  S )z=Return the overall time (in seconds) since the timer started.)rq   rm   r   s    r$   timez
Timer.time6  s    zz|djj((r%   c                 p    | j                         }|| j                  z
  | _        || _        | j                  S )z=Split and return the lap time (in seconds) in between splits.rq   rr   rs   )r   currents     r$   splitzTimer.split:  s.    **,*	||r%   c                     |s| j                   }|j                  d      dk  r| j                  ||dz  }|S 	 |d|iz  }|S # t        t        f$ r Y |S w xY w)zFormat '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   ri   rv   rv   )default_msgfindr   KeyErrorr   )r   ri   rv   s      r$   
formatTimezTimer.formatTimeA  sw     ""C88I"%%T(BBC 
	VTN* 
 j) 
s   A AAc                 >    | j                         | _        d| _        | S )zStart a new laprp   rx   ru   s    r$   	__enter__zTimer.__enter__R  s    JJL	r%   c                     | j                         }| j                  |ry| j                  | j                  |      }| j                  |d}| j                  j	                  | j
                  ||       y)zEnd the current lap. If timer has a logger, log the time elapsed,
        using the format string in self.msg (or the default one).
        Nr|   )rz   r9   r   ri   logr"   )r   exc_type	exc_value	tracebackrv   message	msg_partss          r$   __exit__zTimer.__exit__X  s\     zz|;;( //$((D1 !HHd3	

GY7r%   c                 2    t        |t              r8| j                  sdj                  z   _        t	               fd       }|S |xs |j                  d      }|j                  d j                        } j                   j                  ||      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                  D    5   | i |cd d d        S # 1 sw Y   y xY wr'    )argskwdsfuncr   s     r$   wrapperzTimer.__call__.<locals>.wrappert  s(     /../ / /s   ri   r"   )	r   r   ri   r-   r   r(   r"   r#   r9   )r   func_or_msgrK   r   ri   r"   r   s   `     @r$   __call__zTimer.__call__g  s     k8,D88%54[/ / N2E!2CJJw

3E>>$++sE::r%   c                     | j                   S r'   rs   ru   s    r$   	__float__zTimer.__float__  s    ||r%   c                 ,    t        | j                        S r'   )intrs   ru   s    r$   __int__zTimer.__int__  s    4<<  r%   c                      d| j                   z  S )Nz%.3fr   ru   s    r$   __str__zTimer.__str__  s    $$r%   )NNNNr'   )r-   r.   r/   r0   timeitdefault_timerrq   r}   r   r   rj   rv   rz   r   r   r   r   r   r   r   r   r%   r$   rg   rg      sV    6r   E-K2N)"8;0!%r%   rg   c                       e Zd ZdZd Zd Zy)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                 z    || _         t        |      | _        |D ci c]  }|t        |       c}| _        y c c}w r'   )namesrY   numlengths)r   r   ns      r$   r   zChannelsFilter.__init__  s1    
u:+01a3q6	11s   8c                     | j                   dk(  ry| j                  D ]W  }| j                  |   }||j                  k(  r y|j                  j	                  |d|      dk(  sD|j                  |   dk(  sW y y)Nr   TrT   F)r   r   r   rC   r~   )r   r,   rC   nlens       r$   filterzChannelsFilter.filter  ss    88q=JJ 	D<<%Dv{{"!!$40A5&++d:Ks:R	 r%   N)r-   r.   r/   r0   r   r   r   r%   r$   r   r     s    42
	r%   r   c                   8     e Zd Z fdZd Zd Zd ZddZ xZS )CapturingLogHandlerc                     t         t        |   |       g | _        t	        |t
              rt        j                  |      | _        y || _        y )N)r"   )	r   r   r   recordsr   r   r   rA   r9   )r   r9   r"   r#   s      r$   r   zCapturingLogHandler.__init__  s@    !411>fc"!++F3DK DKr%   c                 l   | j                   j                  | _        | j                   j                  | _        | j                   j
                  | _        | j                   j                  |        | j                   j                  | j                         d| j                   _        d| j                   _        | S )NF)	r9   r^   original_disabledr"   original_levelr>   original_propagaterG   rH   ru   s    r$   r   zCapturingLogHandler.__enter__  s}    !%!5!5"kk//"&++"7"7t$TZZ($ %r%   c                     | j                   j                  |        | j                   j                  | j                         | j                  | j                   _        | j                  | j                   _        | S r'   )r9   r\   rH   r   r   r^   r   r>   )r   typevaluer   s       r$   r   zCapturingLogHandler.__exit__  sU    !!$'T001#55 $ 7 7r%   c                 :    | j                   j                  |       y r'   )r   rZ   )r   r,   s     r$   emitzCapturingLogHandler.emit  s    F#r%   c                     dd l }|j                  |      }| j                  D ]#  }|j                  |j	                               s# y |d|z  }J |       )Nr   Tz(Pattern '%s' not found in logger records)recompiler   search
getMessage)r   regexpri   r   patternrs         r$   assertRegexzCapturingLogHandler.assertRegex  sU    **V$ 	A~~alln-	 ;<vEC#qr%   r'   )	r-   r.   r/   r   r   r   r   r   r1   r2   s   @r$   r   r     s    !
$	r%   r   c                        e Zd ZdZed        Zy)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                     t        | d      sUdj                  | j                  j                  | j                  j                  f      }t        j                  |      | _        | j                  S )N_logrT   )hasattrrI   r#   r.   r-   r   rA   r   )r   rC   s     r$   r   zLogMixin.log  sO    tV$88T^^668O8OPQD))$/DIyyr%   N)r-   r.   r/   r0   propertyr   r   r%   r$   r   r     s    6  r%   r   c                 >    t        j                  | d||d       y)z:Raise a warning about deprecated function argument 'name'. is deprecated;    category
stacklevelN)warningswarn)rC   ri   r   s      r$   deprecateArgumentr     s    MMD#6VWXr%   c                       fd}|S )zBDecorator to raise a warning when a deprecated function is called.c                 4     t                fd       }|S )Nc                  b    t        j                  j                  dd        | i |S )Nr      r   )r   r   r-   )r   rK   r   r   ri   s     r$   r   z5deprecateFunction.<locals>.decorator.<locals>.wrapper  s3    MM*.--=!
 (((r%   r   )r   r   r   ri   s   ` r$   	decoratorz$deprecateFunction.<locals>.decorator  s     	t	) 
	) r%   r   )ri   r   r   s   `` r$   deprecateFunctionr   
  s    
 r%   __main__)optionflags)r=   )!sysr   r   	functoolsr   collections.abcr   r   r   r   r
   rl   r   	Formatterr   rQ   rB   objectrg   Filterr   Handlerr   r   UserWarningr   r   r-   doctestexittestmodELLIPSISfailedr   r%   r$   <module>r      s    
    -    ]]

 
&@:W&& @:F`@F&$Ra%F a%H)W^^ )X)'// )X!v !H +6 Y
 %0 $ zCHH_W__)9)9:AAB r%   