aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBrian Harring <ferringb@gmail.com>2024-01-15 20:50:04 -0800
committerBrian Harring <ferringb@gmail.com>2024-01-23 00:52:08 -0800
commit6c1e1f997b0a99954f0eadd7898a368076fb0ea5 (patch)
treef26581b0365c62ee96d5c4ab76ccba0c1b99f49a
parentrefactor: Add missing abstractmethods for ConfiguredTree. (diff)
downloadpkgcore-6c1e1f997b0a99954f0eadd7898a368076fb0ea5.tar.gz
pkgcore-6c1e1f997b0a99954f0eadd7898a368076fb0ea5.tar.bz2
pkgcore-6c1e1f997b0a99954f0eadd7898a368076fb0ea5.zip
fix filtered.tree.{categories,packages,versions} .
The implementation wasn't properly aliasing _get_* to the underlying raw_repo, and it should've been filtering packages and versions according to the filter. This adds that. This isn't a huge issue, but it breaks API guarantees for code tring to efficienctly access this sort of info for a repository stack. Signed-off-by: Brian Harring <ferringb@gmail.com>
-rw-r--r--src/pkgcore/repository/filtered.py22
-rw-r--r--tests/repository/test_filtered.py22
2 files changed, 43 insertions, 1 deletions
diff --git a/src/pkgcore/repository/filtered.py b/src/pkgcore/repository/filtered.py
index 2e700d7e4..81f5b7e7f 100644
--- a/src/pkgcore/repository/filtered.py
+++ b/src/pkgcore/repository/filtered.py
@@ -5,12 +5,15 @@ filtering repository
__all__ = ("tree",)
from itertools import filterfalse
+import typing
-from snakeoil.klass import DirProxy, GetAttrProxy
+from snakeoil.klass import DirProxy, GetAttrProxy, alias_method
from ..operations.repo import operations_proxy
from ..restrictions import restriction
from . import errors, prototype
+from pkgcore.ebuild.restricts import CategoryDep
+from pkgcore.ebuild.atom import atom
class tree(prototype.tree):
@@ -33,6 +36,7 @@ class tree(prototype.tree):
self._filterfunc = filter
else:
self._filterfunc = filterfalse
+ super().__init__()
def itermatch(self, restrict, **kwds):
# note that this lets the repo do the initial filtering.
@@ -54,6 +58,22 @@ class tree(prototype.tree):
count += 1
return count
+ # note: for the _get_* methods they use itermatch which would typically
+ # be a cycle; this class's itermatch is fully reliant on the raw repo
+ # thus no cycle.
+
+ # TODO: add support for .{category,package,version}.force_regen via custom class. No code relies upon this,
+ # but that functionality missing means the implementation has a known potential for developing a stale cache.
+ _get_categories = alias_method("raw_repo.categories.__iter__")
+
+ def _get_packages(self, category: str) -> typing.Iterable[str]:
+ for package in self.raw_repo.packages[category]:
+ if any(self.itermatch(atom(f"{category}/{package}"))):
+ yield package
+
+ def _get_versions(self, catpkg: tuple[str, str]) -> typing.Iterable[str]:
+ return (pkg.fullver for pkg in self.itermatch(atom(f"{catpkg[0]}/{catpkg[1]}")))
+
__getattr__ = GetAttrProxy("raw_repo")
__dir__ = DirProxy("raw_repo")
diff --git a/tests/repository/test_filtered.py b/tests/repository/test_filtered.py
index 312e2528b..7a04c21b9 100644
--- a/tests/repository/test_filtered.py
+++ b/tests/repository/test_filtered.py
@@ -1,4 +1,5 @@
from pkgcore.ebuild.atom import atom
+from pkgcore.ebuild.restricts import CategoryDep
from pkgcore.ebuild.cpv import VersionedCPV
from pkgcore.repository import filtered
from pkgcore.repository.util import SimpleTree
@@ -57,3 +58,24 @@ class TestVisibility:
)
)
assert sorted(vrepo) == sorted(repo.itermatch(atom("dev-util/bsdiff")))
+
+ def test_categories_api(self):
+ # filter to just dev-util/diffball; this confirms that empty categories are filter,
+ # and that filtering of a package (leaving one in a category still) doesn't filter the category.
+ _, vrepo = self.setup_repos(
+ packages.OrRestriction(CategoryDep("dev-lib"), atom("dev-util/bsdiff"))
+ )
+ assert sorted(vrepo.categories) == sorted(
+ [
+ "dev-lib",
+ "dev-util",
+ ]
+ ), "category filtering must not filter dev-lib even if there are no packages left post filtering"
+
+ def test_packages_api(self):
+ _, vrepo = self.setup_repos(atom("dev-util/diffball"))
+ assert sorted(vrepo.packages["dev-util"]) == ["bsdiff"]
+
+ def test_versions_api(self):
+ _, vrepo = self.setup_repos(atom("=dev-util/diffball-1.0"))
+ assert sorted(vrepo.versions[("dev-util", "diffball")]) == ["0.7"]