commit:     d87eeb7b8edf846330e3c2031eea2f326f149506
Author:     Zac Medico <zmedico <AT> gentoo <DOT> org>
AuthorDate: Sat Aug 29 05:10:45 2015 +0000
Commit:     Zac Medico <zmedico <AT> gentoo <DOT> org>
CommitDate: Sun Aug 30 23:42:42 2015 +0000
URL:        https://gitweb.gentoo.org/proj/portage.git/commit/?id=d87eeb7b

emerge --search: fix duplication of results (bug 559044)

Fix search._cp_all() to ensure sorted input for MultiIterGroupBy.
Add a boolean "sort" keyword argument to all dbapi.cp_all()
implementations, and set defaults for backward compatible behavior.

X-Gentoo-Bug: 559044
X-Gentoo-Bug-url: https://bugs.gentoo.org/show_bug.cgi?id=559044
Acked-by: Brian Dolbec <dolsen <AT> gentoo.org>

 pym/_emerge/PackageVirtualDbapi.py | 4 ++--
 pym/_emerge/search.py              | 3 ++-
 pym/portage/dbapi/IndexedPortdb.py | 4 ++--
 pym/portage/dbapi/IndexedVardb.py  | 6 +++---
 pym/portage/dbapi/__init__.py      | 4 ++--
 pym/portage/dbapi/bintree.py       | 4 ++--
 pym/portage/dbapi/porttree.py      | 6 ++++--
 pym/portage/dbapi/vartree.py       | 4 ++--
 pym/portage/dbapi/virtual.py       | 4 ++--
 9 files changed, 21 insertions(+), 18 deletions(-)

diff --git a/pym/_emerge/PackageVirtualDbapi.py 
b/pym/_emerge/PackageVirtualDbapi.py
index 56a5576..26293dd 100644
--- a/pym/_emerge/PackageVirtualDbapi.py
+++ b/pym/_emerge/PackageVirtualDbapi.py
@@ -105,8 +105,8 @@ class PackageVirtualDbapi(dbapi):
                self._match_cache[cache_key] = cpv_list
                return cpv_list[:]
 
-       def cp_all(self):
-               return list(self._cp_map)
+       def cp_all(self, sort=False):
+               return sorted(self._cp_map) if sort else list(self._cp_map)
 
        def cpv_all(self):
                return list(self._cpv_map)

diff --git a/pym/_emerge/search.py b/pym/_emerge/search.py
index 41c182d..32d326e 100644
--- a/pym/_emerge/search.py
+++ b/pym/_emerge/search.py
@@ -72,7 +72,8 @@ class search(object):
        def _cp_all(self):
                iterators = []
                for db in self._dbs:
-                       i = db.cp_all()
+                       # MultiIterGroupBy requires sorted input
+                       i = db.cp_all(sort=True)
                        try:
                                i = iter(i)
                        except TypeError:

diff --git a/pym/portage/dbapi/IndexedPortdb.py 
b/pym/portage/dbapi/IndexedPortdb.py
index e96f83c..510e027 100644
--- a/pym/portage/dbapi/IndexedPortdb.py
+++ b/pym/portage/dbapi/IndexedPortdb.py
@@ -127,14 +127,14 @@ class IndexedPortdb(object):
                                if new_cp is not None:
                                        yield cp_group[0].cp
 
-       def cp_all(self):
+       def cp_all(self, sort=True):
                """
                Returns an ordered iterator instead of a list, so that search
                results can be displayed incrementally.
                """
                if self._cp_map is None:
                        return self._init_index()
-               return iter(sorted(self._cp_map))
+               return iter(sorted(self._cp_map)) if sort else 
iter(self._cp_map)
 
        def match(self, atom):
                """

diff --git a/pym/portage/dbapi/IndexedVardb.py 
b/pym/portage/dbapi/IndexedVardb.py
index 38bfeed..b946670 100644
--- a/pym/portage/dbapi/IndexedVardb.py
+++ b/pym/portage/dbapi/IndexedVardb.py
@@ -35,13 +35,13 @@ class IndexedVardb(object):
 
                self._cp_map = None
 
-       def cp_all(self):
+       def cp_all(self, sort=True):
                """
                Returns an ordered iterator instead of a list, so that search
                results can be displayed incrementally.
                """
                if self._cp_map is not None:
-                       return iter(sorted(self._cp_map))
+                       return iter(sorted(self._cp_map)) if sort else 
iter(self._cp_map)
 
                delta_data = self._vardb._cache_delta.loadRace()
                if delta_data is None:
@@ -62,7 +62,7 @@ class IndexedVardb(object):
                                cp_map[cpv.cp] = cp_list
                        cp_list.append(cpv)
 
-               return iter(sorted(self._cp_map))
+               return iter(sorted(self._cp_map)) if sort else 
iter(self._cp_map)
 
        def _iter_cp_all(self):
                self._cp_map = cp_map = {}

diff --git a/pym/portage/dbapi/__init__.py b/pym/portage/dbapi/__init__.py
index 044faec..b6745fa 100644
--- a/pym/portage/dbapi/__init__.py
+++ b/pym/portage/dbapi/__init__.py
@@ -94,10 +94,10 @@ class dbapi(object):
                        cpv_list.extend(self.cp_list(cp))
                return cpv_list
 
-       def cp_all(self):
+       def cp_all(self, sort=False):
                """ Implement this in a child class
                Args
-                       None
+                       sort - return sorted results
                Returns:
                        A list of strings 1 per CP in the datastore
                """

diff --git a/pym/portage/dbapi/bintree.py b/pym/portage/dbapi/bintree.py
index f415a63..9f47436 100644
--- a/pym/portage/dbapi/bintree.py
+++ b/pym/portage/dbapi/bintree.py
@@ -223,10 +223,10 @@ class bindbapi(fakedbapi):
                        self.bintree.populate()
                return fakedbapi.cp_list(self, *pargs, **kwargs)
 
-       def cp_all(self):
+       def cp_all(self, sort=False):
                if not self.bintree.populated:
                        self.bintree.populate()
-               return fakedbapi.cp_all(self)
+               return fakedbapi.cp_all(self, sort=sort)
 
        def cpv_all(self):
                if not self.bintree.populated:

diff --git a/pym/portage/dbapi/porttree.py b/pym/portage/dbapi/porttree.py
index 590e3c5..d13fdee 100644
--- a/pym/portage/dbapi/porttree.py
+++ b/pym/portage/dbapi/porttree.py
@@ -706,7 +706,7 @@ class portdbapi(dbapi):
                else:
                        return 0
 
-       def cp_all(self, categories=None, trees=None, reverse=False):
+       def cp_all(self, categories=None, trees=None, reverse=False, sort=True):
                """
                This returns a list of all keys in our tree or trees
                @param categories: optional list of categories to search or 
@@ -714,6 +714,7 @@ class portdbapi(dbapi):
                @param trees: optional list of trees to search the categories 
in or
                        defaults to self.porttrees
                @param reverse: reverse sort order (default is False)
+               @param sort: return sorted results (default is True)
                @rtype list of [cat/pkg,...]
                """
                d = {}
@@ -732,7 +733,8 @@ class portdbapi(dbapi):
                                                continue
                                        d[atom.cp] = None
                l = list(d)
-               l.sort(reverse=reverse)
+               if sort:
+                       l.sort(reverse=reverse)
                return l
 
        def cp_list(self, mycp, use_cache=1, mytree=None):

diff --git a/pym/portage/dbapi/vartree.py b/pym/portage/dbapi/vartree.py
index 62d880e..927c645 100644
--- a/pym/portage/dbapi/vartree.py
+++ b/pym/portage/dbapi/vartree.py
@@ -491,7 +491,7 @@ class vardbapi(dbapi):
 
                                yield subpath
 
-       def cp_all(self, use_cache=1):
+       def cp_all(self, use_cache=1, sort=False):
                mylist = self.cpv_all(use_cache=use_cache)
                d={}
                for y in mylist:
@@ -506,7 +506,7 @@ class vardbapi(dbapi):
                                self.invalidentry(self.getpath(y))
                                continue
                        d[mysplit[0]+"/"+mysplit[1]] = None
-               return list(d)
+               return sorted(d) if sort else list(d)
 
        def checkblockers(self, origdep):
                pass

diff --git a/pym/portage/dbapi/virtual.py b/pym/portage/dbapi/virtual.py
index 3b7d10e..a59c3b5 100644
--- a/pym/portage/dbapi/virtual.py
+++ b/pym/portage/dbapi/virtual.py
@@ -115,8 +115,8 @@ class fakedbapi(dbapi):
                self._match_cache[cache_key] = cpv_list
                return cpv_list[:]
 
-       def cp_all(self):
-               return list(self.cpdict)
+       def cp_all(self, sort=False):
+               return sorted(self.cpdict) if sort else list(self.cpdict)
 
        def cpv_all(self):
                if self._multi_instance:

Reply via email to