BVB Source Codes

rq Show dictconfig.py Source code

Return Download rq: download dictconfig.py Source code - Download rq Source code - Type:.py
  1. # flake8: noqa
  2. # This is a copy of the Python logging.config.dictconfig module.  It is
  3. # provided here for backwards compatibility for Python versions prior to 2.7.
  4. #
  5. # Copyright 2009-2010 by Vinay Sajip. All Rights Reserved.
  6. #
  7. # Permission to use, copy, modify, and distribute this software and its
  8. # documentation for any purpose and without fee is hereby granted,
  9. # provided that the above copyright notice appear in all copies and that
  10. # both that copyright notice and this permission notice appear in
  11. # supporting documentation, and that the name of Vinay Sajip
  12. # not be used in advertising or publicity pertaining to distribution
  13. # of the software without specific, written prior permission.
  14. # VINAY SAJIP DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
  15. # ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL
  16. # VINAY SAJIP BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
  17. # ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER
  18. # IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
  19. # OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
  20.  
  21. import logging.handlers
  22. import re
  23. import sys
  24. import types
  25. from rq.compat import string_types
  26.  
  27. IDENTIFIER = re.compile('^[a-z_][a-z0-9_]*$', re.I)
  28.  
  29. def valid_ident(s):
  30.     m = IDENTIFIER.match(s)
  31.     if not m:
  32.         raise ValueError('Not a valid Python identifier: %r' % s)
  33.     return True
  34.  
  35. #
  36. # This function is defined in logging only in recent versions of Python
  37. #
  38. try:
  39.     from logging import _checkLevel
  40. except ImportError:
  41.     def _checkLevel(level):
  42.         if isinstance(level, int):
  43.             rv = level
  44.         elif str(level) == level:
  45.             if level not in logging._levelNames:
  46.                 raise ValueError('Unknown level: %r' % level)
  47.             rv = logging._levelNames[level]
  48.         else:
  49.             raise TypeError('Level not an integer or a '
  50.                             'valid string: %r' % level)
  51.         return rv
  52.  
  53. # The ConvertingXXX classes are wrappers around standard Python containers,
  54. # and they serve to convert any suitable values in the container. The
  55. # conversion converts base dicts, lists and tuples to their wrapped
  56. # equivalents, whereas strings which match a conversion format are converted
  57. # appropriately.
  58. #
  59. # Each wrapper should have a configurator attribute holding the actual
  60. # configurator to use for conversion.
  61.  
  62. class ConvertingDict(dict):
  63.     """A converting dictionary wrapper."""
  64.  
  65.     def __getitem__(self, key):
  66.         value = dict.__getitem__(self, key)
  67.         result = self.configurator.convert(value)
  68.         #If the converted value is different, save for next time
  69.         if value is not result:
  70.             self[key] = result
  71.             if type(result) in (ConvertingDict, ConvertingList,
  72.                                 ConvertingTuple):
  73.                 result.parent = self
  74.                 result.key = key
  75.         return result
  76.  
  77.     def get(self, key, default=None):
  78.         value = dict.get(self, key, default)
  79.         result = self.configurator.convert(value)
  80.         #If the converted value is different, save for next time
  81.         if value is not result:
  82.             self[key] = result
  83.             if type(result) in (ConvertingDict, ConvertingList,
  84.                                 ConvertingTuple):
  85.                 result.parent = self
  86.                 result.key = key
  87.         return result
  88.  
  89.     def pop(self, key, default=None):
  90.         value = dict.pop(self, key, default)
  91.         result = self.configurator.convert(value)
  92.         if value is not result:
  93.             if type(result) in (ConvertingDict, ConvertingList,
  94.                                 ConvertingTuple):
  95.                 result.parent = self
  96.                 result.key = key
  97.         return result
  98.  
  99. class ConvertingList(list):
  100.     """A converting list wrapper."""
  101.     def __getitem__(self, key):
  102.         value = list.__getitem__(self, key)
  103.         result = self.configurator.convert(value)
  104.         #If the converted value is different, save for next time
  105.         if value is not result:
  106.             self[key] = result
  107.             if type(result) in (ConvertingDict, ConvertingList,
  108.                                 ConvertingTuple):
  109.                 result.parent = self
  110.                 result.key = key
  111.         return result
  112.  
  113.     def pop(self, idx=-1):
  114.         value = list.pop(self, idx)
  115.         result = self.configurator.convert(value)
  116.         if value is not result:
  117.             if type(result) in (ConvertingDict, ConvertingList,
  118.                                 ConvertingTuple):
  119.                 result.parent = self
  120.         return result
  121.  
  122. class ConvertingTuple(tuple):
  123.     """A converting tuple wrapper."""
  124.     def __getitem__(self, key):
  125.         value = tuple.__getitem__(self, key)
  126.         result = self.configurator.convert(value)
  127.         if value is not result:
  128.             if type(result) in (ConvertingDict, ConvertingList,
  129.                                 ConvertingTuple):
  130.                 result.parent = self
  131.                 result.key = key
  132.         return result
  133.  
  134. class BaseConfigurator(object):
  135.     """
  136.    The configurator base class which defines some useful defaults.
  137.    """
  138.  
  139.     CONVERT_PATTERN = re.compile(r'^(?P<prefix>[a-z]+)://(?P<suffix>.*)$')
  140.  
  141.     WORD_PATTERN = re.compile(r'^\s*(\w+)\s*')
  142.     DOT_PATTERN = re.compile(r'^\.\s*(\w+)\s*')
  143.     INDEX_PATTERN = re.compile(r'^\[\s*(\w+)\s*\]\s*')
  144.     DIGIT_PATTERN = re.compile(r'^\d+$')
  145.  
  146.     value_converters = {
  147.         'ext' : 'ext_convert',
  148.         'cfg' : 'cfg_convert',
  149.     }
  150.  
  151.     # We might want to use a different one, e.g. importlib
  152.     importer = __import__
  153.  
  154.     def __init__(self, config):
  155.         self.config = ConvertingDict(config)
  156.         self.config.configurator = self
  157.  
  158.     def resolve(self, s):
  159.         """
  160.        Resolve strings to objects using standard import and attribute
  161.        syntax.
  162.        """
  163.         name = s.split('.')
  164.         used = name.pop(0)
  165.         try:
  166.             found = self.importer(used)
  167.             for frag in name:
  168.                 used += '.' + frag
  169.                 try:
  170.                     found = getattr(found, frag)
  171.                 except AttributeError:
  172.                     self.importer(used)
  173.                     found = getattr(found, frag)
  174.             return found
  175.         except ImportError:
  176.             e, tb = sys.exc_info()[1:]
  177.             v = ValueError('Cannot resolve %r: %s' % (s, e))
  178.             v.__cause__, v.__traceback__ = e, tb
  179.             raise v
  180.  
  181.     def ext_convert(self, value):
  182.         """Default converter for the ext:// protocol."""
  183.         return self.resolve(value)
  184.  
  185.     def cfg_convert(self, value):
  186.         """Default converter for the cfg:// protocol."""
  187.         rest = value
  188.         m = self.WORD_PATTERN.match(rest)
  189.         if m is None:
  190.             raise ValueError("Unable to convert %r" % value)
  191.         else:
  192.             rest = rest[m.end():]
  193.             d = self.config[m.groups()[0]]
  194.             #print d, rest
  195.             while rest:
  196.                 m = self.DOT_PATTERN.match(rest)
  197.                 if m:
  198.                     d = d[m.groups()[0]]
  199.                 else:
  200.                     m = self.INDEX_PATTERN.match(rest)
  201.                     if m:
  202.                         idx = m.groups()[0]
  203.                         if not self.DIGIT_PATTERN.match(idx):
  204.                             d = d[idx]
  205.                         else:
  206.                             try:
  207.                                 n = int(idx) # try as number first (most likely)
  208.                                 d = d[n]
  209.                             except TypeError:
  210.                                 d = d[idx]
  211.                 if m:
  212.                     rest = rest[m.end():]
  213.                 else:
  214.                     raise ValueError('Unable to convert '
  215.                                      '%r at %r' % (value, rest))
  216.         #rest should be empty
  217.         return d
  218.  
  219.     def convert(self, value):
  220.         """
  221.        Convert values to an appropriate type. dicts, lists and tuples are
  222.        replaced by their converting alternatives. Strings are checked to
  223.        see if they have a conversion format and are converted if they do.
  224.        """
  225.         if not isinstance(value, ConvertingDict) and isinstance(value, dict):
  226.             value = ConvertingDict(value)
  227.             value.configurator = self
  228.         elif not isinstance(value, ConvertingList) and isinstance(value, list):
  229.             value = ConvertingList(value)
  230.             value.configurator = self
  231.         elif not isinstance(value, ConvertingTuple) and\
  232.                  isinstance(value, tuple):
  233.             value = ConvertingTuple(value)
  234.             value.configurator = self
  235.         elif isinstance(value, string_types): # str for py3k
  236.             m = self.CONVERT_PATTERN.match(value)
  237.             if m:
  238.                 d = m.groupdict()
  239.                 prefix = d['prefix']
  240.                 converter = self.value_converters.get(prefix, None)
  241.                 if converter:
  242.                     suffix = d['suffix']
  243.                     converter = getattr(self, converter)
  244.                     value = converter(suffix)
  245.         return value
  246.  
  247.     def configure_custom(self, config):
  248.         """Configure an object with a user-supplied factory."""
  249.         c = config.pop('()')
  250.         if not hasattr(c, '__call__') and type(c) != type:
  251.             c = self.resolve(c)
  252.         props = config.pop('.', None)
  253.         # Check for valid identifiers
  254.         kwargs = dict([(k, config[k]) for k in config if valid_ident(k)])
  255.         result = c(**kwargs)
  256.         if props:
  257.             for name, value in props.items():
  258.                 setattr(result, name, value)
  259.         return result
  260.  
  261.     def as_tuple(self, value):
  262.         """Utility function which converts lists to tuples."""
  263.         if isinstance(value, list):
  264.             value = tuple(value)
  265.         return value
  266.  
  267. class DictConfigurator(BaseConfigurator):
  268.     """
  269.    Configure logging using a dictionary-like object to describe the
  270.    configuration.
  271.    """
  272.  
  273.     def configure(self):
  274.         """Do the configuration."""
  275.  
  276.         config = self.config
  277.         if 'version' not in config:
  278.             raise ValueError("dictionary doesn't specify a version")
  279.         if config['version'] != 1:
  280.             raise ValueError("Unsupported version: %s" % config['version'])
  281.         incremental = config.pop('incremental', False)
  282.         EMPTY_DICT = {}
  283.         logging._acquireLock()
  284.         try:
  285.             if incremental:
  286.                 handlers = config.get('handlers', EMPTY_DICT)
  287.                 # incremental handler config only if handler name
  288.                 # ties in to logging._handlers (Python 2.7)
  289.                 if sys.version_info[:2] == (2, 7):
  290.                     for name in handlers:
  291.                         if name not in logging._handlers:
  292.                             raise ValueError('No handler found with '
  293.                                              'name %r'  % name)
  294.                         else:
  295.                             try:
  296.                                 handler = logging._handlers[name]
  297.                                 handler_config = handlers[name]
  298.                                 level = handler_config.get('level', None)
  299.                                 if level:
  300.                                     handler.setLevel(_checkLevel(level))
  301.                             except Exception as e:
  302.                                 raise ValueError('Unable to configure handler '
  303.                                                  '%r: %s' % (name, e))
  304.                 loggers = config.get('loggers', EMPTY_DICT)
  305.                 for name in loggers:
  306.                     try:
  307.                         self.configure_logger(name, loggers[name], True)
  308.                     except Exception as e:
  309.                         raise ValueError('Unable to configure logger '
  310.                                          '%r: %s' % (name, e))
  311.                 root = config.get('root', None)
  312.                 if root:
  313.                     try:
  314.                         self.configure_root(root, True)
  315.                     except Exception as e:
  316.                         raise ValueError('Unable to configure root '
  317.                                          'logger: %s' % e)
  318.             else:
  319.                 disable_existing = config.pop('disable_existing_loggers', True)
  320.  
  321.                 logging._handlers.clear()
  322.                 del logging._handlerList[:]
  323.  
  324.                 # Do formatters first - they don't refer to anything else
  325.                 formatters = config.get('formatters', EMPTY_DICT)
  326.                 for name in formatters:
  327.                     try:
  328.                         formatters[name] = self.configure_formatter(
  329.                                                             formatters[name])
  330.                     except Exception as e:
  331.                         raise ValueError('Unable to configure '
  332.                                          'formatter %r: %s' % (name, e))
  333.                 # Next, do filters - they don't refer to anything else, either
  334.                 filters = config.get('filters', EMPTY_DICT)
  335.                 for name in filters:
  336.                     try:
  337.                         filters[name] = self.configure_filter(filters[name])
  338.                     except Exception as e:
  339.                         raise ValueError('Unable to configure '
  340.                                          'filter %r: %s' % (name, e))
  341.  
  342.                 # Next, do handlers - they refer to formatters and filters
  343.                 # As handlers can refer to other handlers, sort the keys
  344.                 # to allow a deterministic order of configuration
  345.                 handlers = config.get('handlers', EMPTY_DICT)
  346.                 for name in sorted(handlers):
  347.                     try:
  348.                         handler = self.configure_handler(handlers[name])
  349.                         handler.name = name
  350.                         handlers[name] = handler
  351.                     except Exception as e:
  352.                         raise ValueError('Unable to configure handler '
  353.                                          '%r: %s' % (name, e))
  354.                 # Next, do loggers - they refer to handlers and filters
  355.  
  356.                 #we don't want to lose the existing loggers,
  357.                 #since other threads may have pointers to them.
  358.                 #existing is set to contain all existing loggers,
  359.                 #and as we go through the new configuration we
  360.                 #remove any which are configured. At the end,
  361.                 #what's left in existing is the set of loggers
  362.                 #which were in the previous configuration but
  363.                 #which are not in the new configuration.
  364.                 root = logging.root
  365.                 existing = root.manager.loggerDict.keys()
  366.                 #The list needs to be sorted so that we can
  367.                 #avoid disabling child loggers of explicitly
  368.                 #named loggers. With a sorted list it is easier
  369.                 #to find the child loggers.
  370.                 existing.sort()
  371.                 #We'll keep the list of existing loggers
  372.                 #which are children of named loggers here...
  373.                 child_loggers = []
  374.                 #now set up the new ones...
  375.                 loggers = config.get('loggers', EMPTY_DICT)
  376.                 for name in loggers:
  377.                     if name in existing:
  378.                         i = existing.index(name)
  379.                         prefixed = name + "."
  380.                         pflen = len(prefixed)
  381.                         num_existing = len(existing)
  382.                         i = i + 1 # look at the entry after name
  383.                         while (i < num_existing) and\
  384.                               (existing[i][:pflen] == prefixed):
  385.                             child_loggers.append(existing[i])
  386.                             i = i + 1
  387.                         existing.remove(name)
  388.                     try:
  389.                         self.configure_logger(name, loggers[name])
  390.                     except Exception as e:
  391.                         raise ValueError('Unable to configure logger '
  392.                                          '%r: %s' % (name, e))
  393.  
  394.                 #Disable any old loggers. There's no point deleting
  395.                 #them as other threads may continue to hold references
  396.                 #and by disabling them, you stop them doing any logging.
  397.                 #However, don't disable children of named loggers, as that's
  398.                 #probably not what was intended by the user.
  399.                 for log in existing:
  400.                     logger = root.manager.loggerDict[log]
  401.                     if log in child_loggers:
  402.                         logger.level = logging.NOTSET
  403.                         logger.handlers = []
  404.                         logger.propagate = True
  405.                     elif disable_existing:
  406.                         logger.disabled = True
  407.  
  408.                 # And finally, do the root logger
  409.                 root = config.get('root', None)
  410.                 if root:
  411.                     try:
  412.                         self.configure_root(root)
  413.                     except Exception as e:
  414.                         raise ValueError('Unable to configure root '
  415.                                          'logger: %s' % e)
  416.         finally:
  417.             logging._releaseLock()
  418.  
  419.     def configure_formatter(self, config):
  420.         """Configure a formatter from a dictionary."""
  421.         if '()' in config:
  422.             factory = config['()'] # for use in exception handler
  423.             try:
  424.                 result = self.configure_custom(config)
  425.             except TypeError as te:
  426.                 if "'format'" not in str(te):
  427.                     raise
  428.                 #Name of parameter changed from fmt to format.
  429.                 #Retry with old name.
  430.                 #This is so that code can be used with older Python versions
  431.                 #(e.g. by Django)
  432.                 config['fmt'] = config.pop('format')
  433.                 config['()'] = factory
  434.                 result = self.configure_custom(config)
  435.         else:
  436.             fmt = config.get('format', None)
  437.             dfmt = config.get('datefmt', None)
  438.             result = logging.Formatter(fmt, dfmt)
  439.         return result
  440.  
  441.     def configure_filter(self, config):
  442.         """Configure a filter from a dictionary."""
  443.         if '()' in config:
  444.             result = self.configure_custom(config)
  445.         else:
  446.             name = config.get('name', '')
  447.             result = logging.Filter(name)
  448.         return result
  449.  
  450.     def add_filters(self, filterer, filters):
  451.         """Add filters to a filterer from a list of names."""
  452.         for f in filters:
  453.             try:
  454.                 filterer.addFilter(self.config['filters'][f])
  455.             except Exception as e:
  456.                 raise ValueError('Unable to add filter %r: %s' % (f, e))
  457.  
  458.     def configure_handler(self, config):
  459.         """Configure a handler from a dictionary."""
  460.         formatter = config.pop('formatter', None)
  461.         if formatter:
  462.             try:
  463.                 formatter = self.config['formatters'][formatter]
  464.             except Exception as e:
  465.                 raise ValueError('Unable to set formatter '
  466.                                  '%r: %s' % (formatter, e))
  467.         level = config.pop('level', None)
  468.         filters = config.pop('filters', None)
  469.         if '()' in config:
  470.             c = config.pop('()')
  471.             if not hasattr(c, '__call__') and type(c) != type:
  472.                 c = self.resolve(c)
  473.             factory = c
  474.         else:
  475.             klass = self.resolve(config.pop('class'))
  476.             #Special case for handler which refers to another handler
  477.             if issubclass(klass, logging.handlers.MemoryHandler) and\
  478.                 'target' in config:
  479.                 try:
  480.                     config['target'] = self.config['handlers'][config['target']]
  481.                 except Exception as e:
  482.                     raise ValueError('Unable to set target handler '
  483.                                      '%r: %s' % (config['target'], e))
  484.             elif issubclass(klass, logging.handlers.SMTPHandler) and\
  485.                 'mailhost' in config:
  486.                 config['mailhost'] = self.as_tuple(config['mailhost'])
  487.             elif issubclass(klass, logging.handlers.SysLogHandler) and\
  488.                 'address' in config:
  489.                 config['address'] = self.as_tuple(config['address'])
  490.             factory = klass
  491.         kwargs = dict([(str(k), config[k]) for k in config if valid_ident(k)])
  492.         try:
  493.             result = factory(**kwargs)
  494.         except TypeError as te:
  495.             if "'stream'" not in str(te):
  496.                 raise
  497.             #The argument name changed from strm to stream
  498.             #Retry with old name.
  499.             #This is so that code can be used with older Python versions
  500.             #(e.g. by Django)
  501.             kwargs['strm'] = kwargs.pop('stream')
  502.             result = factory(**kwargs)
  503.         if formatter:
  504.             result.setFormatter(formatter)
  505.         if level is not None:
  506.             result.setLevel(_checkLevel(level))
  507.         if filters:
  508.             self.add_filters(result, filters)
  509.         return result
  510.  
  511.     def add_handlers(self, logger, handlers):
  512.         """Add handlers to a logger from a list of names."""
  513.         for h in handlers:
  514.             try:
  515.                 logger.addHandler(self.config['handlers'][h])
  516.             except Exception as e:
  517.                 raise ValueError('Unable to add handler %r: %s' % (h, e))
  518.  
  519.     def common_logger_config(self, logger, config, incremental=False):
  520.         """
  521.        Perform configuration which is common to root and non-root loggers.
  522.        """
  523.         level = config.get('level', None)
  524.         if level is not None:
  525.             logger.setLevel(_checkLevel(level))
  526.         if not incremental:
  527.             #Remove any existing handlers
  528.             for h in logger.handlers[:]:
  529.                 logger.removeHandler(h)
  530.             handlers = config.get('handlers', None)
  531.             if handlers:
  532.                 self.add_handlers(logger, handlers)
  533.             filters = config.get('filters', None)
  534.             if filters:
  535.                 self.add_filters(logger, filters)
  536.  
  537.     def configure_logger(self, name, config, incremental=False):
  538.         """Configure a non-root logger from a dictionary."""
  539.         logger = logging.getLogger(name)
  540.         self.common_logger_config(logger, config, incremental)
  541.         propagate = config.get('propagate', None)
  542.         if propagate is not None:
  543.             logger.propagate = propagate
  544.  
  545.     def configure_root(self, config, incremental=False):
  546.         """Configure a root logger from a dictionary."""
  547.         root = logging.getLogger()
  548.         self.common_logger_config(root, config, incremental)
  549.  
  550. dictConfigClass = DictConfigurator
  551.  
  552. def dictConfig(config):
  553.     """Configure logging using a dictionary."""
  554.     dictConfigClass(config).configure()
  555.  
downloaddictconfig.py Source code - Download rq Source code
Related Source Codes/Software:
amazon-dsstne - Deep Scalable Sparse Tensor Network Engine (DSSTNE... 2017-01-08
webpack-demos - a collection of simple demos of Webpack 2017-01-08
Squire - HTML5 rich text editor. Try the demo integration a... 2017-01-08
thor - Thor is a toolkit for building powerful command-li... 2017-01-08
glide - Package Management for Golang h... 2017-01-08
emmet-vim - emmet for vim: http://emmet.io/ ... 2017-01-08
prose - A Content Editor for GitHub. ht... 2017-01-08
sshrc - ring your .bashrc, .vimrc, etc. with you when you ... 2017-01-08
typed.js - A jQuery typing animation script. ... 2017-01-08
find - High-precision indoor positioning framework for mo... 2017-01-08
CRYENGINE - CRYENGINE is a powerful real-time game development... 2017-06-11
postal - 2017-06-11
reactide - Reactide is the first dedicated IDE for React web ... 2017-06-11
rkt - rkt is a pod-native container engine for Linux. It... 2017-06-11
uWebSockets - Tiny WebSockets https://for... 2017-06-11
realworld - TodoMVC for the RealWorld - Exemplary fullstack Me... 2017-06-11
goreplay - GoReplay is an open-source tool for capturing and ... 2017-06-10
pyenv - Simple Python version management 2017-06-10
redux-saga - An alternative side effect model for Redux apps ... 2017-06-10
angular-starter - 2017-06-10

 Back to top