Bug 1257823 - Remove imply_option implementation for @depends functions draft
authorMike Hommey <mh+mozilla@glandium.org>
Wed, 23 Mar 2016 16:08:07 +0900
changeset 343871 245f0b805e7b8163b37c73296010f0d280a356f6
parent 343870 bca81ea8743049e08802b4e5d6860e64ee81f0d7
child 343872 26a29449aac3998864c851d9a8e0cd9bea4da9a5
push id13691
push userbmo:mh+mozilla@glandium.org
push dateWed, 23 Mar 2016 10:00:34 +0000
bugs1257823
milestone48.0a1
Bug 1257823 - Remove imply_option implementation for @depends functions
python/mozbuild/mozbuild/configure/__init__.py
python/mozbuild/mozbuild/test/configure/data/moz.configure
python/mozbuild/mozbuild/test/configure/test_configure.py
--- a/python/mozbuild/mozbuild/configure/__init__.py
+++ b/python/mozbuild/mozbuild/configure/__init__.py
@@ -37,30 +37,16 @@ class DummyFunction(object):
         raise RuntimeError('The `%s` function may not be called'
                            % self.__name__)
 
 
 class SandboxedGlobal(dict):
     '''Identifiable dict type for use as function global'''
 
 
-class DependsOutput(object):
-    '''Class for objects holding the options implied by a @depends function.'''
-    __slots__ = ('implied_options',)
-
-    def __init__(self):
-        super(DependsOutput, self).__init__()
-        self.implied_options = []
-
-    def imply_option(self, option, reason=None):
-        if not isinstance(option, types.StringTypes):
-            raise TypeError('imply_option must be given a string')
-        self.implied_options.append((option, inspect.stack()[1], reason))
-
-
 def forbidden_import(*args, **kwargs):
     raise ImportError('Importing modules is forbidden')
 
 
 class ConfigureSandbox(dict):
     """Represents a sandbox for executing Python code for build configuration.
     This is a different kind of sandboxing than the one used for moz.build
     processing.
@@ -287,19 +273,17 @@ class ConfigureSandbox(dict):
         references. The decorated function is called as soon as the decorator
         is called, and the arguments it receives are the OptionValue or
         function results corresponding to each of the arguments to @depends.
         As an exception, when a HelpFormatter is attached, only functions that
         have '--help' in their @depends argument list are called.
 
         The decorated function is altered to use a different global namespace
         for its execution. This different global namespace exposes a limited
-        set of functions from os.path, and one additional functions:
-        `imply_option`. It allows to inject additional options as if they had
-        been passed on the command line.
+        set of functions from os.path.
         '''
         if not args:
             raise ConfigureError('@depends needs at least one argument')
 
         resolved_args = []
         dependencies = []
         for arg in args:
             if isinstance(arg, types.StringTypes):
@@ -329,55 +313,30 @@ class ConfigureSandbox(dict):
             resolved_args.append(resolved_arg)
         dependencies = tuple(dependencies)
 
         def decorator(func):
             if inspect.isgeneratorfunction(func):
                 raise ConfigureError(
                     'Cannot decorate generator functions with @depends')
             func, glob = self._prepare_function(func)
-            result = DependsOutput()
-            glob.update(
-                imply_option=result.imply_option,
-            )
             dummy = wraps(func)(DummyFunction())
             self._depends[dummy] = func, dependencies
             with_help = self._help_option in dependencies
             if with_help:
                 for arg in args:
                     if (isinstance(arg, DummyFunction) and
                             self._help_option not in self._depends[arg][1]):
                         raise ConfigureError(
                             "`%s` depends on '--help' and `%s`. "
                             "`%s` must depend on '--help'"
                             % (func.__name__, arg.__name__, arg.__name__))
 
-            if self._help and not with_help:
-                return dummy
-
-            self._results[func] = func(*resolved_args)
-
-            for option, frameinfo, reason in result.implied_options:
-                self._helper.add(option, 'implied')
-                if not reason:
-                    deps = []
-                    for arg in dependencies:
-                        if not isinstance(arg, Option):
-                            raise ConfigureError(
-                                "Cannot infer what implied '%s'" % option)
-                        if arg == self._help_option:
-                            continue
-                        deps.append(self._raw_options.get(arg) or
-                                    self.arg.option)
-                    if len(deps) != 1:
-                        raise ConfigureError(
-                            "Cannot infer what implied '%s'" % option)
-                    reason = deps[0]
-
-                self._implied_options[option] = frameinfo, reason
+            if not self._help or with_help:
+                self._results[func] = func(*resolved_args)
 
             return dummy
 
         return decorator
 
     def include_impl(self, what):
         '''Implementation of include().
         Allows to include external files for execution in the sandbox.
@@ -402,16 +361,17 @@ class ConfigureSandbox(dict):
         '''
         template, glob = self._prepare_function(func)
         glob.update(
             advanced=self.advanced_impl,
             depends=self.depends_impl,
             option=self.option_impl,
             set_config=self.set_config_impl,
             set_define=self.set_define_impl,
+            imply_option=self.imply_option_impl,
         )
         self._templates.add(template)
         return template
 
     def advanced_impl(self, func):
         '''Implementation of @advanced.
         This function gives the decorated function access to the complete set
         of builtins, allowing the import keyword as an expected side effect.
--- a/python/mozbuild/mozbuild/test/configure/data/moz.configure
+++ b/python/mozbuild/mozbuild/test/configure/data/moz.configure
@@ -100,50 +100,16 @@ def simple(simple, help):
 option('--with-returned-default', default=simple, help='Returned default')
 
 @depends('--with-returned-default')
 def default(value):
     return value
 
 set_config('DEFAULTED', default)
 
-# @depends functions can also declare that some extra options are implied.
-# Those options need to be defined _after_ the function, and they mustn't
-# appear on the command line or the environment with conflicting values.
-@depends('--enable-values')
-def values(values):
-    if values:
-        imply_option('--enable-implied')
-        imply_option(values.format('--with-implied-values'))
-        imply_option(values.format('WITH_IMPLIED_ENV'))
-
-option('--enable-implied', help='Implied')
-
-option('--with-implied-values', nargs='*', help='Implied values')
-
-option(env='WITH_IMPLIED_ENV', nargs='*', help='Implied env')
-
-@depends('--enable-implied')
-def implied(value):
-    return value
-
-set_config('IMPLIED', implied)
-
-@depends('--with-implied-values')
-def implied(values):
-    return values
-
-set_config('IMPLIED_VALUES', implied)
-
-@depends('WITH_IMPLIED_ENV')
-def implied(values):
-    return values
-
-set_config('IMPLIED_ENV', implied)
-
 @depends('--enable-values', '--help')
 def choices(values, help):
     if len(values):
         return {
             'alpha': ('a', 'b', 'c'),
             'numeric': ('0', '1', '2'),
         }.get(values[0])
 
--- a/python/mozbuild/mozbuild/test/configure/test_configure.py
+++ b/python/mozbuild/mozbuild/test/configure/test_configure.py
@@ -52,19 +52,16 @@ class TestConfigure(unittest.TestCase):
             'IS_GCC': NegativeOptionValue(),
             'REMAINDER': (PositiveOptionValue(), NegativeOptionValue(),
                           NegativeOptionValue(), NegativeOptionValue()),
             'SIMPLE': NegativeOptionValue(),
             'VALUES': NegativeOptionValue(),
             'VALUES2': NegativeOptionValue(),
             'VALUES3': NegativeOptionValue(),
             'WITH_ENV': NegativeOptionValue(),
-            'IMPLIED': NegativeOptionValue(),
-            'IMPLIED_ENV': NegativeOptionValue(),
-            'IMPLIED_VALUES': NegativeOptionValue(),
         }, config)
 
     def test_help(self):
         config, out = self.get_result(['--help'])
         self.assertEquals({}, config)
         self.maxDiff = None
         self.assertEquals(
             'Usage: configure [options]\n'
@@ -73,27 +70,24 @@ class TestConfigure(unittest.TestCase):
             '  --help                    print this message\n'
             '  --enable-simple           Enable simple\n'
             '  --enable-with-env         Enable with env\n'
             '  --enable-values           Enable values\n'
             '  --without-thing           Build without thing\n'
             '  --with-stuff              Build with stuff\n'
             '  --option                  Option\n'
             '  --with-returned-default   Returned default [not-simple]\n'
-            '  --enable-implied          Implied\n'
-            '  --with-implied-values     Implied values\n'
             '  --returned-choices        Choices\n'
             '  --enable-advanced-template\n'
             '                            Advanced template\n'
             '  --enable-include          Include\n'
             '  --with-advanced           Advanced\n'
             '\n'
             'Environment variables:\n'
-            '  CC                        C Compiler\n'
-            '  WITH_IMPLIED_ENV          Implied env\n',
+            '  CC                        C Compiler\n',
             out
         )
 
     def test_unknown(self):
         with self.assertRaises(InvalidOptionError):
             self.get_config(['--unknown'])
 
     def test_simple(self):
@@ -186,57 +180,16 @@ class TestConfigure(unittest.TestCase):
         self.assertEquals(
             PositiveOptionValue(('simple',)), config['DEFAULTED'])
 
         config = self.get_config(['--disable-simple'])
         self.assertIn('DEFAULTED', config)
         self.assertEquals(
             PositiveOptionValue(('not-simple',)), config['DEFAULTED'])
 
-    def test_implied_options(self):
-        config = self.get_config(['--enable-values'])
-        self.assertIn('IMPLIED', config)
-        self.assertIn('IMPLIED_VALUES', config)
-        self.assertIn('IMPLIED_ENV', config)
-        self.assertEquals(PositiveOptionValue(), config['IMPLIED'])
-        self.assertEquals(PositiveOptionValue(), config['IMPLIED_VALUES'])
-        self.assertEquals(PositiveOptionValue(), config['IMPLIED_ENV'])
-
-        config = self.get_config(['--enable-values=a'])
-        self.assertIn('IMPLIED', config)
-        self.assertIn('IMPLIED_VALUES', config)
-        self.assertIn('IMPLIED_ENV', config)
-        self.assertEquals(PositiveOptionValue(), config['IMPLIED'])
-        self.assertEquals(
-            PositiveOptionValue(('a',)), config['IMPLIED_VALUES'])
-        self.assertEquals(PositiveOptionValue(('a',)), config['IMPLIED_ENV'])
-
-        config = self.get_config(['--enable-values=a,b'])
-        self.assertIn('IMPLIED', config)
-        self.assertIn('IMPLIED_VALUES', config)
-        self.assertIn('IMPLIED_ENV', config)
-        self.assertEquals(PositiveOptionValue(), config['IMPLIED'])
-        self.assertEquals(
-            PositiveOptionValue(('a', 'b')), config['IMPLIED_VALUES'])
-        self.assertEquals(
-            PositiveOptionValue(('a', 'b')), config['IMPLIED_ENV'])
-
-        config = self.get_config(['--disable-values'])
-        self.assertIn('IMPLIED', config)
-        self.assertIn('IMPLIED_VALUES', config)
-        self.assertIn('IMPLIED_ENV', config)
-        self.assertEquals(NegativeOptionValue(), config['IMPLIED'])
-        self.assertEquals(NegativeOptionValue(), config['IMPLIED_VALUES'])
-        self.assertEquals(NegativeOptionValue(), config['IMPLIED_ENV'])
-
-        # --enable-values implies --enable-implied, which conflicts with
-        # --disable-implied
-        with self.assertRaises(InvalidOptionError):
-            self.get_config(['--enable-values', '--disable-implied'])
-
     def test_returned_choices(self):
         for val in ('a', 'b', 'c'):
             config = self.get_config(
                 ['--enable-values=alpha', '--returned-choices=%s' % val])
             self.assertIn('CHOICES', config)
             self.assertEquals(PositiveOptionValue((val,)), config['CHOICES'])
 
         for val in ('0', '1', '2'):