Factor out canonical_deptype function, cleanup spec.py
This commit is contained in:
parent
cd960caf8d
commit
43ca805248
@ -123,6 +123,39 @@
|
||||
from spack.version import *
|
||||
from spack.provider_index import ProviderIndex
|
||||
|
||||
__all__ = [
|
||||
'Spec',
|
||||
'alldeps',
|
||||
'nolink',
|
||||
'nobuild',
|
||||
'canonical_deptype',
|
||||
'validate_deptype',
|
||||
'parse',
|
||||
'parse_anonymous_spec',
|
||||
'SpecError',
|
||||
'SpecParseError',
|
||||
'DuplicateDependencyError',
|
||||
'DuplicateVariantError',
|
||||
'DuplicateCompilerSpecError',
|
||||
'UnsupportedCompilerError',
|
||||
'UnknownVariantError',
|
||||
'DuplicateArchitectureError',
|
||||
'InconsistentSpecError',
|
||||
'InvalidDependencyError',
|
||||
'InvalidDependencyTypeError',
|
||||
'NoProviderError',
|
||||
'MultipleProviderError',
|
||||
'UnsatisfiableSpecError',
|
||||
'UnsatisfiableSpecNameError',
|
||||
'UnsatisfiableVersionSpecError',
|
||||
'UnsatisfiableCompilerSpecError',
|
||||
'UnsatisfiableVariantSpecError',
|
||||
'UnsatisfiableCompilerFlagSpecError',
|
||||
'UnsatisfiableArchitectureSpecError',
|
||||
'UnsatisfiableProviderSpecError',
|
||||
'UnsatisfiableDependencySpecError',
|
||||
'SpackYAMLError',
|
||||
'AmbiguousHashError']
|
||||
|
||||
# Valid pattern for an identifier in Spack
|
||||
identifier_re = r'\w[\w-]*'
|
||||
@ -157,11 +190,44 @@
|
||||
# Special types of dependencies.
|
||||
alldeps = ('build', 'link', 'run')
|
||||
nolink = ('build', 'run')
|
||||
nobuild = ('link', 'run')
|
||||
norun = ('link', 'build')
|
||||
special_types = {
|
||||
'alldeps': alldeps,
|
||||
'nolink': nolink,
|
||||
'nobuild': nobuild,
|
||||
'norun': norun,
|
||||
}
|
||||
|
||||
legal_deps = tuple(special_types) + alldeps
|
||||
|
||||
|
||||
def validate_deptype(deptype):
|
||||
if isinstance(deptype, str):
|
||||
if deptype not in legal_deps:
|
||||
raise InvalidDependencyTypeError(
|
||||
"Invalid dependency type: %s" % deptype)
|
||||
|
||||
elif isinstance(deptype, (list, tuple)):
|
||||
for t in deptype:
|
||||
validate_deptype(t)
|
||||
|
||||
elif deptype is None:
|
||||
raise InvalidDependencyTypeError("deptype cannot be None!")
|
||||
|
||||
|
||||
def canonical_deptype(deptype):
|
||||
if deptype is None:
|
||||
return alldeps
|
||||
|
||||
elif isinstance(deptype, str):
|
||||
return special_types.get(deptype, (deptype,))
|
||||
|
||||
elif isinstance(deptype, (tuple, list)):
|
||||
return (sum((canonical_deptype(d) for d in deptype), ()))
|
||||
|
||||
return deptype
|
||||
|
||||
|
||||
def colorize_spec(spec):
|
||||
"""Returns a spec colorized according to the colors specified in
|
||||
@ -542,17 +608,8 @@ def get_dependency(self, name):
|
||||
raise InvalidDependencyException(
|
||||
self.name + " does not depend on " + comma_or(name))
|
||||
|
||||
def _deptype_norm(self, deptype):
|
||||
if deptype is None:
|
||||
return alldeps
|
||||
# Force deptype to be a set object so that we can do set intersections.
|
||||
if isinstance(deptype, str):
|
||||
# Support special deptypes.
|
||||
return special_types.get(deptype, (deptype,))
|
||||
return deptype
|
||||
|
||||
def _find_deps(self, where, deptype):
|
||||
deptype = self._deptype_norm(deptype)
|
||||
deptype = canonical_deptype(deptype)
|
||||
|
||||
return [dep.spec
|
||||
for dep in where.values()
|
||||
@ -565,7 +622,7 @@ def dependents(self, deptype=None):
|
||||
return self._find_deps(self._dependents, deptype)
|
||||
|
||||
def _find_deps_dict(self, where, deptype):
|
||||
deptype = self._deptype_norm(deptype)
|
||||
deptype = canonical_deptype(deptype)
|
||||
|
||||
return dict((dep.spec.name, dep)
|
||||
for dep in where.values()
|
||||
@ -2718,6 +2775,10 @@ class InvalidDependencyError(SpecError):
|
||||
of the package."""
|
||||
|
||||
|
||||
class InvalidDependencyTypeError(SpecError):
|
||||
"""Raised when a dependency type is not a legal Spack dep type."""
|
||||
|
||||
|
||||
class NoProviderError(SpecError):
|
||||
"""Raised when there is no package that provides a particular
|
||||
virtual dependency.
|
||||
@ -2804,8 +2865,6 @@ def __init__(self, provided, required):
|
||||
|
||||
# TODO: get rid of this and be more specific about particular incompatible
|
||||
# dep constraints
|
||||
|
||||
|
||||
class UnsatisfiableDependencySpecError(UnsatisfiableSpecError):
|
||||
"""Raised when some dependency of constrained specs are incompatible"""
|
||||
def __init__(self, provided, required):
|
||||
|
@ -24,34 +24,34 @@
|
||||
##############################################################################
|
||||
import unittest
|
||||
|
||||
import spack.spec
|
||||
import spack.spec as sp
|
||||
from spack.parse import Token
|
||||
from spack.spec import *
|
||||
|
||||
# Sample output for a complex lexing.
|
||||
complex_lex = [Token(ID, 'mvapich_foo'),
|
||||
Token(DEP),
|
||||
Token(ID, '_openmpi'),
|
||||
Token(AT),
|
||||
Token(ID, '1.2'),
|
||||
Token(COLON),
|
||||
Token(ID, '1.4'),
|
||||
Token(COMMA),
|
||||
Token(ID, '1.6'),
|
||||
Token(PCT),
|
||||
Token(ID, 'intel'),
|
||||
Token(AT),
|
||||
Token(ID, '12.1'),
|
||||
Token(COLON),
|
||||
Token(ID, '12.6'),
|
||||
Token(ON),
|
||||
Token(ID, 'debug'),
|
||||
Token(OFF),
|
||||
Token(ID, 'qt_4'),
|
||||
Token(DEP),
|
||||
Token(ID, 'stackwalker'),
|
||||
Token(AT),
|
||||
Token(ID, '8.1_1e')]
|
||||
complex_lex = [Token(sp.ID, 'mvapich_foo'),
|
||||
Token(sp.DEP),
|
||||
Token(sp.ID, '_openmpi'),
|
||||
Token(sp.AT),
|
||||
Token(sp.ID, '1.2'),
|
||||
Token(sp.COLON),
|
||||
Token(sp.ID, '1.4'),
|
||||
Token(sp.COMMA),
|
||||
Token(sp.ID, '1.6'),
|
||||
Token(sp.PCT),
|
||||
Token(sp.ID, 'intel'),
|
||||
Token(sp.AT),
|
||||
Token(sp.ID, '12.1'),
|
||||
Token(sp.COLON),
|
||||
Token(sp.ID, '12.6'),
|
||||
Token(sp.ON),
|
||||
Token(sp.ID, 'debug'),
|
||||
Token(sp.OFF),
|
||||
Token(sp.ID, 'qt_4'),
|
||||
Token(sp.DEP),
|
||||
Token(sp.ID, 'stackwalker'),
|
||||
Token(sp.AT),
|
||||
Token(sp.ID, '8.1_1e')]
|
||||
|
||||
|
||||
class SpecSyntaxTest(unittest.TestCase):
|
||||
@ -74,16 +74,16 @@ def check_parse(self, expected, spec=None, remove_arch=True):
|
||||
"""
|
||||
if spec is None:
|
||||
spec = expected
|
||||
output = spack.spec.parse(spec)
|
||||
output = sp.parse(spec)
|
||||
|
||||
parsed = (" ".join(str(spec) for spec in output))
|
||||
self.assertEqual(expected, parsed)
|
||||
|
||||
def check_lex(self, tokens, spec):
|
||||
"""Check that the provided spec parses to the provided token list."""
|
||||
lex_output = SpecLexer().lex(spec)
|
||||
lex_output = sp.SpecLexer().lex(spec)
|
||||
for tok, spec_tok in zip(tokens, lex_output):
|
||||
if tok.type == ID:
|
||||
if tok.type == sp.ID:
|
||||
self.assertEqual(tok, spec_tok)
|
||||
else:
|
||||
# Only check the type for non-identifiers.
|
||||
|
Loading…
Reference in New Issue
Block a user