
    hM                        S SK r S SKrS SKrS SKJr  S SKJrJr  S SKrS SKJ	r	  \R                  rSSSS.r " S S	\R                  5      rS
 rSS jr " S S\5      r " S S\R&                  5      r " S S\R*                  5      r " S S\5      r\4S jr\4S jr\S:X  a9  S SKr\ R:                  " \R<                  " \R>                  S9R@                  5        gg)    Nwraps)MappingCallable)PercentStylez%(levelname)s: %(message)sz%(message)s)*INFODEBUGc                   <   ^  \ rS rSrSrSU 4S jjrU 4S jrSrU =r$ )LevelFormatter   a  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                   > US:w  a  [        S5      eUc  [        n[        U[        5      (       a  Un0 nOA[        U[        5      (       a  [        U5      nUR                  SS 5      nO[        SU-  5      e[        [        U ]+  XB5        U R                  U l        0 U l        UR                  5        H)  u  pa[        R                   " U5      nXR                  U'   M+     g )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          M/var/www/html/env/lib/python3.13/site-packages/fontTools/misc/loggingTools.pyr   LevelFormatter.__init__8   s    C<L  ;!Cc3 NNW%%!#YN+//T:NDsJKKnd,^E"ii (..0JE''.E),& 1    c                   > U R                   (       aa  U R                   R                  UR                  U R                  5      nU R                  U:w  a!  X l        [
        (       a  [        U5      U l        [        [        U ]'  U5      $ N)
r   getlevelnor   r   r   _styler   r   format)r   recordr    r$   s      r%   r-   LevelFormatter.formatN   sb    %%))&..$:M:MNCyyC	<".s"3DK^T1&99r'   )r   r,   r   r   )NNr   )	__name__
__module____qualname____firstlineno____doc__r   r-   __static_attributes____classcell__r$   s   @r%   r   r      s    B-,: :r'   r   c                     U R                  SS5      nUc  SU ;   a  SU ;   a  [        S5      eOSU ;   d  SU ;   a  [        S5      eUcm  U R                  SS5      nU R                  SS5      nU(       a  [        R                  " X#5      nO(U R                  SS5      n[        R                  " U5      nU/nU R                  S	S
5      nU(       a  [        U[        5      (       a  [        R                  " U5      n[        UR                  S9  U R                  SS5      nU R                  SS5      nU R                  SS5      n	[        XxU	5      n
U R                  S/ 5      nU H]  nUR                  c  UR                  U
5        UR                  (       d  U H  nUR                  U5        M     UR                  U5        M_     UR                  S:w  a  U R                  SS5      Ul        U R                  SS5      nUb  UR#                  U5        U (       a-  SR%                  U R'                  5       5      n[        SU-  5      eg)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setFormatterrA   	addFilter
addHandlerrC   setLeveljoinkeys)kwargsr9   r;   modehr:   r>   fsdfsr"   r    rA   fr#   rO   s                  r%   configLoggerrV   Y   s   Z zz*d+Hv*"6M  vv!55  ::j$/zz*c*##H3AZZ$/F%%f-A3ZZ+.FZ,,""6*-	Hd	#B
**Y
%CJJw$E
%
(CjjB'G;;NN3yyA !  {{f!::k59JJw%Eyy'7$>?? r'   c                    [         R                  n[        UR                  R                  R                  5       5      nU S:X  a  U /U-   nOlX;  a  gX;   aa  U /nUR                  U 5      S-   nU S-   n[        U5      n[        U5      nXG:  a*  X$   SU U:X  a  UR                  X$   5        US-  nXG:  a  M*  W H  nUS:X  av  UR                  [         R                  5        UR                  SS  H  n	UR                  U	5        M     UR                  SS  H  n
UR                  U
5        M     SUl        M  UR                  R                  U   n[         R                   Ul        / Ul        / Ul        SUl        SUl        M     g)zReset the logger named 'parent' and all its children to their initial
state, if they already exist in the current configuration.
rB   N   .FT)r   rB   sortedmanager
loggerDictrO   indexlenappendrM   WARNINGr9   removeHandlerrA   removeFiltersdisabledNOTSETr#   rC   )r@   rB   existingloggers_to_resetiprefixedpflennum_existingrH   rR   rU   r>   s               r%   rG   rG      sc    <<Ddll--2245H"8h.				"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                       \ rS rSrSr\R                  rSrSr	SS jr
SS jrS rS	 rS
 rS rS rSS jrS rS rS rSrg)Timer   a  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                     U R                  U5        Uc1  S H+  n[        5       R                  U5      c  M  [        SU-  5      e   Xl        Ub  UO[
        U l        X l        g )N)msgr#   z*'%s' can't be specified without a 'logger')resetlocalsr*   r   r>   
TIME_LEVELr#   ro   )r   r>   ro   r#   startargs         r%   r   Timer.__init__#  sZ    

5>'8<<$0$%QTW%WXX ( #/UZ
r'   c                 r    Uc  U R                  5       U l        OXl        U R                  U l        SU l        g)z0Reset timer to 'start_time' or the current time.N        )_timers   lastelapsed)r   rs   s     r%   rp   Timer.reset-  s+    =DJJJJ	r'   c                 <    U R                  5       U R                  -
  $ )z=Return the overall time (in seconds) since the timer started.)rx   rs   r   s    r%   time
Timer.time6  s    zz|djj((r'   c                 l    U R                  5       nXR                  -
  U l        Xl        U R                  $ )z=Split and return the lap time (in seconds) in between splits.rx   ry   rz   )r   currents     r%   splitTimer.split:  s*    **,*	||r'   c                     U(       d  U R                   nUR                  S5      S:  a  U R                  XS.-  nU$  USU0-  nU$ ! [        [        4 a     U$ f = f)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   ro   r~   r~   )default_msgfindr   KeyErrorr   )r   ro   r~   s      r%   
formatTimeTimer.formatTimeA  su     ""C88I"%%(BBC 
	VTN* 
 j) 
s   A AAc                 >    U R                  5       U l        SU l        U $ )zStart a new laprw   r   r}   s    r%   	__enter__Timer.__enter__R  s    JJL	r'   c                     U R                  5       nU R                  b  U(       a  gU R                  U R                  U5      nU R                  US.nU R                  R	                  U R
                  XV5        g)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).
Nr   )r   r>   r   ro   logr#   )r   exc_type	exc_value	tracebackr~   message	msg_partss          r%   __exit__Timer.__exit__X  sZ     zz|;;( //$((D1 !HHd3	

G7r'   c                 P  ^ ^ [        U[        5      (       a>  UmT R                  (       d  STR                  -  T l        [	        T5      UU 4S j5       nU$ U=(       d    UR                  S5      nUR                  ST R                  5      nT R                  T R                  XE5      $ )a.  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                  N   > T   T" U 0 UD6sS S S 5        $ ! , (       d  f       g = fr)    )argskwdsfuncr   s     r%   wrapperTimer.__call__.<locals>.wrappert  s    .. TTs   
$ro   r#   )	r   r   ro   r0   r   r*   r#   r$   r>   )r   func_or_msgrP   r   ro   r#   r   s   `     @r%   __call__Timer.__call__g  s     k8,,D88%54[/ / N2E!2CJJw

3E>>$++s::r'   c                     U R                   $ r)   rz   r}   s    r%   	__float__Timer.__float__  s    ||r'   c                 ,    [        U R                  5      $ r)   )intrz   r}   s    r%   __int__Timer.__int__  s    4<<  r'   c                      SU R                   -  $ )Nz%.3fr   r}   s    r%   __str__Timer.__str__  s    $$r'   )rz   ry   r#   r>   ro   rs   )NNNNr)   )r0   r1   r2   r3   r4   timeitdefault_timerrx   r   r   r   rp   r~   r   r   r   r   r   r   r   r   r5   r   r'   r%   rl   rl      sV    6r   E-K2N)"8;0!%r'   rl   c                   $    \ rS rSrSrS rS rSrg)ChannelsFilteri  a  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                 |    Xl         [        U5      U l        U Vs0 s H  o"[        U5      _M     snU l        g s  snf r)   )namesr^   numlengths)r   r   ns      r%   r   ChannelsFilter.__init__  s1    
u:+015a3q6	511s   9c                     U R                   S:X  a  gU R                   H[  nU R                  U   nX!R                  :X  a    gUR                  R	                  USU5      S:X  d  MF  UR                  U   S:X  d  M[    g   g)Nr   TrY   F)r   r   r   rH   r   )r   r.   rH   nlens       r%   filterChannelsFilter.filter  sl    88q=JJD<<%D{{"!!$40A5&++d:Ks:R  r'   )r   r   r   N)r0   r1   r2   r3   r4   r   r   r5   r   r'   r%   r   r     s    42
	r'   r   c                   D   ^  \ rS rSrU 4S jrS rS rS rSS jrSr	U =r
$ )	CapturingLogHandleri  c                    > [         [        U ]  US9  / U l        [	        U[
        5      (       a  [        R                  " U5      U l        g Xl        g )N)r#   )	r   r   r   recordsr   r   r   rF   r>   )r   r>   r#   r$   s      r%   r   CapturingLogHandler.__init__  sA    !411>fc""!++F3DK Kr'   c                 l   U R                   R                  U l        U R                   R                  U l        U R                   R
                  U l        U R                   R                  U 5        U R                   R                  U R                  5        SU R                   l        SU R                   l        U $ )NF)	r>   rc   original_disabledr#   original_levelrC   original_propagaterL   rM   r}   s    r%   r   CapturingLogHandler.__enter__  s}    !%!5!5"kk//"&++"7"7t$TZZ($ %r'   c                     U R                   R                  U 5        U R                   R                  U R                  5        U R                  U R                   l        U R                  U R                   l        U $ r)   )r>   ra   rM   r   r   rc   r   rC   )r   typevaluer   s       r%   r   CapturingLogHandler.__exit__  sU    !!$'T001#55 $ 7 7r'   c                 :    U R                   R                  U5        g r)   )r   r_   )r   r.   s     r%   emitCapturingLogHandler.emit  s    F#r'   c                     SS K nUR                  U5      nU R                   H)  nUR                  UR	                  5       5      (       d  M)    g   Uc  SU-  n U5       e)Nr   Tz(Pattern '%s' not found in logger records)recompiler   search
getMessage)r   regexpro   r   patternrs         r%   assertRegexCapturingLogHandler.assertRegex  sS    **V$A~~alln--  ;<vEC#qr'   )r>   r   r   r   r   r)   )r0   r1   r2   r3   r   r   r   r   r   r5   r6   r7   s   @r%   r   r     s!    !
$	 	r'   r   c                   (    \ rS rSrSr\S 5       rSrg)LogMixini  a  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                     [        U S5      (       dV  SR                  U R                  R                  U R                  R                  45      n[
        R                  " U5      U l        U R                  $ )N_logrY   )hasattrrN   r$   r1   r0   r   rF   r   )r   rH   s     r%   r   LogMixin.log  sR    tV$$88T^^668O8OPQD))$/DIyyr'   )r   N)r0   r1   r2   r3   r4   propertyr   r5   r   r'   r%   r   r     s    6  r'   r   c                 >    [         R                  " U < SU< 3USS9  g)z:Raise a warning about deprecated function argument 'name'. is deprecated;    category
stacklevelN)warningswarn)rH   ro   r   s      r%   deprecateArgumentr     s    MMD#6VWXr'   c                    ^ ^ UU 4S jnU$ )zBDecorator to raise a warning when a deprecated function is called.c                 6   >^  [        T 5      UU U4S j5       nU$ )Nc                  b   > [         R                  " TR                  < ST< 3TSS9  T" U 0 UD6$ )Nr      r   )r   r   r0   )r   rP   r   r   ro   s     r%   r   5deprecateFunction.<locals>.decorator.<locals>.wrapper  s3    MM*.--=!
 (((r'   r   )r   r   r   ro   s   ` r%   	decorator$deprecateFunction.<locals>.decorator  s     	t	) 
	) r'   r   )ro   r   r   s   `` r%   deprecateFunctionr   
  s    
 r'   __main__)optionflags)rB   )!sysr   r   	functoolsr   collections.abcr   r   r   r   r
   rr   r   	Formatterr   rV   rG   objectrl   Filterr   Handlerr   r   UserWarningr   r   r0   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HHW__)9)9:AAB r'   