Bug 1264831 - Defer applying @imports until the function is actually called. r?gps draft
authorMike Hommey <mh+mozilla@glandium.org>
Fri, 15 Apr 2016 11:11:28 +0900
changeset 351824 cab2140741129ada0dee2503ebcd7674ad21f4bd
parent 351823 543ee065efc0ee7dcccbf94c1e6bd032ace2af12
child 351825 fb8d6e0a54a5c75ae50a22129df973f202254c09
push id15531
push userbmo:mh+mozilla@glandium.org
push dateFri, 15 Apr 2016 02:18:00 +0000
reviewersgps
bugs1264831
milestone48.0a1
Bug 1264831 - Defer applying @imports until the function is actually called. r?gps
python/mozbuild/mozbuild/configure/__init__.py
--- a/python/mozbuild/mozbuild/configure/__init__.py
+++ b/python/mozbuild/mozbuild/configure/__init__.py
@@ -701,17 +701,16 @@ class ConfigureSandbox(dict):
                 inspect.isclass(v) and issubclass(v, Exception))
         )
         glob.update(
             __builtins__=self.BUILTINS,
             __file__=self._paths[-1] if self._paths else '',
             os=self.OS,
             log=self.log_impl,
         )
-        self._apply_imports(func, glob)
 
         # The execution model in the sandbox doesn't guarantee the execution
         # order will always be the same for a given function, and if it uses
         # variables from a closure that are changed after the function is
         # declared, depending when the function is executed, the value of the
         # variable can differ. For consistency, we force the function to use
         # the value from the earliest it can be run, which is at declaration.
         # Note this is not entirely bullet proof (if the value is e.g. a list,
@@ -721,17 +720,22 @@ class ConfigureSandbox(dict):
             def makecell(content):
                 def f():
                     content
                 return f.func_closure[0]
 
             closure = tuple(makecell(cell.cell_contents)
                             for cell in func.func_closure)
 
-        func = wraps(func)(types.FunctionType(
+        new_func = wraps(func)(types.FunctionType(
             func.func_code,
             glob,
             func.__name__,
             func.func_defaults,
             closure
         ))
-        self._prepared_functions.add(func)
-        return func, glob
+        @wraps(new_func)
+        def wrapped(*args, **kwargs):
+            self._apply_imports(func, glob)
+            return new_func(*args, **kwargs)
+
+        self._prepared_functions.add(wrapped)
+        return wrapped, glob