Bug 946175 - Make all sandbox variables default to an instance of their class type. r=gps
authorMike Hommey <mh+mozilla@glandium.org>
Mon, 09 Dec 2013 13:27:58 +0900
changeset 175140 e926070b0d18361ecabc60324690f142d2ea47a2
parent 175138 551efcc4de6f1c965179975e3b12ab9e9e4c208a
child 175141 c9d4612aef4c5e14a194d8cd815fee3a302ccfaf
push id445
push userffxbld
push dateMon, 10 Mar 2014 22:05:19 +0000
treeherdermozilla-release@dc38b741b04e [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersgps
bugs946175
milestone28.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 946175 - Make all sandbox variables default to an instance of their class type. r=gps
python/mozbuild/mozbuild/frontend/data.py
python/mozbuild/mozbuild/frontend/sandbox.py
python/mozbuild/mozbuild/frontend/sandbox_symbols.py
python/mozbuild/mozbuild/sphinx.py
python/mozbuild/mozbuild/test/frontend/test_sandbox_symbols.py
--- a/python/mozbuild/mozbuild/frontend/data.py
+++ b/python/mozbuild/mozbuild/frontend/data.py
@@ -19,17 +19,17 @@ from __future__ import unicode_literals
 
 import os
 
 from collections import OrderedDict
 from mozbuild.util import (
     shell_quote,
     StrictOrderingOnAppendList,
 )
-from .sandbox_symbols import compute_final_target
+from .sandbox_symbols import FinalTargetValue
 
 
 class TreeMetadata(object):
     """Base class for all data being captured."""
 
     def __init__(self):
         self._ack = False
 
@@ -494,11 +494,11 @@ class InstallationTarget(SandboxDerived)
         self.subdir = sandbox.get('DIST_SUBDIR', '')
         self.target = sandbox['FINAL_TARGET']
         self.enabled = not sandbox.get('NO_DIST_INSTALL', False)
 
     def is_custom(self):
         """Returns whether or not the target is not derived from the default
         given xpiname and subdir."""
 
-        return compute_final_target(dict(
+        return FinalTargetValue(dict(
             XPI_NAME=self.xpiname,
             DIST_SUBDIR=self.subdir)) == self.target
--- a/python/mozbuild/mozbuild/frontend/sandbox.py
+++ b/python/mozbuild/mozbuild/frontend/sandbox.py
@@ -29,16 +29,22 @@ import sys
 from contextlib import contextmanager
 
 from mozbuild.util import (
     ReadOnlyDefaultDict,
     ReadOnlyDict,
 )
 
 
+class SandboxDerivedValue(object):
+    """Classes deriving from this one receive a special treatment in a
+    sandbox GlobalNamespace. See GlobalNamespace documentation.
+    """
+
+
 def alphabetical_sorted(iterable, cmp=None, key=lambda x: x.lower(),
                         reverse=False):
     """sorted() replacement for the sandbox, ordering alphabetically by
     default.
     """
     return sorted(iterable, cmp, key, reverse)
 
 
@@ -56,20 +62,27 @@ class GlobalNamespace(dict):
 
     When variables are assigned to, we verify assignment is allowed. Assignment
     is allowed if the variable is known (set defined at constructor time) and
     if the value being assigned is the expected type (also defined at
     constructor time).
 
     When variables are read, we first try to read the existing value. If a
     value is not found and it is defined in the allowed variables set, we
-    return the default value for it. We don't assign default values until
-    they are accessed because this makes debugging the end-result much
-    simpler. Instead of a data structure with lots of empty/default values,
-    you have a data structure with only the values that were read or touched.
+    return a new instance of the class for that variable. We don't assign
+    default instances until they are accessed because this makes debugging
+    the end-result much simpler. Instead of a data structure with lots of
+    empty/default values, you have a data structure with only the values
+    that were read or touched.
+
+    Instances of variables classes are created by invoking class_name(),
+    except when class_name derives from SandboxDerivedValue, in which
+    case class_name(instance_of_the_global_namespace) is invoked.
+    A value is added to those calls when instances are created during
+    assignment (setitem).
 
     Instantiators of this class are given a backdoor to perform setting of
     arbitrary values. e.g.
 
         ns = GlobalNamespace()
         with ns.allow_all_writes():
             ns['foo'] = True
 
@@ -121,32 +134,34 @@ class GlobalNamespace(dict):
         default = self._allowed_variables.get(name, None)
         if default is None:
             self.last_name_error = KeyError('global_ns', 'get_unknown', name)
             raise self.last_name_error
 
         # If the default is specifically a lambda (or, rather, any function--but
         # not a class that can be called), then it is actually a rule to
         # generate the default that should be used.
-        default_rule = default[2]
-        if isinstance(default_rule, type(lambda: None)):
-            default_rule = default_rule(self)
+        default = default[0]
+        if issubclass(default, SandboxDerivedValue):
+            value = default(self)
+        else:
+            value = default()
 
-        dict.__setitem__(self, name, copy.deepcopy(default_rule))
+        dict.__setitem__(self, name, value)
         return dict.__getitem__(self, name)
 
     def __setitem__(self, name, value):
         if self._allow_all_writes:
             dict.__setitem__(self, name, value)
             return
 
         # We don't need to check for name.isupper() here because LocalNamespace
         # only sends variables our way if isupper() is True.
-        stored_type, input_type, default, docs, tier = \
-            self._allowed_variables.get(name, (None, None, None, None, None))
+        stored_type, input_type, docs, tier = \
+            self._allowed_variables.get(name, (None, None, None, None))
 
         # Variable is unknown.
         if stored_type is None:
             self.last_name_error = KeyError('global_ns', 'set_unknown', name,
                 value)
             raise self.last_name_error
 
         # If the incoming value is not the type we store, we try to convert
@@ -155,17 +170,20 @@ class GlobalNamespace(dict):
         # not be in the allowed set if the constructor function for the stored
         # type does not accept an instance of that type.
         if not isinstance(value, stored_type):
             if not isinstance(value, input_type):
                 self.last_name_error = ValueError('global_ns', 'set_type', name,
                     value, input_type)
                 raise self.last_name_error
 
-            value = stored_type(value)
+            if issubclass(stored_type, SandboxDerivedValue):
+                value = stored_type(self, value)
+            else:
+                value = stored_type(value)
 
         dict.__setitem__(self, name, value)
 
     @contextmanager
     def allow_all_writes(self):
         """Allow any variable to be written to this instance.
 
         This is used as a context manager. When activated, all writes
@@ -377,11 +395,11 @@ class Sandbox(object):
 
     def __contains__(self, key):
         return key in self._globals
 
     def get(self, key, default=None):
         return self._globals.get(key, default)
 
     def get_affected_tiers(self):
-        tiers = (self._allowed_variables[key][4] for key in self
+        tiers = (self._allowed_variables[key][3] for key in self
                  if key in self._allowed_variables)
         return set(tier for tier in tiers if tier)
--- a/python/mozbuild/mozbuild/frontend/sandbox_symbols.py
+++ b/python/mozbuild/mozbuild/frontend/sandbox_symbols.py
@@ -17,111 +17,114 @@ the Sandbox consists of, you've come to 
 
 from __future__ import unicode_literals
 
 from collections import OrderedDict
 from mozbuild.util import (
     HierarchicalStringList,
     StrictOrderingOnAppendList,
 )
+from .sandbox import SandboxDerivedValue
+from types import StringTypes
 
 
-def compute_final_target(variables):
-    """Convert the default value for FINAL_TARGET"""
-    basedir = 'dist/'
-    if variables['XPI_NAME']:
-        basedir += 'xpi-stage/' + variables['XPI_NAME']
-    else:
-        basedir += 'bin'
-    if variables['DIST_SUBDIR']:
-        basedir += '/' + variables['DIST_SUBDIR']
-    return basedir
- 
- 
+class FinalTargetValue(SandboxDerivedValue, unicode):
+    def __new__(cls, sandbox, value=""):
+        if not value:
+            value = 'dist/'
+            if sandbox['XPI_NAME']:
+                value += 'xpi-stage/' + sandbox['XPI_NAME']
+            else:
+                value += 'bin'
+            if sandbox['DIST_SUBDIR']:
+                value += '/' + sandbox['DIST_SUBDIR']
+        return unicode.__new__(cls, value)
+
+
 # This defines the set of mutable global variables.
 #
 # Each variable is a tuple of:
 #
-#   (storage_type, input_types, default_value, docs, tier)
+#   (storage_type, input_types, docs, tier)
 #
 # Tier says for which specific tier the variable has an effect.
 # Valid tiers are:
 # - 'export'
 # - 'compile': everything in relation with compiling objects.
 # - 'binaries': everything in relation with linking objects, producing
 #      programs and libraries.
 # - 'libs': everything that is not compile or binaries and that has
 #      traditionally been in the libs tier.
 # - 'tools'
 # A value of None means the variable has no direct effect on any tier.
 
 VARIABLES = {
     # Variables controlling reading of other frontend files.
-    'ANDROID_GENERATED_RESFILES': (StrictOrderingOnAppendList, list, [],
+    'ANDROID_GENERATED_RESFILES': (StrictOrderingOnAppendList, list,
         """Android resource files generated as part of the build.
 
         This variable contains a list of files that are expected to be
         generated (often by preprocessing) into a 'res' directory as
         part of the build process, and subsequently merged into an APK
         file.
         """, 'export'),
 
-    'ANDROID_RESFILES': (StrictOrderingOnAppendList, list, [],
+    'ANDROID_RESFILES': (StrictOrderingOnAppendList, list,
         """Android resource files.
 
         This variable contains a list of files to package into a 'res'
         directory and merge into an APK file.
         """, 'export'),
 
-    'SOURCES': (StrictOrderingOnAppendList, list, [],
+    'SOURCES': (StrictOrderingOnAppendList, list,
         """Source code files.
 
         This variable contains a list of source code files to compile.
         Accepts assembler, C, C++, Objective C/C++.
         """, 'compile'),
 
-    'GENERATED_SOURCES': (StrictOrderingOnAppendList, list, [],
+    'GENERATED_SOURCES': (StrictOrderingOnAppendList, list,
         """Generated source code files.
 
         This variable contains a list of generated source code files to
         compile. Accepts assembler, C, C++, Objective C/C++.
         """, 'compile'),
 
-    'FILES_PER_UNIFIED_FILE': (int, int, None,
+    'FILES_PER_UNIFIED_FILE': (int, int,
         """The number of source files to compile into each unified source file.
 
         """, 'None'),
 
-    'UNIFIED_SOURCES': (StrictOrderingOnAppendList, list, [],
+    'UNIFIED_SOURCES': (StrictOrderingOnAppendList, list,
         """Source code files that can be compiled together.
 
         This variable contains a list of source code files to compile,
         that can be concatenated all together and built as a single source
         file. This can help make the build faster and reduce the debug info
         size.
         """, 'compile'),
 
-    'GENERATED_UNIFIED_SOURCES': (StrictOrderingOnAppendList, list, [],
+    'GENERATED_UNIFIED_SOURCES': (StrictOrderingOnAppendList, list,
         """Generated source code files that can be compiled together.
 
         This variable contains a list of generated source code files to
         compile, that can be concatenated all together, with UNIFIED_SOURCES,
         and built as a single source file. This can help make the build faster
         and reduce the debug info size.
         """, 'compile'),
 
-    'GENERATED_FILES': (StrictOrderingOnAppendList, list, [],
+    'GENERATED_FILES': (StrictOrderingOnAppendList, list,
         """Generic generated files.
 
         This variable contains a list of generate files for the build system
         to generate at export time. The rules for those files still live in
         Makefile.in.
         """, 'export'),
 
-    'DEFINES': (OrderedDict, dict, OrderedDict(),
+    'DEFINES': (OrderedDict, dict,
         """Dictionary of compiler defines to declare.
 
         These are passed in to the compiler as ``-Dkey='value'`` for string
         values, ``-Dkey=value`` for numeric values, or ``-Dkey`` if the
         value is True. Note that for string values, the outer-level of
         single-quotes will be consumed by the shell. If you want to have
         a string-literal in the program, the value needs to have
         double-quotes.
@@ -139,230 +142,230 @@ VARIABLES = {
 
            DEFINES.update({
                'NS_NO_XPCOM': True,
                'MOZ_EXTENSIONS_DB_SCHEMA': 15,
                'DLL_SUFFIX': '".so"',
            })
         """, None),
 
-    'DIRS': (list, list, [],
+    'DIRS': (list, list,
         """Child directories to descend into looking for build frontend files.
 
         This works similarly to the ``DIRS`` variable in make files. Each str
         value in the list is the name of a child directory. When this file is
         done parsing, the build reader will descend into each listed directory
         and read the frontend file there. If there is no frontend file, an error
         is raised.
 
         Values are relative paths. They can be multiple directory levels
         above or below. Use ``..`` for parent directories and ``/`` for path
         delimiters.
         """, None),
 
-    'EXPORT_LIBRARY': (bool, bool, False,
+    'EXPORT_LIBRARY': (bool, bool,
         """Install the library to the static libraries folder.
         """, None),
 
-    'EXTRA_COMPONENTS': (StrictOrderingOnAppendList, list, [],
+    'EXTRA_COMPONENTS': (StrictOrderingOnAppendList, list,
         """Additional component files to distribute.
 
        This variable contains a list of files to copy into
        ``$(FINAL_TARGET)/components/``.
         """, 'libs'),
 
-    'EXTRA_JS_MODULES': (StrictOrderingOnAppendList, list, [],
+    'EXTRA_JS_MODULES': (StrictOrderingOnAppendList, list,
         """Additional JavaScript files to distribute.
 
         This variable contains a list of files to copy into
         ``$(FINAL_TARGET)/$(JS_MODULES_PATH)``. ``JS_MODULES_PATH`` defaults
         to ``modules`` if left undefined.
         """, 'libs'),
 
-    'EXTRA_PP_JS_MODULES': (StrictOrderingOnAppendList, list, [],
+    'EXTRA_PP_JS_MODULES': (StrictOrderingOnAppendList, list,
         """Additional JavaScript files to distribute.
 
         This variable contains a list of files to copy into
         ``$(FINAL_TARGET)/$(JS_MODULES_PATH)``, after preprocessing.
         ``JS_MODULES_PATH`` defaults to ``modules`` if left undefined.
         """, 'libs'),
 
-    'EXTRA_PP_COMPONENTS': (StrictOrderingOnAppendList, list, [],
+    'EXTRA_PP_COMPONENTS': (StrictOrderingOnAppendList, list,
         """Javascript XPCOM files.
 
        This variable contains a list of files to preprocess.  Generated
        files will be installed in the ``/components`` directory of the distribution.
         """, 'libs'),
 
-    'FINAL_LIBRARY': (unicode, unicode, "",
+    'FINAL_LIBRARY': (unicode, unicode,
         """Library in which the objects of the current directory will be linked.
 
         This variable contains the name of a library, defined elsewhere with
         ``LIBRARY_NAME``, in which the objects of the current directory will be
         linked.
         """, 'binaries'),
 
-    'CPP_UNIT_TESTS': (StrictOrderingOnAppendList, list, [],
+    'CPP_UNIT_TESTS': (StrictOrderingOnAppendList, list,
         """C++ source files for unit tests.
 
         This is a list of C++ unit test sources. Entries must be files that
         exist. These generally have ``.cpp`` extensions.
         """, 'binaries'),
 
-    'FAIL_ON_WARNINGS': (bool, bool, False,
+    'FAIL_ON_WARNINGS': (bool, bool,
         """Whether to treat warnings as errors.
         """, None),
 
-    'FORCE_SHARED_LIB': (bool, bool, False,
+    'FORCE_SHARED_LIB': (bool, bool,
         """Whether the library in this directory is a shared library.
         """, None),
 
-    'FORCE_STATIC_LIB': (bool, bool, False,
+    'FORCE_STATIC_LIB': (bool, bool,
         """Whether the library in this directory is a static library.
         """, None),
 
-    'GENERATED_INCLUDES' : (StrictOrderingOnAppendList, list, [],
+    'GENERATED_INCLUDES' : (StrictOrderingOnAppendList, list,
         """Directories generated by the build system to be searched for include
         files by the compiler.
         """, None),
 
-    'HOST_SOURCES': (StrictOrderingOnAppendList, list, [],
+    'HOST_SOURCES': (StrictOrderingOnAppendList, list,
         """Source code files to compile with the host compiler.
 
         This variable contains a list of source code files to compile.
         with the host compiler.
         """, 'compile'),
 
-    'IS_COMPONENT': (bool, bool, False,
+    'IS_COMPONENT': (bool, bool,
         """Whether the library contains a binary XPCOM component manifest.
         """, None),
 
-    'PARALLEL_DIRS': (list, list, [],
+    'PARALLEL_DIRS': (list, list,
         """A parallel version of ``DIRS``.
 
         Ideally this variable does not exist. It is provided so a transition
         from recursive makefiles can be made. Once the build system has been
         converted to not use Makefile's for the build frontend, this will
         likely go away.
         """, None),
 
-    'HOST_LIBRARY_NAME': (unicode, unicode, "",
+    'HOST_LIBRARY_NAME': (unicode, unicode,
         """Name of target library generated when cross compiling.
         """, 'binaries'),
 
-    'JAVA_JAR_TARGETS': (dict, dict, {},
+    'JAVA_JAR_TARGETS': (dict, dict,
         """Defines Java JAR targets to be built.
 
         This variable should not be populated directly. Instead, it should
         populated by calling add_java_jar().
         """, 'binaries'),
 
-    'JS_MODULES_PATH': (unicode, unicode, "",
+    'JS_MODULES_PATH': (unicode, unicode,
         """Sub-directory of ``$(FINAL_TARGET)`` to install
         ``EXTRA_JS_MODULES``.
 
         ``EXTRA_JS_MODULES`` files are copied to
         ``$(FINAL_TARGET)/$(JS_MODULES_PATH)``. This variable does not
         need to be defined if the desired destination directory is
         ``$(FINAL_TARGET)/modules``.
         """, None),
 
-    'LIBRARY_NAME': (unicode, unicode, "",
+    'LIBRARY_NAME': (unicode, unicode,
         """The name of the library generated for a directory.
 
         In ``example/components/moz.build``,::
 
            LIBRARY_NAME = 'xpcomsample'
 
         would generate ``example/components/libxpcomsample.so`` on Linux, or
         ``example/components/xpcomsample.lib`` on Windows.
         """, 'binaries'),
 
-    'LIBS': (StrictOrderingOnAppendList, list, [],
+    'LIBS': (StrictOrderingOnAppendList, list,
         """Linker libraries and flags.
 
         A list of libraries and flags to include when linking.
         """, None),
 
-    'LIBXUL_LIBRARY': (bool, bool, False,
+    'LIBXUL_LIBRARY': (bool, bool,
         """Whether the library in this directory is linked into libxul.
 
         Implies ``MOZILLA_INTERNAL_API`` and ``FORCE_STATIC_LIB``.
         """, None),
 
-    'LOCAL_INCLUDES': (StrictOrderingOnAppendList, list, [],
+    'LOCAL_INCLUDES': (StrictOrderingOnAppendList, list,
         """Additional directories to be searched for include files by the compiler.
         """, None),
 
-    'MSVC_ENABLE_PGO': (bool, bool, False,
+    'MSVC_ENABLE_PGO': (bool, bool,
         """Whether profile-guided optimization is enabled in this directory.
         """, None),
 
-    'NO_VISIBILITY_FLAGS': (bool, bool, False,
+    'NO_VISIBILITY_FLAGS': (bool, bool,
         """Build sources listed in this file without VISIBILITY_FLAGS.
         """, None),
 
-    'OS_LIBS': (list, list, [],
+    'OS_LIBS': (list, list,
         """System link libraries.
 
         This variable contains a list of system libaries to link against.
         """, None),
 
-    'SDK_LIBRARY': (StrictOrderingOnAppendList, list, [],
+    'SDK_LIBRARY': (StrictOrderingOnAppendList, list,
         """Elements of the distributed SDK.
 
         Files on this list will be copied into ``SDK_LIB_DIR``
         (``$DIST/sdk/lib``).
         """, None),
 
-    'SIMPLE_PROGRAMS': (StrictOrderingOnAppendList, list, [],
+    'SIMPLE_PROGRAMS': (StrictOrderingOnAppendList, list,
         """Compile a list of executable names.
 
         Each name in this variable corresponds to an executable built from the
         corresponding source file with the same base name.
 
         If the configuration token ``BIN_SUFFIX`` is set, its value will be
         automatically appended to each name. If a name already ends with
         ``BIN_SUFFIX``, the name will remain unchanged.
         """, 'binaries'),
 
-    'HOST_SIMPLE_PROGRAMS': (StrictOrderingOnAppendList, list, [],
+    'HOST_SIMPLE_PROGRAMS': (StrictOrderingOnAppendList, list,
         """Compile a list of host executable names.
 
         Each name in this variable corresponds to a hosst executable built
         from the corresponding source file with the same base name.
 
         If the configuration token ``HOST_BIN_SUFFIX`` is set, its value will
         be automatically appended to each name. If a name already ends with
         ``HOST_BIN_SUFFIX``, the name will remain unchanged.
         """, 'binaries'),
 
-    'TOOL_DIRS': (list, list, [],
+    'TOOL_DIRS': (list, list,
         """Like DIRS but for tools.
 
         Tools are for pieces of the build system that aren't required to
         produce a working binary (in theory). They provide things like test
         code and utilities.
         """, None),
 
-    'TEST_DIRS': (list, list, [],
+    'TEST_DIRS': (list, list,
         """Like DIRS but only for directories that contain test-only code.
 
         If tests are not enabled, this variable will be ignored.
 
         This variable may go away once the transition away from Makefiles is
         complete.
         """, None),
 
-    'TEST_TOOL_DIRS': (list, list, [],
+    'TEST_TOOL_DIRS': (list, list,
         """TOOL_DIRS that is only executed if tests are enabled.
         """, None),
 
 
-    'TIERS': (OrderedDict, dict, OrderedDict(),
+    'TIERS': (OrderedDict, dict,
         """Defines directories constituting the tier traversal mechanism.
 
         The recursive make backend iteration is organized into tiers. There are
         major tiers (keys in this dict) that correspond roughly to applications
         or libraries being built. e.g. base, nspr, js, platform, app. Within
         each tier are phases like export, libs, and tools. The recursive make
         backend iterates over each phase in the first tier then proceeds to the
         next tier until all tiers are exhausted.
@@ -370,196 +373,196 @@ VARIABLES = {
         Tiers are a way of working around deficiencies in recursive make. These
         will probably disappear once we no longer rely on recursive make for
         the build backend. They will likely be replaced by ``DIRS``.
 
         This variable is typically not populated directly. Instead, it is
         populated by calling add_tier_dir().
         """, None),
 
-    'EXTERNAL_MAKE_DIRS': (list, list, [],
+    'EXTERNAL_MAKE_DIRS': (list, list,
         """Directories that build with make but don't use moz.build files.
 
         This is like ``DIRS`` except it implies that ``make`` is used to build the
         directory and that the directory does not define itself with moz.build
         files.
         """, None),
 
-    'PARALLEL_EXTERNAL_MAKE_DIRS': (list, list, [],
+    'PARALLEL_EXTERNAL_MAKE_DIRS': (list, list,
         """Parallel version of ``EXTERNAL_MAKE_DIRS``.
         """, None),
 
-    'CONFIGURE_SUBST_FILES': (StrictOrderingOnAppendList, list, [],
+    'CONFIGURE_SUBST_FILES': (StrictOrderingOnAppendList, list,
         """Output files that will be generated using configure-like substitution.
 
         This is a substitute for ``AC_OUTPUT`` in autoconf. For each path in this
         list, we will search for a file in the srcdir having the name
         ``{path}.in``. The contents of this file will be read and variable
         patterns like ``@foo@`` will be substituted with the values of the
         ``AC_SUBST`` variables declared during configure.
         """, None),
 
-    'CONFIGURE_DEFINE_FILES': (StrictOrderingOnAppendList, list, [],
+    'CONFIGURE_DEFINE_FILES': (StrictOrderingOnAppendList, list,
         """Output files generated from configure/config.status.
 
         This is a substitute for ``AC_CONFIG_HEADER`` in autoconf. This is very
         similar to ``CONFIGURE_SUBST_FILES`` except the generation logic takes
         into account the values of ``AC_DEFINE`` instead of ``AC_SUBST``.
         """, None),
 
-    'EXPORTS': (HierarchicalStringList, list, HierarchicalStringList(),
+    'EXPORTS': (HierarchicalStringList, list,
         """List of files to be exported, and in which subdirectories.
 
         ``EXPORTS`` is generally used to list the include files to be exported to
         ``dist/include``, but it can be used for other files as well. This variable
         behaves as a list when appending filenames for export in the top-level
         directory. Files can also be appended to a field to indicate which
         subdirectory they should be exported to. For example, to export
         ``foo.h`` to the top-level directory, and ``bar.h`` to ``mozilla/dom/``,
         append to ``EXPORTS`` like so::
 
            EXPORTS += ['foo.h']
            EXPORTS.mozilla.dom += ['bar.h']
         """, None),
 
-    'PROGRAM' : (unicode, unicode, "",
+    'PROGRAM' : (unicode, unicode,
         """Compiled executable name.
 
         If the configuration token ``BIN_SUFFIX`` is set, its value will be
         automatically appended to ``PROGRAM``. If ``PROGRAM`` already ends with
         ``BIN_SUFFIX``, ``PROGRAM`` will remain unchanged.
         """, 'binaries'),
 
-    'HOST_PROGRAM' : (unicode, unicode, "",
+    'HOST_PROGRAM' : (unicode, unicode,
         """Compiled host executable name.
 
         If the configuration token ``HOST_BIN_SUFFIX`` is set, its value will be
         automatically appended to ``HOST_PROGRAM``. If ``HOST_PROGRAM`` already
         ends with ``HOST_BIN_SUFFIX``, ``HOST_PROGRAM`` will remain unchanged.
         """, 'binaries'),
 
-    'NO_DIST_INSTALL': (bool, bool, False,
+    'NO_DIST_INSTALL': (bool, bool,
         """Disable installing certain files into the distribution directory.
 
         If present, some files defined by other variables won't be
         distributed/shipped with the produced build.
         """, None),
 
     # IDL Generation.
-    'XPIDL_SOURCES': (StrictOrderingOnAppendList, list, [],
+    'XPIDL_SOURCES': (StrictOrderingOnAppendList, list,
         """XPCOM Interface Definition Files (xpidl).
 
         This is a list of files that define XPCOM interface definitions.
         Entries must be files that exist. Entries are almost certainly ``.idl``
         files.
         """, 'libs'),
 
-    'XPIDL_MODULE': (unicode, unicode, "",
+    'XPIDL_MODULE': (unicode, unicode,
         """XPCOM Interface Definition Module Name.
 
         This is the name of the ``.xpt`` file that is created by linking
         ``XPIDL_SOURCES`` together. If unspecified, it defaults to be the same
         as ``MODULE``.
         """, None),
 
-    'IPDL_SOURCES': (StrictOrderingOnAppendList, list, [],
+    'IPDL_SOURCES': (StrictOrderingOnAppendList, list,
         """IPDL source files.
 
         These are ``.ipdl`` files that will be parsed and converted to
         ``.cpp`` files.
         """, 'export'),
 
-    'WEBIDL_FILES': (StrictOrderingOnAppendList, list, [],
+    'WEBIDL_FILES': (StrictOrderingOnAppendList, list,
         """WebIDL source files.
 
         These will be parsed and converted to ``.cpp`` and ``.h`` files.
         """, 'export'),
 
-    'GENERATED_EVENTS_WEBIDL_FILES': (StrictOrderingOnAppendList, list, [],
+    'GENERATED_EVENTS_WEBIDL_FILES': (StrictOrderingOnAppendList, list,
         """WebIDL source files for generated events.
 
         These will be parsed and converted to ``.cpp`` and ``.h`` files.
         """, 'export'),
 
-    'TEST_WEBIDL_FILES': (StrictOrderingOnAppendList, list, [],
+    'TEST_WEBIDL_FILES': (StrictOrderingOnAppendList, list,
          """Test WebIDL source files.
 
          These will be parsed and converted to ``.cpp`` and ``.h`` files
          if tests are enabled.
          """, 'export'),
 
-    'GENERATED_WEBIDL_FILES': (StrictOrderingOnAppendList, list, [],
+    'GENERATED_WEBIDL_FILES': (StrictOrderingOnAppendList, list,
          """Generated WebIDL source files.
 
          These will be generated from some other files.
          """, 'export'),
 
-    'PREPROCESSED_TEST_WEBIDL_FILES': (StrictOrderingOnAppendList, list, [],
+    'PREPROCESSED_TEST_WEBIDL_FILES': (StrictOrderingOnAppendList, list,
          """Preprocessed test WebIDL source files.
 
          These will be preprocessed, then parsed and converted to .cpp
          and ``.h`` files if tests are enabled.
          """, 'export'),
 
-    'PREPROCESSED_WEBIDL_FILES': (StrictOrderingOnAppendList, list, [],
+    'PREPROCESSED_WEBIDL_FILES': (StrictOrderingOnAppendList, list,
          """Preprocessed WebIDL source files.
 
          These will be preprocessed before being parsed and converted.
          """, 'export'),
 
     # Test declaration.
-    'A11Y_MANIFESTS': (StrictOrderingOnAppendList, list, [],
+    'A11Y_MANIFESTS': (StrictOrderingOnAppendList, list,
         """List of manifest files defining a11y tests.
         """, None),
 
-    'BROWSER_CHROME_MANIFESTS': (StrictOrderingOnAppendList, list, [],
+    'BROWSER_CHROME_MANIFESTS': (StrictOrderingOnAppendList, list,
         """List of manifest files defining browser chrome tests.
         """, None),
 
-    'METRO_CHROME_MANIFESTS': (StrictOrderingOnAppendList, list, [],
+    'METRO_CHROME_MANIFESTS': (StrictOrderingOnAppendList, list,
         """List of manifest files defining metro browser chrome tests.
         """, None),
 
-    'MOCHITEST_CHROME_MANIFESTS': (StrictOrderingOnAppendList, list, [],
+    'MOCHITEST_CHROME_MANIFESTS': (StrictOrderingOnAppendList, list,
         """List of manifest files defining mochitest chrome tests.
         """, None),
 
-    'MOCHITEST_MANIFESTS': (StrictOrderingOnAppendList, list, [],
+    'MOCHITEST_MANIFESTS': (StrictOrderingOnAppendList, list,
         """List of manifest files defining mochitest tests.
         """, None),
 
-    'MOCHITEST_WEBAPPRT_CHROME_MANIFESTS': (StrictOrderingOnAppendList, list, [],
+    'MOCHITEST_WEBAPPRT_CHROME_MANIFESTS': (StrictOrderingOnAppendList, list,
         """List of manifest files defining webapprt mochitest chrome tests.
         """, None),
 
-    'WEBRTC_SIGNALLING_TEST_MANIFESTS': (StrictOrderingOnAppendList, list, [],
+    'WEBRTC_SIGNALLING_TEST_MANIFESTS': (StrictOrderingOnAppendList, list,
         """List of manifest files defining WebRTC signalling tests.
         """, None),
 
-    'XPCSHELL_TESTS_MANIFESTS': (StrictOrderingOnAppendList, list, [],
+    'XPCSHELL_TESTS_MANIFESTS': (StrictOrderingOnAppendList, list,
         """List of manifest files defining xpcshell tests.
         """, None),
 
     # The following variables are used to control the target of installed files.
-    'XPI_NAME': (unicode, unicode, "",
+    'XPI_NAME': (unicode, unicode,
         """The name of an extension XPI to generate.
 
         When this variable is present, the results of this directory will end up
         being packaged into an extension instead of the main dist/bin results.
         """, 'libs'),
 
-    'DIST_SUBDIR': (unicode, unicode, "",
+    'DIST_SUBDIR': (unicode, unicode,
         """The name of an alternate directory to install files to.
 
         When this variable is present, the results of this directory will end up
         being placed in the $(DIST_SUBDIR) subdirectory of where it would
         otherwise be placed.
         """, 'libs'),
 
-    'FINAL_TARGET': (unicode, unicode, compute_final_target,
+    'FINAL_TARGET': (FinalTargetValue, unicode,
         """The name of the directory to install targets to.
 
         The directory is relative to the top of the object directory. The
         default value is dependent on the values of XPI_NAME and DIST_SUBDIR. If
         neither are present, the result is dist/bin. If XPI_NAME is present, the
         result is dist/xpi-stage/$(XPI_NAME). If DIST_SUBDIR is present, then
         the $(DIST_SUBDIR) directory of the otherwise default value is used.
         """, 'libs'),
--- a/python/mozbuild/mozbuild/sphinx.py
+++ b/python/mozbuild/mozbuild/sphinx.py
@@ -44,34 +44,33 @@ def function_reference(f, attr, args, do
     ])
 
     lines.extend(docstring[1:])
     lines.append('')
 
     return lines
 
 
-def variable_reference(v, st_type, in_type, default, doc, tier):
+def variable_reference(v, st_type, in_type, doc, tier):
     lines = [
         v,
         '-' * len(v),
         '',
     ]
 
     docstring = prepare_docstring(doc)
 
     lines.extend([
         docstring[0],
         '',
     ])
 
     lines.extend([
         ':Storage Type: ``%s``' % st_type.__name__,
         ':Input Type: ``%s``' % in_type.__name__,
-        ':Default Value: %s' % default,
         '',
     ])
 
     lines.extend(docstring[1:])
     lines.append('')
 
     return lines
 
--- a/python/mozbuild/mozbuild/test/frontend/test_sandbox_symbols.py
+++ b/python/mozbuild/mozbuild/test/frontend/test_sandbox_symbols.py
@@ -31,17 +31,17 @@ class TestSymbols(unittest.TestCase):
 
         self.assertGreater(len(lines), 0)
         self.assertGreater(len(lines[0].strip()), 0)
 
         # Last line should be empty.
         self.assertEqual(lines[-1].strip(), '')
 
     def test_documentation_formatting(self):
-        for typ, inp, default, doc, tier in VARIABLES.values():
+        for typ, inp, doc, tier in VARIABLES.values():
             self._verify_doc(doc)
 
         for attr, args, doc in FUNCTIONS.values():
             self._verify_doc(doc)
 
         for typ, doc in SPECIAL_VARIABLES.values():
             self._verify_doc(doc)