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 |