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:
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,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:
|
||||
|
@ -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):
|
||||
|
Loading…
Reference in New Issue
Block a user