Bug 1363811 - Allow to combine two DependsFunctions with "&". r=cmanchester+432261

Similar to how they can be combined with "|", we now allow using "&".
As for "|", it would have been better if it were "and", but it's not
possible to override "and" in python ; __and__ is for "&".
This commit is contained in:
Mike Hommey 2017-05-17 15:27:26 +09:00
Родитель 91e718c2f2
Коммит 853aefa3b4
2 изменённых файлов: 33 добавлений и 5 удалений

Просмотреть файл

@ -46,6 +46,7 @@ class SandboxDependsFunction(object):
'''Sandbox-visible representation of @depends functions.'''
def __init__(self, unsandboxed):
self._or = unsandboxed.__or__
self._and = unsandboxed.__and__
def __call__(self, *arg, **kwargs):
raise ConfigureError('The `%s` function may not be called'
@ -57,6 +58,12 @@ class SandboxDependsFunction(object):
'with another @depends function.')
return self._or(other).sandboxed
def __and__(self, other):
if not isinstance(other, SandboxDependsFunction):
raise ConfigureError('Can only do binary arithmetic operations '
'with another @depends function.')
return self._and(other).sandboxed
def __nonzero__(self):
raise ConfigureError(
'Cannot do boolean operations on @depends functions.')
@ -135,6 +142,23 @@ class DependsFunction(object):
return i
return i
def __and__(self, other):
if isinstance(other, SandboxDependsFunction):
other = self.sandbox._depends.get(other)
assert isinstance(other, DependsFunction)
assert self.sandbox is other.sandbox
return CombinedDependsFunction(self.sandbox, self.and_impl,
(self, other))
@staticmethod
def and_impl(iterable):
# Applies "and" to all the items of iterable.
# e.g. if iterable contains a, b and c, returns `a and b and c`.
for i in iterable:
if not i:
return i
return i
class CombinedDependsFunction(DependsFunction):
def __init__(self, sandbox, func, dependencies):

Просмотреть файл

@ -1287,7 +1287,7 @@ class TestConfigure(unittest.TestCase):
''' + moz_configure):
self.get_config(['--enable-when'])
def test_depends_or(self):
def test_depends_binary_ops(self):
with self.moz_configure('''
option('--foo', nargs=1, help='foo')
@depends('--foo')
@ -1304,8 +1304,10 @@ class TestConfigure(unittest.TestCase):
def baz(value):
return value
set_config('FOOBAR', foo | bar)
set_config('FOOBARBAZ', foo | bar | baz)
set_config('FOOorBAR', foo | bar)
set_config('FOOorBARorBAZ', foo | bar | baz)
set_config('FOOandBAR', foo & bar)
set_config('FOOandBARandBAZ', foo & bar & baz)
'''):
for foo_opt, foo_value in (
('', 0),
@ -1322,8 +1324,10 @@ class TestConfigure(unittest.TestCase):
config = self.get_config(
[x for x in (foo_opt, bar_opt, baz_opt) if x])
self.assertEqual(config, {
'FOOBAR': foo_value or bar_value,
'FOOBARBAZ': foo_value or bar_value or baz_value,
'FOOorBAR': foo_value or bar_value,
'FOOorBARorBAZ': foo_value or bar_value or baz_value,
'FOOandBAR': foo_value and bar_value,
'FOOandBARandBAZ': foo_value and bar_value and baz_value,
})