diff --git a/src/plaster_pastedeploy/__init__.py b/src/plaster_pastedeploy/__init__.py index 1dada65..0704cbd 100644 --- a/src/plaster_pastedeploy/__init__.py +++ b/src/plaster_pastedeploy/__init__.py @@ -1,5 +1,4 @@ -from collections import OrderedDict -from configparser import NoSectionError +from configparser import ConfigParser, NoSectionError import logging from logging.config import fileConfig import os @@ -44,7 +43,7 @@ def get_sections(self): parser = self._get_parser() return parser.sections() - def get_settings(self, section=None, defaults=None): + def get_settings(self, section=None, defaults=None, *, raw=False): """ Gets a named section from the configuration source. @@ -54,24 +53,39 @@ def get_settings(self, section=None, defaults=None): :param defaults: a :class:`dict` that will get passed to :class:`configparser.ConfigParser` and will populate the ``DEFAULT`` section. + :param raw: when not True, return the section without interpolation, + application of defaults, or other alteration. The return + value then has a :attr:`global_config` of :code:`None`. :return: A :class:`plaster_pastedeploy.ConfigDict` of key/value pairs. """ - # This is a partial reimplementation of + # This contains a partial reimplementation of # ``paste.deploy.loadwsgi.ConfigLoader:get_context`` which supports # "set" and "get" options and filters out any other globals section = self._maybe_get_default_name(section) if self.filepath is None: return {} - parser = self._get_parser(defaults) - defaults = parser.defaults() + + if raw: + parser = ConfigParser(default_section=None, interpolation=None) + with open(self.uri.path) as fd: + parser.read_file(fd, source=self.uri.path) + else: + parser = self._get_parser(defaults) + defaults = parser.defaults() try: raw_items = parser.items(section) except NoSectionError: return {} - local_conf = OrderedDict() + local_conf = {} + + if raw: + for option, value in raw_items: + local_conf[option] = value + return ConfigDict(local_conf, None, self) + get_from_globals = {} for option, value in raw_items: if option.startswith("set "): @@ -161,7 +175,7 @@ def get_wsgi_filter(self, name=None, defaults=None): def get_wsgi_app_settings(self, name=None, defaults=None): """ - Return an :class:`collections.OrderedDict` representing the + Return a dict representing the application config for a WSGI application named ``name`` in the PasteDeploy config file specified by ``self.uri``. @@ -251,7 +265,7 @@ def get_pastedeploy_scheme(uri): return scheme -class ConfigDict(OrderedDict, loadwsgi.AttrDict): +class ConfigDict(loadwsgi.AttrDict): def __init__(self, local_conf, global_conf, loader): super().__init__(local_conf) self.global_conf = global_conf diff --git a/tests/test_get_settings.py b/tests/test_get_settings.py index 5e6e0ad..b0e17b4 100644 --- a/tests/test_get_settings.py +++ b/tests/test_get_settings.py @@ -24,50 +24,81 @@ def test_missing_section(self): result = self.loader.get_settings("missing", {"a": "b"}) assert result == {} - def test_no_defaults_passed(self): - result = self.loader.get_settings("section1") - assert list(result.items()) == [ - ("a", "a_val"), - ("c", "override_b"), - ("b", "default_b"), - ] - - assert result.global_conf["default_a"] == "default_a" - assert result.global_conf["default_b"] == "override_b" + @pytest.mark.parametrize("raw", [False, True]) + def test_no_defaults_passed(self, raw): + result = self.loader.get_settings("section1", raw=raw) + if raw: + assert list(result.items()) == [ + ("a", "a_val"), + ("get c", "default_b"), + ("b", "%(default_b)s"), + ("set default_b", "override_b"), + ] + else: + assert list(result.items()) == [ + ("a", "a_val"), + ("c", "override_b"), + ("b", "default_b"), + ] + + if raw: + assert result.global_conf is None + else: + assert result.global_conf["default_a"] == "default_a" + assert result.global_conf["default_b"] == "override_b" assert result.loader == self.loader - with pytest.raises(Exception, match="default_c"): - self.loader.get_settings("section2") + if not raw: + with pytest.raises(Exception, match="default_c"): + self.loader.get_settings("section2", raw=raw) - def test_defaults_passed(self): + @pytest.mark.parametrize("raw", [False, True]) + def test_defaults_passed(self, raw): defaults = {"default_c": "default_c"} - result = self.loader.get_settings("section1", defaults=defaults) + result = self.loader.get_settings("section1", defaults=defaults, raw=raw) assert result["a"] == "a_val" - assert result["b"] == "default_b" + if raw: + assert result["b"] == "%(default_b)s" + else: + assert result["b"] == "default_b" assert "default_c" not in result - assert result.global_conf["default_a"] == "default_a" - assert result.global_conf["default_b"] == "override_b" - assert result.global_conf["default_c"] == "default_c" + if raw: + assert result.global_conf is None + else: + assert result.global_conf["default_a"] == "default_a" + assert result.global_conf["default_b"] == "override_b" + assert result.global_conf["default_c"] == "default_c" - result = self.loader.get_settings("section2", defaults=defaults) + result = self.loader.get_settings("section2", defaults=defaults, raw=raw) assert result["a"] == "a_val" assert result["b"] == "b_val" - assert result["c"] == "default_c" + if raw: + assert result["c"] == "%(default_c)s" + else: + assert result["c"] == "default_c" - assert result.global_conf["default_a"] == "default_a" - assert result.global_conf["default_b"] == "default_b" - assert result.global_conf["default_c"] == "default_c" + if raw: + assert result.global_conf is None + else: + assert result.global_conf["default_a"] == "default_a" + assert result.global_conf["default_b"] == "default_b" + assert result.global_conf["default_c"] == "default_c" class TestSectionedURI(TestSimpleUri): config_uri = test_settings_path + "#section1" - def test_no_section_name_passed(self): - result = self.loader.get_settings() + @pytest.mark.parametrize("raw", [False, True]) + def test_no_section_name_passed(self, raw): + result = self.loader.get_settings(raw=raw) assert result["a"] == "a_val" - assert result["b"] == "default_b" - assert result["c"] == "override_b" + if raw: + assert result["b"] == "%(default_b)s" + assert "c" not in result + else: + assert result["b"] == "default_b" + assert result["c"] == "override_b" assert "default_b" not in result @@ -86,10 +117,12 @@ def test_sections(self): result = self.loader.get_sections() assert result == [] - def test_settings(self): - result = self.loader.get_settings() + @pytest.mark.parametrize("raw", [False, True]) + def test_settings(self, raw): + result = self.loader.get_settings(raw=raw) assert result == {} - def test_named_settings(self): - result = self.loader.get_settings("missing") + @pytest.mark.parametrize("raw", [False, True]) + def test_named_settings(self, raw): + result = self.loader.get_settings("missing", raw=raw) assert result == {}