1 |
Since profile IUSE_IMPLICIT settings may diverge from those |
2 |
that a binary package was built with, consider members of |
3 |
built USE settings to be members of IUSE_EFFECTIVE. Only do |
4 |
this for EAPIs that support IUSE_EFFECTIVE, since built USE |
5 |
settings for earlier EAPIs may contain a large number of |
6 |
irrelevant flags. |
7 |
|
8 |
Note that the binary package may be remote, so it's only |
9 |
possible to rely on metadata that is available in the remote |
10 |
Packages file, and the IUSE_IMPLICIT header in the Packages |
11 |
file is vulnerable to mutation. |
12 |
|
13 |
Bug: https://bugs.gentoo.org/640318 |
14 |
--- |
15 |
pym/_emerge/Package.py | 32 +++++++++++++++++++++++++++++++ |
16 |
pym/portage/dbapi/__init__.py | 5 +++++ |
17 |
pym/portage/package/ebuild/config.py | 6 ++++++ |
18 |
pym/portage/tests/dbapi/test_fakedbapi.py | 20 +++++++++++++++++++ |
19 |
4 files changed, 63 insertions(+) |
20 |
|
21 |
diff --git a/pym/_emerge/Package.py b/pym/_emerge/Package.py |
22 |
index 2c1a116ea..e1943175d 100644 |
23 |
--- a/pym/_emerge/Package.py |
24 |
+++ b/pym/_emerge/Package.py |
25 |
@@ -3,6 +3,7 @@ |
26 |
|
27 |
from __future__ import unicode_literals |
28 |
|
29 |
+import functools |
30 |
import sys |
31 |
from itertools import chain |
32 |
import warnings |
33 |
@@ -82,6 +83,10 @@ class Package(Task): |
34 |
|
35 |
if eapi_attrs.iuse_effective: |
36 |
implicit_match = self.root_config.settings._iuse_effective_match |
37 |
+ if self.built: |
38 |
+ implicit_match = functools.partial( |
39 |
+ self._built_iuse_effective_match, |
40 |
+ implicit_match, frozenset(self._metadata['USE'].split())) |
41 |
else: |
42 |
implicit_match = self.root_config.settings._iuse_implicit_match |
43 |
usealiases = self.root_config.settings._use_manager.getUseAliases(self) |
44 |
@@ -109,6 +114,33 @@ class Package(Task): |
45 |
type_name=self.type_name) |
46 |
self._hash_value = hash(self._hash_key) |
47 |
|
48 |
+ @staticmethod |
49 |
+ def _built_iuse_effective_match(prof_effective_match, built_use, flag): |
50 |
+ """ |
51 |
+ For built packages, it is desirable for the built USE setting to be |
52 |
+ independent of the profile's current IUSE_IMPLICIT state, since the |
53 |
+ profile's IUSE_IMPLICT setting may have diverged. Therefore, any |
54 |
+ member the built USE is setting considered to be a valid member of |
55 |
+ IUSE_EFFECTIVE. Note that the binary package may be remote, so it's |
56 |
+ only possible to rely on metadata that is available in the remote |
57 |
+ Packages file, and the IUSE_IMPLICIT header in the Packages file is |
58 |
+ vulnerable to mutation (see bug 640318). |
59 |
+ |
60 |
+ This function is only used for EAPIs that support IUSE_EFFECTIVE, |
61 |
+ since built USE settings for earlier EAPIs may contain a large |
62 |
+ number of irrelevant flags. |
63 |
+ |
64 |
+ @param prof_effective_match: function to match IUSE_EFFECTIVE |
65 |
+ values for the current profile |
66 |
+ @type prof_effective_match: callable |
67 |
+ @param built_use: built USE setting |
68 |
+ @type built_use: frozenset |
69 |
+ @return: True if flag is a valid USE value which may |
70 |
+ be specified in USE dependencies, False otherwise. |
71 |
+ @rtype: bool |
72 |
+ """ |
73 |
+ return flag in built_use or prof_effective_match(flag) |
74 |
+ |
75 |
@property |
76 |
def eapi(self): |
77 |
return self._metadata["EAPI"] |
78 |
diff --git a/pym/portage/dbapi/__init__.py b/pym/portage/dbapi/__init__.py |
79 |
index 95053840d..2574b63df 100644 |
80 |
--- a/pym/portage/dbapi/__init__.py |
81 |
+++ b/pym/portage/dbapi/__init__.py |
82 |
@@ -5,6 +5,7 @@ from __future__ import unicode_literals |
83 |
|
84 |
__all__ = ["dbapi"] |
85 |
|
86 |
+import functools |
87 |
import re |
88 |
|
89 |
import portage |
90 |
@@ -219,6 +220,10 @@ class dbapi(object): |
91 |
eapi_attrs = _get_eapi_attrs(metadata["EAPI"]) |
92 |
if eapi_attrs.iuse_effective: |
93 |
iuse_implicit_match = self.settings._iuse_effective_match |
94 |
+ if not self._use_mutable: |
95 |
+ iuse_implicit_match = functools.partial( |
96 |
+ Package._built_iuse_effective_match, |
97 |
+ iuse_implicit_match, frozenset(metadata["USE"].split())) |
98 |
else: |
99 |
iuse_implicit_match = self.settings._iuse_implicit_match |
100 |
usealiases = self.settings._use_manager.getUseAliases(pkg) |
101 |
diff --git a/pym/portage/package/ebuild/config.py b/pym/portage/package/ebuild/config.py |
102 |
index cd2b009aa..d0225a311 100644 |
103 |
--- a/pym/portage/package/ebuild/config.py |
104 |
+++ b/pym/portage/package/ebuild/config.py |
105 |
@@ -1693,6 +1693,12 @@ class config(object): |
106 |
iuse_implicit_match = self._iuse_effective_match |
107 |
portage_iuse = set(self._iuse_effective) |
108 |
portage_iuse.update(explicit_iuse) |
109 |
+ if built_use is not None: |
110 |
+ # When the binary package was built, the profile may have |
111 |
+ # had different IUSE_IMPLICIT settings, so any member of |
112 |
+ # the built USE setting is considered to be a member of |
113 |
+ # IUSE_EFFECTIVE (see bug 640318). |
114 |
+ portage_iuse.update(built_use) |
115 |
self.configdict["pkg"]["IUSE_EFFECTIVE"] = \ |
116 |
" ".join(sorted(portage_iuse)) |
117 |
else: |
118 |
diff --git a/pym/portage/tests/dbapi/test_fakedbapi.py b/pym/portage/tests/dbapi/test_fakedbapi.py |
119 |
index e4f5dd771..19ea9cd00 100644 |
120 |
--- a/pym/portage/tests/dbapi/test_fakedbapi.py |
121 |
+++ b/pym/portage/tests/dbapi/test_fakedbapi.py |
122 |
@@ -14,6 +14,20 @@ class TestFakedbapi(TestCase): |
123 |
|
124 |
def testFakedbapi(self): |
125 |
packages = ( |
126 |
+ ("app-misc/foo-1", { |
127 |
+ "EAPI" : "2", # does not support IUSE_EFFECTIVE |
128 |
+ "IUSE" : "", |
129 |
+ "repository" : "gentoo", |
130 |
+ "SLOT" : "1", |
131 |
+ "USE" : "missing-iuse", |
132 |
+ }), |
133 |
+ ("app-misc/foo-2", { |
134 |
+ "EAPI" : "5", # supports IUSE_EFFECTIVE |
135 |
+ "IUSE" : "", |
136 |
+ "repository" : "gentoo", |
137 |
+ "SLOT" : "2", |
138 |
+ "USE" : "missing-iuse", |
139 |
+ }), |
140 |
("sys-apps/portage-2.1.10", { |
141 |
"EAPI" : "2", |
142 |
"IUSE" : "ipc doc", |
143 |
@@ -29,6 +43,12 @@ class TestFakedbapi(TestCase): |
144 |
) |
145 |
|
146 |
match_tests = ( |
147 |
+ # The missing-iuse match is only intended to work for binary |
148 |
+ # packages with EAPIs that support IUSE_EFFECTIVE (bug 640318). |
149 |
+ ("app-misc/foo[missing-iuse]", ["app-misc/foo-2"]), |
150 |
+ ("app-misc/foo[-missing-iuse]", []), |
151 |
+ ("app-misc/foo", ["app-misc/foo-1", "app-misc/foo-2"]), |
152 |
+ |
153 |
("sys-apps/portage:0[ipc]", ["sys-apps/portage-2.1.10"]), |
154 |
("sys-apps/portage:0[-ipc]", []), |
155 |
("sys-apps/portage:0[doc]", []), |
156 |
-- |
157 |
2.13.6 |