From: Fabian Groffen Date: Mon, 21 Sep 2009 17:02:37 +0000 (-0000) Subject: Merged from trunk -r14274:14284 X-Git-Url: http://git.tremily.us/gitweb.cgi?a=commitdiff_plain;h=89886846f1825ccdf94b6bc65d471233b85f8127;p=portage.git Merged from trunk -r14274:14284 | 14279 | Atom optimizations. Remove the metaclass and cache since it | | zmedico | just slows it down. Thanks to Marat Radchenko | | | for this patch. | | 14280 | Use a dict for Package.metadata, because it's faster. Thanks | | zmedico | to Marat Radchenko for this patch | | | from bug #276813. | | 14281 | Fix _expand_new_virtuals() to preserve USE deps in atoms for | | zmedico | new-style virtuals, and update the corresponding depgraph | | | code. | | 14282 | Avoid lots of redundant Atom constructor calls. Thanks to | | zmedico | Marat Radchenko for the initial | | | patch from bug #276813. | | 14283 | Remove obsolete InvalidAtom handler in | | zmedico | _add_pkg_dep_string(). | | 14284 | Revert accidental changes | | zmedico | _unicode_module_wrapper.__getattribute__ from previous | | | commit. | svn path=/main/branches/prefix/; revision=14332 --- diff --git a/pym/_emerge/Blocker.py b/pym/_emerge/Blocker.py index ea93d6b8a..fcebb8b37 100644 --- a/pym/_emerge/Blocker.py +++ b/pym/_emerge/Blocker.py @@ -18,7 +18,7 @@ class Blocker(Task): def __init__(self, **kwargs): Task.__init__(self, **kwargs) - self.cp = portage.dep_getkey(self.atom) + self.cp = self.atom.cp def _get_hash_key(self): hash_key = getattr(self, "_hash_key", None) diff --git a/pym/_emerge/FakeVartree.py b/pym/_emerge/FakeVartree.py index 25bed2905..e895cc86b 100644 --- a/pym/_emerge/FakeVartree.py +++ b/pym/_emerge/FakeVartree.py @@ -76,8 +76,7 @@ class FakeVartree(portage.vartree): portage.locks.unlockdir(vdb_lock) # Populate the old-style virtuals using the cached values. if not self.settings.treeVirtuals: - self.settings.treeVirtuals = portage.util.map_dictlist_vals( - portage.getCPFromCPV, self.get_all_provides()) + self.settings._populate_treeVirtuals(self) # Intialize variables needed for lazy cache pulls of the live ebuild # metadata. This ensures that the vardb lock is released ASAP, without diff --git a/pym/_emerge/Package.py b/pym/_emerge/Package.py index 6371f5d05..14570d1ae 100644 --- a/pym/_emerge/Package.py +++ b/pym/_emerge/Package.py @@ -5,7 +5,6 @@ import re from itertools import chain import portage -from portage.cache.mappings import slot_dict_class from portage.dep import paren_reduce, use_reduce, \ paren_normalize, paren_enclose from _emerge.Task import Task @@ -152,33 +151,56 @@ _all_metadata_keys = set(x for x in portage.auxdbkeys \ if not x.startswith("UNUSED_")) _all_metadata_keys.discard("CDEPEND") _all_metadata_keys.update(Package.metadata_keys) +_all_metadata_keys = frozenset(_all_metadata_keys) -_PackageMetadataWrapperBase = slot_dict_class(_all_metadata_keys) - -class _PackageMetadataWrapper(_PackageMetadataWrapperBase): +class _PackageMetadataWrapper(dict): """ Detect metadata updates and synchronize Package attributes. """ __slots__ = ("_pkg",) - _wrapped_keys = frozenset( - ["COUNTER", "INHERITED", "IUSE", "SLOT", "_mtime_"]) _use_conditional_keys = frozenset( ['LICENSE', 'PROPERTIES', 'PROVIDE', 'RESTRICT',]) def __init__(self, pkg, metadata): - _PackageMetadataWrapperBase.__init__(self) self._pkg = pkg - """LICENSE with USE conditionals evaluated.""" - if not pkg.built: # USE is lazy, but we want it to show up in self.keys(). self['USE'] = '' - self.update(metadata) + for k, v in self.iteritems(): + if k == 'INHERITED': + if isinstance(v, basestring): + v = frozenset(v.split()) + self._pkg.inherited = v + elif k == 'SLOT': + self._pkg.slot = v + elif k == 'IUSE': + self._pkg.iuse = self._pkg._iuse( + v.split(), self._pkg.root_config.iuse_implicit) + elif k == 'COUNTER': + if isinstance(v, basestring): + try: + v = long(v.strip()) + except ValueError: + v = 0 + self['COUNTER'] = str(v) + self._pkg.counter = v + elif k == '_mtime_': + if isinstance(v, basestring): + try: + v = long(v.strip()) + except ValueError: + v = 0 + self._pkg.mtime = v + elif k in self._use_conditional_keys: + try: + use_reduce(paren_reduce(v), matchall=1) + except portage.exception.InvalidDependString, e: + self._pkg._invalid_metadata(k + ".syntax", "%s: %s" % (k, e)) def __getitem__(self, k): - v = _PackageMetadataWrapperBase.__getitem__(self, k) + v = dict.__getitem__(self, k) if k in self._use_conditional_keys: if self._pkg.root_config.settings.local_config and '?' in v: try: @@ -202,44 +224,6 @@ class _PackageMetadataWrapper(_PackageMetadataWrapperBase): return v - def __setitem__(self, k, v): - _PackageMetadataWrapperBase.__setitem__(self, k, v) - if k in self._wrapped_keys: - getattr(self, "_set_" + k.lower())(k, v) - elif k in self._use_conditional_keys: - try: - use_reduce(paren_reduce(v), matchall=1) - except portage.exception.InvalidDependString, e: - self._pkg._invalid_metadata(k + ".syntax", "%s: %s" % (k, e)) - - def _set_inherited(self, k, v): - if isinstance(v, basestring): - v = frozenset(v.split()) - self._pkg.inherited = v - - def _set_iuse(self, k, v): - self._pkg.iuse = self._pkg._iuse( - v.split(), self._pkg.root_config.iuse_implicit) - - def _set_slot(self, k, v): - self._pkg.slot = v - - def _set_counter(self, k, v): - if isinstance(v, basestring): - try: - v = long(v.strip()) - except ValueError: - v = 0 - self._pkg.counter = v - - def _set__mtime_(self, k, v): - if isinstance(v, basestring): - try: - v = long(v.strip()) - except ValueError: - v = 0 - self._pkg.mtime = v - @property def properties(self): return self['PROPERTIES'].split() diff --git a/pym/_emerge/actions.py b/pym/_emerge/actions.py index 10d657719..8dff6c5bb 100644 --- a/pym/_emerge/actions.py +++ b/pym/_emerge/actions.py @@ -2677,8 +2677,7 @@ def display_news_notification(root_config, myopts): if not settings.treeVirtuals: # Populate these using our existing vartree, to avoid # having a temporary one instantiated. - settings.treeVirtuals = portage.util.map_dictlist_vals( - portage.getCPFromCPV, trees["vartree"].get_all_provides()) + settings._populate_treeVirtuals(trees["vartree"]) for repo in portdb.getRepositories(): unreadItems = checkUpdatedNewsItems( diff --git a/pym/_emerge/depgraph.py b/pym/_emerge/depgraph.py index ad3e2d06e..df54f2e0d 100644 --- a/pym/_emerge/depgraph.py +++ b/pym/_emerge/depgraph.py @@ -1148,26 +1148,16 @@ class depgraph(object): vardb = self._frozen_config.roots[dep_root].trees["vartree"].dbapi for atom in selected_atoms[pkg]: - try: - - atom = portage.dep.Atom(atom) - - mypriority = dep_priority.copy() - if not atom.blocker and vardb.match(atom): - mypriority.satisfied = True - if not self._add_dep(Dependency(atom=atom, - blocker=atom.blocker, depth=depth, parent=pkg, - priority=mypriority, root=dep_root), - allow_unsatisfied=allow_unsatisfied): - return 0 + mypriority = dep_priority.copy() + if not atom.blocker and vardb.match(atom): + mypriority.satisfied = True - except portage.exception.InvalidAtom, e: - show_invalid_depstring_notice( - pkg, dep_string, str(e)) - del e - if not pkg.installed: - return 0 + if not self._add_dep(Dependency(atom=atom, + blocker=atom.blocker, depth=depth, parent=pkg, + priority=mypriority, root=dep_root), + allow_unsatisfied=allow_unsatisfied): + return 0 selected_atoms.pop(pkg) @@ -1306,16 +1296,15 @@ class depgraph(object): atom_arg_map = self._dynamic_config._atom_arg_map root_config = self._frozen_config.roots[pkg.root] for atom in self._dynamic_config._set_atoms.iterAtomsForPackage(pkg): - atom_cp = portage.dep_getkey(atom) - if atom_cp != pkg.cp and \ - self._have_new_virt(pkg.root, atom_cp): + if atom.cp != pkg.cp and \ + self._have_new_virt(pkg.root, atom.cp): continue visible_pkgs = \ self._dynamic_config._visible_pkgs[pkg.root].match_pkgs(atom) visible_pkgs.reverse() # descending order higher_slot = None for visible_pkg in visible_pkgs: - if visible_pkg.cp != atom_cp: + if visible_pkg.cp != atom.cp: continue if pkg >= visible_pkg: # This is descending order, and we're not @@ -1606,9 +1595,8 @@ class depgraph(object): self._spinner_update() dep = Dependency(atom=atom, onlydeps=onlydeps, root=myroot, parent=arg) - atom_cp = portage.dep_getkey(atom) try: - pprovided = pprovideddict.get(portage.dep_getkey(atom)) + pprovided = pprovideddict.get(atom.cp) if pprovided and portage.match_from_list(atom, pprovided): # A provided package has been specified on the command line. self._dynamic_config._pprovided_args.append((arg, atom)) @@ -1651,10 +1639,10 @@ class depgraph(object): return 0, myfavorites self._dynamic_config._missing_args.append((arg, atom)) continue - if atom_cp != pkg.cp: + if atom.cp != pkg.cp: # For old-style virtuals, we need to repeat the # package.provided check against the selected package. - expanded_atom = atom.replace(atom_cp, pkg.cp) + expanded_atom = atom.replace(atom.cp, pkg.cp) pprovided = pprovideddict.get(pkg.cp) if pprovided and \ portage.match_from_list(expanded_atom, pprovided): @@ -1901,16 +1889,20 @@ class depgraph(object): for node in atom_graph: if isinstance(node, Atom): continue - if node == parent.cpv: + if node is parent: pkg = parent else: - virt_atom = Atom('=' + node) + pkg, virt_atom = node if virt_atom not in chosen_atoms: continue - pkg, existing_node = self._select_package( - root, virt_atom) - if pkg is None: - raise AssertionError(node) + if not portage.match_from_list(virt_atom, [pkg]): + # Typically this means that the atom + # specifies USE deps that are unsatisfied + # by the selected package. The caller will + # record this as an unsatisfied dependency + # when necessary. + continue + selected_atoms[pkg] = [atom for atom in \ atom_graph.child_nodes(node) if atom in chosen_atoms] @@ -2392,7 +2384,7 @@ class depgraph(object): # Filter out any old-style virtual matches if they are # mixed with new-style virtual matches. - cp = portage.dep_getkey(atom) + cp = atom.cp if len(matched_packages) > 1 and \ "virtual" == portage.catsplit(cp)[0]: for pkg in matched_packages: @@ -2733,8 +2725,8 @@ class depgraph(object): for provider_entry in virtuals[blocker.cp]: provider_cp = \ portage.dep_getkey(provider_entry) - atoms.append(blocker.atom.replace( - blocker.cp, provider_cp)) + atoms.append(Atom(blocker.atom.replace( + blocker.cp, provider_cp))) else: atoms = [blocker.atom] @@ -4892,7 +4884,6 @@ class _dep_check_composite_db(portage.dbapi): # any matching slots in the graph db. slots = set() slots.add(pkg.metadata["SLOT"]) - atom_cp = portage.dep_getkey(atom) if pkg.cp.startswith("virtual/"): # For new-style virtual lookahead that occurs inside # dep_check(), examine all slots. This is needed @@ -4913,7 +4904,7 @@ class _dep_check_composite_db(portage.dbapi): ret.append(pkg.cpv) slots.remove(pkg.metadata["SLOT"]) while slots: - slot_atom = "%s:%s" % (atom_cp, slots.pop()) + slot_atom = Atom("%s:%s" % (atom.cp, slots.pop())) pkg, existing = self._depgraph._select_package( self._root, slot_atom) if not pkg: @@ -5000,6 +4991,8 @@ class _dep_check_composite_db(portage.dbapi): metadata = self._cpv_pkg_map[cpv].metadata return [metadata.get(x, "") for x in wants] + def match_pkgs(self, atom): + return [self._cpv_pkg_map[cpv] for cpv in self.match(atom)] def ambiguous_package_name(arg, atoms, root_config, spinner, myopts): diff --git a/pym/portage/__init__.py b/pym/portage/__init__.py index d6ca5aebd..c9939c24b 100644 --- a/pym/portage/__init__.py +++ b/pym/portage/__init__.py @@ -3265,7 +3265,6 @@ class config(object): # an incremental! myincrementals.remove("USE") - mydbs = self.configlist[:-1] mydbs.append(self.backupenv) @@ -3512,12 +3511,21 @@ class config(object): if self.local_config and not self.treeVirtuals: temp_vartree = vartree(myroot, None, categories=self.categories, settings=self) - # Reduce the provides into a list by CP. - self.treeVirtuals = map_dictlist_vals(getCPFromCPV,temp_vartree.get_all_provides()) + self._populate_treeVirtuals(temp_vartree) self.virtuals = self.__getvirtuals_compile() return self.virtuals + def _populate_treeVirtuals(self, vartree): + """Reduce the provides into a list by CP.""" + for provide, cpv_list in vartree.get_all_provides().iteritems(): + try: + provide = dep.Atom(provide) + except exception.InvalidAtom: + continue + self.treeVirtuals[provide.cp] = \ + [dep.Atom(cpv_getkey(cpv)) for cpv in cpv_list] + def __getvirtuals_compile(self): """Stack installed and profile virtuals. Preference for virtuals decreases from left to right. @@ -6928,7 +6936,6 @@ def doebuild(myebuild, mydo, myroot, mysettings, debug=0, listonly=0, # so do not check them again. checkme = [] - if not emerge_skip_distfiles and \ need_distfiles and not fetch( fetchme, mysettings, listonly=listonly, fetchonly=fetchonly): @@ -7411,10 +7418,6 @@ def unmerge(cat, pkg, myroot, mysettings, mytrimworld=1, vartree=None, vartree.dbapi.linkmap._clear_cache() mylink.unlockdb() -def getCPFromCPV(mycpv): - """Calls pkgsplit on a cpv and returns only the cp.""" - return pkgsplit(mycpv)[0] - def dep_virtual(mysplit, mysettings): "Does virtual dependency conversion" newsplit=[] @@ -7441,10 +7444,6 @@ def dep_virtual(mysplit, mysettings): newsplit.append(x) return newsplit -# According to GLEP 37, RDEPEND is the only dependency type that is valid -# for new-style virtuals. Repoman should enforce this. -_virt_dep_keys = ("RDEPEND",) - def _expand_new_virtuals(mysplit, edebug, mydbapi, mysettings, myroot="/", trees=None, use_mask=None, use_force=None, **kwargs): """Recursively expand new-style virtuals so as to collapse one or more @@ -7461,15 +7460,14 @@ def _expand_new_virtuals(mysplit, edebug, mydbapi, mysettings, myroot="/", atom_graph = mytrees.get("atom_graph") parent = mytrees.get("parent") virt_parent = mytrees.get("virt_parent") - virt_eapi = mytrees.get("virt_eapi") - parent_cpv = None + graph_parent = None eapi = None if parent is not None: if virt_parent is not None: - parent_cpv = virt_parent - eapi = virt_eapi + graph_parent = virt_parent + eapi = virt_parent[0].metadata['EAPI'] else: - parent_cpv = parent.cpv + graph_parent = parent eapi = parent.metadata["EAPI"] repoman = not mysettings.local_config if kwargs["use_binaries"]: @@ -7524,31 +7522,30 @@ def _expand_new_virtuals(mysplit, edebug, mydbapi, mysettings, myroot="/", evaluated_atom += str(x.use.evaluate_conditionals(myuse)) x = portage.dep.Atom(evaluated_atom) - mykey = dep_getkey(x) + mykey = x.cp if not mykey.startswith("virtual/"): newsplit.append(x) - if parent_cpv is not None: - atom_graph.add(x, parent_cpv) + if atom_graph is not None: + atom_graph.add(x, graph_parent) continue mychoices = myvirtuals.get(mykey, []) - isblocker = x.startswith("!") - if isblocker: + if x.blocker: # Virtual blockers are no longer expanded here since # the un-expanded virtual atom is more useful for # maintaining a cache of blocker atoms. newsplit.append(x) - if parent_cpv is not None: - atom_graph.add(x, parent_cpv) + if atom_graph is not None: + atom_graph.add(x, graph_parent) continue - if repoman: + if repoman or not hasattr(portdb, 'match_pkgs'): if portdb.cp_list(x.cp): newsplit.append(x) else: # TODO: Add PROVIDE check for repoman. a = [] for y in mychoices: - a.append(portage.dep.Atom(x.replace(mykey, str(y.cp), 1))) + a.append(dep.Atom(x.replace(x.cp, y.cp, 1))) if not a: newsplit.append(x) elif len(a) == 1: @@ -7557,15 +7554,17 @@ def _expand_new_virtuals(mysplit, edebug, mydbapi, mysettings, myroot="/", newsplit.append(['||'] + a) continue - match_atom = x pkgs = [] - matches = portdb.match(match_atom) + # Ignore USE deps here, since otherwise we might not + # get any matches. Choices with correct USE settings + # will be preferred in dep_zapdeps(). + matches = portdb.match_pkgs(x.without_use) # Use descending order to prefer higher versions. matches.reverse() - for cpv in matches: + for pkg in matches: # only use new-style matches - if cpv.startswith("virtual/"): - pkgs.append((cpv, catpkgsplit(cpv)[1:], portdb)) + if pkg.cp.startswith("virtual/"): + pkgs.append(pkg) if not (pkgs or mychoices): # This one couldn't be expanded as a new-style virtual. Old-style # virtuals have already been expanded by dep_virtual, so this one @@ -7573,29 +7572,30 @@ def _expand_new_virtuals(mysplit, edebug, mydbapi, mysettings, myroot="/", # atom is not eliminated here since it may still represent a # dependency that needs to be satisfied. newsplit.append(x) - if parent_cpv is not None: - atom_graph.add(x, parent_cpv) + if atom_graph is not None: + atom_graph.add(x, graph_parent) continue a = [] - for y in pkgs: - cpv, pv_split, db = y - depstring = " ".join(db.aux_get(cpv, _virt_dep_keys)) + for pkg in pkgs: + virt_atom = '=' + pkg.cpv + if x.use: + virt_atom += str(x.use) + virt_atom = dep.Atom(virt_atom) + # According to GLEP 37, RDEPEND is the only dependency + # type that is valid for new-style virtuals. Repoman + # should enforce this. + depstring = pkg.metadata['RDEPEND'] pkg_kwargs = kwargs.copy() - if repoman: - pass - else: - # for emerge - use_split = db.aux_get(cpv, ["USE"])[0].split() - pkg_kwargs["myuse"] = use_split + pkg_kwargs["myuse"] = pkg.use.enabled if edebug: - print _("Virtual Parent: "), y[0] - print _("Virtual Depstring:"), depstring + util.writemsg_level(_("Virtual Parent: %s\n") \ + % (pkg,), noiselevel=-1, level=logging.DEBUG) + util.writemsg_level(_("Virtual Depstring: %s\n") \ + % (depstring,), noiselevel=-1, level=logging.DEBUG) # Set EAPI used for validation in dep_check() recursion. - new_eapi, = db.aux_get(cpv, ["EAPI"]) - mytrees["virt_eapi"] = new_eapi - mytrees["virt_parent"] = cpv + mytrees["virt_parent"] = (pkg, virt_atom) try: mycheck = dep_check(depstring, mydbapi, mysettings, @@ -7604,49 +7604,45 @@ def _expand_new_virtuals(mysplit, edebug, mydbapi, mysettings, myroot="/", # Restore previous EAPI after recursion. if virt_parent is not None: mytrees["virt_parent"] = virt_parent - mytrees["virt_eapi"] = virt_eapi else: del mytrees["virt_parent"] - del mytrees["virt_eapi"] if not mycheck[0]: raise portage.exception.ParseError( "%s: %s '%s'" % (y[0], mycheck[1], depstring)) # pull in the new-style virtual - virt_atom = dep.Atom('=' + cpv) mycheck[1].append(virt_atom) a.append(mycheck[1]) - if parent_cpv is not None: - atom_graph.add(virt_atom, parent_cpv) + if atom_graph is not None: + atom_graph.add(virt_atom, graph_parent) # Plain old-style virtuals. New-style virtuals are preferred. if not pkgs: for y in mychoices: - new_atom = portage.dep.Atom( - x.replace(mykey, dep_getkey(y), 1)) + new_atom = dep.Atom(x.replace(x.cp, y.cp, 1)) matches = portdb.match(new_atom) # portdb is an instance of depgraph._dep_check_composite_db, so # USE conditionals are already evaluated. if matches and mykey in \ portdb.aux_get(matches[-1], ['PROVIDE'])[0].split(): a.append(new_atom) - if parent_cpv is not None: - atom_graph.add(new_atom, parent_cpv) + if atom_graph is not None: + atom_graph.add(new_atom, graph_parent) if not a and mychoices: # Check for a virtual package.provided match. for y in mychoices: - new_atom = portage.dep.Atom(x.replace(mykey, dep_getkey(y), 1)) + new_atom = dep.Atom(x.replace(x.cp, y.cp, 1)) if match_from_list(new_atom, pprovideddict.get(new_atom.cp, [])): a.append(new_atom) - if parent_cpv is not None: - atom_graph.add(new_atom, parent_cpv) + if atom_graph is not None: + atom_graph.add(new_atom, graph_parent) if not a: newsplit.append(x) - if parent_cpv is not None: - atom_graph.add(x, parent_cpv) + if atom_graph is not None: + atom_graph.add(x, graph_parent) elif len(a) == 1: newsplit.append(a[0]) else: @@ -7692,12 +7688,12 @@ def dep_zapdeps(unreduced, reduced, myroot, use_binaries=0, trees=None): if unreduced[0] != "||": unresolved = [] - for dep, satisfied in izip(unreduced, reduced): - if isinstance(dep, list): - unresolved += dep_zapdeps(dep, satisfied, myroot, + for x, satisfied in izip(unreduced, reduced): + if isinstance(x, list): + unresolved += dep_zapdeps(x, satisfied, myroot, use_binaries=use_binaries, trees=trees) elif not satisfied: - unresolved.append(dep) + unresolved.append(x) return unresolved # We're at a ( || atom ... ) type level and need to make a choice @@ -7734,12 +7730,12 @@ def dep_zapdeps(unreduced, reduced, myroot, use_binaries=0, trees=None): # Sort the deps into installed, not installed but already # in the graph and other, not installed and not in the graph # and other, with values of [[required_atom], availablility] - for dep, satisfied in izip(deps, satisfieds): - if isinstance(dep, list): - atoms = dep_zapdeps(dep, satisfied, myroot, + for x, satisfied in izip(deps, satisfieds): + if isinstance(x, list): + atoms = dep_zapdeps(x, satisfied, myroot, use_binaries=use_binaries, trees=trees) else: - atoms = [dep] + atoms = [x] if not vardb: # called by repoman other.append((atoms, None, False)) @@ -7749,15 +7745,15 @@ def dep_zapdeps(unreduced, reduced, myroot, use_binaries=0, trees=None): all_use_satisfied = True versions = {} for atom in atoms: - if atom[:1] == "!": + if atom.blocker: continue # Ignore USE dependencies here since we don't want USE # settings to adversely affect || preference evaluation. avail_pkg = mydbapi.match(atom.without_use) if avail_pkg: avail_pkg = avail_pkg[-1] # highest (ascending order) - avail_slot = "%s:%s" % (dep_getkey(atom), - mydbapi.aux_get(avail_pkg, ["SLOT"])[0]) + avail_slot = dep.Atom("%s:%s" % (atom.cp, + mydbapi.aux_get(avail_pkg, ["SLOT"])[0])) if not avail_pkg: all_available = False all_use_satisfied = False @@ -7772,8 +7768,8 @@ def dep_zapdeps(unreduced, reduced, myroot, use_binaries=0, trees=None): avail_pkg_use = avail_pkg_use[-1] if avail_pkg_use != avail_pkg: avail_pkg = avail_pkg_use - avail_slot = "%s:%s" % (dep_getkey(atom), - mydbapi.aux_get(avail_pkg, ["SLOT"])[0]) + avail_slot = dep.Atom("%s:%s" % (atom.cp, + mydbapi.aux_get(avail_pkg, ["SLOT"])[0])) versions[avail_slot] = avail_pkg @@ -7783,8 +7779,8 @@ def dep_zapdeps(unreduced, reduced, myroot, use_binaries=0, trees=None): # If any version of a package is already in the graph then we # assume that it is preferred over other possible packages choices. all_installed = True - for atom in set([dep_getkey(atom) for atom in atoms \ - if atom[:1] != "!"]): + for atom in set(dep.Atom(atom.cp) for atom in atoms \ + if not atom.blocker): # New-style virtuals have zero cost to install. if not vardb.match(atom) and not atom.startswith("virtual/"): all_installed = False @@ -7832,13 +7828,13 @@ def dep_zapdeps(unreduced, reduced, myroot, use_binaries=0, trees=None): # installed package. cpv_slot_list = [parent] for atom in atoms: - if "!" == atom[:1]: + if atom.blocker: continue if vardb.match(atom): # If the atom is satisfied by an installed # version then it's not a circular dep. continue - if dep_getkey(atom) != parent.cp: + if atom.cp != parent.cp: continue if match_from_list(atom, cpv_slot_list): circular_atom = atom @@ -7880,14 +7876,19 @@ def dep_zapdeps(unreduced, reduced, myroot, use_binaries=0, trees=None): assert(False) # This point should not be reachable - def dep_expand(mydep, mydb=None, use_cache=1, settings=None): + ''' + @rtype: Atom + ''' if not len(mydep): return mydep if mydep[0]=="*": mydep=mydep[1:] orig_dep = mydep - mydep = dep_getcpv(orig_dep) + if isinstance(orig_dep, dep.Atom): + mydep = orig_dep.cpv + else: + mydep = dep_getcpv(orig_dep) myindex = orig_dep.index(mydep) prefix = orig_dep[:myindex] postfix = orig_dep[myindex+len(mydep):] @@ -8004,7 +8005,7 @@ def dep_wordreduce(mydeplist,mysettings,mydbapi,mode,use_cache=1): elif token[:1] == "!": deplist[mypos] = False else: - mykey = dep_getkey(deplist[mypos]) + mykey = deplist[mypos].cp if mysettings and mykey in mysettings.pprovideddict and \ match_from_list(deplist[mypos], mysettings.pprovideddict[mykey]): deplist[mypos]=True @@ -8034,8 +8035,23 @@ def dep_wordreduce(mydeplist,mysettings,mydbapi,mode,use_cache=1): return None return deplist +_cpv_key_re = re.compile('^' + dep._cpv + '$', re.VERBOSE) def cpv_getkey(mycpv): - return dep.dep_getkey('=' + mycpv) + """Calls pkgsplit on a cpv and returns only the cp.""" + m = _cpv_key_re.match(mycpv) + if m is not None: + return m.group(2) + myslash = mycpv.split("/", 1) + mysplit=pkgsplit(myslash[-1]) + if mysplit is None: + return None + mylen=len(myslash) + if mylen==2: + return myslash[0]+"/"+mysplit[0] + else: + return mysplit[0] + +getCPFromCPV = cpv_getkey def key_expand(mykey, mydb=None, use_cache=1, settings=None): mysplit=mykey.split("/") @@ -8356,7 +8372,6 @@ def getmaskingstatus(mycpv, settings=None, portdb=None): return rValue - auxdbkeys=[ 'DEPEND', 'RDEPEND', 'SLOT', 'SRC_URI', 'RESTRICT', 'HOMEPAGE', 'LICENSE', 'DESCRIPTION', @@ -8961,7 +8976,6 @@ def init_legacy_globals(): root = settings["ROOT"] output._init(config_root=settings['PORTAGE_CONFIGROOT']) - # ======================================================================== # COMPATIBILITY # These attributes should not be used diff --git a/pym/portage/dbapi/porttree.py b/pym/portage/dbapi/porttree.py index 10baa4b9c..4cc07362a 100644 --- a/pym/portage/dbapi/porttree.py +++ b/pym/portage/dbapi/porttree.py @@ -949,7 +949,7 @@ class portdbapi(dbapi): #this stuff only runs on first call of xmatch() #create mydep, mykey from origdep mydep = dep_expand(origdep, mydb=self, settings=self.mysettings) - mykey = dep_getkey(mydep) + mykey = mydep.cp if level == "list-visible": #a list of all visible packages, not called directly (just by xmatch()) @@ -1133,7 +1133,6 @@ def close_portdbapi_caches(): for i in portdbapi.portdbapi_instances: i.close_caches() - class portagetree(object): def __init__(self, root="/", virtual=None, clone=None, settings=None): """ diff --git a/pym/portage/dep.py b/pym/portage/dep.py index b54c528fa..bd576b768 100644 --- a/pym/portage/dep.py +++ b/pym/portage/dep.py @@ -488,20 +488,6 @@ class _use_dep(object): return _use_dep(tokens) -class _AtomCache(type): - """ - Cache Atom instances from constructor calls and reuse - identical instances when available. - """ - def __call__(cls, s): - if isinstance(s, Atom): - return s - instance = cls._atoms.get(s) - if instance is None: - instance = super(_AtomCache, cls).__call__(s) - cls._atoms[s] = instance - return instance - class Atom(object): """ @@ -509,9 +495,6 @@ class Atom(object): class emulates most of the str methods that are useful with atoms. """ - __metaclass__ = _AtomCache - _atoms = weakref.WeakValueDictionary() - __slots__ = ("__weakref__", "blocker", "cp", "cpv", "operator", "slot", "use", "without_use", "_str",) @@ -528,12 +511,11 @@ class Atom(object): self.overlap = self._overlap(forbid=forbid_overlap) def __init__(self, mypkg): - s = mypkg + s = mypkg = str(mypkg) obj_setattr = object.__setattr__ obj_setattr(self, '_str', s) - blocker = "!" == s[:1] - if blocker: + if "!" == s[:1]: blocker = self._blocker(forbid_overlap=("!" == s[1:2])) if blocker.overlap.forbid: s = s[2:] @@ -546,31 +528,25 @@ class Atom(object): if m is None: raise InvalidAtom(mypkg) - # Package name must not end in pattern - # which appears to be a valid version. if m.group('op') is not None: - if m.group(_atom_re.groupindex['op'] + 4) is not None: + base = _atom_re.groupindex['op'] + op = m.group(base + 1) + cpv = m.group(base + 2) + cp = m.group(base + 3) + if m.group(base + 4) is not None: raise InvalidAtom(mypkg) elif m.group('star') is not None: - if m.group(_atom_re.groupindex['star'] + 3) is not None: + base = _atom_re.groupindex['star'] + op = '=*' + cpv = m.group(base + 1) + cp = m.group(base + 2) + if m.group(base + 3) is not None: raise InvalidAtom(mypkg) elif m.group('simple') is not None: - if m.group(_atom_re.groupindex['simple'] + 2) is not None: - raise InvalidAtom(mypkg) - else: - raise AssertionError(_("required group not found in atom: '%s'") % mypkg) - - if m.group('op'): - op = m.group(_atom_re.groupindex['op'] + 1) - cpv = m.group(_atom_re.groupindex['op'] + 2) - cp = m.group(_atom_re.groupindex['op'] + 3) - elif m.group('star'): - op = '=*' - cpv = m.group(_atom_re.groupindex['star'] + 1) - cp = m.group(_atom_re.groupindex['star'] + 2) - elif m.group('simple'): op = None cpv = cp = m.group(_atom_re.groupindex['simple'] + 1) + if m.group(_atom_re.groupindex['simple'] + 2) is not None: + raise InvalidAtom(mypkg) else: raise AssertionError(_("required group not found in atom: '%s'") % s) obj_setattr(self, "cp", cp) @@ -578,13 +554,10 @@ class Atom(object): obj_setattr(self, "slot", m.group(_atom_re.groups - 1)) obj_setattr(self, "operator", op) - use = dep_getusedeps(s) - if use: - use = _use_dep(use) - without_use = remove_slot(self) - if self.slot is not None: - without_use += ":" + self.slot - without_use = Atom(without_use) + use_str = m.group(_atom_re.groups) + if use_str is not None: + use = _use_dep(dep_getusedeps(s)) + without_use = Atom(m.group('without_use')) else: use = None without_use = self @@ -830,9 +803,6 @@ def dep_getusedeps( depend ): @rtype: List @return: List of use flags ( or [] if no flags exist ) """ - use = getattr(depend, "use", None) - if use is not None and hasattr(use, "tokens"): - return use.tokens use_list = [] open_bracket = depend.find('[') # -1 = failure (think c++ string::npos) @@ -886,17 +856,16 @@ _pkg = r'[\w+][\w+-]*?' # 2.1.3 A slot name may contain any of the characters [A-Za-z0-9+_.-]. # It must not begin with a hyphen or a dot. _slot = r':([\w+][\w+.-]*)' -_optional_slot = '(?:' + _slot + ')?' -_use = r'(\[.*\])?' +_use = r'\[.*\]' _op = r'([=~]|[><]=?)' _cp = '(' + _cat + '/' + _pkg + '(-' + _version + ')?)' _cpv = '(' + _cp + '-' + _version + ')' -_atom_re = re.compile('^(?:' + +_atom_re = re.compile('^(?P(?:' + '(?P' + _op + _cpv + ')|' + '(?P=' + _cpv + r'\*)|' + - '(?P' + _cp + '))' + _optional_slot + _use + '$', re.VERBOSE) + '(?P' + _cp + '))(?:' + _slot + ')?)(' + _use + ')?$', re.VERBOSE) def isvalidatom(atom, allow_blockers=False): """ @@ -1021,6 +990,8 @@ def match_to_list(mypkg, mylist): """ matches = [] for x in mylist: + if not isinstance(x, Atom): + x = Atom(x) if match_from_list(x, [mypkg]): if x not in matches: matches.append(x) @@ -1055,7 +1026,7 @@ def best_match_to_list(mypkg, mylist): if maxvalue < 3: maxvalue = 3 bestm = x - op_val = operator_values[get_operator(x)] + op_val = operator_values[x.operator] if op_val > maxvalue: maxvalue = op_val bestm = x @@ -1082,9 +1053,9 @@ def match_from_list(mydep, candidate_list): if not isinstance(mydep, Atom): mydep = Atom(mydep) - mycpv = dep_getcpv(mydep) + mycpv = mydep.cpv mycpv_cps = catpkgsplit(mycpv) # Can be None if not specific - slot = dep_getslot(mydep) + slot = mydep.slot if not mycpv_cps: cat, pkg = catsplit(mycpv) @@ -1097,7 +1068,7 @@ def match_from_list(mydep, candidate_list): " (%s) (try adding an '=')") % (mydep)) if ver and rev: - operator = get_operator(mydep) + operator = mydep.operator if not operator: writemsg(_("!!! Invalid atom: %s\n") % mydep, noiselevel=-1) return [] diff --git a/pym/portage/sets/base.py b/pym/portage/sets/base.py index 87a0d1db7..adf05fbf8 100644 --- a/pym/portage/sets/base.py +++ b/pym/portage/sets/base.py @@ -104,9 +104,8 @@ class PackageSet(object): self._atommap.clear() atoms = self._atoms for a in atoms: - cp = dep_getkey(a) - self._atommap.setdefault(cp, set()) - self._atommap[cp].add(a) + self._atommap.setdefault(a.cp, set()) + self._atommap[a.cp].add(a) # Not sure if this one should really be in PackageSet def findAtomForPackage(self, pkg):