diff options
Diffstat (limited to 'lib/spack/spack/spec.py')
-rw-r--r-- | lib/spack/spack/spec.py | 66 |
1 files changed, 14 insertions, 52 deletions
diff --git a/lib/spack/spack/spec.py b/lib/spack/spack/spec.py index e861877036..66cdafa59c 100644 --- a/lib/spack/spack/spec.py +++ b/lib/spack/spack/spec.py @@ -128,7 +128,6 @@ from ruamel.yaml.error import MarkedYAMLError __all__ = [ 'Spec', 'parse', - 'parse_anonymous_spec', 'SpecError', 'SpecParseError', 'DuplicateDependencyError', @@ -2554,17 +2553,9 @@ class Spec(object): it. If it's a string, tries to parse a string. If that fails, tries to parse a local spec from it (i.e. name is assumed to be self's name). """ - if isinstance(spec_like, spack.spec.Spec): + if isinstance(spec_like, Spec): return spec_like - - try: - spec = spack.spec.Spec(spec_like) - if not spec.name: - raise SpecError( - "anonymous package -- this will always be handled") - return spec - except SpecError: - return parse_anonymous_spec(spec_like, self.name) + return Spec(spec_like) def satisfies(self, other, deps=True, strict=False, strict_deps=False): """Determine if this spec satisfies all constraints of another. @@ -2933,15 +2924,21 @@ class Spec(object): return value def __contains__(self, spec): - """True if this spec satisfies the provided spec, or if any dependency - does. If the spec has no name, then we parse this one first. + """True if this spec or some dependency satisfies the spec. + + Note: If ``spec`` is anonymous, we ONLY check whether the root + satisfies it, NOT dependencies. This is because most anonymous + specs (e.g., ``@1.2``) don't make sense when applied across an + entire DAG -- we limit them to the root. + """ spec = self._autospec(spec) - for s in self.traverse(): - if s.satisfies(spec, strict=True): - return True - return False + # if anonymous or same name, we only have to look at the root + if not spec.name or spec.name == self.name: + return self.satisfies(spec) + else: + return any(s.satisfies(spec) for s in self.traverse(root=False)) def sorted_deps(self): """Return a list of all dependencies sorted by name.""" @@ -3945,41 +3942,6 @@ def parse(string): return SpecParser().parse(string) -def parse_anonymous_spec(spec_like, pkg_name): - """Allow the user to omit the package name part of a spec if they - know what it has to be already. - - e.g., provides('mpi@2', when='@1.9:') says that this package - provides MPI-3 when its version is higher than 1.9. - """ - if not isinstance(spec_like, (str, Spec)): - raise TypeError('spec must be Spec or spec string. Found %s' - % type(spec_like)) - - if isinstance(spec_like, str): - try: - anon_spec = Spec(spec_like) - if anon_spec.name != pkg_name: - raise SpecParseError(spack.parse.ParseError( - "", - "", - "Expected anonymous spec for package %s but found spec for" - "package %s" % (pkg_name, anon_spec.name))) - except SpecParseError: - anon_spec = Spec(pkg_name + ' ' + spec_like) - if anon_spec.name != pkg_name: - raise ValueError( - "Invalid spec for package %s: %s" % (pkg_name, spec_like)) - else: - anon_spec = spec_like.copy() - - if anon_spec.name != pkg_name: - raise ValueError("Spec name '%s' must match package name '%s'" - % (anon_spec.name, pkg_name)) - - return anon_spec - - def save_dependency_spec_yamls( root_spec_as_yaml, output_directory, dependencies=None): """Given a root spec (represented as a yaml object), index it with a subset |