summaryrefslogtreecommitdiffstats
path: root/gi
diff options
context:
space:
mode:
authorSimon van der Linden <svdlinden@src.gnome.org>2010-01-22 13:41:21 +0100
committerSimon van der Linden <svdlinden@src.gnome.org>2010-01-22 13:41:21 +0100
commiteaf7cb8ebb7e34f9493ac83b2f04af4dcf45f40f (patch)
tree92c184f82369ffc181701450fe4045ac0cef2ef3 /gi
parentb11cf2595987c1f0fc4ffd834f07c98b92aa2355 (diff)
downloadpygi-eaf7cb8ebb7e34f9493ac83b2f04af4dcf45f40f.tar.gz
pygi-eaf7cb8ebb7e34f9493ac83b2f04af4dcf45f40f.tar.xz
pygi-eaf7cb8ebb7e34f9493ac83b2f04af4dcf45f40f.zip
Restore the overrides support
Add a ModuleProxy in front of the DynamicModule when an overrides module is present. There is no need for an overrides module to be a class; it can just be a module. Add an override decorator to override the wrapper of a registered type. Adapt Gdk and Gtk accordingly. Add tests. https://bugzilla.gnome.org/show_bug.cgi?id=602830
Diffstat (limited to 'gi')
-rw-r--r--gi/importer.py40
-rw-r--r--gi/module.py43
-rw-r--r--gi/overrides/Gdk.py42
-rw-r--r--gi/overrides/Gtk.py16
-rw-r--r--gi/types.py6
5 files changed, 83 insertions, 64 deletions
diff --git a/gi/importer.py b/gi/importer.py
index f283a41..ad9ede2 100644
--- a/gi/importer.py
+++ b/gi/importer.py
@@ -26,10 +26,11 @@ import sys
import gobject
from ._gi import Repository, RepositoryError
-from .module import DynamicModule
+from .module import DynamicModule, ModuleProxy
repository = Repository.get_default()
+modules = {}
class DynamicImporter(object):
@@ -39,17 +40,6 @@ class DynamicImporter(object):
def __init__(self, path):
self.path = path
- def _create_module(self, module_type, name, namespace):
- module = module_type.__new__(module_type)
- module.__dict__ = {
- '__file__': '<%s>' % name,
- '__name__': name,
- '__namespace__': namespace,
- '__loader__': self
- }
- module.__init__()
- return module
-
def find_module(self, fullname, path=None):
if not fullname.startswith(self.path):
return
@@ -75,23 +65,21 @@ class DynamicImporter(object):
sys.modules[fullname] = gobject
return gobject
- module_type = DynamicModule
- module = self._create_module(module_type, fullname, namespace)
- sys.modules[fullname] = module
+ dynamic_module = DynamicModule(namespace)
+ modules[namespace] = dynamic_module
- # Look for an overrides module
- overrides_name = 'gi.overrides.%s' % namespace
- overrides_type_name = '%sModule' % namespace
- try:
+ overrides_modules = __import__('gi.overrides', fromlist=[namespace])
+ overrides_module = getattr(overrides_modules, namespace, None)
- overrides_module = __import__(overrides_name, fromlist=[overrides_type_name])
- module_type = getattr(overrides_module, overrides_type_name)
- except ImportError, e:
- pass
+ if overrides_module is not None:
+ module = ModuleProxy(fullname, namespace, dynamic_module, overrides_module)
+ else:
+ module = dynamic_module
- if module_type is not DynamicModule:
- module = self._create_module(module_type, fullname, namespace)
- sys.modules[fullname] = module
+ module.__file__ = '<%s>' % fullname
+ module.__loader__ = self
+
+ sys.modules[fullname] = module
return module
diff --git a/gi/module.py b/gi/module.py
index 72a6a53..61fbdfc 100644
--- a/gi/module.py
+++ b/gi/module.py
@@ -75,15 +75,11 @@ def get_interfaces_for_object(object_info):
class DynamicModule(object):
- def __str__(self):
- path = repository.get_typelib_path(self.__namespace__)
- return "<dynamic module %r from %r>" % (self.__name__, path)
+ def __init__(self, namespace):
+ self._namespace = namespace
def __getattr__(self, name):
- if self.__dict__.has_key(name):
- return self.__dict__[name]
-
- info = repository.find_by_name(self.__namespace__, name)
+ info = repository.find_by_name(self._namespace, name)
if not info:
raise AttributeError("%r object has no attribute %r" % (
self.__class__.__name__, name))
@@ -139,7 +135,7 @@ class DynamicModule(object):
name = info.get_name()
dict_ = {
'__info__': info,
- '__module__': self.__namespace__,
+ '__module__': self._namespace,
'__gtype__': g_type
}
value = metaclass(name, bases, dict_)
@@ -158,10 +154,29 @@ class DynamicModule(object):
self.__dict__[name] = value
return value
- @property
- def __members__(self):
- r = []
- for type_info in repository.get_infos(self.__namespace__):
- r.append(type_info.get_name())
- return r
+ def __repr__(self):
+ path = repository.get_typelib_path(self._namespace)
+ return "<DynamicModule %r from %r>" % (self._namespace, path)
+
+
+class ModuleProxy(object):
+
+ def __init__(self, name, namespace, dynamic_module, overrides_module):
+ self.__name__ = name
+
+ self._namespace = namespace
+ self._dynamic_module = dynamic_module
+ self._overrides_module = overrides_module
+
+ def __getattr__(self, name):
+ attribute = getattr(self._overrides_module, name, None)
+ exports = getattr(self._overrides_module, '__all__', ())
+ if attribute is not None and attribute not in exports:
+ attribute = None
+ if attribute is None:
+ attribute = getattr(self._dynamic_module, name)
+ return attribute
+
+ def __str__(self):
+ return "<ModuleProxy %r>" % self.__name__
diff --git a/gi/overrides/Gdk.py b/gi/overrides/Gdk.py
index e3e2d29..2662046 100644
--- a/gi/overrides/Gdk.py
+++ b/gi/overrides/Gdk.py
@@ -1,21 +1,33 @@
-import sys
+from ..types import override
+from ..importer import modules
+
+Gdk = modules['Gdk']
+
+
+class Rectangle(Gdk.Rectangle):
-from ..module import DynamicModule
+ def __init__(self, x, y, width, height):
+ Gdk.Rectangle.__init__(self)
+ self.x = x
+ self.y = y
+ self.width = width
+ self.height = height
-class GdkModule(DynamicModule):
+ def __new__(cls, *args, **kwargs):
+ return Gdk.Rectangle.__new__(cls)
- def __init__(self):
- super(GdkModule, self).__init__()
+ def __repr__(self):
+ return '<Gdk.Rectangle(x=%d, y=%d, width=%d, height=%d)>' % (
+ self.x, self.y, self.width, self.height)
- initialized, argv = self.init_check(tuple(sys.argv))
- if not initialized:
- raise RuntimeError("Gdk couldn't be initialized")
+Rectangle = override(Rectangle)
- def rectangle_new(self, x, y, width, height):
- rectangle = self.Rectangle()
- rectangle.x = x
- rectangle.y = y
- rectangle.width = width
- rectangle.height = height
- return rectangle
+__all__ = [Rectangle]
+
+
+import sys
+
+initialized, argv = Gdk.init_check(sys.argv)
+if not initialized:
+ raise RuntimeError("Gdk couldn't be initialized")
diff --git a/gi/overrides/Gtk.py b/gi/overrides/Gtk.py
index b4e9596..0f5d46a 100644
--- a/gi/overrides/Gtk.py
+++ b/gi/overrides/Gtk.py
@@ -1,15 +1,13 @@
-import sys
+from ..importer import modules
-from ..module import DynamicModule
+Gtk = modules['Gtk']
-class GtkModule(DynamicModule):
- import keysyms
+__all__ = []
- def __init__(self):
- super(GtkModule, self).__init__()
- initialized, argv = self.init_check(tuple(sys.argv))
- if not initialized:
- raise RuntimeError("Gtk couldn't be initialized")
+import sys
+initialized, argv = Gtk.init_check(sys.argv)
+if not initialized:
+ raise RuntimeError("Gtk couldn't be initialized")
diff --git a/gi/types.py b/gi/types.py
index e4d7c5f..b7061bd 100644
--- a/gi/types.py
+++ b/gi/types.py
@@ -126,3 +126,9 @@ class StructMeta(type, MetaClassHelper):
cls._setup_methods()
cls._setup_constructors()
+
+def override(type_):
+ g_type = type_.__info__.get_g_type()
+ if g_type != gobject.TYPE_INVALID:
+ g_type.pytype = type_
+ return type_