interpolation.py 1.8 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465
  1. from __future__ import absolute_import
  2. from __future__ import unicode_literals
  3. import logging
  4. from string import Template
  5. import six
  6. from .environment import Environment
  7. from .errors import ConfigurationError
  8. log = logging.getLogger(__name__)
  9. def interpolate_environment_variables(config, section):
  10. mapping = Environment.get_instance()
  11. def process_item(name, config_dict):
  12. return dict(
  13. (key, interpolate_value(name, key, val, section, mapping))
  14. for key, val in (config_dict or {}).items()
  15. )
  16. return dict(
  17. (name, process_item(name, config_dict or {}))
  18. for name, config_dict in config.items()
  19. )
  20. def interpolate_value(name, config_key, value, section, mapping):
  21. try:
  22. return recursive_interpolate(value, mapping)
  23. except InvalidInterpolation as e:
  24. raise ConfigurationError(
  25. 'Invalid interpolation format for "{config_key}" option '
  26. 'in {section} "{name}": "{string}"'.format(
  27. config_key=config_key,
  28. name=name,
  29. section=section,
  30. string=e.string))
  31. def recursive_interpolate(obj, mapping):
  32. if isinstance(obj, six.string_types):
  33. return interpolate(obj, mapping)
  34. elif isinstance(obj, dict):
  35. return dict(
  36. (key, recursive_interpolate(val, mapping))
  37. for (key, val) in obj.items()
  38. )
  39. elif isinstance(obj, list):
  40. return [recursive_interpolate(val, mapping) for val in obj]
  41. else:
  42. return obj
  43. def interpolate(string, mapping):
  44. try:
  45. return Template(string).substitute(mapping)
  46. except ValueError:
  47. raise InvalidInterpolation(string)
  48. class InvalidInterpolation(Exception):
  49. def __init__(self, string):
  50. self.string = string