diff options
author | Simon van der Linden <svdlinden@src.gnome.org> | 2010-01-22 13:41:21 +0100 |
---|---|---|
committer | Simon van der Linden <svdlinden@src.gnome.org> | 2010-01-22 13:41:21 +0100 |
commit | eaf7cb8ebb7e34f9493ac83b2f04af4dcf45f40f (patch) | |
tree | 92c184f82369ffc181701450fe4045ac0cef2ef3 /gi | |
parent | b11cf2595987c1f0fc4ffd834f07c98b92aa2355 (diff) | |
download | pygi-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.py | 40 | ||||
-rw-r--r-- | gi/module.py | 43 | ||||
-rw-r--r-- | gi/overrides/Gdk.py | 42 | ||||
-rw-r--r-- | gi/overrides/Gtk.py | 16 | ||||
-rw-r--r-- | gi/types.py | 6 |
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_ |