diff --git a/swift/common/utils.py b/swift/common/utils.py index 0b5bb1eea3..6f0224c221 100644 --- a/swift/common/utils.py +++ b/swift/common/utils.py @@ -72,6 +72,7 @@ if not six.PY2: utf16_decoder = codecs.getdecoder('utf-16') utf16_encoder = codecs.getencoder('utf-16') from six.moves import cPickle as pickle +from six.moves import configparser from six.moves.configparser import (ConfigParser, NoSectionError, NoOptionError, RawConfigParser) from six.moves import range, http_client @@ -2965,6 +2966,17 @@ def read_conf_dir(parser, conf_dir): return parser.read(sorted(conf_files)) +if six.PY2: + NicerInterpolation = None # just don't cause ImportErrors over in wsgi.py +else: + class NicerInterpolation(configparser.BasicInterpolation): + def before_get(self, parser, section, option, value, defaults): + if '%(' not in value: + return value + return super(NicerInterpolation, self).before_get( + parser, section, option, value, defaults) + + def readconf(conf_path, section_name=None, log_name=None, defaults=None, raw=False): """ @@ -2986,7 +2998,19 @@ def readconf(conf_path, section_name=None, log_name=None, defaults=None, if raw: c = RawConfigParser(defaults) else: - c = ConfigParser(defaults) + if six.PY2: + c = ConfigParser(defaults) + else: + # In general, we haven't really thought much about interpolation + # in configs. Python's default ConfigParser has always supported + # it, though, so *we* got it "for free". Unfortunatley, since we + # "supported" interpolation, we have to assume there are + # deployments in the wild that use it, and try not to break them. + # So, do what we can to mimic the py2 behavior of passing through + # values like "1%" (which we want to support for + # fallocate_reserve). + c = ConfigParser(defaults, interpolation=NicerInterpolation()) + if hasattr(conf_path, 'readline'): if hasattr(conf_path, 'seek'): conf_path.seek(0) diff --git a/swift/common/wsgi.py b/swift/common/wsgi.py index 7d4246689d..1b2b86557a 100644 --- a/swift/common/wsgi.py +++ b/swift/common/wsgi.py @@ -32,7 +32,6 @@ from eventlet.green import socket, ssl, os as green_os import six from six import BytesIO from six import StringIO -from six.moves import configparser from swift.common import utils, constraints from swift.common.storage_policy import BindPortsCache @@ -41,7 +40,7 @@ from swift.common.swob import Request, wsgi_quote, wsgi_unquote, \ from swift.common.utils import capture_stdio, disable_fallocate, \ drop_privileges, get_logger, NullLogger, config_true_value, \ validate_configuration, get_hub, config_auto_int_value, \ - reiterate + reiterate, NicerInterpolation SIGNUM_TO_NAME = {getattr(signal, n): n for n in dir(signal) if n.startswith('SIG') and '_' not in n} @@ -56,23 +55,6 @@ except (ImportError, NotImplementedError): CPU_COUNT = 1 -if not six.PY2: - # In general, we haven't really thought much about interpolation in - # configs. Python's default ConfigParser has always supported it, though, - # so *we* got it "for free". Unfortunatley, since we "supported" - # interpolation, we have to assume there are deployments in the wild that - # use it, and try not to break them. So, do what we can to mimic the py2 - # behavior of passing through values like "1%" (which we want to support - # for fallocate_reserve). - class NicerInterpolation(configparser.BasicInterpolation): - def before_get(self, parser, section, option, value, defaults): - if '%(' not in value: - return value - return super(NicerInterpolation, self).before_get( - parser, section, option, value, defaults) - configparser.ConfigParser._DEFAULT_INTERPOLATION = NicerInterpolation() - - class NamedConfigLoader(loadwsgi.ConfigLoader): """ Patch paste.deploy's ConfigLoader so each context object will know what @@ -80,6 +62,8 @@ class NamedConfigLoader(loadwsgi.ConfigLoader): """ def get_context(self, object_type, name=None, global_conf=None): + if not six.PY2: + self.parser._interpolation = NicerInterpolation() context = super(NamedConfigLoader, self).get_context( object_type, name=name, global_conf=global_conf) context.name = name