From 61b859193db23b81860b7d4bcc219db3aa56ddec Mon Sep 17 00:00:00 2001 From: Todd Gamblin Date: Wed, 5 Dec 2018 10:34:46 -0600 Subject: multimethod uses Spec() instead of parse_anonymous_spec() - simplify logic in multimethod - remove the requirement of multimethod invocations to walk up the stack. --- lib/spack/spack/multimethod.py | 25 ++++++++-------------- lib/spack/spack/test/spec_semantics.py | 7 ++---- .../builtin.mock/packages/multimethod/package.py | 2 +- 3 files changed, 12 insertions(+), 22 deletions(-) diff --git a/lib/spack/spack/multimethod.py b/lib/spack/spack/multimethod.py index a66abe7bf7..7682ca063f 100644 --- a/lib/spack/spack/multimethod.py +++ b/lib/spack/spack/multimethod.py @@ -26,11 +26,11 @@ so package authors should use their judgement. """ import functools -from llnl.util.lang import caller_locals, get_calling_module_name +from llnl.util.lang import caller_locals import spack.architecture import spack.error -from spack.spec import parse_anonymous_spec +from spack.spec import Spec class SpecMultiMethod(object): @@ -46,11 +46,6 @@ class SpecMultiMethod(object): to find one that matches the package's spec. If it finds one (and only one), it will call that method. - The package author is responsible for ensuring that only one - condition on multi-methods ever evaluates to true. If - multiple methods evaluate to true, this will raise an - exception. - This is intended for use with decorators (see below). The decorator (see docs below) creates SpecMultiMethods and registers method versions with them. @@ -76,7 +71,7 @@ class SpecMultiMethod(object): functools.update_wrapper(self, default) def register(self, spec, method): - """Register a version of a method for a particular sys_type.""" + """Register a version of a method for a particular spec.""" self.method_list.append((spec, method)) if not hasattr(self, '__name__'): @@ -91,6 +86,7 @@ class SpecMultiMethod(object): # element in the list. The first registered function # will be the one 'wrapped'. wrapped_method = self.method_list[0][1] + # Call functools.wraps manually to get all the attributes # we need to be disguised as the wrapped_method func = functools.wraps(wrapped_method)( @@ -178,10 +174,6 @@ class when(object): self.setup() # Do more common install stuff - There must be one (and only one) @when clause that matches the - package's spec. If there is more than one, or if none match, - then the method will raise an exception when it's called. - Note that the default version of decorated methods must *always* come first. Otherwise it will override all of the platform-specific versions. There's not much we can do to get @@ -189,11 +181,12 @@ class when(object): """ def __init__(self, spec): - pkg = get_calling_module_name() if spec is True: - spec = pkg - self.spec = (parse_anonymous_spec(spec, pkg) - if spec is not False else None) + self.spec = Spec() + elif spec is not False: + self.spec = Spec(spec) + else: + self.spec = None def __call__(self, method): # Get the first definition of the method in the calling scope diff --git a/lib/spack/spack/test/spec_semantics.py b/lib/spack/spack/test/spec_semantics.py index f1efd0ef6b..9e9da3bddd 100644 --- a/lib/spack/spack/test/spec_semantics.py +++ b/lib/spack/spack/test/spec_semantics.py @@ -14,7 +14,7 @@ from spack.variant import MultipleValuesInExclusiveVariantError def target_factory(spec_string, target_concrete): spec = Spec(spec_string) if spec_string else Spec() - print spec, spec_string, "AAAAA" + if target_concrete: spec._mark_concrete() substitute_abstract_variants(spec) @@ -27,18 +27,15 @@ def argument_factory(argument_spec, left): # If it's not anonymous, allow it right = target_factory(argument_spec, False) except Exception: - print "HAHA" right = parse_anonymous_spec(argument_spec, left.name) return right def check_satisfies(target_spec, argument_spec, target_concrete=False): - + left = target_factory(target_spec, target_concrete) right = argument_factory(argument_spec, left) - print left, 'left', left.name - print right, right.name # Satisfies is one-directional. assert left.satisfies(right) if argument_spec: diff --git a/var/spack/repos/builtin.mock/packages/multimethod/package.py b/var/spack/repos/builtin.mock/packages/multimethod/package.py index 3224d73fe9..a8e3d4995a 100644 --- a/var/spack/repos/builtin.mock/packages/multimethod/package.py +++ b/var/spack/repos/builtin.mock/packages/multimethod/package.py @@ -21,7 +21,7 @@ class Multimethod(MultimethodBase): url = 'http://www.example.com/example-1.0.tar.gz' # - # These functions are only valid for versions 1, 2, and 3. + # These functions are only valid for versions 1, 3, and 4. # @when('@1.0') def no_version_2(self): -- cgit v1.2.3-60-g2f50