def default_filter(self, features=None, filter=None): if filter is None: filter = {} else: filter.clear() filter.update({fstr+'@': False for fstr in iterkeys(self.trackers)}) if features: filter.update({fstr+'@': True for fstr in features}) return filter
def __init__(self, index): self.index = index.copy() for fn, info in iteritems(index): for fstr in chain(info.get('features', '').split(), info.get('track_features', '').split()): fpkg = fstr + '@' if fpkg not in self.index: self.index[fpkg] = { 'name': fpkg, 'version': '0', 'build_number': 0, 'build': '', 'depends': [], 'track_features': fstr} for fstr in iterkeys(info.get('with_features_depends', {})): fn2 = fn + '[' + fstr + ']' self.index[fn2] = info self.groups, self.trackers = build_groups(self.index) self.find_matches_ = {} self.ms_depends_ = {}
def gen_clauses(self, groups, trackers, specs): C = Clauses() # Creates a variable that represents the proposition: # Does the package set include a package that matches MatchSpec "ms"? def push_MatchSpec(ms): name = self.ms_to_v(ms) m = C.from_name(name) if m is None: libs = [fn for fn in self.find_matches_group(ms, groups, trackers)] # If the MatchSpec is optional, then there may be cases where we want # to assert that it is *not* True. This requires polarity=None. m = C.Any(libs, polarity=None if ms.optional else True, name=name) return m # Creates a variable that represents the proposition: # Does the package set include package "fn"? for group in itervalues(groups): for fn in group: C.new_var(fn) # Install no more than one version of each package C.Require(C.AtMostOne, group) # Create a variable that represents the proposition: # Is the feature "name" active in this package set? # We mark this as "optional" below because sometimes we need to be able to # assert the proposition is False during the feature minimization pass. for name in iterkeys(trackers): ms = MatchSpec('@' + name) ms.optional = True push_MatchSpec(ms) # Create a variable that represents the proposition: # Is the MatchSpec "ms" satisfied by the current package set? for ms in specs: push_MatchSpec(ms) # Create propositions that assert: # If package "fn" is installed, its dependencie must be satisfied for group in itervalues(groups): for fn in group: for ms in self.ms_depends(fn): if not ms.optional: C.Require(C.Or, C.Not(fn), push_MatchSpec(ms)) return C
def __init__(self, bad_deps, chains=True): bad_deps = [list(map(str, dep)) for dep in bad_deps] if chains: chains = {} for dep in sorted(bad_deps, key=len, reverse=True): dep1 = [str(MatchSpec(s)).partition(' ') for s in dep[1:]] key = (dep[0],) + tuple(v[0] for v in dep1) vals = ('',) + tuple(v[2] for v in dep1) found = False for key2, csets in iteritems(chains): if key2[:len(key)] == key: for cset, val in zip(csets, vals): cset.add(val) found = True if not found: chains[key] = [{val} for val in vals] bad_deps = [] for key, csets in iteritems(chains): deps = [] for name, cset in zip(key, csets): if '' not in cset: pass elif len(cset) == 1: cset.clear() else: cset.remove('') cset.add('*') deps.append('%s %s' % (name, '|'.join(sorted(cset))) if cset else name) chains[key] = ' -> '.join(deps) bad_deps = [chains[key] for key in sorted(iterkeys(chains))] msg = '''The following specifications were found to be in conflict:%s Use "conda info <package>" to see the dependencies for each package.''' else: bad_deps = [sorted(dep) for dep in bad_deps] bad_deps = [', '.join(dep) for dep in sorted(bad_deps)] msg = '''The following specifications were found to be incompatible with the others, or with the existing package set:%s Use "conda info <package>" to see the dependencies for each package.''' msg = msg % dashlist(bad_deps) super(Unsatisfiable, self).__init__(msg)
def generate_feature_count(self, C, trackers): return {self.feat_to_v(name): 1 for name in iterkeys(trackers)}