Gentoo Archives: gentoo-portage-dev

From: Zac Medico <zmedico@g.o>
To: gentoo-portage-dev@l.g.o
Cc: Zac Medico <zmedico@g.o>
Subject: [gentoo-portage-dev] [PATCH] portdbapi: add async_xmatch method (bug 666940)
Date: Mon, 24 Sep 2018 03:30:54
Message-Id: 20180924033027.28180-1-zmedico@gentoo.org
1 Add an async_xmatch method, and use it to implement the synchronous
2 xmatch method. Deprecate unused xmatch method parameters. Use the
3 compat_coroutine decorator for backward compatibility with python2.7
4 (via PEP 342 enhanced generators).
5
6 Bug: https://bugs.gentoo.org/666940
7 Suggested-by: Daniel Robbins <drobbins@××××××.org>
8 Signed-off-by: Zac Medico <zmedico@g.o>
9 ---
10 lib/portage/dbapi/porttree.py | 62 +++++++++++++++++++++++++++++++++++--------
11 1 file changed, 51 insertions(+), 11 deletions(-)
12
13 diff --git a/lib/portage/dbapi/porttree.py b/lib/portage/dbapi/porttree.py
14 index 56955ec34..fc2980cdb 100644
15 --- a/lib/portage/dbapi/porttree.py
16 +++ b/lib/portage/dbapi/porttree.py
17 @@ -37,6 +37,7 @@ from portage import _unicode_encode
18 from portage import OrderedDict
19 from portage.util._eventloop.EventLoop import EventLoop
20 from portage.util.futures import asyncio
21 +from portage.util.futures.compat_coroutine import coroutine, coroutine_return
22 from portage.util.futures.iter_completed import iter_gather
23 from _emerge.EbuildMetadataPhase import EbuildMetadataPhase
24
25 @@ -1055,8 +1056,41 @@ class portdbapi(dbapi):
26 self._better_cache = None
27 self.frozen = 0
28
29 - def xmatch(self,level,origdep,mydep=None,mykey=None,mylist=None):
30 - "caching match function; very trick stuff"
31 + def xmatch(self, level, origdep, mydep=DeprecationWarning,
32 + mykey=DeprecationWarning, mylist=DeprecationWarning):
33 + """
34 + Caching match function.
35 +
36 + @param level: xmatch level (bestmatch-visible, match-all-cpv-only
37 + match-allmatch-visible, minimum-all, minimum-all-ignore-profile,
38 + or minimum-visible)
39 + @type level: str
40 + @param origdep: dependency to match (may omit category)
41 + @type origdep: portage.dep.Atom or str
42 + @return: match result(s)
43 + @rtype: _pkg_str or list of _pkg_str (depends on level)
44 + """
45 + loop = self._event_loop
46 + return loop.run_until_complete(
47 + self.async_xmatch(level, origdep, mydep=mydep, loop=loop))
48 +
49 + @coroutine
50 + def async_xmatch(self, level, origdep, mydep=DeprecationWarning, loop=None):
51 + """
52 + Asynchronous form form of xmatch.
53 +
54 + @param level: xmatch level (bestmatch-visible, match-all-cpv-only
55 + match-allmatch-visible, minimum-all, minimum-all-ignore-profile,
56 + or minimum-visible)
57 + @type level: str
58 + @param origdep: dependency to match (may omit category)
59 + @type origdep: portage.dep.Atom or str
60 + @param loop: event loop (defaults to global event loop)
61 + @type loop: EventLoop
62 + @return: match result(s)
63 + @rtype: asyncio.Future (or compatible), which results in a _pkg_str
64 + or list of _pkg_str (depends on level)
65 + """
66 if level == "list-visible":
67 level = "match-visible"
68 warnings.warn("The 'list-visible' mode of "
69 @@ -1064,21 +1098,25 @@ class portdbapi(dbapi):
70 "has been renamed to match-visible",
71 DeprecationWarning, stacklevel=2)
72
73 - if mydep is None:
74 - #this stuff only runs on first call of xmatch()
75 - #create mydep, mykey from origdep
76 - mydep = dep_expand(origdep, mydb=self, settings=self.settings)
77 - mykey = mydep.cp
78 + if mydep is not DeprecationWarning:
79 + warnings.warn("The 'mydep' parameter of "
80 + "portage.dbapi.porttree.portdbapi.xmatch"
81 + " is deprecated and ignored",
82 + DeprecationWarning, stacklevel=2)
83 +
84 + mydep = dep_expand(origdep, mydb=self, settings=self.settings)
85 + mykey = mydep.cp
86
87 #if no updates are being made to the tree, we can consult our xcache...
88 cache_key = None
89 if self.frozen:
90 cache_key = (mydep, mydep.unevaluated_atom)
91 try:
92 - return self.xcache[level][cache_key][:]
93 + coroutine_return(self.xcache[level][cache_key][:])
94 except KeyError:
95 pass
96
97 + loop = asyncio._wrap_loop(loop)
98 myval = None
99 mytree = None
100 if mydep.repo is not None:
101 @@ -1131,12 +1169,14 @@ class portdbapi(dbapi):
102
103 for cpv in iterfunc(mylist):
104 try:
105 - metadata = dict(zip(aux_keys,
106 - self.aux_get(cpv, aux_keys, myrepo=cpv.repo)))
107 + metadata_list = yield self.async_aux_get(cpv,
108 + aux_keys, myrepo=cpv.repo, loop=loop)
109 except KeyError:
110 # ebuild not in this repo, or masked by corruption
111 continue
112
113 + metadata = dict(zip(aux_keys, metadata_list))
114 +
115 try:
116 pkg_str = _pkg_str(cpv, metadata=metadata,
117 settings=self.settings, db=self)
118 @@ -1176,7 +1216,7 @@ class portdbapi(dbapi):
119 if not isinstance(myval, _pkg_str):
120 myval = myval[:]
121
122 - return myval
123 + coroutine_return(myval)
124
125 def match(self, mydep, use_cache=1):
126 return self.xmatch("match-visible", mydep)
127 --
128 2.16.4