diff options
-rw-r--r-- | pym/_emerge/Package.py | 32 | ||||
-rw-r--r-- | pym/portage/dbapi/__init__.py | 5 | ||||
-rw-r--r-- | pym/portage/package/ebuild/config.py | 6 | ||||
-rw-r--r-- | pym/portage/tests/dbapi/test_fakedbapi.py | 20 |
4 files changed, 63 insertions, 0 deletions
diff --git a/pym/_emerge/Package.py b/pym/_emerge/Package.py index 2c1a116ea..cebfd8281 100644 --- a/pym/_emerge/Package.py +++ b/pym/_emerge/Package.py @@ -3,6 +3,7 @@ from __future__ import unicode_literals +import functools import sys from itertools import chain import warnings @@ -82,6 +83,10 @@ class Package(Task): if eapi_attrs.iuse_effective: implicit_match = self.root_config.settings._iuse_effective_match + if self.built: + implicit_match = functools.partial( + self._built_iuse_effective_match, + implicit_match, frozenset(self._metadata['USE'].split())) else: implicit_match = self.root_config.settings._iuse_implicit_match usealiases = self.root_config.settings._use_manager.getUseAliases(self) @@ -109,6 +114,33 @@ class Package(Task): type_name=self.type_name) self._hash_value = hash(self._hash_key) + @staticmethod + def _built_iuse_effective_match(prof_effective_match, built_use, flag): + """ + For built packages, it is desirable for the built USE setting to be + independent of the profile's current IUSE_IMPLICIT state, since the + profile's IUSE_IMPLICT setting may have diverged. Therefore, any + member of the built USE setting is considered to be a valid member of + IUSE_EFFECTIVE. Note that the binary package may be remote, so it's + only possible to rely on metadata that is available in the remote + Packages file, and the IUSE_IMPLICIT header in the Packages file is + vulnerable to mutation (see bug 640318). + + This function is only used for EAPIs that support IUSE_EFFECTIVE, + since built USE settings for earlier EAPIs may contain a large + number of irrelevant flags. + + @param prof_effective_match: function to match IUSE_EFFECTIVE + values for the current profile + @type prof_effective_match: callable + @param built_use: built USE setting + @type built_use: frozenset + @return: True if flag is a valid USE value which may + be specified in USE dependencies, False otherwise. + @rtype: bool + """ + return flag in built_use or prof_effective_match(flag) + @property def eapi(self): return self._metadata["EAPI"] diff --git a/pym/portage/dbapi/__init__.py b/pym/portage/dbapi/__init__.py index 95053840d..2574b63df 100644 --- a/pym/portage/dbapi/__init__.py +++ b/pym/portage/dbapi/__init__.py @@ -5,6 +5,7 @@ from __future__ import unicode_literals __all__ = ["dbapi"] +import functools import re import portage @@ -219,6 +220,10 @@ class dbapi(object): eapi_attrs = _get_eapi_attrs(metadata["EAPI"]) if eapi_attrs.iuse_effective: iuse_implicit_match = self.settings._iuse_effective_match + if not self._use_mutable: + iuse_implicit_match = functools.partial( + Package._built_iuse_effective_match, + iuse_implicit_match, frozenset(metadata["USE"].split())) else: iuse_implicit_match = self.settings._iuse_implicit_match usealiases = self.settings._use_manager.getUseAliases(pkg) diff --git a/pym/portage/package/ebuild/config.py b/pym/portage/package/ebuild/config.py index cd2b009aa..d0225a311 100644 --- a/pym/portage/package/ebuild/config.py +++ b/pym/portage/package/ebuild/config.py @@ -1693,6 +1693,12 @@ class config(object): iuse_implicit_match = self._iuse_effective_match portage_iuse = set(self._iuse_effective) portage_iuse.update(explicit_iuse) + if built_use is not None: + # When the binary package was built, the profile may have + # had different IUSE_IMPLICIT settings, so any member of + # the built USE setting is considered to be a member of + # IUSE_EFFECTIVE (see bug 640318). + portage_iuse.update(built_use) self.configdict["pkg"]["IUSE_EFFECTIVE"] = \ " ".join(sorted(portage_iuse)) else: diff --git a/pym/portage/tests/dbapi/test_fakedbapi.py b/pym/portage/tests/dbapi/test_fakedbapi.py index e4f5dd771..19ea9cd00 100644 --- a/pym/portage/tests/dbapi/test_fakedbapi.py +++ b/pym/portage/tests/dbapi/test_fakedbapi.py @@ -14,6 +14,20 @@ class TestFakedbapi(TestCase): def testFakedbapi(self): packages = ( + ("app-misc/foo-1", { + "EAPI" : "2", # does not support IUSE_EFFECTIVE + "IUSE" : "", + "repository" : "gentoo", + "SLOT" : "1", + "USE" : "missing-iuse", + }), + ("app-misc/foo-2", { + "EAPI" : "5", # supports IUSE_EFFECTIVE + "IUSE" : "", + "repository" : "gentoo", + "SLOT" : "2", + "USE" : "missing-iuse", + }), ("sys-apps/portage-2.1.10", { "EAPI" : "2", "IUSE" : "ipc doc", @@ -29,6 +43,12 @@ class TestFakedbapi(TestCase): ) match_tests = ( + # The missing-iuse match is only intended to work for binary + # packages with EAPIs that support IUSE_EFFECTIVE (bug 640318). + ("app-misc/foo[missing-iuse]", ["app-misc/foo-2"]), + ("app-misc/foo[-missing-iuse]", []), + ("app-misc/foo", ["app-misc/foo-1", "app-misc/foo-2"]), + ("sys-apps/portage:0[ipc]", ["sys-apps/portage-2.1.10"]), ("sys-apps/portage:0[-ipc]", []), ("sys-apps/portage:0[doc]", []), |