diff options
author | 2023-11-21 02:29:41 -0800 | |
---|---|---|
committer | 2023-12-03 07:18:39 +0200 | |
commit | 4414df46c2c01fa61c2afec95a1826f00dbc980e (patch) | |
tree | 2ce73b200335e0edfaa4f2f27d52d3a01e5946e7 | |
parent | repo: Simplify SimpleTree signature (diff) | |
download | pkgcore-4414df46c2c01fa61c2afec95a1826f00dbc980e.tar.gz pkgcore-4414df46c2c01fa61c2afec95a1826f00dbc980e.tar.bz2 pkgcore-4414df46c2c01fa61c2afec95a1826f00dbc980e.zip |
core: remove the ability to have multi-level categories
The support for multiple levels of categories never was
used, thus it's time to remove it since it also simplifies
things.
Doing this means the original dict functionality of
repo.categories should be replaced w/ a sequence which
this also does.
Signed-off-by: Brian Harring <ferringb@gmail.com>
Closes: https://github.com/pkgcore/pkgcore/pull/417
Signed-off-by: Arthur Zamarin <arthurzam@gentoo.org>
-rw-r--r-- | src/pkgcore/binpkg/repository.py | 5 | ||||
-rw-r--r-- | src/pkgcore/ebuild/repository.py | 7 | ||||
-rw-r--r-- | src/pkgcore/repository/multiplex.py | 35 | ||||
-rw-r--r-- | src/pkgcore/repository/prototype.py | 65 | ||||
-rw-r--r-- | src/pkgcore/repository/util.py | 4 | ||||
-rw-r--r-- | src/pkgcore/repository/virtual.py | 7 | ||||
-rw-r--r-- | src/pkgcore/vdb/ondisk.py | 5 | ||||
-rw-r--r-- | tests/ebuild/test_repository.py | 2 |
8 files changed, 43 insertions, 87 deletions
diff --git a/src/pkgcore/binpkg/repository.py b/src/pkgcore/binpkg/repository.py index e4b8acc63..204414083 100644 --- a/src/pkgcore/binpkg/repository.py +++ b/src/pkgcore/binpkg/repository.py @@ -239,10 +239,7 @@ class tree(prototype.tree): def __str__(self): return self.repo_id - def _get_categories(self, *optional_category): - # return if optional_category is passed... cause it's not yet supported - if optional_category: - return {} + def _get_categories(self): try: return tuple(x for x in listdir_dirs(self.base) if x.lower() != "all") except EnvironmentError as e: diff --git a/src/pkgcore/ebuild/repository.py b/src/pkgcore/ebuild/repository.py index 49bd72e19..18a6f0ca7 100644 --- a/src/pkgcore/ebuild/repository.py +++ b/src/pkgcore/ebuild/repository.py @@ -518,12 +518,7 @@ class UnconfiguredTree(prototype.tree): logger.error(f"failed listing categories: {e}") return () - def _get_categories(self, *optional_category): - # why the auto return? current porttrees don't allow/support - # categories deeper then one dir. - if optional_category: - # raise KeyError - return () + def _get_categories(self): categories = frozenset( chain.from_iterable(repo.config.categories for repo in self.trees) ) diff --git a/src/pkgcore/repository/multiplex.py b/src/pkgcore/repository/multiplex.py index f56dfb0e3..d7b218cc4 100644 --- a/src/pkgcore/repository/multiplex.py +++ b/src/pkgcore/repository/multiplex.py @@ -91,50 +91,37 @@ class tree(prototype.tree): ) self.trees = trees - def _get_categories(self, *optional_category): + def _get_categories(self): d = set() - failures = 0 - if optional_category: - optional_category = optional_category[0] - for x in self.trees: - try: - d.update(x.categories[optional_category]) - except KeyError: - failures += 1 - else: - for x in self.trees: - try: - list(map(d.add, x.categories)) - except (errors.RepoError, KeyError): - failures += 1 - if failures == len(self.trees): - if optional_category: - raise KeyError("category base '%s' not found" % str(optional_category)) + for x in self.trees: + try: + d.update(x.categories) + except (errors.RepoError, KeyError): + pass + if not d: raise KeyError("failed getting categories") return tuple(d) def _get_packages(self, category): d = set() - failures = 0 for x in self.trees: try: d.update(x.packages[category]) except (errors.RepoError, KeyError): - failures += 1 - if failures == len(self.trees): + pass + if not d: raise KeyError(f"category {category!r} not found") return tuple(d) def _get_versions(self, package): d = set() - failures = 0 for x in self.trees: try: d.update(x.versions[package]) except (errors.RepoError, KeyError): - failures += 1 + pass - if failures == len(self.trees): + if not d: raise KeyError(f"category {package!r} not found") return tuple(d) diff --git a/src/pkgcore/repository/prototype.py b/src/pkgcore/repository/prototype.py index 52221108a..8830459e9 100644 --- a/src/pkgcore/repository/prototype.py +++ b/src/pkgcore/repository/prototype.py @@ -2,9 +2,10 @@ base repository template """ -__all__ = ("CategoryIterValLazyDict", "PackageMapping", "VersionMapping", "tree") +__all__ = ("CategoryLazyFrozenSet", "PackageMapping", "VersionMapping", "tree") from pathlib import Path +import typing from snakeoil.klass import jit_attr from snakeoil.mappings import DictMixin, LazyValDict @@ -16,38 +17,28 @@ from ..restrictions import boolean, packages, restriction, values from ..restrictions.util import collect_package_restrictions -class IterValLazyDict(LazyValDict): - __slots__ = () +class CategoryLazyFrozenSet: + """Lazy frozenset for holding categories""" - def __str__(self): - return str(list(self)) - - def force_regen(self, key): - if key in self._vals: - del self._vals[key] - else: - self._keys = tuple(x for x in self._keys if x != key) - - -class CategoryIterValLazyDict(IterValLazyDict): - __slots__ = () + __slots__ = ("_get_values", "_values") - def force_add(self, key): - if key not in self: - s = set(self._keys) - s.add(key) - self._keys = tuple(s) + def __init__(self, get_values: typing.Callable[[], typing.Iterable[str]]): + self._get_values = get_values + self._values = None # type: typing.Union[None, frozenset] - def force_remove(self, key): - if key in self: - self._keys = tuple(x for x in self._keys if x != key) + def __iter__(self): + if self._values is None: + self._values = frozenset(self._get_values()) + return iter(self._values) - __iter__ = IterValLazyDict.keys + def __contains__(self, cat: str): + if self._values is None: + self._values = frozenset(self._get_values()) + return cat in self._values - def __contains__(self, key): - if self._keys_func is not None: - return key in list(self.keys()) - return key in self._keys + def force_regen(self): + """wipe cached values to trigger a refresh""" + self._values = None class PackageMapping(DictMixin): @@ -66,16 +57,13 @@ class PackageMapping(DictMixin): return vals def keys(self): - return self._parent.keys() + return iter(self._parent) def __contains__(self, key): return key in self._cache or key in self._parent def force_regen(self, cat): - try: - del self._cache[cat] - except KeyError: - pass + self._cache.pop(cat, None) class VersionMapping(DictMixin): @@ -139,9 +127,7 @@ class tree: pkg_masks = frozenset() def __init__(self, frozen=False): - self.categories = CategoryIterValLazyDict( - self._get_categories, self._get_categories - ) + self.categories = CategoryLazyFrozenSet(self._get_categories) self.packages = PackageMapping(self.categories, self._get_packages) self.versions = VersionMapping(self.packages, self._get_versions) @@ -153,7 +139,7 @@ class tree: """Return a configured form of the repository.""" raise NotImplementedError(self, "configure") - def _get_categories(self, *args): + def _get_categories(self): """this must return a list, or sequence""" raise NotImplementedError(self, "_get_categories") @@ -477,7 +463,7 @@ class tree: wipe = list(self.packages[pkg.category]) == [pkg.package] self.packages.force_regen(pkg.category) if wipe: - self.categories.force_regen(pkg.category) + self.categories.force_regen() self.versions.force_regen(ver_key, tuple(l)) def notify_add_package(self, pkg): @@ -488,8 +474,7 @@ class tree: ver_key = (pkg.category, pkg.package) s = set(self.versions.get(ver_key, ())) s.add(pkg.fullver) - if pkg.category not in self.categories: - self.categories.force_add(pkg.category) + self.categories.force_regen() self.packages.force_regen(pkg.category) self.versions.force_regen(ver_key, tuple(s)) diff --git a/src/pkgcore/repository/util.py b/src/pkgcore/repository/util.py index 8cc485478..aae530f4a 100644 --- a/src/pkgcore/repository/util.py +++ b/src/pkgcore/repository/util.py @@ -32,9 +32,7 @@ class SimpleTree(prototype.tree): self.package_class = pkg_klass super().__init__(frozen=frozen) - def _get_categories(self, *arg): - if arg: - return () + def _get_categories(self): return tuple(self.cpv_dict.keys()) def _get_packages(self, category): diff --git a/src/pkgcore/repository/virtual.py b/src/pkgcore/repository/virtual.py index 000eb0e46..b584c71b3 100644 --- a/src/pkgcore/repository/virtual.py +++ b/src/pkgcore/repository/virtual.py @@ -41,10 +41,7 @@ class tree(prototype.tree): ): yield pkg - def _get_categories(self, *optional_category): - # return if optional_category is passed... cause it's not yet supported - if optional_category: - return () + def _get_categories(self): return ("virtual",) def _load_data(self): @@ -157,7 +154,7 @@ class RestrictionRepo(tree): def restriction(self): return OrRestriction(*self._restrictions.keys()) - def _get_categories(self, *args): + def _get_categories(self): return tuple(x.category for x in self._injected_pkgs) def _get_packages(self, category): diff --git a/src/pkgcore/vdb/ondisk.py b/src/pkgcore/vdb/ondisk.py index e871129e2..9e5eb924d 100644 --- a/src/pkgcore/vdb/ondisk.py +++ b/src/pkgcore/vdb/ondisk.py @@ -72,10 +72,7 @@ class tree(prototype.tree): def configure(self, *args): return ConfiguredTree(self, *args) - def _get_categories(self, *optional_category): - # return if optional_category is passed... cause it's not yet supported - if optional_category: - return {} + def _get_categories(self): try: try: return tuple( diff --git a/tests/ebuild/test_repository.py b/tests/ebuild/test_repository.py index 2ba4eda57..71366ba2e 100644 --- a/tests/ebuild/test_repository.py +++ b/tests/ebuild/test_repository.py @@ -179,7 +179,7 @@ class TestUnconfiguredTree: (tmp_path / "empty" / "empty").mkdir(parents=True) (tmp_path / "cat" / "pkg" / "pkg-3.ebuild").touch() repo = self.mk_tree(tmp_path) - assert {"cat": (), "empty": ()} == dict(repo.categories) + assert frozenset(["cat", "empty"]) == frozenset(repo.categories) assert {"cat": ("pkg",), "empty": ("empty",)} == dict(repo.packages) assert {("cat", "pkg"): ("3",), ("empty", "empty"): ()} == dict(repo.versions) |