multimethod uses Spec() instead of parse_anonymous_spec()
- simplify logic in multimethod - remove the requirement of multimethod invocations to walk up the stack.
This commit is contained in:
		
				
					committed by
					
						
						Greg Becker
					
				
			
			
				
	
			
			
			
						parent
						
							88cb11758b
						
					
				
				
					commit
					61b859193d
				
			@@ -26,11 +26,11 @@
 | 
			
		||||
"""
 | 
			
		||||
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 @@ def __init__(self, default=None):
 | 
			
		||||
            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 @@ def __get__(self, obj, objtype):
 | 
			
		||||
        # 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 @@ def install(self, prefix):
 | 
			
		||||
                  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 @@ def install(self, prefix):
 | 
			
		||||
    """
 | 
			
		||||
 | 
			
		||||
    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
 | 
			
		||||
 
 | 
			
		||||
@@ -14,7 +14,7 @@
 | 
			
		||||
 | 
			
		||||
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,7 +27,6 @@ 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
 | 
			
		||||
 | 
			
		||||
@@ -37,8 +36,6 @@ 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:
 | 
			
		||||
 
 | 
			
		||||
@@ -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):
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user