diff options
author | Martin Pitt <martin.pitt@ubuntu.com> | 2011-01-29 12:20:50 +0100 |
---|---|---|
committer | Martin Pitt <martin.pitt@ubuntu.com> | 2011-02-08 15:29:07 +0100 |
commit | b7f32e4cca0cef201489b55653f96ac64a8f9ab9 (patch) | |
tree | de5b2f0c3f3e2e3050657111106daf45c4f6bccc | |
parent | 8dad0eaed60a9de26e9a729a48a1f6bc74be486e (diff) | |
download | pygobject-b7f32e4cca0cef201489b55653f96ac64a8f9ab9.tar.gz |
[gi] Provide comfortable GSettings API
Make Gio.Settings behave like a dictionary, with transparent conversion from/to
GVariants. Also provide a more comfortable constructor.
https://bugzilla.gnome.org/show_bug.cgi?id=640838
-rw-r--r-- | gi/overrides/Gio.py | 54 | ||||
-rw-r--r-- | tests/org.gnome.test.gschema.xml | 9 | ||||
-rw-r--r-- | tests/test_overrides.py | 73 |
3 files changed, 122 insertions, 14 deletions
diff --git a/gi/overrides/Gio.py b/gi/overrides/Gio.py index 5a6af2f2..78affa2a 100644 --- a/gi/overrides/Gio.py +++ b/gi/overrides/Gio.py @@ -21,6 +21,8 @@ from ..overrides import override from ..importer import modules +from gi.repository import GLib + Gio = modules['Gio']._introspection_module __all__ = [] @@ -43,3 +45,55 @@ class FileEnumerator(Gio.FileEnumerator): FileEnumerator = override(FileEnumerator) __all__.append('FileEnumerator') + +class Settings(Gio.Settings): + '''Provide dictionary-like access to GLib.Settings.''' + + def __init__(self, schema, path=None, backend=None): + Gio.Settings.__init__(self, schema=schema, backend=backend, path=path) + + def __contains__(self, key): + return key in self.list_keys() + + def __len__(self): + return len(self.list_keys()) + + def __bool__(self): + # for "if mysettings" we don't want a dictionary-like test here, just + # if the object isn't None + return True + + # alias for Python 2.x object protocol + __nonzero__ = __bool__ + + def __getitem__(self, key): + # get_value() aborts the program on an unknown key + if not key in self: + raise KeyError('unknown key: %r' % (key,)) + + return self.get_value(key).unpack() + + def __setitem__(self, key, value): + # set_value() aborts the program on an unknown key + if not key in self: + raise KeyError('unknown key: %r' % (key,)) + + # determine type string of this key + range = self.get_range(key) + type_ = range.get_child_value(0).get_string() + v = range.get_child_value(1) + if type_ == 'type': + # v is boxed empty array, type of its elements is the allowed value type + type_str = v.get_child_value(0).get_type_string() + assert type_str.startswith('a') + type_str = type_str[1:] + else: + raise NotImplementedError('Cannot handle allowed type range class' + str(type_)) + + self.set_value(key, GLib.Variant(type_str, value)) + + def keys(self): + return self.list_keys() + +Settings = override(Settings) +__all__.append('Settings') diff --git a/tests/org.gnome.test.gschema.xml b/tests/org.gnome.test.gschema.xml index 0002e852..221b87a5 100644 --- a/tests/org.gnome.test.gschema.xml +++ b/tests/org.gnome.test.gschema.xml @@ -13,4 +13,13 @@ <default>[1,2]</default> </key> </schema> + + <schema id="org.gnome.nopathtest"> + <key name="np-int" type="i"> + <default>42</default> + </key> + </schema> + + <schema id="org.gnome.empty" path="/tests/"> + </schema> </schemalist> diff --git a/tests/test_overrides.py b/tests/test_overrides.py index 0642dcc7..766beaf0 100644 --- a/tests/test_overrides.py +++ b/tests/test_overrides.py @@ -1234,6 +1234,11 @@ class TestGio(unittest.TestCase): def setUp(self): os.environ['GSETTINGS_BACKEND'] = 'memory' os.environ['GSETTINGS_SCHEMA_DIR'] = os.path.dirname(__file__) + self.settings = Gio.Settings('org.gnome.test') + # we change the values in the tests, so set them to predictable start + # value + self.settings.reset('test-string') + self.settings.reset('test-array') def test_file_enumerator(self): self.assertEquals(Gio.FileEnumerator, overrides.Gio.FileEnumerator) @@ -1253,29 +1258,69 @@ class TestGio(unittest.TestCase): self.assertEquals(iter_info, next_info) - def test_gsettings(self): - settings = Gio.Settings.new('org.gnome.test') - - self.assert_('test-array' in settings.list_keys()) + def test_gsettings_native(self): + self.assertTrue('test-array' in self.settings.list_keys()) # get various types - v = settings.get_value('test-boolean') + v = self.settings.get_value('test-boolean') self.assertEqual(v.get_boolean(), True) - self.assertEqual(settings.get_boolean('test-boolean'), True) + self.assertEqual(self.settings.get_boolean('test-boolean'), True) - v = settings.get_value('test-string') + v = self.settings.get_value('test-string') self.assertEqual(v.get_string(), 'Hello') - self.assertEqual(settings.get_string('test-string'), 'Hello') + self.assertEqual(self.settings.get_string('test-string'), 'Hello') - v = settings.get_value('test-array') + v = self.settings.get_value('test-array') self.assertEqual(v.unpack(), [1, 2]) - v = settings.get_value('test-tuple') + v = self.settings.get_value('test-tuple') self.assertEqual(v.unpack(), (1, 2)) # set a value - settings.set_string('test-string', 'World') - self.assertEqual(settings.get_string('test-string'), 'World') + self.settings.set_string('test-string', 'World') + self.assertEqual(self.settings.get_string('test-string'), 'World') + + self.settings.set_value('test-string', GLib.Variant('s', 'Goodbye')) + self.assertEqual(self.settings.get_string('test-string'), 'Goodbye') + + def test_gsettings_constructor(self): + # default constructor uses path from schema + self.assertEqual(self.settings.get_property('path'), '/tests/') + + # optional constructor arguments + with_path = Gio.Settings('org.gnome.nopathtest', path='/mypath/') + self.assertEqual(with_path.get_property('path'), '/mypath/') + self.assertEqual(with_path['np-int'], 42) + + def test_gsettings_override(self): + # dictionary interface + self.assertEqual(len(self.settings), 4) + self.assertTrue('test-array' in self.settings) + self.assertTrue('test-array' in self.settings.keys()) + self.failIf('nonexisting' in self.settings) + self.failIf(4 in self.settings) + self.assertEqual(bool(self.settings), True) - settings.set_value('test-string', GLib.Variant('s', 'Goodbye')) - self.assertEqual(settings.get_string('test-string'), 'Goodbye') + # get various types + self.assertEqual(self.settings['test-boolean'], True) + self.assertEqual(self.settings['test-string'], 'Hello') + self.assertEqual(self.settings['test-array'], [1, 2]) + self.assertEqual(self.settings['test-tuple'], (1, 2)) + + self.assertRaises(KeyError, self.settings.__getitem__, 'unknown') + self.assertRaises(KeyError, self.settings.__getitem__, 2) + + # set a value + self.settings['test-string'] = 'Goodbye' + self.assertEqual(self.settings['test-string'], 'Goodbye') + self.settings['test-array'] = [3, 4, 5] + self.assertEqual(self.settings['test-array'], [3, 4, 5]) + + self.assertRaises(TypeError, self.settings.__setitem__, 'test-string', 1) + self.assertRaises(KeyError, self.settings.__setitem__, 'unknown', 'moo') + + def test_gsettings_empty(self): + empty = Gio.Settings('org.gnome.empty', path='/tests/') + self.assertEqual(len(empty), 0) + self.assertEqual(bool(empty), True) + self.assertEqual(empty.keys(), []) |