Bug 1402010 - Don't use mutable default argument value; r?chmanchester draft
authorGregory Szorc <gps@mozilla.com>
Thu, 21 Sep 2017 09:17:52 -0700
changeset 668486 51607c9defa7b2bcb537f9f7c6d9158f1357ef9f
parent 668485 a71490730baa86f21a310b47fd975b6d36003cae
child 668487 23dbfc6d8ebf99c5c3c49656acd9ba644a6a2637
push id81062
push usergszorc@mozilla.com
push dateThu, 21 Sep 2017 18:37:24 +0000
reviewerschmanchester
bugs1402010
milestone58.0a1
Bug 1402010 - Don't use mutable default argument value; r?chmanchester MozReview-Commit-ID: Ko2AV0KitjP
python/mozbuild/mozbuild/frontend/context.py
python/mozbuild/mozbuild/frontend/reader.py
--- a/python/mozbuild/mozbuild/frontend/context.py
+++ b/python/mozbuild/mozbuild/frontend/context.py
@@ -85,18 +85,18 @@ class Context(KeyedDefaultDict):
     this context instance. Keys in this dict are the strings representing keys
     in this context which are valid. Values are tuples of stored type,
     assigned type, default value, a docstring describing the purpose of the
     variable, and a tier indicator (see comment above the VARIABLES declaration
     in this module).
 
     config is the ConfigEnvironment for this context.
     """
-    def __init__(self, allowed_variables={}, config=None, finder=None):
-        self._allowed_variables = allowed_variables
+    def __init__(self, allowed_variables=None, config=None, finder=None):
+        self._allowed_variables = allowed_variables or {}
         self.main_path = None
         self.current_path = None
         # There aren't going to be enough paths for the performance of scanning
         # a list to be a problem.
         self._all_paths = []
         self.config = config
         self._sandbox = None
         self._finder = finder
@@ -249,17 +249,17 @@ class Context(KeyedDefaultDict):
             if not isinstance(value, stored_type):
                 update[key] = stored_type(value)
             else:
                 update[key] = value
         KeyedDefaultDict.update(self, update)
 
 
 class TemplateContext(Context):
-    def __init__(self, template=None, allowed_variables={}, config=None):
+    def __init__(self, template=None, allowed_variables=None, config=None):
         self.template = template
         super(TemplateContext, self).__init__(allowed_variables, config)
 
     def _validate(self, key, value):
         return Context._validate(self, key, value, True)
 
 
 class SubContext(Context, ContextDerivedValue):
--- a/python/mozbuild/mozbuild/frontend/reader.py
+++ b/python/mozbuild/mozbuild/frontend/reader.py
@@ -180,24 +180,24 @@ class MozbuildSandbox(Sandbox):
     We expose a few useful functions and expose the set of variables defining
     Mozilla's build system.
 
     context is a Context instance.
 
     metadata is a dict of metadata that can be used during the sandbox
     evaluation.
     """
-    def __init__(self, context, metadata={}, finder=default_finder):
+    def __init__(self, context, metadata=None, finder=default_finder):
         assert isinstance(context, Context)
 
         Sandbox.__init__(self, context, finder=finder)
 
         self._log = logging.getLogger(__name__)
 
-        self.metadata = dict(metadata)
+        self.metadata = dict(metadata or {})
         exports = self.metadata.get('exports', {})
         self.exports = set(exports.keys())
         context.update(exports)
         self.templates = self.metadata.setdefault('templates', {})
         self.special_variables = self.metadata.setdefault('special_variables',
                                                           SPECIAL_VARIABLES)
         self.functions = self.metadata.setdefault('functions', FUNCTIONS)
         self.subcontext_types = self.metadata.setdefault('subcontexts',
@@ -1025,17 +1025,17 @@ class BuildReader(object):
                 source = fh.read()
 
             tree = ast.parse(source, full)
             Visitor().visit(tree)
 
             for name, key, value in assignments:
                 yield p, name, key, value
 
-    def read_mozbuild(self, path, config, descend=True, metadata={}):
+    def read_mozbuild(self, path, config, descend=True, metadata=None):
         """Read and process a mozbuild file, descending into children.
 
         This starts with a single mozbuild file, executes it, and descends into
         other referenced files per our traversal logic.
 
         The traversal logic is to iterate over the *DIRS variables, treating
         each element as a relative directory path. For each encountered
         directory, we will open the moz.build file located in that
@@ -1046,16 +1046,18 @@ class BuildReader(object):
 
         Arbitrary metadata in the form of a dict can be passed into this
         function. This feature is intended to facilitate the build reader
         injecting state and annotations into moz.build files that is
         independent of the sandbox's execution context.
 
         Traversal is performed depth first (for no particular reason).
         """
+        metadata = metadata or {}
+
         self._execution_stack.append(path)
         try:
             for s in self._read_mozbuild(path, config, descend=descend,
                                          metadata=metadata):
                 yield s
 
         except BuildReaderError as bre:
             raise bre