aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBrian Harring <ferringb@gmail.com>2023-11-21 02:29:41 -0800
committerArthur Zamarin <arthurzam@gentoo.org>2023-12-03 07:18:39 +0200
commit4414df46c2c01fa61c2afec95a1826f00dbc980e (patch)
tree2ce73b200335e0edfaa4f2f27d52d3a01e5946e7
parentrepo: Simplify SimpleTree signature (diff)
downloadpkgcore-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.py5
-rw-r--r--src/pkgcore/ebuild/repository.py7
-rw-r--r--src/pkgcore/repository/multiplex.py35
-rw-r--r--src/pkgcore/repository/prototype.py65
-rw-r--r--src/pkgcore/repository/util.py4
-rw-r--r--src/pkgcore/repository/virtual.py7
-rw-r--r--src/pkgcore/vdb/ondisk.py5
-rw-r--r--tests/ebuild/test_repository.py2
8 files changed, 43 insertions, 87 deletions
diff --git a/src/pkgcore/binpkg/repository.py b/src/pkgcore/binpkg/repository.py
index e4b8acc6..20441408 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 49bd72e1..18a6f0ca 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 f56dfb0e..d7b218cc 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 52221108..8830459e 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 8cc48547..aae530f4 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 000eb0e4..b584c71b 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 e871129e..9e5eb924 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 2ba4eda5..71366ba2 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)