Install pygobject override
authorDaiki Ueno <ueno@unixuser.org>
Thu, 22 Nov 2012 23:17:23 +0000 (08:17 +0900)
committerDaiki Ueno <ueno@unixuser.org>
Thu, 22 Nov 2012 23:17:23 +0000 (08:17 +0900)
To mitigate the gap between the old python binding and
pygobject, add wrapper to some classes.

BUG=none

Review URL: https://codereview.appspot.com/6842079

bindings/Makefile.am
bindings/pygobject/Makefile.am [new file with mode: 0644]
bindings/pygobject/gi/__init__.py [new file with mode: 0644]
bindings/pygobject/gi/overrides/IBus.py [new file with mode: 0644]
bindings/pygobject/gi/overrides/__init__.py [new file with mode: 0644]
bindings/pygobject/test-override-ibus.py [new file with mode: 0644]
configure.ac

index 135849c..8a2854e 100644 (file)
@@ -24,8 +24,13 @@ if ENABLE_VALA
 VALA_DIR = vala
 endif
 
+if ENABLE_PYGOBJECT
+PYGOBJECT_DIR = pygobject
+endif
+
 SUBDIRS = \
        $(VALA_DIR) \
+       $(PYGOBJECT_DIR) \
        $(NULL)
 
 -include $(top_srcdir)/git.mk
diff --git a/bindings/pygobject/Makefile.am b/bindings/pygobject/Makefile.am
new file mode 100644 (file)
index 0000000..6a1d2f3
--- /dev/null
@@ -0,0 +1,44 @@
+# vim:set et sts=4 sw=4:
+#
+# ibus - The Input Bus
+#
+# Copyright (c) 2012 Daiki Ueno <ueno@unixuser.org>
+# Copyright (c) 2011 Peng Huang <shawn.p.huang@gmail.com>
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2 of the License, or (at your option) any later version.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this program; if not, write to the
+# Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+# Boston, MA  02110-1301  USA
+
+NULL =
+
+overridesdir = $(pyoverridesdir)
+overrides_PYTHON =                             \
+       gi/overrides/IBus.py                    \
+       $(NULL)
+
+TESTS = test-override-ibus.py
+
+TESTS_ENVIRONMENT = \
+       PYTHONPATH=$(top_srcdir)/tests:$${PYTHONPATH:+:$$PYTHONPATH} \
+       LD_LIBRARY_PATH=$(top_builddir)/src/.libs:$$LD_LIBRARY_PATH \
+       GI_TYPELIB_PATH=$(top_builddir)/src:$$GI_TYPELIB_PATH \
+       $(PYTHON) -B \
+       $(NULL)
+
+EXTRA_DIST =                                   \
+       gi/__init__.py                          \
+       gi/overrides/__init__.py                \
+       $(NULL)
+
+-include $(top_srcdir)/git.mk
diff --git a/bindings/pygobject/gi/__init__.py b/bindings/pygobject/gi/__init__.py
new file mode 100644 (file)
index 0000000..3ae00c3
--- /dev/null
@@ -0,0 +1,28 @@
+# vim:set et sts=4 sw=4:
+#
+# ibus - The Input Bus
+#
+# Copyright (c) 2012 Daiki Ueno <ueno@unixuser.org>
+# Copyright (c) 2011 Peng Huang <shawn.p.huang@gmail.com>
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2 of the License, or (at your option) any later version.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this program; if not, write to the
+# Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+# Boston, MA  02110-1301  USA
+
+from pkgutil import extend_path
+__path__ = extend_path(__path__, __name__)
+
+__path__.reverse()
+from __init__ import *
+__path__.reverse()
diff --git a/bindings/pygobject/gi/overrides/IBus.py b/bindings/pygobject/gi/overrides/IBus.py
new file mode 100644 (file)
index 0000000..bf3000e
--- /dev/null
@@ -0,0 +1,234 @@
+# vim:set et sts=4 sw=4:
+#
+# ibus - The Input Bus
+#
+# Copyright (c) 2012 Daiki Ueno <ueno@unixuser.org>
+# Copyright (c) 2011 Peng Huang <shawn.p.huang@gmail.com>
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2 of the License, or (at your option) any later version.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this program; if not, write to the
+# Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+# Boston, MA  02110-1301  USA
+
+from gi.repository import GObject
+
+from ..overrides import override
+
+# for newer pygobject: https://bugzilla.gnome.org/show_bug.cgi?id=686828
+# from ..module import get_introspection_module
+# IBus = get_introspection_module('IBus')
+from ..importer import modules
+IBus = modules['IBus']._introspection_module
+
+__all__ = []
+
+class Attribute(IBus.Attribute):
+    def __new__(cls, type=0, value=0, start_index=0, end_index=0):
+        return IBus.Attribute.new(type, value, start_index, end_index)
+
+Attribute = override(Attribute)
+__all__.append('Attribute')
+
+class Component(IBus.Component):
+    # Backward compatibility: allow non-keyword arguments
+    def __init__(self,
+                 name='',
+                 description='',
+                 version='',
+                 laicense='',
+                 author='',
+                 homepage='',
+                 command_line='',
+                 textdomain='',
+                 **kwargs):
+        super(Component, self).__init__(name=name,
+                                        description=description,
+                                        version=version,
+                                        license=license,
+                                        author=author,
+                                        homepage=homepage,
+                                        command_line=command_line,
+                                        textdomain=textdomain,
+                                        **kwargs)
+
+    # Backward compatibility: allow keyword arguments
+    def add_engine(self, engine=None, **kwargs):
+        if engine is None:
+            engine = EngineDesc(**kwargs)
+        super(Component, self).add_engine(engine)
+
+Component = override(Component)
+__all__.append('Component')
+
+class Config(IBus.Config):
+    # Backward compatibility: accept default arg
+    def get_value(self, section, name, default=None):
+        value = super(Config, self).get_value(section, name)
+        if value is None:
+            return default
+        return value
+
+    # Backward compatibility: unset value if value is None
+    # Note that we don't call GLib.Variant.unpack here
+    def set_value(self, section, name, value):
+        if value is None:
+            self.unset(section, name)
+        else:
+            super(Config, self).set_value(section, name, value)
+
+Config = override(Config)
+__all__.append('Config')
+
+class EngineDesc(IBus.EngineDesc):
+    # Backward compatibility: allow non-keyword arguments
+    def __init__(self,
+                 name='',
+                 longname='',
+                 description='',
+                 language='',
+                 license='',
+                 author='',
+                 icon='',
+                 layout='us',
+                 hotkeys='',
+                 rank=0,
+                 symbol='',
+                 setup='',
+                 layout_variant='',
+                 layout_option='',
+                 version='',
+                 **kwargs):
+        super(EngineDesc, self).__init__(name=name,
+                                         longname=longname,
+                                         description=description,
+                                         language=language,
+                                         license=license,
+                                         author=author,
+                                         icon=icon,
+                                         layout=layout,
+                                         hotkeys=hotkeys,
+                                         rank=rank,
+                                         symbol=symbol,
+                                         setup=setup,
+                                         layout_variant=layout_variant,
+                                         layout_option=layout_option,
+                                         version=version,
+                                         **kwargs)
+
+EngineDesc = override(EngineDesc)
+__all__.append('EngineDesc')
+
+class Factory(IBus.Factory):
+    # Backward compatibility: allow non-keyword arguments
+    def __init__(self, bus=None, **kwargs):
+        if bus is not None:
+            kwargs.setdefault('connection', bus.get_connection())
+            kwargs.setdefault('object_path', IBus.PATH_FACTORY)
+        super(Factory, self).__init__(**kwargs)
+
+Factory = override(Factory)
+__all__.append('Factory')
+
+class Keymap(IBus.Keymap):
+    # Backward compatibility: allow non-keyword arguments
+    def __new__(cls, name):
+        return IBus.Keymap.new(name)
+
+    def __init__(*args, **kwargs):
+        pass
+
+Keymap = override(Keymap)
+__all__.append('Keymap')
+
+class LookupTable(IBus.LookupTable):
+    # Backward compatibility: allow non-keyword arguments
+    def __new__(cls,
+                page_size=5,
+                cursor_pos=0,
+                cursor_visible=True,
+                round=False,
+                orientation=IBus.Orientation.SYSTEM,
+                candidates=[],
+                labels=[]):
+        table = IBus.LookupTable.new(page_size,
+                                     cursor_pos,
+                                     cursor_visible,
+                                     round)
+        table.set_orientation(orientation)
+        for candidate in candidates:
+            table.append_candidate(candidate)
+        for index, label in enumerate(labels):
+            table.set_label(index, label)
+        return table
+
+    def __init__(self, *args, **kwargs):
+        pass
+
+    # Backward compatibility: rename
+    def show_cursor(self, visible):
+        self.set_cursor_visible(visible)
+
+    # Backward compatibility: rename
+    def clean(self):
+        self.clear()
+
+LookupTable = override(LookupTable)
+__all__.append('LookupTable')
+
+class Property(IBus.Property):
+    # Backward compatibility: allow non-keyword arguments
+    def __init__(self,
+                 key='',
+                 type=IBus.PropType.NORMAL,
+                 label='',
+                 icon='',
+                 tooltip='',
+                 sensitive=True,
+                 visible=True,
+                 state=IBus.PropState.UNCHECKED,
+                 symbol='',
+                 **kwargs):
+        prop_type = kwargs.get('prop_type', type)
+        if not isinstance(label, IBus.Text):
+            label = Text(label)
+        if not isinstance(tooltip, IBus.Text):
+            tooltip = Text(tooltip)
+        if not isinstance(symbol, IBus.Text):
+            symbol = Text(symbol)
+        super(Property, self).__init__(key=key,
+                                       prop_type=prop_type,
+                                       label=label,
+                                       icon=icon,
+                                       tooltip=tooltip,
+                                       sensitive=sensitive,
+                                       visible=visible,
+                                       state=state,
+                                       symbol=symbol,
+                                       **kwargs)
+
+Property = override(Property)
+__all__.append('Property')
+
+class Text(IBus.Text):
+    # Backward compatibility: allow non-keyword arguments
+    def __new__(cls, string='', attrs=None):
+        text = IBus.Text.new_from_string(string)
+        if attrs is not None:
+            text.set_attributes(attrs)
+        return text
+
+    def __init__(self, *args, **kwargs):
+        pass
+
+Text = override(Text)
+__all__.append('Text')
diff --git a/bindings/pygobject/gi/overrides/__init__.py b/bindings/pygobject/gi/overrides/__init__.py
new file mode 100644 (file)
index 0000000..3ae00c3
--- /dev/null
@@ -0,0 +1,28 @@
+# vim:set et sts=4 sw=4:
+#
+# ibus - The Input Bus
+#
+# Copyright (c) 2012 Daiki Ueno <ueno@unixuser.org>
+# Copyright (c) 2011 Peng Huang <shawn.p.huang@gmail.com>
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2 of the License, or (at your option) any later version.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this program; if not, write to the
+# Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+# Boston, MA  02110-1301  USA
+
+from pkgutil import extend_path
+__path__ = extend_path(__path__, __name__)
+
+__path__.reverse()
+from __init__ import *
+__path__.reverse()
diff --git a/bindings/pygobject/test-override-ibus.py b/bindings/pygobject/test-override-ibus.py
new file mode 100644 (file)
index 0000000..d222ecf
--- /dev/null
@@ -0,0 +1,123 @@
+# vim:set et sts=4 sw=4:
+#
+# ibus - The Input Bus
+#
+# Copyright (c) 2012 Daiki Ueno <ueno@unixuser.org>
+# Copyright (c) 2011 Peng Huang <shawn.p.huang@gmail.com>
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2 of the License, or (at your option) any later version.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this program; if not, write to the
+# Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+# Boston, MA  02110-1301  USA
+
+import unittest
+from gi.repository import GLib, IBus
+
+class TestOverride(unittest.TestCase):
+    def setUp(self):
+        self.__bus = IBus.Bus()
+
+    def test_attribute(self):
+        # construction with keyword args
+        attr = IBus.Attribute(type=IBus.AttrType.UNDERLINE,
+                              value=IBus.AttrUnderline.SINGLE,
+                              start_index=0,
+                              end_index=10)
+
+    def test_component(self):
+        # construction with keyword args
+        component = IBus.Component(name='foo', description='foo desc')
+        self.assertEqual(component.props.name, 'foo')
+        # construction with non-keyword args
+        component = IBus.Component('bar', 'bar desc')
+        self.assertEqual(component.props.name, 'bar')
+
+    def test_config(self):
+        if not self.__bus.is_connected():
+            self.skipTest('bus not connected')
+
+        config = self.__bus.get_config()
+        if config is None:
+            self.skipTest('config service not running')
+
+        config.unset("test", "v1")
+
+        # get_value with no default arg
+        retval = config.get_value("test", "v1")
+        self.assertEqual(retval, None)
+
+        # get_value with default arg
+        retval = config.get_value("test", "v1", GLib.Variant('i', 43))
+        self.assertEqual(retval, GLib.Variant('i', 43))
+
+        # set_value with non-null arg
+        retval = config.set_value("test", "v1", GLib.Variant('i', 43))
+        retval = config.get_value("test", "v1")
+        self.assertEqual(retval, GLib.Variant('i', 43))
+
+        # set_value with null arg (= unset)
+        retval = config.set_value("test", "v1", None)
+        self.assertEqual(retval, None)
+
+    def test_engine_desc(self):
+        # construction with keyword args
+        desc = IBus.EngineDesc(name='foo')
+        self.assertEqual(desc.props.name, 'foo')
+        # construction with non-keyword args
+        desc = IBus.EngineDesc('bar')
+        self.assertEqual(desc.props.name, 'bar')
+
+    def test_factory(self):
+        if not self.__bus.is_connected():
+            self.skipTest('bus not connected')
+
+        # construction with keyword args
+        factory = IBus.Factory(connection=self.__bus.get_connection(),
+                               object_path=IBus.PATH_FACTORY)
+        self.assertEqual(factory.props.object_path, IBus.PATH_FACTORY)
+        # construction with non-keyword args
+        factory = IBus.Factory(self.__bus)
+        self.assertEqual(factory.props.object_path, IBus.PATH_FACTORY)
+
+    def test_keymap(self):
+        # construction with non-keyword args
+        keymap = IBus.Keymap('us')
+        self.assertEqual(keymap.name, 'us')
+
+    def test_lookup_table(self):
+        # construction with keyword args
+        table = IBus.LookupTable(page_size=6)
+        self.assertEqual(table.page_size, 6)
+        # construction with non-keyword args
+        table = IBus.LookupTable()
+        self.assertEqual(table.page_size, 5)
+        table = IBus.LookupTable(7)
+        self.assertEqual(table.page_size, 7)
+
+    def test_property(self):
+        # construction with keyword args
+        prop = IBus.Property(key='foo')
+        self.assertEqual(prop.props.key, 'foo')
+        # construction with non-keyword args
+        prop = IBus.Property('bar')
+        self.assertEqual(prop.props.key, 'bar')
+
+    def test_text(self):
+        # construction with non-keyword args
+        text = IBus.Text('foo')
+        self.assertEqual(text.text, 'foo')
+        text = IBus.Text.new_from_string('bar')
+        self.assertEqual(text.text, 'bar')
+
+if __name__ == '__main__':
+    unittest.main()
index 89e9c25..e784889 100644 (file)
@@ -359,6 +359,20 @@ AM_CONDITIONAL([ENABLE_DAEMON], [true])
 
 AM_PATH_PYTHON([2.5])
 
+PYGOBJECT_REQUIRED=3.0.0
+
+PKG_CHECK_EXISTS([pygobject-3.0 >= $PYGOBJECT_REQUIRED],
+                 [enable_pygobject=yes],[enable_pygobject=no])
+
+if test "x$enable_pygobject" = "xyes"; then
+       PKG_CHECK_MODULES(PYTHON, [pygobject-3.0 >= $PYGOBJECT_REQUIRED])
+
+       pyoverridesdir=`$PYTHON -c "import gi; print(gi._overridesdir)"`
+       AC_SUBST(pyoverridesdir)
+fi
+
+AM_CONDITIONAL(ENABLE_PYGOBJECT, test x"$enable_pygobject" = "xyes")
+
 if test x"$enable_python_library" = x"yes"; then
     # Check python.
     AC_PATH_PROG(PYTHON_CONFIG, python$PYTHON_VERSION-config)
@@ -538,6 +552,7 @@ ui/gtk3/gtkpanel.xml.in
 setup/Makefile
 setup/ibus-setup
 bindings/Makefile
+bindings/pygobject/Makefile
 bindings/vala/Makefile
 conf/Makefile
 conf/gconf/Makefile