Bug 1053069 - Make mozbuild.util.ReadOnlyDefaultDict raise an exception on update() and del. r=gps
authorMike Hommey <mh+mozilla@glandium.org>
Thu, 14 Aug 2014 07:15:38 +0900
changeset 199433 9ab7126c7cba3a8803b71a75b0600032a8f0a170
parent 199432 fab1f203cab049cf2484e562b5c870644e958068
child 199434 4b87bdfaf50e405b8fd386e37193e344146fcf86
push id27307
push useremorley@mozilla.com
push dateThu, 14 Aug 2014 07:50:45 +0000
treeherdermozilla-central@5299864050ee [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersgps
bugs1053069
milestone34.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 1053069 - Make mozbuild.util.ReadOnlyDefaultDict raise an exception on update() and del. r=gps
python/mozbuild/mozbuild/test/common.py
python/mozbuild/mozbuild/test/frontend/test_emitter.py
python/mozbuild/mozbuild/test/test_containers.py
python/mozbuild/mozbuild/util.py
--- a/python/mozbuild/mozbuild/test/common.py
+++ b/python/mozbuild/mozbuild/test/common.py
@@ -22,19 +22,17 @@ class MockConfig(object):
         self.topsrcdir = topsrcdir
         self.topobjdir = '/path/to/topobjdir'
 
         self.substs = ReadOnlyDict({
             'MOZ_FOO': 'foo',
             'MOZ_BAR': 'bar',
             'MOZ_TRUE': '1',
             'MOZ_FALSE': '',
-        })
-
-        self.substs.update(extra_substs)
+        }, **extra_substs)
 
         self.substs_unicode = ReadOnlyDict({k.decode('utf-8'): v.decode('utf-8',
             'replace') for k, v in self.substs.items()})
 
         self.defines = self.substs
 
     def child_path(self, p):
         return os.path.join(self.topsrcdir, p)
--- a/python/mozbuild/mozbuild/test/frontend/test_emitter.py
+++ b/python/mozbuild/mozbuild/test/frontend/test_emitter.py
@@ -215,17 +215,17 @@ class TestEmitterBasic(unittest.TestCase
         self.assertIn('overwrite', exports._children)
         overwrite = exports._children['overwrite']
         self.assertEqual(overwrite.get_strings(), ['new.h'])
 
     def test_resources(self):
         reader = self.reader('resources')
         objs = self.read_topsrcdir(reader)
 
-        expected_defines = reader.config.defines
+        expected_defines = dict(reader.config.defines)
         expected_defines.update({
             'FOO': True,
             'BAR': 'BAZ',
         })
 
         self.assertEqual(len(objs), 2)
         self.assertIsInstance(objs[0], Defines)
         self.assertIsInstance(objs[1], Resources)
--- a/python/mozbuild/mozbuild/test/test_containers.py
+++ b/python/mozbuild/mozbuild/test/test_containers.py
@@ -22,16 +22,36 @@ class TestReadOnlyDict(unittest.TestCase
         self.assertEqual(test['foo'], 1)
 
         with self.assertRaises(KeyError):
             value = test['missing']
 
         with self.assertRaises(Exception):
             test['baz'] = True
 
+    def test_update(self):
+        original = {'foo': 1, 'bar': 2}
+
+        test = ReadOnlyDict(original)
+
+        with self.assertRaises(Exception):
+            test.update(foo=2)
+
+        self.assertEqual(original, test)
+
+    def test_del(self):
+        original = {'foo': 1, 'bar': 2}
+
+        test = ReadOnlyDict(original)
+
+        with self.assertRaises(Exception):
+            del test['foo']
+
+        self.assertEqual(original, test)
+
 
 class TestReadOnlyDefaultDict(unittest.TestCase):
     def test_simple(self):
         original = {'foo': 1, 'bar': 2}
 
         test = ReadOnlyDefaultDict(bool, original)
 
         self.assertEqual(original, test)
--- a/python/mozbuild/mozbuild/util.py
+++ b/python/mozbuild/mozbuild/util.py
@@ -48,19 +48,25 @@ def hash_file(path):
     return h.hexdigest()
 
 
 class ReadOnlyDict(dict):
     """A read-only dictionary."""
     def __init__(self, *args, **kwargs):
         dict.__init__(self, *args, **kwargs)
 
-    def __setitem__(self, name, value):
+    def __delitem__(self, key):
+        raise Exception('Object does not support deletion.')
+
+    def __setitem__(self, key, value):
         raise Exception('Object does not support assignment.')
 
+    def update(self, *args, **kwargs):
+        raise Exception('Object does not support update.')
+
 
 class undefined_default(object):
     """Represents an undefined argument value that isn't None."""
 
 
 undefined = undefined_default()