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)
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
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
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:
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()
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(
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)
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
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))
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):
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]
# 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:
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]
# 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
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:
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):
# an incremental!
myincrementals.remove("USE")
-
mydbs = self.configlist[:-1]
mydbs.append(self.backupenv)
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.
# so do not check them again.
checkme = []
-
if not emerge_skip_distfiles and \
need_distfiles and not fetch(
fetchme, mysettings, listonly=listonly, fetchonly=fetchonly):
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=[]
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
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"]:
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:
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
# 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,
# 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:
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
# 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))
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
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
# 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
# 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
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):]
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
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("/")
return rValue
-
auxdbkeys=[
'DEPEND', 'RDEPEND', 'SLOT', 'SRC_URI',
'RESTRICT', 'HOMEPAGE', 'LICENSE', 'DESCRIPTION',
root = settings["ROOT"]
output._init(config_root=settings['PORTAGE_CONFIGROOT'])
-
# ========================================================================
# COMPATIBILITY
# These attributes should not be used
#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())
for i in portdbapi.portdbapi_instances:
i.close_caches()
-
class portagetree(object):
def __init__(self, root="/", virtual=None, clone=None, settings=None):
"""
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):
"""
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",)
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:]
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)
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
@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)
# 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<without_use>(?:' +
'(?P<op>' + _op + _cpv + ')|' +
'(?P<star>=' + _cpv + r'\*)|' +
- '(?P<simple>' + _cp + '))' + _optional_slot + _use + '$', re.VERBOSE)
+ '(?P<simple>' + _cp + '))(?:' + _slot + ')?)(' + _use + ')?$', re.VERBOSE)
def isvalidatom(atom, allow_blockers=False):
"""
"""
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)
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
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)
" (%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 []
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):