aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBrian Harring <ferringb@gmail.com>2023-01-16 23:22:56 -0800
committerArthur Zamarin <arthurzam@gentoo.org>2023-02-05 20:08:21 +0200
commit07602f09835ad21fed1603cd44923fe6e288c24a (patch)
tree607f266b4abaf220cdd9430fa95446e528535985
parentrefactor(config): remove indirection of multiplex.config_tree for multiplex.tree (diff)
downloadpkgcore-07602f09835ad21fed1603cd44923fe6e288c24a.tar.gz
pkgcore-07602f09835ad21fed1603cd44923fe6e288c24a.tar.bz2
pkgcore-07602f09835ad21fed1603cd44923fe6e288c24a.zip
refactor(config): remove the notion of config layer incremental prepend/append.
Many moons gone past the original config system tried to support the idea of incrementally stacked values (x y -x z -y == z). This commit removes the fundamental core of that functionality; the incremental logic is now implemented in domain specific layers, rather than being a capability of the config layer. Note: this just removes the logic. The signature of [before, mid, after] return is still in place, and will be removed as the API is normalized. In particular, pconfig still reports on .prepend/.apend, there just no longer is content there. That behaviour (and signature) change will be a followon commit. Signed-off-by: Brian Harring <ferringb@gmail.com> Signed-off-by: Arthur Zamarin <arthurzam@gentoo.org>
-rw-r--r--src/pkgcore/config/basics.py95
-rw-r--r--src/pkgcore/ebuild/portage_conf.py6
-rw-r--r--tests/config/test_basics.py81
-rw-r--r--tests/config/test_central.py86
-rw-r--r--tests/config/test_cparser.py5
5 files changed, 24 insertions, 249 deletions
diff --git a/src/pkgcore/config/basics.py b/src/pkgcore/config/basics.py
index 95792ea26..3ab3e73f7 100644
--- a/src/pkgcore/config/basics.py
+++ b/src/pkgcore/config/basics.py
@@ -10,7 +10,6 @@ __all__ = (
"LazyNamedSectionRef",
"ConfigSection",
"DictConfigSection",
- "FakeIncrementalDictConfigSection",
"convert_string",
"convert_asis",
"convert_hybrid",
@@ -247,50 +246,12 @@ class DictConfigSection(ConfigSection):
func: typing.Callable
dict: dict[str, typing.Any]
- def __init__(self, conversion_func, source_dict: dict[str, typing.Any]) -> None:
- """Initialize.
-
- :type conversion_func: callable.
- :param conversion_func: called with a ConfigManager, a value from
- the dict and a type name.
- :type source_dict: dict with string keys and arbitrary values.
- """
- super().__init__()
- self.func = conversion_func
- self.dict = source_dict
-
- def __contains__(self, name: str) -> bool:
- return name in self.dict
-
- def keys(self) -> list[str]:
- return list(self.dict.keys())
-
- def render_value(self, central, name: str, arg_type: str):
- try:
- return self.func(central, self.dict[name], arg_type)
- except IGNORED_EXCEPTIONS:
- raise
- except Exception as e:
- raise errors.ConfigurationError(
- f"Failed converting argument {name!r} to {arg_type}"
- ) from e
-
-
-class FakeIncrementalDictConfigSection(ConfigSection):
- """Turns a dict and a conversion function into a ConfigSection."""
-
- func: typing.Callable
- dict: dict[str, typing.Any]
-
def __init__(
self, conversion_func: typing.Callable, source_dict: dict[str, typing.Any]
) -> None:
"""Initialize.
- A request for a section of a list type will look for
- name.prepend and name.append keys too, using those for values
- prepended/appended to the inherited values. The conversion
- func should return a single sequence for list types and in
+ The conversion func should return a single sequence for list types and in
repr for list types.
:type conversion_func: callable.
@@ -303,47 +264,31 @@ class FakeIncrementalDictConfigSection(ConfigSection):
self.dict = source_dict
def __contains__(self, name: str) -> bool:
- return (
- name in self.dict
- or name + ".append" in self.dict
- or name + ".prepend" in self.dict
- )
+ return name in self.dict
def keys(self) -> list[str]:
- keys = set()
- for key in self.dict:
- if key.endswith(".append"):
- key = key[:-7]
- elif key.endswith(".prepend"):
- key = key[:-8]
- keys.add(key)
- return list(keys)
+ return list(self.dict.keys())
def render_value(self, central, name: str, arg_type: str):
# Check if we need our special incremental magic.
if arg_type in ("list", "str", "repr") or arg_type.startswith("refs:"):
- result = []
- # Careful: None is a valid dict value, so use something else here.
- missing = object()
- for subname in (name + ".prepend", name, name + ".append"):
- val = self.dict.get(subname, missing)
- if val is missing:
- val = None
- else:
- try:
- val = self.func(central, val, arg_type)
- except IGNORED_EXCEPTIONS:
- raise
- except Exception as e:
- raise errors.ConfigurationError(
- f"Failed converting argument {subname!r} to {arg_type}"
- ) from e
- result.append(val)
- if result[0] is result[1] is result[2] is None:
+ try:
+ val = self.func(central, self.dict[name], arg_type)
+ except IGNORED_EXCEPTIONS:
+ raise
+ except Exception as e:
+ raise errors.ConfigurationError(
+ f"Failed converting argument {name!r} to {arg_type}"
+ ) from e
+ if val is None:
raise KeyError(name)
+ result = [None, val, None]
if arg_type != "repr":
# Done.
return result
+ # what follows is basically a type annotation shoved into this pathway, resulting
+ # in a differing signature from norms. repr arg_type needs to be removed for this reason.
+
# If "kind" is of some incremental-ish kind or we have
# .prepend or .append for this key then we need to
# convert everything we have to the same kind and
@@ -428,7 +373,7 @@ class FakeIncrementalDictConfigSection(ConfigSection):
else:
converted.append([val])
return target_kind, converted
- # Not incremental.
+ # simple types.
try:
return self.func(central, self.dict[name], arg_type)
except IGNORED_EXCEPTIONS:
@@ -597,9 +542,9 @@ def convert_hybrid(central, value, arg_type: str):
# "Invalid name" (pylint thinks these are module-level constants)
# pylint: disable-msg=C0103
-HardCodedConfigSection = partial(FakeIncrementalDictConfigSection, convert_asis)
-ConfigSectionFromStringDict = partial(FakeIncrementalDictConfigSection, convert_string)
-AutoConfigSection = partial(FakeIncrementalDictConfigSection, convert_hybrid)
+HardCodedConfigSection = partial(DictConfigSection, convert_asis)
+ConfigSectionFromStringDict = partial(DictConfigSection, convert_string)
+AutoConfigSection = partial(DictConfigSection, convert_hybrid)
def section_alias(target, typename: str) -> AutoConfigSection:
diff --git a/src/pkgcore/ebuild/portage_conf.py b/src/pkgcore/ebuild/portage_conf.py
index d33d2e37d..84f39ce27 100644
--- a/src/pkgcore/ebuild/portage_conf.py
+++ b/src/pkgcore/ebuild/portage_conf.py
@@ -213,7 +213,7 @@ class PortageConfig(DictMixin):
self._make_repo_syncers(repos_conf, make_conf)
if repos:
- self["repo-stack"] = basics.FakeIncrementalDictConfigSection(
+ self["repo-stack"] = basics.DictConfigSection(
my_convert_hybrid,
{
"class": "pkgcore.repository.multiplex.tree",
@@ -248,9 +248,7 @@ class PortageConfig(DictMixin):
}
)
- self["livefs"] = basics.FakeIncrementalDictConfigSection(
- my_convert_hybrid, make_conf
- )
+ self["livefs"] = basics.DictConfigSection(my_convert_hybrid, make_conf)
def __setitem__(self, key, value):
self._config[key] = value
diff --git a/tests/config/test_basics.py b/tests/config/test_basics.py
index e04cc7047..10f0841e1 100644
--- a/tests/config/test_basics.py
+++ b/tests/config/test_basics.py
@@ -248,87 +248,6 @@ class TestDictConfigSection:
section.render_value(None, "list", "spoon")
-class TestFakeIncrementalDictConfigSection:
- @staticmethod
- def _convert(central, value, arg_type):
- return central, value, arg_type
-
- @staticmethod
- def _fail(central, value, arg_type):
- raise errors.ConfigurationError("fail")
-
- def test_misc(self):
- section = basics.FakeIncrementalDictConfigSection(
- self._convert, {"list": [1, 2]}
- )
- assert "foo" not in section
- assert "list" in section
- assert ["list"] == list(section.keys())
- with pytest.raises(errors.ConfigurationError):
- obj = basics.FakeIncrementalDictConfigSection(self._fail, {"a": "b"})
- obj.render_value(None, "a", "str")
-
- def test_fake_incrementals(self):
- section = basics.FakeIncrementalDictConfigSection(
- self._convert, {"seq.append": [1, 2]}
- )
- manager = object()
- assert [None, None, (manager, [1, 2], "list")] == section.render_value(
- manager, "seq", "list"
- )
-
- def _repr(central, value, arg_type):
- return "list", ["thing"]
-
- section = basics.FakeIncrementalDictConfigSection(_repr, {"foo": None})
- assert ("list", (None, ["thing"], None)) == section.render_value(
- manager, "foo", "repr"
- )
- with pytest.raises(errors.ConfigurationError):
- obj = basics.FakeIncrementalDictConfigSection(
- self._fail, {"a.prepend": "b"}
- )
- obj.render_value(None, "a", "list")
-
- def test_repr(self):
- def asis(central, value, arg_type):
- assert arg_type == "repr", arg_type
- return value
-
- source_dict = {
- "seq.append": ("list", [1, 2]),
- "simple": ("bool", True),
- "multistr": ("str", "body"),
- "multistr.prepend": ("str", "head"),
- "refs": ("str", "lost"),
- "refs.append": ("ref", "main"),
- "refs.prepend": ("refs", ["a", "b"]),
- "strlist": ("callable", asis),
- "strlist.prepend": ("str", "whatever"),
- "wrong.prepend": ("wrong", "wrong"),
- }
- section = basics.FakeIncrementalDictConfigSection(asis, source_dict)
- manager = object()
- with pytest.raises(KeyError):
- section.render_value(manager, "spoon", "repr")
- assert ("list", [None, None, [1, 2]]) == section.render_value(
- manager, "seq", "repr"
- )
- assert ("bool", True) == section.render_value(manager, "simple", "repr")
- assert ("str", ["head", "body", None]) == section.render_value(
- manager, "multistr", "repr"
- )
- assert ("refs", [["a", "b"], ["lost"], ["main"]]) == section.render_value(
- manager, "refs", "repr"
- )
- assert (
- "list",
- [["whatever"], ["tests.config.test_basics.asis"], None],
- ) == section.render_value(manager, "strlist", "repr")
- with pytest.raises(errors.ConfigurationError):
- section.render_value(manager, "wrong", "repr")
-
-
class TestConvertString:
def test_render_value(self):
source = {
diff --git a/tests/config/test_central.py b/tests/config/test_central.py
index 5ffb8072b..55b541f8f 100644
--- a/tests/config/test_central.py
+++ b/tests/config/test_central.py
@@ -970,89 +970,3 @@ def test_self_inherit():
)
assert manager.collapse_named_section("self")
assert manager.collapse_section([section])
-
-
-def test_prepend_inherit():
- manager = central.ConfigManager(
- [{"sect": basics.HardCodedConfigSection({"inherit.prepend": ["self"]})}]
- )
- check_error(
- "Collapsing section named 'sect':\n"
- "Prepending or appending to the inherit list makes no sense",
- manager.collapse_named_section,
- "sect",
- )
-
-
-def test_list_prepend():
- @configurable(types={"seq": "list"})
- def seq(seq):
- return seq
-
- manager = central.ConfigManager(
- [
- {
- "inh": basics.HardCodedConfigSection(
- {
- "inherit": ["sect"],
- "seq.prepend": ["pre"],
- }
- ),
- "sect": basics.HardCodedConfigSection(
- {
- "inherit": ["base"],
- "seq": ["1", "2"],
- }
- ),
- },
- {
- "base": basics.HardCodedConfigSection(
- {
- "class": seq,
- "seq.prepend": ["-1"],
- "seq.append": ["post"],
- }
- )
- },
- ]
- )
- assert ["-1", "post"] == manager.objects.seq["base"]
- assert ["1", "2"] == manager.objects.seq["sect"]
- assert ["pre", "1", "2"] == manager.objects.seq["inh"]
-
-
-def test_str_prepend():
- @configurable(types={"string": "str"})
- def sect(string):
- return string
-
- manager = central.ConfigManager(
- [
- {
- "inh": basics.HardCodedConfigSection(
- {
- "inherit": ["sect"],
- "string.prepend": "pre",
- }
- ),
- "sect": basics.HardCodedConfigSection(
- {
- "inherit": ["base"],
- "string": "b",
- }
- ),
- },
- {
- "base": basics.HardCodedConfigSection(
- {
- "class": sect,
- "string.prepend": "a",
- "string.append": "c",
- }
- )
- },
- ]
- )
- assert "a c" == manager.objects.sect["base"]
- assert "b" == manager.objects.sect["sect"]
- assert "pre b" == manager.objects.sect["inh"]
diff --git a/tests/config/test_cparser.py b/tests/config/test_cparser.py
index e7d0b0ea5..a9082adbf 100644
--- a/tests/config/test_cparser.py
+++ b/tests/config/test_cparser.py
@@ -2,6 +2,7 @@ import textwrap
from io import StringIO
import pytest
+
from pkgcore.config import central, cparser, errors
@@ -33,8 +34,6 @@ class TestConfigFromIni:
[test]
string = 'hi I am a string'
list = foo bar baz
- list.prepend = pre bits
- list.append = post bits
true = yes
false = no
"""
@@ -48,7 +47,7 @@ class TestConfigFromIni:
(
"list",
"list",
- [["pre", "bits"], ["foo", "bar", "baz"], ["post", "bits"]],
+ [None, ["foo", "bar", "baz"], None],
),
("true", "bool", True),
("false", "bool", False),