summaryrefslogtreecommitdiff
path: root/gi
diff options
context:
space:
mode:
Diffstat (limited to 'gi')
-rw-r--r--gi/Makefile.in3
-rw-r--r--gi/gimodule.c2
-rw-r--r--gi/module.py22
-rw-r--r--gi/overrides/GIMarshallingTests.py2
-rw-r--r--gi/overrides/Gdk.py2
-rw-r--r--gi/overrides/Gtk.py548
-rw-r--r--gi/overrides/Makefile.in3
-rw-r--r--gi/overrides/__init__.py43
-rw-r--r--gi/pygi-argument.c17
-rw-r--r--gi/pygi-foreign-cairo.c62
-rw-r--r--gi/pygi-foreign.c5
-rw-r--r--gi/pygi-info.c136
-rw-r--r--gi/pygi-info.h7
-rw-r--r--gi/pygi-invoke.c25
-rw-r--r--gi/pygi.h12
-rw-r--r--gi/repository/Makefile.in3
-rw-r--r--gi/types.py10
17 files changed, 828 insertions, 74 deletions
diff --git a/gi/Makefile.in b/gi/Makefile.in
index 1aecd0a..f0dd624 100644
--- a/gi/Makefile.in
+++ b/gi/Makefile.in
@@ -244,6 +244,8 @@ PACKAGE_URL = @PACKAGE_URL@
PACKAGE_VERSION = @PACKAGE_VERSION@
PATH_SEPARATOR = @PATH_SEPARATOR@
PKG_CONFIG = @PKG_CONFIG@
+PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@
+PKG_CONFIG_PATH = @PKG_CONFIG_PATH@
PLATFORM = @PLATFORM@
PYCAIRO_CFLAGS = @PYCAIRO_CFLAGS@
PYCAIRO_LIBS = @PYCAIRO_LIBS@
@@ -301,7 +303,6 @@ libdir = @libdir@
libexecdir = @libexecdir@
localedir = @localedir@
localstatedir = @localstatedir@
-lt_ECHO = @lt_ECHO@
mandir = @mandir@
mkdir_p = @mkdir_p@
oldincludedir = @oldincludedir@
diff --git a/gi/gimodule.c b/gi/gimodule.c
index 89caf4e..f7624ae 100644
--- a/gi/gimodule.c
+++ b/gi/gimodule.c
@@ -328,7 +328,7 @@ PYGLIB_MODULE_START(_gi, "_gi")
_pygi_boxed_register_types (module);
_pygi_argument_init();
- api = PyCObject_FromVoidPtr ( (void *) &CAPI, NULL);
+ api = PYGLIB_CPointer_WrapPointer ( (void *) &CAPI, "gi._API");
if (api == NULL) {
return;
}
diff --git a/gi/module.py b/gi/module.py
index 819fcc6..c7b6557 100644
--- a/gi/module.py
+++ b/gi/module.py
@@ -25,6 +25,8 @@ from __future__ import absolute_import
import os
import gobject
+from .overrides import registry
+
from ._gi import \
Repository, \
FunctionInfo, \
@@ -47,7 +49,6 @@ from .types import \
repository = Repository.get_default()
-
def get_parent_for_object(object_info):
parent_object_info = object_info.get_parent()
@@ -85,6 +86,7 @@ class IntrospectionModule(object):
self.__name__ = 'gi.repository.' + namespace
repository.require(self._namespace, self.version)
+ self.__path__ = repository.get_typelib_path(self._namespace)
if self.version is None:
self.version = repository.get_version(self._namespace)
@@ -172,6 +174,9 @@ class IntrospectionModule(object):
path = repository.get_typelib_path(self._namespace)
return "<IntrospectionModule %r from %r>" % (self._namespace, path)
+ def __dir__ (self):
+ attribs_list = repository.get_infos(self._namespace)
+ return list(map(lambda x: x.get_name(), attribs_list))
class DynamicGObjectModule(IntrospectionModule):
"""Wrapper for the GObject module
@@ -222,6 +227,7 @@ class DynamicModule(object):
overrides_modules = __import__('gi.overrides', fromlist=[self._namespace])
self._overrides_module = getattr(overrides_modules, self._namespace, None)
+ self.__path__ = repository.get_typelib_path(self._namespace)
def __getattr__(self, name):
if self.introspection_module is None:
@@ -231,5 +237,19 @@ class DynamicModule(object):
override_exports = getattr(self._overrides_module, '__all__', ())
if name in override_exports:
return getattr(self._overrides_module, name, None)
+ else:
+ # check the registry just in case the module hasn't loaded yet
+ # TODO: Only gtypes are registered in the registry right now
+ # but it would be nice to register all overrides and
+ # get rid of the module imports. We might actually see a
+ # speedup.
+ key = '%s.%s' % (self._namespace, name)
+ if key in registry:
+ return registry[key]
return getattr(self.introspection_module, name)
+
+ def __dir__ (self):
+ repository.require(self._namespace, self._version)
+ attribs_list = repository.get_infos(self._namespace)
+ return list(map(lambda x: x.get_name(), attribs_list))
diff --git a/gi/overrides/GIMarshallingTests.py b/gi/overrides/GIMarshallingTests.py
index ee01495..25a882f 100644
--- a/gi/overrides/GIMarshallingTests.py
+++ b/gi/overrides/GIMarshallingTests.py
@@ -18,7 +18,7 @@
# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301
# USA
-from ..types import override
+from ..overrides import override
from ..importer import modules
GIMarshallingTests = modules['GIMarshallingTests'].introspection_module
diff --git a/gi/overrides/Gdk.py b/gi/overrides/Gdk.py
index 23a9d8e..08141d7 100644
--- a/gi/overrides/Gdk.py
+++ b/gi/overrides/Gdk.py
@@ -19,7 +19,7 @@
# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301
# USA
-from ..types import override
+from ..overrides import override
from ..importer import modules
Gdk = modules['Gdk'].introspection_module
diff --git a/gi/overrides/Gtk.py b/gi/overrides/Gtk.py
index 1f6901c..a2f38ac 100644
--- a/gi/overrides/Gtk.py
+++ b/gi/overrides/Gtk.py
@@ -23,7 +23,7 @@ import sys
import gobject
from gi.repository import Gdk
from gi.repository import GObject
-from ..types import override
+from ..overrides import override
from ..importer import modules
if sys.version_info >= (3, 0):
@@ -36,6 +36,44 @@ else:
Gtk = modules['Gtk'].introspection_module
__all__ = []
+class Widget(Gtk.Widget):
+
+ def translate_coordinates(self, dest_widget, src_x, src_y):
+ success, dest_x, dest_y = super(Widget, self).translate_coordinates(
+ dest_widget, src_x, src_y)
+ if success:
+ return (dest_x, dest_y,)
+
+Widget = override(Widget)
+__all__.append('Widget')
+
+class Container(Gtk.Container, Widget):
+
+ def get_focus_chain(self):
+ success, widgets = super(Container, self).get_focus_chain()
+ if success:
+ return widgets
+
+Container = override(Container)
+__all__.append('Container')
+
+class Editable(Gtk.Editable):
+
+ def insert_text(self, text, position):
+ pos = super(Editable, self).insert_text(text, -1, position)
+
+ return pos
+
+ def get_selection_bounds(self):
+ success, start_pos, end_pos = super(Editable, self).get_selection_bounds()
+ if success:
+ return (start_pos, end_pos,)
+ else:
+ return tuple()
+
+Editable = override(Editable)
+__all__.append("Editable")
+
class ActionGroup(Gtk.ActionGroup):
def add_actions(self, entries, user_data=None):
"""
@@ -202,6 +240,16 @@ class UIManager(Gtk.UIManager):
UIManager = override(UIManager)
__all__.append('UIManager')
+class ComboBox(Gtk.ComboBox, Container):
+
+ def get_active_iter(self):
+ success, aiter = super(ComboBox, self).get_active_iter()
+ if success:
+ return aiter
+
+ComboBox = override(ComboBox)
+__all__.append('ComboBox')
+
class Builder(Gtk.Builder):
def connect_signals(self, obj_or_map):
@@ -252,10 +300,24 @@ class Builder(Gtk.Builder):
Builder = override(Builder)
__all__.append('Builder')
-class Dialog(Gtk.Dialog):
- def __init__(self, title=None, parent=None, flags=0, buttons=None):
- Gtk.Dialog.__init__(self)
+class Dialog(Gtk.Dialog, Container):
+
+ def __init__(self,
+ title=None,
+ parent=None,
+ flags=0,
+ buttons=None,
+ _buttons_property=None,
+ **kwds):
+
+ # buttons is overloaded by PyGtk so we have to do the same here
+ # this breaks some subclasses of Dialog so add a _buttons_property
+ # keyword to work around this
+ if _buttons_property is not None:
+ kwds['buttons'] = _buttons_property
+
+ Gtk.Dialog.__init__(self, **kwds)
if title:
self.set_title(title)
if parent:
@@ -272,7 +334,7 @@ class Dialog(Gtk.Dialog):
except AttributeError:
pass
- if buttons:
+ if buttons is not None:
self.add_buttons(*buttons)
def add_buttons(self, *args):
@@ -287,15 +349,14 @@ class Dialog(Gtk.Dialog):
will add "Open" and "Close" buttons to dialog.
"""
-
- def buttons(b):
+ def _button(b):
while b:
t, r = b[0:2]
b = b[2:]
yield t, r
try:
- for text, response in buttons(args):
+ for text, response in _button(args):
self.add_button(text, response)
except (IndexError):
raise TypeError('Must pass an even number of arguments')
@@ -303,6 +364,124 @@ class Dialog(Gtk.Dialog):
Dialog = override(Dialog)
__all__.append('Dialog')
+class MessageDialog(Gtk.MessageDialog, Dialog):
+ def __init__(self,
+ parent=None,
+ flags=0,
+ type=Gtk.MessageType.INFO,
+ buttons=Gtk.ButtonsType.NONE,
+ message_format=None,
+ **kwds):
+
+ if message_format != None:
+ kwds['text'] = message_format
+ Gtk.MessageDialog.__init__(self,
+ _buttons_property=buttons,
+ **kwds)
+ Dialog.__init__(self, parent=parent, flags=flags)
+
+MessageDialog = override(MessageDialog)
+__all__.append('MessageDialog')
+
+class AboutDialog(Gtk.AboutDialog, Dialog):
+ def __init__(self, **kwds):
+ Gtk.AboutDialog.__init__(self, **kwds)
+ Dialog.__init__(self)
+
+AboutDialog = override(AboutDialog)
+__all__.append('AboutDialog')
+
+class ColorSelectionDialog(Gtk.ColorSelectionDialog, Dialog):
+ def __init__(self, title=None, **kwds):
+ Gtk.ColorSelectionDialog.__init__(self, **kwds)
+ Dialog.__init__(self, title=title)
+
+ColorSelectionDialog = override(ColorSelectionDialog)
+__all__.append('ColorSelectionDialog')
+
+class FileChooserDialog(Gtk.FileChooserDialog, Dialog):
+ def __init__(self,
+ title=None,
+ parent=None,
+ action=Gtk.FileChooserAction.OPEN,
+ buttons=None,
+ **kwds):
+ Gtk.FileChooserDialog.__init__(self,
+ action=action,
+ **kwds)
+ Dialog.__init__(self,
+ title=title,
+ parent=parent,
+ buttons=buttons)
+
+FileChooserDialog = override(FileChooserDialog)
+__all__.append('FileChooserDialog')
+
+class FontSelectionDialog(Gtk.FontSelectionDialog, Dialog):
+ def __init__(self, title=None, **kwds):
+ Gtk.FontSelectionDialog.__init__(self, **kwds)
+ Dialog.__init__(self, title=title)
+
+FontSelectionDialog = override(FontSelectionDialog)
+__all__.append('FontSelectionDialog')
+
+class RecentChooserDialog(Gtk.RecentChooserDialog, Dialog):
+ def __init__(self,
+ title=None,
+ parent=None,
+ manager=None,
+ buttons=None,
+ **kwds):
+
+ Gtk.RecentChooserDialog.__init__(self, recent_manager=manager, **kwds)
+ Dialog.__init__(self,
+ title=title,
+ parent=parent,
+ buttons=buttons)
+
+RecentChooserDialog = override(RecentChooserDialog)
+__all__.append('RecentChooserDialog')
+
+class IconView(Gtk.IconView):
+
+ def get_item_at_pos(self, x, y):
+ success, path, cell = super(IconView, self).get_item_at_pos(x, y)
+ if success:
+ return (path, cell,)
+
+ def get_visible_range(self):
+ success, start_path, end_path = super(IconView, self).get_visible_range()
+ if success:
+ return (start_path, end_path,)
+
+ def get_dest_item_at_pos(self, drag_x, drag_y):
+ success, path, pos = super(IconView, self).get_dest_item_at_pos(drag_x, drag_y)
+ if success:
+ return path, pos
+
+IconView = override(IconView)
+__all__.append('IconView')
+
+class IMContext(Gtk.IMContext):
+
+ def get_surrounding(self):
+ success, text, cursor_index = super(IMContext, self).get_surrounding()
+ if success:
+ return (text, cursor_index,)
+
+IMContext = override(IMContext)
+__all__.append('IMContext')
+
+class RecentInfo(Gtk.RecentInfo):
+
+ def get_application_info(self, app_name):
+ success, app_exec, count, time = super(RecentInfo, self).get_application_info(app_name)
+ if success:
+ return (app_exec, count, time,)
+
+RecentInfo = override(RecentInfo)
+__all__.append('RecentInfo')
+
class TextBuffer(Gtk.TextBuffer):
def _get_or_create_tag_table(self):
table = self.get_tag_table()
@@ -351,23 +530,121 @@ class TextBuffer(Gtk.TextBuffer):
length = len(text)
Gtk.TextBuffer.insert_at_cursor(self, text, length)
+ def get_selection_bounds(self):
+ success, start, end = super(TextBuffer, self).get_selection_bounds(string,
+ flags, limit)
+ return (start, end)
+
TextBuffer = override(TextBuffer)
__all__.append('TextBuffer')
+class TextIter(Gtk.TextIter):
+
+ def forward_search(self, string, flags, limit):
+ success, match_start, match_end = super(TextIter, self).forward_search(string,
+ flags, limit)
+ return (match_start, match_end,)
+
+ def backward_search(self, string, flags, limit):
+ success, match_start, match_end = super(TextIter, self).backward_search(string,
+ flags, limit)
+ return (match_start, match_end,)
+
+TextIter = override(TextIter)
+__all__.append('TextIter')
+
class TreeModel(Gtk.TreeModel):
def __len__(self):
return self.iter_n_children(None)
-TreeModel = override(TreeModel)
-__all__.append('TreeModel')
+ def __bool__(self):
+ return True
+
+ # alias for Python 2.x object protocol
+ __nonzero__ = __bool__
+
+ def __getitem__(self, key):
+ if isinstance(key, Gtk.TreeIter):
+ return TreeModelRow(self, key)
+ elif isinstance(key, int) and key < 0:
+ index = len(self) + key
+ if index < 0:
+ raise IndexError("row index is out of bounds: %d" % key)
+ try:
+ aiter = self.get_iter(index)
+ except ValueError:
+ raise IndexError("could not find tree path '%s'" % key)
+ return TreeModelRow(self, aiter)
+ else:
+ try:
+ aiter = self.get_iter(key)
+ except ValueError:
+ raise IndexError("could not find tree path '%s'" % key)
+ return TreeModelRow(self, aiter)
-class ListStore(Gtk.ListStore, TreeModel):
- def __init__(self, *column_types):
- Gtk.ListStore.__init__(self)
- self.set_column_types(column_types)
+ def __iter__(self):
+ return TreeModelRowIter(self, self.get_iter_first())
- def append(self, row):
- treeiter = Gtk.ListStore.append(self)
+ def get_iter(self, path):
+ if isinstance(path, Gtk.TreePath):
+ pass
+ elif isinstance(path, (int, str,)):
+ path = self._tree_path_from_string(str(path))
+ elif isinstance(path, tuple):
+ path_str = ":".join(str(val) for val in path)
+ path = self._tree_path_from_string(path_str)
+ else:
+ raise TypeError("tree path must be one of Gtk.TreeIter, Gtk.TreePath, \
+ int, str or tuple, not %s" % type(path).__name__)
+
+ success, aiter = super(TreeModel, self).get_iter(path)
+ if not success:
+ raise ValueError("invalid tree path '%s'" % path)
+ return aiter
+
+ def _tree_path_from_string(self, path):
+ if len(path) == 0:
+ raise TypeError("could not parse subscript '%s' as a tree path" % path)
+ try:
+ return TreePath.new_from_string(path)
+ except TypeError:
+ raise TypeError("could not parse subscript '%s' as a tree path" % path)
+
+ def get_iter_first(self):
+ success, aiter = super(TreeModel, self).get_iter_first()
+ if success:
+ return aiter
+
+ def get_iter_from_string(self, path_string):
+ success, aiter = super(TreeModel, self).get_iter_from_string(path_string)
+ if not success:
+ raise ValueError("invalid tree path '%s'" % path_string)
+ return aiter
+
+ def iter_next(self, aiter):
+ next_iter = aiter.copy()
+ success = super(TreeModel, self).iter_next(next_iter)
+ if success:
+ return next_iter
+
+ def iter_children(self, aiter):
+ success, child_iter = super(TreeModel, self).iter_children(aiter)
+ if success:
+ return child_iter
+
+ def iter_nth_child(self, parent, n):
+ success, child_iter = super(TreeModel, self).iter_nth_child(parent, n)
+ if success:
+ return child_iter
+
+ def iter_parent(self, aiter):
+ success, parent_iter = super(TreeModel, self).iter_parent(aiter)
+ if success:
+ return parent_iter
+
+ def set_row(self, treeiter, row):
+ # TODO: Accept a dictionary for row
+ # model.append(None,{COLUMN_ICON: icon, COLUMN_NAME: name})
n_columns = self.get_n_columns();
if len(row) != n_columns:
@@ -377,34 +654,236 @@ class ListStore(Gtk.ListStore, TreeModel):
if row[i] is not None:
self.set_value(treeiter, i, row[i])
+TreeModel = override(TreeModel)
+__all__.append('TreeModel')
+
+class TreeSortable(Gtk.TreeSortable, ):
+
+ def get_sort_column_id(self):
+ success, sort_column_id, order = super(TreeSortable, self).get_sort_column_id()
+ if success:
+ return (sort_column_id, order,)
+ else:
+ return (None, None,)
+
+TreeSortable = override(TreeSortable)
+__all__.append('TreeSortable')
+
+class ListStore(Gtk.ListStore, TreeModel, TreeSortable):
+ def __init__(self, *column_types):
+ Gtk.ListStore.__init__(self)
+ self.set_column_types(column_types)
+
+ def append(self, row=None):
+ treeiter = Gtk.ListStore.append(self)
+
+ if row is not None:
+ self.set_row(treeiter, row)
+
+ return treeiter
+
+ def insert(self, position, row=None):
+ treeiter = Gtk.ListStore.insert(self, position)
+
+ if row is not None:
+ self.set_row(treeiter, row)
+
+ return treeiter
+
+ def insert_before(self, sibling, row=None):
+ treeiter = Gtk.ListStore.insert_before(self, sibling)
+
+ if row is not None:
+ self.set_row(treeiter, row)
+
return treeiter
+
+ def insert_after(self, sibling, row=None):
+ treeiter = Gtk.ListStore.insert_after(self, sibling)
+
+ if row is not None:
+ self.set_row(treeiter, row)
+
+ return treeiter
+
+
ListStore = override(ListStore)
__all__.append('ListStore')
-class TreeStore(Gtk.TreeStore, TreeModel):
+class TreeModelRow(object):
+
+ def __init__(self, model, iter_or_path):
+ if not isinstance(model, Gtk.TreeModel):
+ raise TypeError("expected Gtk.TreeModel, %s found" % type(model).__name__)
+ self.model = model
+ if isinstance(iter_or_path, Gtk.TreePath):
+ self.iter = model.get_iter(iter_or_path)
+ elif isinstance(iter_or_path, Gtk.TreeIter):
+ self.iter = iter_or_path
+ else:
+ raise TypeError("expected Gtk.TreeIter or Gtk.TreePath, \
+ %s found" % type(iter_or_path).__name__)
+
+ @property
+ def path(self):
+ return self.model.get_path(self.iter)
+
+ @property
+ def next(self):
+ return self.get_next()
+
+ @property
+ def parent(self):
+ return self.get_parent()
+
+ def get_next(self):
+ next_iter = self.model.iter_next(self.iter)
+ if next_iter:
+ return TreeModelRow(self.model, next_iter)
+
+ def get_parent(self):
+ parent_iter = self.model.iter_parent(self.iter)
+ if parent_iter:
+ return TreeModelRow(self.model, parent_iter)
+
+ def __getitem__(self, key):
+ if isinstance(key, int):
+ if key >= self.model.get_n_columns():
+ raise IndexError("column index is out of bounds: %d" % key)
+ elif key < 0:
+ key = self._convert_negative_index(key)
+ return self.model.get_value(self.iter, key)
+ else:
+ raise TypeError("indices must be integers, not %s" % type(key).__name__)
+
+ def __setitem__(self, key, value):
+ if isinstance(key, int):
+ if key >= self.model.get_n_columns():
+ raise IndexError("column index is out of bounds: %d" % key)
+ elif key < 0:
+ key = self._convert_negative_index(key)
+ return self.model.set_value(self.iter, key, value)
+ else:
+ raise TypeError("indices must be integers, not %s" % type(key).__name__)
+
+ def _convert_negative_index(self, index):
+ new_index = self.model.get_n_columns() + index
+ if new_index < 0:
+ raise IndexError("column index is out of bounds: %d" % index)
+ return new_index
+
+ def iterchildren(self):
+ child_iter = self.model.iter_children(self.iter)
+ return TreeModelRowIter(self.model, child_iter)
+
+__all__.append('TreeModelRow')
+
+class TreeModelRowIter(object):
+
+ def __init__(self, model, aiter):
+ self.model = model
+ self.iter = aiter
+
+ def __next__(self):
+ if not self.iter:
+ raise StopIteration
+ row = TreeModelRow(self.model, self.iter)
+ self.iter = self.model.iter_next(self.iter)
+ return row
+
+ # alias for Python 2.x object protocol
+ next = __next__
+
+ def __iter__(self):
+ return self
+
+__all__.append('TreeModelRowIter')
+
+class TreePath(Gtk.TreePath):
+
+ def __str__(self):
+ return self.to_string()
+
+ def __lt__(self, other):
+ return self.compare(other) < 0
+
+ def __le__(self, other):
+ return self.compare(other) <= 0
+
+ def __eq__(self, other):
+ return self.compare(other) == 0
+
+ def __ne__(self, other):
+ return self.compare(other) != 0
+
+ def __gt__(self, other):
+ return self.compare(other) > 0
+
+ def __ge__(self, other):
+ return self.compare(other) >= 0
+
+TreePath = override(TreePath)
+__all__.append('TreePath')
+
+class TreeStore(Gtk.TreeStore, TreeModel, TreeSortable):
def __init__(self, *column_types):
Gtk.TreeStore.__init__(self)
self.set_column_types(column_types)
- def append(self, parent, row):
-
+ def append(self, parent, row=None):
treeiter = Gtk.TreeStore.append(self, parent)
- n_columns = self.get_n_columns();
- if len(row) != n_columns:
- raise ValueError('row sequence has the incorrect number of elements')
+ if row is not None:
+ self.set_row(treeiter, row)
- for i in range(n_columns):
- if row[i] is not None:
- self.set_value(treeiter, i, row[i])
+ return treeiter
+
+ def insert(self, parent, position, row=None):
+ treeiter = Gtk.TreeStore.insert(self, parent, position)
+
+ if row is not None:
+ self.set_row(treeiter, row)
return treeiter
+ def insert_before(self, parent, sibling, row=None):
+ treeiter = Gtk.TreeStore.insert_before(self, parent, sibling)
+
+ if row is not None:
+ self.set_row(treeiter, row)
+
+ return treeiter
+
+
+ def insert_after(self, parent, sibling, row=None):
+ treeiter = Gtk.TreeStore.insert_after(self, parent, sibling)
+
+ if row is not None:
+ self.set_row(treeiter, row)
+
+ return treeiter
+
+
TreeStore = override(TreeStore)
__all__.append('TreeStore')
+class TreeView(Gtk.TreeView, Container):
+
+ def get_path_at_pos(self, x, y):
+ success, path, column, cell_x, cell_y = super(TreeView, self).get_path_at_pos(x, y)
+ if success:
+ return (path, column, cell_x, cell_y,)
+
+ def get_dest_row_at_pos(self, drag_x, drag_y):
+ success, path, pos = super(TreeView, self).get_dest_row_at_pos(drag_x, drag_y)
+ if success:
+ return (path, pos,)
+
+TreeView = override(TreeView)
+__all__.append('TreeView')
+
class TreeViewColumn(Gtk.TreeViewColumn):
def __init__(self, title='',
cell_renderer=None,
@@ -416,10 +895,27 @@ class TreeViewColumn(Gtk.TreeViewColumn):
for (name, value) in attributes.items():
self.add_attribute(cell_renderer, name, value)
+ def cell_get_position(self, cell_renderer):
+ success, start_pos, width = super(TreeViewColumn, self).cell_get_position(cell_renderer)
+ if success:
+ return (start_pos, width,)
+
TreeViewColumn = override(TreeViewColumn)
__all__.append('TreeViewColumn')
-class Button(Gtk.Button):
+class TreeSelection(Gtk.TreeSelection):
+
+ def get_selected(self):
+ success, model, aiter = super(TreeSelection, self).get_selected()
+ if success:
+ return (model, aiter)
+ else:
+ return (model, None)
+
+TreeSelection = override(TreeSelection)
+__all__.append('TreeSelection')
+
+class Button(Gtk.Button, Container):
def __init__(self, label=None, stock=None, use_underline=False):
if stock:
label = stock
diff --git a/gi/overrides/Makefile.in b/gi/overrides/Makefile.in
index 630735c..d0a78be 100644
--- a/gi/overrides/Makefile.in
+++ b/gi/overrides/Makefile.in
@@ -157,6 +157,8 @@ PACKAGE_URL = @PACKAGE_URL@
PACKAGE_VERSION = @PACKAGE_VERSION@
PATH_SEPARATOR = @PATH_SEPARATOR@
PKG_CONFIG = @PKG_CONFIG@
+PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@
+PKG_CONFIG_PATH = @PKG_CONFIG_PATH@
PLATFORM = @PLATFORM@
PYCAIRO_CFLAGS = @PYCAIRO_CFLAGS@
PYCAIRO_LIBS = @PYCAIRO_LIBS@
@@ -214,7 +216,6 @@ libdir = @libdir@
libexecdir = @libexecdir@
localedir = @localedir@
localstatedir = @localstatedir@
-lt_ECHO = @lt_ECHO@
mandir = @mandir@
mkdir_p = @mkdir_p@
oldincludedir = @oldincludedir@
diff --git a/gi/overrides/__init__.py b/gi/overrides/__init__.py
index e69de29..d4cd80b 100644
--- a/gi/overrides/__init__.py
+++ b/gi/overrides/__init__.py
@@ -0,0 +1,43 @@
+import gobject
+
+registry = None
+class _Registry(dict):
+ def __setitem__(self, key, value):
+ '''We do checks here to make sure only submodules of the override
+ module are added. Key and value should be the same object and come
+ from the gi.override module.
+
+ We add the override to the dict as "override_module.name". For instance
+ if we were overriding Gtk.Button you would retrive it as such:
+ registry['Gtk.Button']
+ '''
+ if not key == value:
+ raise KeyError('You have tried to modify the registry. This should only be done by the override decorator')
+
+ info = getattr(value, '__info__')
+ if info == None:
+ raise KeyError('Can not override a type %s, which is not in a gobject introspection typelib' % value.__name__)
+
+ if not value.__module__.startswith('gi.overrides'):
+ raise KeyError('You have tried to modify the registry outside of the overrides module. This is not allowed')
+
+ g_type = info.get_g_type()
+ assert g_type != gobject.TYPE_NONE
+ if g_type != gobject.TYPE_INVALID:
+ g_type.pytype = value
+
+ # strip gi.overrides from module name
+ module = value.__module__[13:]
+ key = "%s.%s" % (module, value.__name__)
+ super(_Registry, self).__setitem__(key, value)
+
+ def register(self, override_class):
+ self[override_class] = override_class
+
+registry = _Registry()
+
+def override(type_):
+ '''Decorator for registering an override'''
+ registry.register(type_)
+ return type_
+
diff --git a/gi/pygi-argument.c b/gi/pygi-argument.c
index e3dd8c3..b768e9e 100644
--- a/gi/pygi-argument.c
+++ b/gi/pygi-argument.c
@@ -222,22 +222,17 @@ _pygi_g_type_interface_check_object (GIBaseInfo *info,
/* Handle special cases. */
type = g_registered_type_info_get_g_type ( (GIRegisteredTypeInfo *) info);
- if (g_type_is_a (type, G_TYPE_VALUE)) {
- GType object_type;
- object_type = pyg_type_from_object ( (PyObject *) object->ob_type);
- if (object_type == G_TYPE_INVALID) {
- PyErr_Format (PyExc_TypeError, "Must be of a known GType, not %s",
- object->ob_type->tp_name);
- retval = 0;
- }
- break;
- } else if (g_type_is_a (type, G_TYPE_CLOSURE)) {
+ if (g_type_is_a (type, G_TYPE_CLOSURE)) {
if (!PyCallable_Check (object)) {
PyErr_Format (PyExc_TypeError, "Must be callable, not %s",
object->ob_type->tp_name);
retval = 0;
}
break;
+ } else if (g_type_is_a (type, G_TYPE_VALUE)) {
+ /* we can't check g_values because we don't have
+ * enough context so just pass them through */
+ break;
}
/* Fallback. */
@@ -904,7 +899,7 @@ array_item_error:
GType object_type;
gint retval;
- object_type = pyg_type_from_object ( (PyObject *) object->ob_type);
+ object_type = pyg_type_from_object_strict ( (PyObject *) object->ob_type, FALSE);
if (object_type == G_TYPE_INVALID) {
PyErr_SetString (PyExc_RuntimeError, "unable to retrieve object's GType");
break;
diff --git a/gi/pygi-foreign-cairo.c b/gi/pygi-foreign-cairo.c
index 095f6cb..6326397 100644
--- a/gi/pygi-foreign-cairo.c
+++ b/gi/pygi-foreign-cairo.c
@@ -22,6 +22,7 @@
*/
#include <cairo.h>
+#include <Python.h>
#if PY_VERSION_HEX < 0x03000000
#include <pycairo.h>
@@ -111,6 +112,58 @@ cairo_surface_release (GIBaseInfo *base_info,
Py_RETURN_NONE;
}
+#ifdef PycairoRectangleInt_FromRectangleInt
+PyObject *
+cairo_rectangle_int_to_arg (PyObject *value,
+ GITypeInfo *type_info,
+ GITransfer transfer,
+ GIArgument *arg)
+{
+ cairo_rectangle_int_t *rect;
+
+ rect = ( (PycairoRectangleInt *) value)->rectangle_int;
+ if (!rect) {
+ PyErr_SetString (PyExc_ValueError, "RectangleInt instance wrapping a NULL pointer");
+ return NULL;
+ }
+
+ if (transfer == GI_TRANSFER_EVERYTHING) {
+ unsigned int size = sizeof(cairo_rectangle_int_t);
+ cairo_rectangle_int_t *transfer = malloc(size);
+ if (!transfer) {
+ PyErr_NoMemory();
+ return NULL;
+ }
+
+ memcpy(transfer, rect, size);
+ rect = transfer;
+ }
+
+ arg->v_pointer = rect;
+ Py_RETURN_NONE;
+}
+
+PyObject *
+cairo_rectangle_int_from_arg (GITypeInfo *type_info, GIArgument *arg)
+{
+ cairo_rectangle_int_t *rect = (cairo_rectangle_int_t*) arg;
+
+ if (rect)
+ return PycairoRectangleInt_FromRectangleInt (rect);
+ else {
+ cairo_rectangle_int_t temp = {};
+ return PycairoRectangleInt_FromRectangleInt (&temp);
+ }
+}
+
+PyObject *
+cairo_rectangle_int_release (GIBaseInfo *base_info,
+ gpointer struct_)
+{
+ g_free (struct_);
+ Py_RETURN_NONE;
+}
+#endif
static PyMethodDef _gi_cairo_functions[] = {};
PYGLIB_MODULE_START(_gi_cairo, "_gi_cairo")
@@ -130,5 +183,14 @@ PYGLIB_MODULE_START(_gi_cairo, "_gi_cairo")
cairo_surface_to_arg,
cairo_surface_from_arg,
cairo_surface_release);
+
+#ifdef PycairoRectangleInt_FromRectangleInt
+ pygi_register_foreign_struct ("cairo",
+ "RectangleInt",
+ cairo_rectangle_int_to_arg,
+ cairo_rectangle_int_from_arg,
+ cairo_rectangle_int_release);
+#endif
+
}
PYGLIB_MODULE_END;
diff --git a/gi/pygi-foreign.c b/gi/pygi-foreign.c
index f80b43c..75d5bb9 100644
--- a/gi/pygi-foreign.c
+++ b/gi/pygi-foreign.c
@@ -22,10 +22,13 @@
* IN THE SOFTWARE.
*/
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
#include "pygi-foreign.h"
#include "pygi-foreign-gvariant.h"
-#include <config.h>
#include <girepository.h>
typedef struct {
diff --git a/gi/pygi-info.c b/gi/pygi-info.c
index feeccf7..33f71c1 100644
--- a/gi/pygi-info.c
+++ b/gi/pygi-info.c
@@ -57,6 +57,34 @@ _base_info_repr (PyGIBaseInfo *self)
(void *) self);
}
+static PyObject *
+_base_info_richcompare (PyGIBaseInfo *self, PyObject *other, int op)
+{
+ PyObject *res;
+ GIBaseInfo *other_info;
+
+ if (!PyObject_TypeCheck(other, &PyGIBaseInfo_Type)) {
+ Py_INCREF(Py_NotImplemented);
+ return Py_NotImplemented;
+ }
+
+ other_info = ((PyGIBaseInfo *)other)->info;
+
+ switch (op) {
+ case Py_EQ:
+ res = g_base_info_equal (self->info, other_info) ? Py_True : Py_False;
+ break;
+ case Py_NE:
+ res = g_base_info_equal (self->info, other_info) ? Py_False : Py_True;
+ break;
+ default:
+ res = Py_NotImplemented;
+ break;
+ }
+ Py_INCREF(res);
+ return res;
+}
+
static PyMethodDef _PyGIBaseInfo_methods[];
PYGLIB_DEFINE_TYPE("gi.BaseInfo", PyGIBaseInfo_Type, PyGIBaseInfo);
@@ -113,14 +141,14 @@ _pygi_info_new (GIBaseInfo *info)
type = &PyGIFunctionInfo_Type;
break;
case GI_INFO_TYPE_CALLBACK:
- PyErr_SetString (PyExc_NotImplementedError, "GICallbackInfo bindings not implemented");
- return NULL;
+ type = &PyGICallbackInfo_Type;
+ break;
case GI_INFO_TYPE_STRUCT:
type = &PyGIStructInfo_Type;
break;
case GI_INFO_TYPE_BOXED:
- PyErr_SetString (PyExc_NotImplementedError, "GIBoxedInfo bindings not implemented");
- return NULL;
+ type = &PyGIBoxedInfo_Type;
+ break;
case GI_INFO_TYPE_ENUM:
case GI_INFO_TYPE_FLAGS:
type = &PyGIEnumInfo_Type;
@@ -135,8 +163,8 @@ _pygi_info_new (GIBaseInfo *info)
type = &PyGIConstantInfo_Type;
break;
case GI_INFO_TYPE_ERROR_DOMAIN:
- PyErr_SetString (PyExc_NotImplementedError, "GIErrorDomainInfo bindings not implemented");
- return NULL;
+ type = &PyGIErrorDomainInfo_Type;
+ break;
case GI_INFO_TYPE_UNION:
type = &PyGIUnionInfo_Type;
break;
@@ -144,23 +172,23 @@ _pygi_info_new (GIBaseInfo *info)
type = &PyGIValueInfo_Type;
break;
case GI_INFO_TYPE_SIGNAL:
- PyErr_SetString (PyExc_NotImplementedError, "GISignalInfo bindings not implemented");
- return NULL;
+ type = &PyGISignalInfo_Type;
+ break;
case GI_INFO_TYPE_VFUNC:
type = &PyGIVFuncInfo_Type;
break;
case GI_INFO_TYPE_PROPERTY:
- PyErr_SetString (PyExc_NotImplementedError, "GIPropertyInfo bindings not implemented");
- return NULL;
+ type = &PyGIPropertyInfo_Type;
+ break;
case GI_INFO_TYPE_FIELD:
type = &PyGIFieldInfo_Type;
break;
case GI_INFO_TYPE_ARG:
- PyErr_SetString (PyExc_NotImplementedError, "GIArgInfo bindings not implemented");
- return NULL;
+ type = &PyGIArgInfo_Type;
+ break;
case GI_INFO_TYPE_TYPE:
- PyErr_SetString (PyExc_NotImplementedError, "GITypeInfo bindings not implemented");
- return NULL;
+ type = &PyGITypeInfo_Type;
+ break;
case GI_INFO_TYPE_UNRESOLVED:
type = &PyGIUnresolvedInfo_Type;
break;
@@ -210,6 +238,55 @@ static PyMethodDef _PyGICallableInfo_methods[] = {
{ NULL, NULL, 0 }
};
+/* CallbackInfo */
+PYGLIB_DEFINE_TYPE ("gi.CallbackInfo", PyGICallbackInfo_Type, PyGIBaseInfo);
+
+static PyMethodDef _PyGICallbackInfo_methods[] = {
+ { NULL, NULL, 0 }
+};
+
+/* BoxedInfo */
+PYGLIB_DEFINE_TYPE ("gi.BoxedInfo", PyGIBoxedInfo_Type, PyGIBaseInfo);
+
+static PyMethodDef _PyGIBoxedInfo_methods[] = {
+ { NULL, NULL, 0 }
+};
+
+/* ErrorDomainInfo */
+PYGLIB_DEFINE_TYPE ("gi.ErrorDomainInfo", PyGIErrorDomainInfo_Type, PyGIBaseInfo);
+
+static PyMethodDef _PyGIErrorDomainInfo_methods[] = {
+ { NULL, NULL, 0 }
+};
+
+/* SignalInfo */
+PYGLIB_DEFINE_TYPE ("gi.SignalInfo", PyGISignalInfo_Type, PyGIBaseInfo);
+
+static PyMethodDef _PyGISignalInfo_methods[] = {
+ { NULL, NULL, 0 }
+};
+
+/* PropertyInfo */
+PYGLIB_DEFINE_TYPE ("gi.PropertyInfo", PyGIPropertyInfo_Type, PyGIBaseInfo);
+
+static PyMethodDef _PyGIPropertyInfo_methods[] = {
+ { NULL, NULL, 0 }
+};
+
+/* ArgInfo */
+PYGLIB_DEFINE_TYPE ("gi.ArgInfo", PyGIArgInfo_Type, PyGIBaseInfo);
+
+static PyMethodDef _PyGIArgInfo_methods[] = {
+ { NULL, NULL, 0 }
+};
+
+/* TypeInfo */
+PYGLIB_DEFINE_TYPE ("gi.TypeInfo", PyGITypeInfo_Type, PyGIBaseInfo);
+
+static PyMethodDef _PyGITypeInfo_methods[] = {
+ { NULL, NULL, 0 }
+};
+
/* FunctionInfo */
PYGLIB_DEFINE_TYPE ("gi.FunctionInfo", PyGIFunctionInfo_Type, PyGIBaseInfo);
@@ -1276,7 +1353,23 @@ static PyMethodDef _PyGIUnresolvedInfo_methods[] = {
/* GIVFuncInfo */
PYGLIB_DEFINE_TYPE ("gi.VFuncInfo", PyGIVFuncInfo_Type, PyGIBaseInfo);
+static PyObject *
+_wrap_g_vfunc_info_get_invoker (PyGIBaseInfo *self)
+{
+ PyObject *result = Py_None;
+ GIBaseInfo *info;
+
+ info = (GIBaseInfo *) g_vfunc_info_get_invoker ( (GIVFuncInfo *) self->info );
+ if (info)
+ result = _pygi_info_new(info);
+ else
+ Py_INCREF(Py_None);
+
+ return result;
+}
+
static PyMethodDef _PyGIVFuncInfo_methods[] = {
+ { "get_invoker", (PyCFunction) _wrap_g_vfunc_info_get_invoker, METH_NOARGS },
{ NULL, NULL, 0 }
};
@@ -1413,6 +1506,7 @@ _pygi_info_register_types (PyObject *m)
PyGIBaseInfo_Type.tp_traverse = (traverseproc) _base_info_traverse;
PyGIBaseInfo_Type.tp_weaklistoffset = offsetof(PyGIBaseInfo, inst_weakreflist);
PyGIBaseInfo_Type.tp_methods = _PyGIBaseInfo_methods;
+ PyGIBaseInfo_Type.tp_richcompare = (richcmpfunc)_base_info_richcompare;
if (PyType_Ready(&PyGIBaseInfo_Type))
return;
@@ -1424,6 +1518,8 @@ _pygi_info_register_types (PyObject *m)
PyGIBaseInfo_Type);
_PyGI_REGISTER_TYPE (m, PyGICallableInfo_Type, CallableInfo,
PyGIBaseInfo_Type);
+ _PyGI_REGISTER_TYPE (m, PyGICallbackInfo_Type, CallbackInfo,
+ PyGIBaseInfo_Type);
_PyGI_REGISTER_TYPE (m, PyGIFunctionInfo_Type, FunctionInfo,
PyGICallableInfo_Type);
_PyGI_REGISTER_TYPE (m, PyGIRegisteredTypeInfo_Type, RegisteredTypeInfo,
@@ -1446,6 +1542,18 @@ _pygi_info_register_types (PyObject *m)
PyGIBaseInfo_Type);
_PyGI_REGISTER_TYPE (m, PyGIUnionInfo_Type, UnionInfo,
PyGIRegisteredTypeInfo_Type);
+ _PyGI_REGISTER_TYPE (m, PyGIBoxedInfo_Type, BoxedInfo,
+ PyGIBaseInfo_Type);
+ _PyGI_REGISTER_TYPE (m, PyGIErrorDomainInfo_Type, ErrorDomainInfo,
+ PyGIBaseInfo_Type);
+ _PyGI_REGISTER_TYPE (m, PyGISignalInfo_Type, SignalInfo,
+ PyGIBaseInfo_Type);
+ _PyGI_REGISTER_TYPE (m, PyGIPropertyInfo_Type, PropertyInfo,
+ PyGIBaseInfo_Type);
+ _PyGI_REGISTER_TYPE (m, PyGIArgInfo_Type, ArgInfo,
+ PyGIBaseInfo_Type);
+ _PyGI_REGISTER_TYPE (m, PyGITypeInfo_Type, TypeInfo,
+ PyGIBaseInfo_Type);
#undef _PyGI_REGISTER_TYPE
diff --git a/gi/pygi-info.h b/gi/pygi-info.h
index 0d2bade..afd65dc 100644
--- a/gi/pygi-info.h
+++ b/gi/pygi-info.h
@@ -35,6 +35,7 @@ gboolean pygi_g_struct_info_is_simple (GIStructInfo *struct_info);
extern PyTypeObject PyGIBaseInfo_Type;
extern PyTypeObject PyGICallableInfo_Type;
+extern PyTypeObject PyGICallbackInfo_Type;
extern PyTypeObject PyGIFunctionInfo_Type;
extern PyTypeObject PyGIRegisteredTypeInfo_Type;
extern PyTypeObject PyGIStructInfo_Type;
@@ -47,6 +48,12 @@ extern PyTypeObject PyGIFieldInfo_Type;
extern PyTypeObject PyGIUnresolvedInfo_Type;
extern PyTypeObject PyGIVFuncInfo_Type;
extern PyTypeObject PyGIUnionInfo_Type;
+extern PyTypeObject PyGIBoxedInfo_Type;
+extern PyTypeObject PyGIErrorDomainInfo_Type;
+extern PyTypeObject PyGISignalInfo_Type;
+extern PyTypeObject PyGIPropertyInfo_Type;
+extern PyTypeObject PyGIArgInfo_Type;
+extern PyTypeObject PyGITypeInfo_Type;
#define PyGIBaseInfo_GET_GI_INFO(object) g_base_info_ref(((PyGIBaseInfo *)object)->info)
diff --git a/gi/pygi-invoke.c b/gi/pygi-invoke.c
index 64b3f31..71d5859 100644
--- a/gi/pygi-invoke.c
+++ b/gi/pygi-invoke.c
@@ -343,9 +343,20 @@ _prepare_invocation_state (struct invocation_state *state,
/* if caller allocates only use one level of indirection */
state->out_args[out_args_pos].v_pointer = NULL;
state->args[i] = &state->out_args[out_args_pos];
- if (g_type_is_a (g_registered_type_info_get_g_type (info), G_TYPE_BOXED))
+ if (g_type_is_a (g_registered_type_info_get_g_type (info), G_TYPE_BOXED)) {
state->args[i]->v_pointer = _pygi_boxed_alloc (info, NULL);
- else {
+ } else if (g_struct_info_is_foreign((GIStructInfo *) info) ) {
+ PyObject *foreign_struct =
+ pygi_struct_foreign_convert_from_g_argument(state->arg_type_infos[i], NULL);
+
+ pygi_struct_foreign_convert_to_g_argument(
+ foreign_struct,
+ state->arg_type_infos[i],
+ GI_TRANSFER_EVERYTHING,
+ state->args[i]);
+
+ Py_DECREF(foreign_struct);
+ } else {
gssize size = g_struct_info_get_size ( (GIStructInfo *) info);
state->args[i]->v_pointer = g_malloc0 (size);
}
@@ -548,8 +559,16 @@ _invoke_function (struct invocation_state *state,
error = NULL;
+ pyg_begin_allow_threads;
retval = g_function_info_invoke ( (GIFunctionInfo *) function_info,
- state->in_args, state->n_in_args, state->out_args, state->n_out_args, &state->return_arg, &error);
+ state->in_args,
+ state->n_in_args,
+ state->out_args,
+ state->n_out_args,
+ &state->return_arg,
+ &error);
+ pyg_end_allow_threads;
+
if (!retval) {
g_assert (error != NULL);
/* TODO: raise the right error, out of the error domain. */
diff --git a/gi/pygi.h b/gi/pygi.h
index d1eaf05..03f71a4 100644
--- a/gi/pygi.h
+++ b/gi/pygi.h
@@ -22,8 +22,11 @@
#ifndef __PYGI_H__
#define __PYGI_H__
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
#define NO_IMPORT_PYGOBJECT
-#include <config.h>
#include <pygobject.h>
#if ENABLE_INTROSPECTION
@@ -83,8 +86,11 @@ _pygi_import (void)
if (PyGI_API != NULL) {
return 1;
}
-
+#if PY_VERSION_HEX >= 0x03000000
+ PyGI_API = (struct PyGI_API*) PyCapsule_Import("gi._API", FALSE);
+#else
PyGI_API = (struct PyGI_API*) PyCObject_Import("gi", "_API");
+#endif
if (PyGI_API == NULL) {
return -1;
}
@@ -152,7 +158,7 @@ static inline PyObject *
pygi_get_property_value (PyGObject *instance,
const gchar *attr_name)
{
- return -1;
+ return NULL;
}
static inline gint
diff --git a/gi/repository/Makefile.in b/gi/repository/Makefile.in
index 7b36c15..7f0ef44 100644
--- a/gi/repository/Makefile.in
+++ b/gi/repository/Makefile.in
@@ -157,6 +157,8 @@ PACKAGE_URL = @PACKAGE_URL@
PACKAGE_VERSION = @PACKAGE_VERSION@
PATH_SEPARATOR = @PATH_SEPARATOR@
PKG_CONFIG = @PKG_CONFIG@
+PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@
+PKG_CONFIG_PATH = @PKG_CONFIG_PATH@
PLATFORM = @PLATFORM@
PYCAIRO_CFLAGS = @PYCAIRO_CFLAGS@
PYCAIRO_LIBS = @PYCAIRO_LIBS@
@@ -214,7 +216,6 @@ libdir = @libdir@
libexecdir = @libexecdir@
localedir = @localedir@
localstatedir = @localstatedir@
-lt_ECHO = @lt_ECHO@
mandir = @mandir@
mkdir_p = @mkdir_p@
oldincludedir = @oldincludedir@
diff --git a/gi/types.py b/gi/types.py
index 0a8768c..18b4013 100644
--- a/gi/types.py
+++ b/gi/types.py
@@ -100,7 +100,7 @@ class MetaClassHelper(object):
for vfunc_info in base.__info__.get_vfuncs():
vfunc = getattr(cls, 'do_' + vfunc_info.get_name(), None)
if vfunc is None and isinstance(base.__info__, InterfaceInfo) and \
- not hasattr(cls, vfunc_info.get_name()):
+ (not hasattr(cls, vfunc_info.get_name()) and not vfunc_info.get_invoker()):
raise TypeError('Class implementing %s.%s should implement '
'the method do_%s()' % (base.__info__.get_namespace(),
base.__info__.get_name(),
@@ -162,14 +162,6 @@ class StructMeta(type, MetaClassHelper):
cls._setup_methods()
cls._setup_constructors()
-
-def override(type_):
- g_type = type_.__info__.get_g_type()
- assert g_type != gobject.TYPE_NONE
- if g_type != gobject.TYPE_INVALID:
- g_type.pytype = type_
- return type_
-
class Enum(int):
__info__ = None
def __init__(self, value):