Bug 1256571 - Move running @depends functions to ConfigureSandbox._value_for(). r?chmanchester draft
authorMike Hommey <mh+mozilla@glandium.org>
Sat, 09 Apr 2016 08:46:10 +0900
changeset 350228 e961522031a50fbd896dc357fb367f394eaee21d
parent 350227 09a1607874d6adbf4cb410fdd6fe7a1a5074c650
child 350229 ab826bf1ecb63997827c45e61aef9bcf15331381
push id15274
push userbmo:mh+mozilla@glandium.org
push dateWed, 13 Apr 2016 01:01:28 +0000
reviewerschmanchester
bugs1256571
milestone48.0a1
Bug 1256571 - Move running @depends functions to ConfigureSandbox._value_for(). r?chmanchester
python/mozbuild/mozbuild/configure/__init__.py
--- a/python/mozbuild/mozbuild/configure/__init__.py
+++ b/python/mozbuild/mozbuild/configure/__init__.py
@@ -113,18 +113,16 @@ class ConfigureSandbox(dict):
         # Store the real function and its dependencies, behind each
         # DependsFunction generated from @depends.
         self._depends = {}
         self._seen = set()
         # Store the @imports added to a given function.
         self._imports = {}
 
         self._options = OrderedDict()
-        # Store the raw values returned by @depends functions
-        self._results = {}
         # Store raw option (as per command line or environment) for each Option
         self._raw_options = {}
 
         # Store options added with `imply_option`, and the reason they were
         # added (which can either have been given to `imply_option`, or
         # inferred.
         self._implied_options = {}
 
@@ -263,27 +261,43 @@ class ConfigureSandbox(dict):
             if need_help_dependency and self._help_option not in deps:
                 raise ConfigureError("Missing @depends for `%s`: '--help'" %
                                      func.__name__)
             return self._value_for(arg)
         return arg
 
     def _value_for(self, obj):
         if isinstance(obj, DependsFunction):
-            assert obj in self._depends
-            func, deps = self._depends[obj]
-            assert not inspect.isgeneratorfunction(func)
-            assert func in self._results
-            return self._results[func]
+            return self._value_for_depends(obj)
+
         elif isinstance(obj, Option):
             return self._value_for_option(obj)
 
         assert False
 
     @memoize
+    def _value_for_depends(self, obj):
+        assert obj in self._depends
+        func, dependencies = self._depends[obj]
+        assert not inspect.isgeneratorfunction(func)
+        with_help = self._help_option in dependencies
+        if with_help:
+            for arg in dependencies:
+                if isinstance(arg, DependsFunction):
+                    _, deps = self._depends[arg]
+                    if self._help_option not in deps:
+                        raise ConfigureError(
+                            "`%s` depends on '--help' and `%s`. "
+                            "`%s` must depend on '--help'"
+                            % (func.__name__, arg.__name__, arg.__name__))
+
+        resolved_args = [self._value_for(d) for d in dependencies]
+        return func(*resolved_args)
+
+    @memoize
     def _value_for_option(self, option):
         try:
             value, option_string = self._helper.handle(option)
         except ConflictingOptionError as e:
             frameinfo, reason = self._implied_options[e.arg]
             reason = self._raw_options.get(reason) or reason.option
             raise InvalidOptionError(
                 "'%s' implied by '%s' conflicts with '%s' from the %s"
@@ -367,30 +381,18 @@ class ConfigureSandbox(dict):
 
         def decorator(func):
             if inspect.isgeneratorfunction(func):
                 raise ConfigureError(
                     'Cannot decorate generator functions with @depends')
             func, glob = self._prepare_function(func)
             dummy = wraps(func)(DependsFunction())
             self._depends[dummy] = func, dependencies
-            with_help = self._help_option in dependencies
-            if with_help:
-                for arg in dependencies:
-                    if isinstance(arg, DependsFunction):
-                        _, deps = self._depends[arg]
-                        if self._help_option not in deps:
-                            raise ConfigureError(
-                                "`%s` depends on '--help' and `%s`. "
-                                "`%s` must depend on '--help'"
-                                % (func.__name__, arg.__name__, arg.__name__))
-
-            if not self._help or with_help:
-                resolved_args = [self._value_for(d) for d in dependencies]
-                self._results[func] = func(*resolved_args)
+            if not self._help or self._help_option in dependencies:
+                self._value_for(dummy)
 
             return dummy
 
         return decorator
 
     def include_impl(self, what):
         '''Implementation of include().
         Allows to include external files for execution in the sandbox.