Bug 1322025 - Make DependsFunction.func less public. r=chmanchester
We're going to change the function signature for CombinedDependsFunction,
so make it visible in the API that the function member is not meant to
be used directly. The linter still does, though, because it needs to
look in their guts.
At the same time, avoid setting DependsFunction names via the function
name itself, because in upcoming changes, it will not be modifiable in
some cases.
--- a/python/mozbuild/mozbuild/configure/__init__.py
+++ b/python/mozbuild/mozbuild/configure/__init__.py
@@ -46,54 +46,61 @@ class SandboxDependsFunction(object):
'''Sandbox-visible representation of @depends functions.'''
def __call__(self, *arg, **kwargs):
raise ConfigureError('The `%s` function may not be called'
% self.__name__)
class DependsFunction(object):
__slots__ = (
- 'func', 'dependencies', 'when', 'sandboxed', 'sandbox', '_result')
+ '_func', '_name', 'dependencies', 'when', 'sandboxed', 'sandbox',
+ '_result')
def __init__(self, sandbox, func, dependencies, when=None):
assert isinstance(sandbox, ConfigureSandbox)
- self.func = func
+ assert not inspect.isgeneratorfunction(func)
+ self._func = func
+ self._name = func.__name__
self.dependencies = dependencies
self.sandboxed = wraps(func)(SandboxDependsFunction())
self.sandbox = sandbox
self.when = when
sandbox._depends[self.sandboxed] = self
# Only @depends functions with a dependency on '--help' are executed
# immediately. Everything else is queued for later execution.
if sandbox._help_option in dependencies:
sandbox._value_for(self)
elif not sandbox._help:
sandbox._execution_queue.append((sandbox._value_for, (self,)))
@property
def name(self):
- return self.func.__name__
+ return self._name
+
+ @name.setter
+ def name(self, value):
+ self._name = value
@property
def sandboxed_dependencies(self):
return [
d.sandboxed if isinstance(d, DependsFunction) else d
for d in self.dependencies
]
@memoize
def result(self, need_help_dependency=False):
if self.when and not self.sandbox._value_for(self.when,
need_help_dependency):
return None
resolved_args = [self.sandbox._value_for(d, need_help_dependency)
for d in self.dependencies]
- return self.func(*resolved_args)
+ return self._func(*resolved_args)
def __repr__(self):
return '<%s.%s %s(%s)>' % (
self.__class__.__module__,
self.__class__.__name__,
self.name,
', '.join(repr(d) for d in self.dependencies),
)
@@ -103,17 +110,17 @@ class CombinedDependsFunction(DependsFun
def __init__(self, sandbox, func, dependencies):
@memoize
@wraps(func)
def wrapper(*args):
return func(args)
flatten_deps = []
for d in dependencies:
- if isinstance(d, CombinedDependsFunction) and d.func == wrapper:
+ if isinstance(d, CombinedDependsFunction) and d._func == wrapper:
for d2 in d.dependencies:
if d2 not in flatten_deps:
flatten_deps.append(d2)
elif d not in flatten_deps:
flatten_deps.append(d)
# Automatically add a --help dependency if one of the dependencies
# depends on it.
@@ -129,21 +136,21 @@ class CombinedDependsFunction(DependsFun
@memoize
def result(self, need_help_dependency=False):
# Ignore --help for the combined result
deps = self.dependencies
if deps[0] == self.sandbox._help_option:
deps = deps[1:]
resolved_args = [self.sandbox._value_for(d, need_help_dependency)
for d in deps]
- return self.func(*resolved_args)
+ return self._func(*resolved_args)
def __eq__(self, other):
return (isinstance(other, self.__class__) and
- self.func == other.func and
+ self._func == other._func and
set(self.dependencies) == set(other.dependencies))
def __ne__(self, other):
return not self == other
class SandboxedGlobal(dict):
'''Identifiable dict type for use as function global'''
@@ -386,17 +393,17 @@ class ConfigureSandbox(dict):
elif (not isinstance(value, SandboxDependsFunction) and
value not in self._templates and
not (inspect.isclass(value) and issubclass(value, Exception))):
raise KeyError('Cannot assign `%s` because it is neither a '
'@depends nor a @template' % key)
if isinstance(value, SandboxDependsFunction):
- self._depends[value].func.__name__ = key
+ self._depends[value].name = key
return super(ConfigureSandbox, self).__setitem__(key, value)
def _resolve(self, arg, need_help_dependency=True):
if isinstance(arg, SandboxDependsFunction):
return self._value_for_depends(self._depends[arg],
need_help_dependency)
return arg
@@ -412,17 +419,16 @@ class ConfigureSandbox(dict):
elif isinstance(obj, Option):
return self._value_for_option(obj)
assert False
@memoize
def _value_for_depends(self, obj, need_help_dependency=False):
- assert not inspect.isgeneratorfunction(obj.func)
return obj.result(need_help_dependency)
@memoize
def _value_for_option(self, option):
implied = {}
for implied_option in self._implied_options[:]:
if implied_option.name not in (option.name, option.env):
continue
--- a/python/mozbuild/mozbuild/configure/lint.py
+++ b/python/mozbuild/mozbuild/configure/lint.py
@@ -35,17 +35,17 @@ class LintSandbox(ConfigureSandbox):
for dep in self._depends.itervalues():
self._check_dependencies(dep)
def _check_dependencies(self, obj):
if isinstance(obj, CombinedDependsFunction) or obj in (self._always,
self._never):
return
- func, glob = self.unwrap(obj.func)
+ func, glob = self.unwrap(obj._func)
loc = '%s:%d' % (func.func_code.co_filename,
func.func_code.co_firstlineno)
func_args = inspect.getargspec(func)
if func_args.keywords:
raise ConfigureError(
'%s: Keyword arguments are not allowed in @depends functions'
% loc
)
@@ -75,17 +75,17 @@ class LintSandbox(ConfigureSandbox):
def _missing_help_dependency(self, obj):
if isinstance(obj, CombinedDependsFunction):
return False
if isinstance(obj, DependsFunction):
if (self._help_option in obj.dependencies or
obj in (self._always, self._never)):
return False
- func, glob = self.unwrap(obj.func)
+ func, glob = self.unwrap(obj._func)
# We allow missing --help dependencies for functions that:
# - don't use @imports
# - don't have a closure
# - don't use global variables
if func in self._imports or func.func_closure:
return True
for op, arg in disassemble_as_iter(func):
if op in ('LOAD_GLOBAL', 'STORE_GLOBAL'):