aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'portage_with_autodep/pym/portage/dbapi/__init__.py')
-rw-r--r--portage_with_autodep/pym/portage/dbapi/__init__.py185
1 files changed, 129 insertions, 56 deletions
diff --git a/portage_with_autodep/pym/portage/dbapi/__init__.py b/portage_with_autodep/pym/portage/dbapi/__init__.py
index a1c5c56..a20a1e8 100644
--- a/portage_with_autodep/pym/portage/dbapi/__init__.py
+++ b/portage_with_autodep/pym/portage/dbapi/__init__.py
@@ -1,6 +1,8 @@
-# Copyright 1998-2012 Gentoo Foundation
+# Copyright 1998-2013 Gentoo Foundation
# Distributed under the terms of the GNU General Public License v2
+from __future__ import unicode_literals
+
__all__ = ["dbapi"]
import re
@@ -8,7 +10,7 @@ import re
import portage
portage.proxy.lazyimport.lazyimport(globals(),
'portage.dbapi.dep_expand:dep_expand@_dep_expand',
- 'portage.dep:match_from_list',
+ 'portage.dep:Atom,match_from_list,_match_slot',
'portage.output:colorize',
'portage.util:cmp_sort_key,writemsg',
'portage.versions:catsplit,catpkgsplit,vercmp,_pkg_str',
@@ -16,14 +18,19 @@ portage.proxy.lazyimport.lazyimport(globals(),
from portage import os
from portage import auxdbkeys
+from portage.eapi import _get_eapi_attrs
+from portage.exception import InvalidData
from portage.localization import _
+from _emerge.Package import Package
class dbapi(object):
- _category_re = re.compile(r'^\w[-.+\w]*$')
+ _category_re = re.compile(r'^\w[-.+\w]*$', re.UNICODE)
_categories = None
_use_mutable = False
_known_keys = frozenset(x for x in auxdbkeys
if not x.startswith("UNUSED_0"))
+ _pkg_str_aux_keys = ("EAPI", "KEYWORDS", "SLOT", "repository")
+
def __init__(self):
pass
@@ -125,29 +132,52 @@ class dbapi(object):
def _iter_match(self, atom, cpv_iter):
cpv_iter = iter(match_from_list(atom, cpv_iter))
+ if atom.repo:
+ cpv_iter = self._iter_match_repo(atom, cpv_iter)
if atom.slot:
cpv_iter = self._iter_match_slot(atom, cpv_iter)
if atom.unevaluated_atom.use:
cpv_iter = self._iter_match_use(atom, cpv_iter)
- if atom.repo:
- cpv_iter = self._iter_match_repo(atom, cpv_iter)
return cpv_iter
+ def _pkg_str(self, cpv, repo):
+ """
+ This is used to contruct _pkg_str instances on-demand during
+ matching. If cpv is a _pkg_str instance with slot attribute,
+ then simply return it. Otherwise, fetch metadata and construct
+ a _pkg_str instance. This may raise KeyError or InvalidData.
+ """
+ try:
+ cpv.slot
+ except AttributeError:
+ pass
+ else:
+ return cpv
+
+ metadata = dict(zip(self._pkg_str_aux_keys,
+ self.aux_get(cpv, self._pkg_str_aux_keys, myrepo=repo)))
+
+ return _pkg_str(cpv, metadata=metadata, settings=self.settings)
+
def _iter_match_repo(self, atom, cpv_iter):
for cpv in cpv_iter:
try:
- if self.aux_get(cpv, ["repository"], myrepo=atom.repo)[0] == atom.repo:
- yield cpv
- except KeyError:
- continue
+ pkg_str = self._pkg_str(cpv, atom.repo)
+ except (KeyError, InvalidData):
+ pass
+ else:
+ if pkg_str.repo == atom.repo:
+ yield pkg_str
def _iter_match_slot(self, atom, cpv_iter):
for cpv in cpv_iter:
try:
- if self.aux_get(cpv, ["SLOT"], myrepo=atom.repo)[0] == atom.slot:
- yield cpv
- except KeyError:
- continue
+ pkg_str = self._pkg_str(cpv, atom.repo)
+ except (KeyError, InvalidData):
+ pass
+ else:
+ if _match_slot(atom, pkg_str):
+ yield pkg_str
def _iter_match_use(self, atom, cpv_iter):
"""
@@ -155,7 +185,7 @@ class dbapi(object):
2) Check enabled/disabled flag states.
"""
- aux_keys = ["IUSE", "SLOT", "USE", "repository"]
+ aux_keys = ["EAPI", "IUSE", "KEYWORDS", "SLOT", "USE", "repository"]
for cpv in cpv_iter:
try:
metadata = dict(zip(aux_keys,
@@ -163,17 +193,31 @@ class dbapi(object):
except KeyError:
continue
+ try:
+ cpv.slot
+ except AttributeError:
+ try:
+ cpv = _pkg_str(cpv, metadata=metadata,
+ settings=self.settings)
+ except InvalidData:
+ continue
+
if not self._match_use(atom, cpv, metadata):
continue
yield cpv
- def _match_use(self, atom, cpv, metadata):
- iuse_implicit_match = self.settings._iuse_implicit_match
- iuse = frozenset(x.lstrip('+-') for x in metadata["IUSE"].split())
+ def _match_use(self, atom, pkg, metadata):
+ eapi_attrs = _get_eapi_attrs(metadata["EAPI"])
+ if eapi_attrs.iuse_effective:
+ iuse_implicit_match = self.settings._iuse_effective_match
+ else:
+ iuse_implicit_match = self.settings._iuse_implicit_match
+ usealiases = self.settings._use_manager.getUseAliases(pkg)
+ iuse = Package._iuse(None, metadata["IUSE"].split(), iuse_implicit_match, usealiases, metadata["EAPI"])
for x in atom.unevaluated_atom.use.required:
- if x not in iuse and not iuse_implicit_match(x):
+ if iuse.get_real_flag(x) is None:
return False
if atom.use is None:
@@ -183,45 +227,54 @@ class dbapi(object):
# Use IUSE to validate USE settings for built packages,
# in case the package manager that built this package
# failed to do that for some reason (or in case of
- # data corruption).
- use = frozenset(x for x in metadata["USE"].split()
- if x in iuse or iuse_implicit_match(x))
- missing_enabled = atom.use.missing_enabled.difference(iuse)
- missing_disabled = atom.use.missing_disabled.difference(iuse)
-
- if atom.use.enabled:
- if atom.use.enabled.intersection(missing_disabled):
+ # data corruption). The enabled flags must be consistent
+ # with implicit IUSE, in order to avoid potential
+ # inconsistencies in USE dep matching (see bug #453400).
+ use = frozenset(x for x in metadata["USE"].split() if iuse.get_real_flag(x) is not None)
+ missing_enabled = frozenset(x for x in atom.use.missing_enabled if iuse.get_real_flag(x) is None)
+ missing_disabled = frozenset(x for x in atom.use.missing_disabled if iuse.get_real_flag(x) is None)
+ enabled = frozenset((iuse.get_real_flag(x) or x) for x in atom.use.enabled)
+ disabled = frozenset((iuse.get_real_flag(x) or x) for x in atom.use.disabled)
+
+ if enabled:
+ if any(x in enabled for x in missing_disabled):
return False
- need_enabled = atom.use.enabled.difference(use)
+ need_enabled = enabled.difference(use)
if need_enabled:
- need_enabled = need_enabled.difference(missing_enabled)
- if need_enabled:
+ if any(x not in missing_enabled for x in need_enabled):
return False
- if atom.use.disabled:
- if atom.use.disabled.intersection(missing_enabled):
+ if disabled:
+ if any(x in disabled for x in missing_enabled):
return False
- need_disabled = atom.use.disabled.intersection(use)
+ need_disabled = disabled.intersection(use)
if need_disabled:
- need_disabled = need_disabled.difference(missing_disabled)
- if need_disabled:
+ if any(x not in missing_disabled for x in need_disabled):
return False
elif not self.settings.local_config:
# Check masked and forced flags for repoman.
- if hasattr(cpv, 'slot'):
- pkg = cpv
- else:
- pkg = _pkg_str(cpv, slot=metadata["SLOT"],
- repo=metadata.get("repository"))
- usemask = self.settings._getUseMask(pkg)
- if usemask.intersection(atom.use.enabled):
+ usemask = self.settings._getUseMask(pkg,
+ stable=self.settings._parent_stable)
+ if any(x in usemask for x in atom.use.enabled):
return False
- useforce = self.settings._getUseForce(pkg).difference(usemask)
- if useforce.intersection(atom.use.disabled):
+ useforce = self.settings._getUseForce(pkg,
+ stable=self.settings._parent_stable)
+ if any(x in useforce and x not in usemask
+ for x in atom.use.disabled):
return False
+ # Check unsatisfied use-default deps
+ if atom.use.enabled:
+ missing_disabled = frozenset(x for x in atom.use.missing_disabled if iuse.get_real_flag(x) is None)
+ if any(x in atom.use.enabled for x in missing_disabled):
+ return False
+ if atom.use.disabled:
+ missing_enabled = frozenset(x for x in atom.use.missing_enabled if iuse.get_real_flag(x) is None)
+ if any(x in atom.use.disabled for x in missing_enabled):
+ return False
+
return True
def invalidentry(self, mypath):
@@ -249,23 +302,30 @@ class dbapi(object):
maxval = len(cpv_all)
aux_get = self.aux_get
aux_update = self.aux_update
- meta_keys = ["DEPEND", "RDEPEND", "PDEPEND", "PROVIDE", 'repository']
+ update_keys = Package._dep_keys + ("PROVIDE",)
+ meta_keys = update_keys + self._pkg_str_aux_keys
repo_dict = None
if isinstance(updates, dict):
repo_dict = updates
- from portage.update import update_dbentries
if onUpdate:
onUpdate(maxval, 0)
if onProgress:
onProgress(maxval, 0)
for i, cpv in enumerate(cpv_all):
- metadata = dict(zip(meta_keys, aux_get(cpv, meta_keys)))
- repo = metadata.pop('repository')
+ try:
+ metadata = dict(zip(meta_keys, aux_get(cpv, meta_keys)))
+ except KeyError:
+ continue
+ try:
+ pkg = _pkg_str(cpv, metadata=metadata, settings=self.settings)
+ except InvalidData:
+ continue
+ metadata = dict((k, metadata[k]) for k in update_keys)
if repo_dict is None:
updates_list = updates
else:
try:
- updates_list = repo_dict[repo]
+ updates_list = repo_dict[pkg.repo]
except KeyError:
try:
updates_list = repo_dict['DEFAULT']
@@ -275,7 +335,8 @@ class dbapi(object):
if not updates_list:
continue
- metadata_updates = update_dbentries(updates_list, metadata)
+ metadata_updates = \
+ portage.update_dbentries(updates_list, metadata, parent=pkg)
if metadata_updates:
aux_update(cpv, metadata_updates)
if onUpdate:
@@ -286,27 +347,39 @@ class dbapi(object):
def move_slot_ent(self, mylist, repo_match=None):
"""This function takes a sequence:
Args:
- mylist: a sequence of (package, originalslot, newslot)
+ mylist: a sequence of (atom, originalslot, newslot)
repo_match: callable that takes single repo_name argument
and returns True if the update should be applied
Returns:
The number of slotmoves this function did
"""
- pkg = mylist[1]
+ atom = mylist[1]
origslot = mylist[2]
newslot = mylist[3]
- origmatches = self.match(pkg)
+
+ try:
+ atom.with_slot
+ except AttributeError:
+ atom = Atom(atom).with_slot(origslot)
+ else:
+ atom = atom.with_slot(origslot)
+
+ origmatches = self.match(atom)
moves = 0
if not origmatches:
return moves
for mycpv in origmatches:
- slot = self.aux_get(mycpv, ["SLOT"])[0]
- if slot != origslot:
+ try:
+ mycpv = self._pkg_str(mycpv, atom.repo)
+ except (KeyError, InvalidData):
continue
- if repo_match is not None \
- and not repo_match(self.aux_get(mycpv, ['repository'])[0]):
+ if repo_match is not None and not repo_match(mycpv.repo):
continue
moves += 1
+ if "/" not in newslot and \
+ mycpv.sub_slot and \
+ mycpv.sub_slot not in (mycpv.slot, newslot):
+ newslot = "%s/%s" % (newslot, mycpv.sub_slot)
mydata = {"SLOT": newslot+"\n"}
self.aux_update(mycpv, mydata)
return moves