Changed anonymous specs to have name=None instead of empty string

This commit is contained in:
Gregory Becker 2016-05-09 16:22:17 -07:00
parent 73107d6b0f
commit 222c84d9be
3 changed files with 37 additions and 32 deletions

View file

@ -161,7 +161,7 @@ def find(parser, args):
# Filter out specs that don't exist. # Filter out specs that don't exist.
query_specs = spack.cmd.parse_specs(args.query_specs) query_specs = spack.cmd.parse_specs(args.query_specs)
query_specs, nonexisting = partition_list( query_specs, nonexisting = partition_list(
query_specs, lambda s: spack.repo.exists(s.name) or s.name == "") query_specs, lambda s: spack.repo.exists(s.name) or not s.name)
if nonexisting: if nonexisting:
msg = "No such package%s: " % ('s' if len(nonexisting) > 1 else '') msg = "No such package%s: " % ('s' if len(nonexisting) > 1 else '')

View file

@ -566,7 +566,7 @@ def _add_dependency(self, spec):
# #
@property @property
def fullname(self): def fullname(self):
return '%s.%s' % (self.namespace, self.name) if self.namespace else self.name return '%s.%s' % (self.namespace, self.name) if self.namespace else (self.name if self.name else '')
@property @property
@ -616,7 +616,7 @@ def virtual(self):
@staticmethod @staticmethod
def is_virtual(name): def is_virtual(name):
"""Test if a name is virtual without requiring a Spec.""" """Test if a name is virtual without requiring a Spec."""
return name != '' and not spack.repo.exists(name) return (not name is None) and ( not spack.repo.exists(name) )
@property @property
@ -1044,7 +1044,7 @@ def concretize(self):
with requirements of its pacakges. See flatten() and normalize() for with requirements of its pacakges. See flatten() and normalize() for
more details on this. more details on this.
""" """
if self.name == "": if not self.name:
raise SpecError("Attempting to concretize anonymous spec") raise SpecError("Attempting to concretize anonymous spec")
if self._concrete: if self._concrete:
@ -1313,7 +1313,7 @@ def normalize(self, force=False):
TODO: normalize should probably implement some form of cycle detection, TODO: normalize should probably implement some form of cycle detection,
to ensure that the spec is actually a DAG. to ensure that the spec is actually a DAG.
""" """
if self.name == "": if not self.name:
raise SpecError("Attempting to normalize anonymous spec") raise SpecError("Attempting to normalize anonymous spec")
if self._normal and not force: if self._normal and not force:
@ -1360,7 +1360,7 @@ def validate_names(self):
""" """
for spec in self.traverse(): for spec in self.traverse():
# Don't get a package for a virtual name. # Don't get a package for a virtual name.
if not spec.virtual and spec.name != '': if (not spec.virtual) and spec.name:
spack.repo.get(spec.fullname) spack.repo.get(spec.fullname)
# validate compiler in addition to the package name. # validate compiler in addition to the package name.
@ -1381,7 +1381,7 @@ def constrain(self, other, deps=True):
""" """
other = self._autospec(other) other = self._autospec(other)
if not (self.name == other.name or self.name == "" or other.name == ""): if not (self.name == other.name or (not self.name) or (not other.name) ):
raise UnsatisfiableSpecNameError(self.name, other.name) raise UnsatisfiableSpecNameError(self.name, other.name)
if other.namespace is not None: if other.namespace is not None:
@ -1485,7 +1485,7 @@ def _autospec(self, spec_like):
try: try:
spec = spack.spec.Spec(spec_like) spec = spack.spec.Spec(spec_like)
if spec.name == "": if not spec.name:
raise SpecError("anonymous package -- this will always be handled") raise SpecError("anonymous package -- this will always be handled")
return spec return spec
except SpecError: except SpecError:
@ -1518,7 +1518,7 @@ def satisfies(self, other, deps=True, strict=False):
return False return False
# Otherwise, first thing we care about is whether the name matches # Otherwise, first thing we care about is whether the name matches
if self.name != other.name and self.name != "" and other.name != "": if self.name != other.name and (not self.name) and (not other.name):
return False return False
# namespaces either match, or other doesn't require one. # namespaces either match, or other doesn't require one.
@ -1540,7 +1540,7 @@ def satisfies(self, other, deps=True, strict=False):
return False return False
var_strict = strict var_strict = strict
if self.name == "" or other.name == "": if (not self.name) or (not other.name):
var_strict = True var_strict = True
if not self.variants.satisfies(other.variants, strict=var_strict): if not self.variants.satisfies(other.variants, strict=var_strict):
return False return False
@ -1559,7 +1559,7 @@ def satisfies(self, other, deps=True, strict=False):
# If we need to descend into dependencies, do it, otherwise we're done. # If we need to descend into dependencies, do it, otherwise we're done.
if deps: if deps:
deps_strict = strict deps_strict = strict
if self.name == "" or other.name == "": if not (self.name and other.name):
deps_strict=True deps_strict=True
return self.satisfies_dependencies(other, strict=deps_strict) return self.satisfies_dependencies(other, strict=deps_strict)
else: else:
@ -1872,7 +1872,8 @@ def write(s, c):
fmt += 's' fmt += 's'
if c == '_': if c == '_':
out.write(fmt % self.name) if name = self.name if self.name else ''
out.write(fmt % name)
elif c == '.': elif c == '.':
out.write(fmt % self.fullname) out.write(fmt % self.fullname)
elif c == '@': elif c == '@':
@ -1923,6 +1924,7 @@ def write(s, c):
named_str += c named_str += c
continue; continue;
if named_str == 'PACKAGE': if named_str == 'PACKAGE':
name = self.name if self.name else ''
write(fmt % self.name, '@') write(fmt % self.name, '@')
if named_str == 'VERSION': if named_str == 'VERSION':
if self.versions and self.versions != _any_version: if self.versions and self.versions != _any_version:
@ -2034,7 +2036,6 @@ def __init__(self):
# This is more liberal than identifier_re (see above). # This is more liberal than identifier_re (see above).
# Checked by check_identifier() for better error messages. # Checked by check_identifier() for better error messages.
(r'([\"\'])(?:(?=(\\?))\2.)*?\1',lambda scanner, val: self.token(QT, val)), (r'([\"\'])(?:(?=(\\?))\2.)*?\1',lambda scanner, val: self.token(QT, val)),
# (r'([\"\'])([^\1]+?)(\1)',lambda scanner, val: self.token(QT, val)),
(r'\w[\w.-]*', lambda scanner, val: self.token(ID, val)), (r'\w[\w.-]*', lambda scanner, val: self.token(ID, val)),
(r'\s+', lambda scanner, val: None)]) (r'\s+', lambda scanner, val: None)])
@ -2051,12 +2052,12 @@ def do_parse(self):
while self.next: while self.next:
# TODO: clean this parsing up a bit # TODO: clean this parsing up a bit
if self.previous: if self.previous:
specs.append(self.previous.value) specs.append(self.spec(self.previous.value))
if self.accept(ID): if self.accept(ID):
self.previous = self.token self.previous = self.token
if self.accept(EQ): if self.accept(EQ):
if not specs: if not specs:
specs.append(self.spec('')) specs.append(self.spec(None))
if self.accept(QT): if self.accept(QT):
self.token.value = self.token.value[1:-1] self.token.value = self.token.value[1:-1]
else: else:
@ -2071,7 +2072,7 @@ def do_parse(self):
elif self.accept(DEP): elif self.accept(DEP):
if not specs: if not specs:
self.previous = self.token self.previous = self.token
specs.append(self.spec('')) specs.append(self.spec(None))
self.previous = None self.previous = None
if self.accept(HASH): if self.accept(HASH):
specs[-1]._add_dependency(self.spec_by_hash()) specs[-1]._add_dependency(self.spec_by_hash())
@ -2082,7 +2083,7 @@ def do_parse(self):
else: else:
# Attempt to construct an anonymous spec, but check that the first token is valid # Attempt to construct an anonymous spec, but check that the first token is valid
# TODO: Is this check even necessary, or will it all be Lex errors now? # TODO: Is this check even necessary, or will it all be Lex errors now?
specs.append(self.spec('',True)) specs.append(self.spec(None,True))
except spack.parse.ParseError, e: except spack.parse.ParseError, e:
raise SpecParseError(e) raise SpecParseError(e)
@ -2107,14 +2108,7 @@ def spec_by_hash(self):
tty.die("%s does not match any installed packages." %self.token.value) tty.die("%s does not match any installed packages." %self.token.value)
if len(matches) != 1: if len(matches) != 1:
tty.error("%s matches multiple installed packages:" %self.token.value) raise AmbiguousHashError("Multiple packages specify hash %s." % self.token.value, *matches)
print
display_specs(matches, long=True)
print
print "You can either:"
print " a) Use a more specific hash, or"
print " b) Specify the package by name."
sys.exit(1)
return matches[0] return matches[0]
@ -2122,12 +2116,15 @@ def spec_by_hash(self):
def spec(self, name, check_valid_token = False): def spec(self, name, check_valid_token = False):
"""Parse a spec out of the input. If a spec is supplied, then initialize """Parse a spec out of the input. If a spec is supplied, then initialize
and return it instead of creating a new one.""" and return it instead of creating a new one."""
spec_namespace, dot, spec_name = name.rpartition('.') if name:
if not spec_namespace: spec_namespace, dot, spec_name = name.rpartition('.')
spec_namespace = None if not spec_namespace:
spec_namespace = None
if spec_name != '':
self.check_identifier(spec_name) self.check_identifier(spec_name)
else:
spec_name = None
# This will init the spec without calling __init__. # This will init the spec without calling __init__.
spec = Spec.__new__(Spec) spec = Spec.__new__(Spec)
@ -2155,6 +2152,8 @@ def spec(self, name, check_valid_token = False):
spec.add_dependency(self.spec_by_hash()) spec.add_dependency(self.spec_by_hash())
else: else:
self.expect(ID) self.expect(ID)
if self.accept(EQ):
raise SpecParseError(spack.parse.ParseError("","","Expected dependency received anonymous spec"))
spec.add_dependency(self.spec(self.token.value)) spec.add_dependency(self.spec(self.token.value))
while self.next: while self.next:
@ -2294,7 +2293,7 @@ def parse_anonymous_spec(spec_like, pkg_name):
try: try:
anon_spec = Spec(spec_like) anon_spec = Spec(spec_like)
if anon_spec.name != pkg_name: if anon_spec.name != pkg_name:
raise SpecParseError(spack.parse.ParseError("","","anon spec created without proper 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: except SpecParseError:
anon_spec = Spec(pkg_name + ' ' + spec_like) anon_spec = Spec(pkg_name + ' ' + spec_like)
if anon_spec.name != pkg_name: raise ValueError( if anon_spec.name != pkg_name: raise ValueError(
@ -2470,3 +2469,9 @@ def __init__(self, msg, yaml_error):
class SpackRecordError(spack.error.SpackError): class SpackRecordError(spack.error.SpackError):
def __init__(self, msg): def __init__(self, msg):
super(SpackRecordError, self).__init__(msg) super(SpackRecordError, self).__init__(msg)
class AmbiguousHashError(SpecError):
def __init__(self, msg, *specs):
super(AmbiguousHashError, self).__init__(msg)
for spec in specs:
print ' ', spec.format('$.$@$%@+$+$=$#')

View file

@ -67,7 +67,7 @@ def update(self, spec):
if type(spec) != spack.spec.Spec: if type(spec) != spack.spec.Spec:
spec = spack.spec.Spec(spec) spec = spack.spec.Spec(spec)
if spec.name == "": if not spec.name:
# Empty specs do not have a package # Empty specs do not have a package
return return