aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-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 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)