Discussion:
[gentoo-portage-dev] [PATCH] portdbapi: add async_xmatch method (bug 666940)
Zac Medico
2018-09-24 03:30:27 UTC
Permalink
Add an async_xmatch method, and use it to implement the synchronous
xmatch method. Deprecate unused xmatch method parameters. Use the
compat_coroutine decorator for backward compatibility with python2.7
(via PEP 342 enhanced generators).

Bug: https://bugs.gentoo.org/666940
Suggested-by: Daniel Robbins <***@funtoo.org>
Signed-off-by: Zac Medico <***@gentoo.org>
---
lib/portage/dbapi/porttree.py | 62 +++++++++++++++++++++++++++++++++++--------
1 file changed, 51 insertions(+), 11 deletions(-)

diff --git a/lib/portage/dbapi/porttree.py b/lib/portage/dbapi/porttree.py
index 56955ec34..fc2980cdb 100644
--- a/lib/portage/dbapi/porttree.py
+++ b/lib/portage/dbapi/porttree.py
@@ -37,6 +37,7 @@ from portage import _unicode_encode
from portage import OrderedDict
from portage.util._eventloop.EventLoop import EventLoop
from portage.util.futures import asyncio
+from portage.util.futures.compat_coroutine import coroutine, coroutine_return
from portage.util.futures.iter_completed import iter_gather
from _emerge.EbuildMetadataPhase import EbuildMetadataPhase

@@ -1055,8 +1056,41 @@ class portdbapi(dbapi):
self._better_cache = None
self.frozen = 0

- def xmatch(self,level,origdep,mydep=None,mykey=None,mylist=None):
- "caching match function; very trick stuff"
+ def xmatch(self, level, origdep, mydep=DeprecationWarning,
+ mykey=DeprecationWarning, mylist=DeprecationWarning):
+ """
+ Caching match function.
+
+ @param level: xmatch level (bestmatch-visible, match-all-cpv-only
+ match-allmatch-visible, minimum-all, minimum-all-ignore-profile,
+ or minimum-visible)
+ @type level: str
+ @param origdep: dependency to match (may omit category)
+ @type origdep: portage.dep.Atom or str
+ @return: match result(s)
+ @rtype: _pkg_str or list of _pkg_str (depends on level)
+ """
+ loop = self._event_loop
+ return loop.run_until_complete(
+ self.async_xmatch(level, origdep, mydep=mydep, loop=loop))
+
+ @coroutine
+ def async_xmatch(self, level, origdep, mydep=DeprecationWarning, loop=None):
+ """
+ Asynchronous form form of xmatch.
+
+ @param level: xmatch level (bestmatch-visible, match-all-cpv-only
+ match-allmatch-visible, minimum-all, minimum-all-ignore-profile,
+ or minimum-visible)
+ @type level: str
+ @param origdep: dependency to match (may omit category)
+ @type origdep: portage.dep.Atom or str
+ @param loop: event loop (defaults to global event loop)
+ @type loop: EventLoop
+ @return: match result(s)
+ @rtype: asyncio.Future (or compatible), which results in a _pkg_str
+ or list of _pkg_str (depends on level)
+ """
if level == "list-visible":
level = "match-visible"
warnings.warn("The 'list-visible' mode of "
@@ -1064,21 +1098,25 @@ class portdbapi(dbapi):
"has been renamed to match-visible",
DeprecationWarning, stacklevel=2)

- if mydep is None:
- #this stuff only runs on first call of xmatch()
- #create mydep, mykey from origdep
- mydep = dep_expand(origdep, mydb=self, settings=self.settings)
- mykey = mydep.cp
+ if mydep is not DeprecationWarning:
+ warnings.warn("The 'mydep' parameter of "
+ "portage.dbapi.porttree.portdbapi.xmatch"
+ " is deprecated and ignored",
+ DeprecationWarning, stacklevel=2)
+
+ mydep = dep_expand(origdep, mydb=self, settings=self.settings)
+ mykey = mydep.cp

#if no updates are being made to the tree, we can consult our xcache...
cache_key = None
if self.frozen:
cache_key = (mydep, mydep.unevaluated_atom)
try:
- return self.xcache[level][cache_key][:]
+ coroutine_return(self.xcache[level][cache_key][:])
except KeyError:
pass

+ loop = asyncio._wrap_loop(loop)
myval = None
mytree = None
if mydep.repo is not None:
@@ -1131,12 +1169,14 @@ class portdbapi(dbapi):

for cpv in iterfunc(mylist):
try:
- metadata = dict(zip(aux_keys,
- self.aux_get(cpv, aux_keys, myrepo=cpv.repo)))
+ metadata_list = yield self.async_aux_get(cpv,
+ aux_keys, myrepo=cpv.repo, loop=loop)
except KeyError:
# ebuild not in this repo, or masked by corruption
continue

+ metadata = dict(zip(aux_keys, metadata_list))
+
try:
pkg_str = _pkg_str(cpv, metadata=metadata,
settings=self.settings, db=self)
@@ -1176,7 +1216,7 @@ class portdbapi(dbapi):
if not isinstance(myval, _pkg_str):
myval = myval[:]

- return myval
+ coroutine_return(myval)

def match(self, mydep, use_cache=1):
return self.xmatch("match-visible", mydep)
--
2.16.4
Loading...