Bug 1402010 - Don't use mutable default argument value; r?chmanchester
MozReview-Commit-ID: Ko2AV0KitjP
--- 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