loggingTools

fontTools.misc.loggingTools.py – tools for interfacing with the Python logging package.

class fontTools.misc.loggingTools.CapturingLogHandler(logger, level)[source]
assertRegex(regexp, msg=None)[source]
emit(record)[source]

Do whatever it takes to actually log the specified logging record.

This version is intended to be implemented by subclasses and so raises a NotImplementedError.

class fontTools.misc.loggingTools.ChannelsFilter(*names)[source]

Filter out records emitted from a list of enabled channel names, including their children. It works the same as the logging.Filter class, but allows 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!')
filter(record)[source]

Determine if the specified record is to be logged.

Is the specified record to be logged? Returns 0 for no, nonzero for yes. If deemed appropriate, the record may be modified in-place.

class fontTools.misc.loggingTools.LevelFormatter(fmt=None, datefmt=None, style='%')[source]

Formatter class which optionally takes a dict of logging levels to format strings, allowing to customise the log records appearance for specific levels. The ‘*’ key identifies the default format string.

>>> 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
format(record)[source]

Format the specified record as text.

The record’s attribute dictionary is used as the operand to a string formatting operation which yields the returned string. Before formatting the dictionary, a couple of preparatory steps are carried out. The message attribute of the record is computed using LogRecord.getMessage(). If the formatting string uses the time (as determined by a call to usesTime(), formatTime() is called to format the event time. If there is exception information, it is formatted using formatException() and appended to the message.

class fontTools.misc.loggingTools.LogMixin[source]

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
log
class fontTools.misc.loggingTools.Timer(logger=None, msg=None, level=None, start=None)[source]

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
default_format = 'Took %(time).3fs to %(msg)s'
default_msg = 'elapsed time: %(time).3fs'
formatTime(msg, time)[source]

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’.

reset(start=None)[source]

Reset timer to ‘start_time’ or the current time.

split()[source]

Split and return the lap time (in seconds) in between splits.

time()[source]

Return the overall time (in seconds) since the timer started.

fontTools.misc.loggingTools.configLogger(**kwargs)[source]

Do basic configuration for the logging system. This is more or less the same as 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.

logger Specifies the logger name or a Logger instance to be configured.
(it 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, which will be added to the handler(s), if the latter do(es) not already have filters assigned.
propagate All loggers have a “propagate” attribute initially set to True,
which determines whether to continue searching for handlers up the logging hierarchy. By default, this arguments sets the “propagate” attribute to False.
fontTools.misc.loggingTools.deprecateArgument(name, msg, category=<class 'UserWarning'>)[source]

Raise a warning about deprecated function argument ‘name’.

fontTools.misc.loggingTools.deprecateFunction(msg, category=<class 'UserWarning'>)[source]

Decorator to raise a warning when a deprecated function is called.