* Add support for Package instances in match_from_list().
authorZac Medico <zmedico@gentoo.org>
Sun, 25 May 2008 22:56:02 +0000 (22:56 -0000)
committerZac Medico <zmedico@gentoo.org>
Sun, 25 May 2008 22:56:02 +0000 (22:56 -0000)
* Remove the Package.cpv_slot attribute.
(trunk r10418:10423)

svn path=/main/branches/2.1.2/; revision=10424

bin/emerge
pym/portage_dep.py

index be5d3a4fc2352ec1ba6f8e25eeb6ee921954f4fb..dc91079b4f56ff3a7bee7a149382edadf58b17a3 100755 (executable)
@@ -819,7 +819,7 @@ class InternalPackageSet(object):
                atoms = list(self.iterAtomsForPackage(pkg))
                if not atoms:
                        return None
-               return portage.best_match_to_list(pkg.cpv_slot, atoms)
+               return portage.best_match_to_list(pkg, atoms)
 
        def iterAtomsForPackage(self, pkg):
                """
@@ -827,7 +827,7 @@ class InternalPackageSet(object):
                arguments against the PROVIDE metadata.  This will raise an
                InvalidDependString exception if PROVIDE is invalid.
                """
-               cpv_slot_list = ["%s:%s" % (pkg.cpv, pkg.metadata["SLOT"])]
+               cpv_slot_list = [pkg]
                cp = portage.cpv_getkey(pkg.cpv)
                atoms = self._atoms.get(cp)
                if atoms:
@@ -1402,7 +1402,8 @@ class Package(Task):
        __slots__ = ("built", "cpv", "depth",
                "installed", "metadata", "onlydeps", "operation",
                "root", "type_name",
-               "category", "cp", "cpv_slot", "pf", "pv_split", "slot_atom")
+               "category", "cp", "cpv_split",
+               "pf", "pv_split", "slot", "slot_atom", "use")
 
        metadata_keys = [
                "CHOST", "COUNTER", "DEPEND", "EAPI", "IUSE", "KEYWORDS",
@@ -1411,11 +1412,33 @@ class Package(Task):
 
        def __init__(self, **kwargs):
                Task.__init__(self, **kwargs)
+               self.metadata = self._metadata_wrapper(self, self.metadata)
                self.cp = portage.cpv_getkey(self.cpv)
-               self.slot_atom = "%s:%s" % (self.cp, self.metadata["SLOT"])
-               self.cpv_slot = "%s:%s" % (self.cpv, self.metadata["SLOT"])
+               self.slot_atom = portage_dep.Atom("%s:%s" % (self.cp, self.slot))
                self.category, self.pf = portage.catsplit(self.cpv)
-               self.pv_split = portage.catpkgsplit(self.cpv)[1:]
+               self.cpv_split = portage.catpkgsplit(self.cpv)
+               self.pv_split = self.cpv_split[1:]
+
+       class _use(object):
+               def __init__(self, use):
+                       self.enabled = frozenset(use)
+
+       class _metadata_wrapper(dict):
+               """
+               Detect metadata updates and synchronize Package attributes.
+               """
+               def __init__(self, pkg, metadata):
+                       dict.__init__(self)
+                       self._pkg = pkg
+                       for k, v in metadata.iteritems():
+                               self[k] = v
+
+               def __setitem__(self, k, v):
+                       dict.__setitem__(self, k, v)
+                       if k == "USE":
+                               self._pkg.use = self._pkg._use(v.split())
+                       elif k == "SLOT":
+                               self._pkg.slot = v
 
        def _get_hash_key(self):
                hash_key = getattr(self, "_hash_key", None)
@@ -3127,18 +3150,7 @@ class depgraph(object):
                                                        installed=installed, metadata=metadata,
                                                        onlydeps=onlydeps, root=root, type_name=pkg_type)
                                                self._pkg_cache[pkg] = pkg
-                                       myarg = None
-                                       if root == self.target_root:
-                                               try:
-                                                       myarg = self._iter_atoms_for_pkg(pkg).next()
-                                               except StopIteration:
-                                                       pass
-                                               except portage_exception.InvalidDependString:
-                                                       if not installed:
-                                                               # masked by corruption
-                                                               continue
-                                       if not installed and myarg:
-                                               found_available_arg = True
+
                                        if not installed or (installed and matched_packages):
                                                # Only enforce visibility on installed packages
                                                # if there is at least one other visible package
@@ -3177,6 +3189,22 @@ class depgraph(object):
                                                # it's expensive.
                                                pkgsettings.setcpv(cpv, mydb=pkg.metadata)
                                                pkg.metadata["USE"] = pkgsettings["PORTAGE_USE"]
+
+                                       myarg = None
+                                       if root == self.target_root:
+                                               try:
+                                                       # Ebuild USE must have been calculated prior
+                                                       # to this point, in case atoms have USE deps.
+                                                       myarg = self._iter_atoms_for_pkg(pkg).next()
+                                               except StopIteration:
+                                                       pass
+                                               except portage_exception.InvalidDependString:
+                                                       if not installed:
+                                                               # masked by corruption
+                                                               continue
+                                       if not installed and myarg:
+                                               found_available_arg = True
+
                                        if pkg.cp == atom_cp:
                                                if highest_version is None:
                                                        highest_version = pkg
@@ -3191,9 +3219,7 @@ class depgraph(object):
                                                e_pkg = self._slot_pkg_map[root].get(pkg.slot_atom)
                                                if not e_pkg:
                                                        break
-                                               cpv_slot = "%s:%s" % \
-                                                       (e_pkg.cpv, e_pkg.metadata["SLOT"])
-                                               if portage_dep.match_from_list(atom, [cpv_slot]):
+                                               if portage_dep.match_from_list(atom, [e_pkg]):
                                                        if highest_version and \
                                                                e_pkg.cp == atom_cp and \
                                                                e_pkg < highest_version and \
index 41c2c54ff8754e15072ae6774d04514efe035689..dea19063bd18f6d24451c228b380c00f4d5fef5f 100644 (file)
@@ -605,6 +605,9 @@ def match_from_list(mydep, candidate_list):
        @return: A list of package atoms that match the given package atom
        """
 
+       if not candidate_list:
+               return []
+
        from portage_util import writemsg
        if "!" == mydep[:1]:
                mydep = mydep[1:]
@@ -637,13 +640,21 @@ def match_from_list(mydep, candidate_list):
 
        if operator is None:
                for x in candidate_list:
-                       if dep_getkey(x) != mycpv:
+                       cp = getattr(x, "cp", None)
+                       if cp is None:
+                               cp = dep_getkey(x)
+                       if cp != mycpv:
                                continue
                        mylist.append(x)
 
        elif operator == "=": # Exact match
-               mylist = [cpv for cpv in candidate_list if \
-                       cpvequal(remove_slot(cpv), mycpv)]
+               for x in candidate_list:
+                       xcpv = getattr(x, "cpv", None)
+                       if xcpv is None:
+                               xcpv = dep_getcpv(x)
+                       if not cpvequal(xcpv, mycpv):
+                               continue
+                       mylist.append(x)
 
        elif operator == "=*": # glob match
                # XXX: Nasty special casing for leading zeros
@@ -655,7 +666,9 @@ def match_from_list(mydep, candidate_list):
                        myver = "0"+myver
                mycpv = mysplit[0]+"/"+mysplit[1]+"-"+myver
                for x in candidate_list:
-                       xs = catpkgsplit(remove_slot(x))
+                       xs = getattr(x, "cpv_split", None)
+                       if xs is None:
+                               xs = catpkgsplit(remove_slot(x))
                        myver = xs[2].lstrip("0")
                        if not myver or not myver[0].isdigit():
                                myver = "0"+myver
@@ -665,7 +678,9 @@ def match_from_list(mydep, candidate_list):
 
        elif operator == "~": # version, any revision, match
                for x in candidate_list:
-                       xs = catpkgsplit(remove_slot(x))
+                       xs = getattr(x, "cpv_split", None)
+                       if xs is None:
+                               xs = catpkgsplit(remove_slot(x))
                        if xs is None:
                                raise InvalidData(x)
                        if not cpvequal(xs[0]+"/"+xs[1]+"-"+xs[2], mycpv_cps[0]+"/"+mycpv_cps[1]+"-"+mycpv_cps[2]):
@@ -677,8 +692,13 @@ def match_from_list(mydep, candidate_list):
        elif operator in [">", ">=", "<", "<="]:
                mysplit = ["%s/%s" % (cat, pkg), ver, rev]
                for x in candidate_list:
+                       xs = getattr(x, "cpv_split", None)
+                       if xs is None:
+                               xs = catpkgsplit(remove_slot(x))
+                       xcat, xpkg, xver, xrev = xs
+                       xs = ["%s/%s" % (xcat, xpkg), xver, xrev]
                        try:
-                               result = pkgcmp(pkgsplit(remove_slot(x)), mysplit)
+                               result = pkgcmp(xs, mysplit)
                        except ValueError: # pkgcmp may return ValueError during int() conversion
                                writemsg("\nInvalid package name: %s\n" % x, noiselevel=-1)
                                raise
@@ -705,7 +725,9 @@ def match_from_list(mydep, candidate_list):
                candidate_list = mylist
                mylist = []
                for x in candidate_list:
-                       xslot = dep_getslot(x)
+                       xslot = getattr(x, "slot", None)
+                       if xslot is None and isinstance(x, basestring):
+                               xslot = dep_getslot(x)
                        if xslot is not None and xslot != slot:
                                continue
                        mylist.append(x)