summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMartin Pitt <martin.pitt@ubuntu.com>2011-01-29 12:20:50 +0100
committerMartin Pitt <martin.pitt@ubuntu.com>2011-02-08 15:29:07 +0100
commitb7f32e4cca0cef201489b55653f96ac64a8f9ab9 (patch)
treede5b2f0c3f3e2e3050657111106daf45c4f6bccc
parent8dad0eaed60a9de26e9a729a48a1f6bc74be486e (diff)
downloadpygobject-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.py54
-rw-r--r--tests/org.gnome.test.gschema.xml9
-rw-r--r--tests/test_overrides.py73
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(), [])