[pygobject] [API add] Add get_introspection_module for getting un-overridden modules
- From: Simon Feltman <sfeltman src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [pygobject] [API add] Add get_introspection_module for getting un-overridden modules
- Date: Thu, 25 Oct 2012 07:45:27 +0000 (UTC)
commit e9624ed1d38c777de2b430e3b0fbae2acbf34956
Author: Simon Feltman <sfeltman src gnome org>
Date: Wed Oct 24 04:31:26 2012 -0700
[API add] Add get_introspection_module for getting un-overridden modules
Add gi.module.get_introspection_module to explicitly get a
wrapped module pulled in through introspection without static
and python override handling. This API is intended for python
overrides to use rather than having them access
gi.importer.modules['<name>']._introspection_module directly.
Replace aforementioned usage in all overrides.
https://bugzilla.gnome.org/show_bug.cgi?id=686828
gi/module.py | 38 +++++++++++++++++++++++++++++++++--
gi/overrides/GIMarshallingTests.py | 4 +-
gi/overrides/GLib.py | 4 +-
gi/overrides/Gdk.py | 6 ++--
gi/overrides/Gio.py | 4 +-
gi/overrides/Gtk.py | 5 ++-
gi/overrides/Pango.py | 4 +-
tests/test_overrides.py | 29 +++++++++++++++++++++++++++
8 files changed, 78 insertions(+), 16 deletions(-)
---
diff --git a/gi/module.py b/gi/module.py
index e115fc7..7e1ae0f 100644
--- a/gi/module.py
+++ b/gi/module.py
@@ -62,6 +62,9 @@ from .types import \
repository = Repository.get_default()
+# Cache of IntrospectionModules that have been loaded.
+_introspection_modules = {}
+
def get_parent_for_object(object_info):
parent_object_info = object_info.get_parent()
@@ -92,7 +95,13 @@ def get_interfaces_for_object(object_info):
class IntrospectionModule(object):
+ """An object which wraps an introspection typelib.
+ This wrapping creates a python module like representation of the typelib
+ using gi repository as a foundation. Accessing attributes of the module
+ will dynamically pull them in and create wrappers for the members.
+ These members are then cached on this introspection module.
+ """
def __init__(self, namespace, version=None):
repository.require(namespace, version)
self._namespace = namespace
@@ -203,6 +212,9 @@ class IntrospectionModule(object):
else:
raise NotImplementedError(info)
+ # Cache the newly created attribute wrapper which will then be
+ # available directly on this introspection module instead of being
+ # retrieved through the __getattr__ we are currently in.
self.__dict__[name] = wrapper
return wrapper
@@ -229,7 +241,29 @@ class IntrospectionModule(object):
return list(result)
+def get_introspection_module(namespace):
+ """
+ :Returns:
+ An object directly wrapping the gi module without overrides.
+ """
+ if namespace in _introspection_modules:
+ return _introspection_modules[namespace]
+
+ version = gi.get_required_version(namespace)
+ module = IntrospectionModule(namespace, version)
+ _introspection_modules[namespace] = module
+ return module
+
+
class DynamicModule(types.ModuleType):
+ """A module composed of an IntrospectionModule and an overrides module.
+
+ DynamicModule wraps up an IntrospectionModule and an overrides module
+ into a single accessible module. This is what is returned from statements
+ like "from gi.repository import Foo". Accessing attributes on a DynamicModule
+ will first look overrides (or the gi.overrides.registry cache) and then
+ in the introspection module if it was not found as an override.
+ """
def __init__(self, namespace):
self._namespace = namespace
self._introspection_module = None
@@ -237,9 +271,7 @@ class DynamicModule(types.ModuleType):
self.__path__ = None
def _load(self):
- version = gi.get_required_version(self._namespace)
- self._introspection_module = IntrospectionModule(self._namespace,
- version)
+ self._introspection_module = get_introspection_module(self._namespace)
try:
overrides_modules = __import__('gi.overrides', fromlist=[self._namespace])
self._overrides_module = getattr(overrides_modules, self._namespace, None)
diff --git a/gi/overrides/GIMarshallingTests.py b/gi/overrides/GIMarshallingTests.py
index a25eda7..af2529a 100644
--- a/gi/overrides/GIMarshallingTests.py
+++ b/gi/overrides/GIMarshallingTests.py
@@ -19,9 +19,9 @@
# USA
from ..overrides import override
-from ..importer import modules
+from ..module import get_introspection_module
-GIMarshallingTests = modules['GIMarshallingTests']._introspection_module
+GIMarshallingTests = get_introspection_module('GIMarshallingTests')
__all__ = []
diff --git a/gi/overrides/GLib.py b/gi/overrides/GLib.py
index b4d74be..22de6bf 100644
--- a/gi/overrides/GLib.py
+++ b/gi/overrides/GLib.py
@@ -21,11 +21,11 @@
import signal
-from ..importer import modules
+from ..module import get_introspection_module
from .._gi import variant_new_tuple, variant_type_from_string, source_new, source_set_callback
from ..overrides import override, deprecated
-GLib = modules['GLib']._introspection_module
+GLib = get_introspection_module('GLib')
__all__ = []
diff --git a/gi/overrides/Gdk.py b/gi/overrides/Gdk.py
index 20ef910..653b3df 100644
--- a/gi/overrides/Gdk.py
+++ b/gi/overrides/Gdk.py
@@ -20,11 +20,11 @@
# USA
from ..overrides import override
-from ..importer import modules
+from ..module import get_introspection_module
import sys
-Gdk = modules['Gdk']._introspection_module
+Gdk = get_introspection_module('Gdk')
__all__ = []
@@ -287,7 +287,7 @@ for event_class in event_member_classes:
class DragContext(Gdk.DragContext):
def finish(self, success, del_, time):
- Gtk = modules['Gtk']._introspection_module
+ Gtk = get_introspection_module('Gtk')
Gtk.drag_finish(self, success, del_, time)
DragContext = override(DragContext)
diff --git a/gi/overrides/Gio.py b/gi/overrides/Gio.py
index 9f96440..6ecd1c4 100644
--- a/gi/overrides/Gio.py
+++ b/gi/overrides/Gio.py
@@ -19,13 +19,13 @@
# USA
from ..overrides import override
-from ..importer import modules
+from ..module import get_introspection_module
from gi.repository import GLib
import sys
-Gio = modules['Gio']._introspection_module
+Gio = get_introspection_module('Gio')
__all__ = []
diff --git a/gi/overrides/Gtk.py b/gi/overrides/Gtk.py
index 5eab41b..1856a4a 100644
--- a/gi/overrides/Gtk.py
+++ b/gi/overrides/Gtk.py
@@ -22,7 +22,7 @@
import sys
from gi.repository import GObject
from ..overrides import override
-from ..importer import modules
+from ..module import get_introspection_module
if sys.version_info >= (3, 0):
_basestring = str
@@ -31,7 +31,8 @@ else:
_basestring = basestring
_callable = callable
-Gtk = modules['Gtk']._introspection_module
+Gtk = get_introspection_module('Gtk')
+
__all__ = []
if Gtk._version == '2.0':
diff --git a/gi/overrides/Pango.py b/gi/overrides/Pango.py
index 34c76cc..15d5edc 100644
--- a/gi/overrides/Pango.py
+++ b/gi/overrides/Pango.py
@@ -19,9 +19,9 @@
# USA
from ..overrides import override
-from ..importer import modules
+from ..module import get_introspection_module
-Pango = modules['Pango']._introspection_module
+Pango = get_introspection_module('Pango')
__all__ = []
diff --git a/tests/test_overrides.py b/tests/test_overrides.py
index dd2aa6a..e1af1f1 100644
--- a/tests/test_overrides.py
+++ b/tests/test_overrides.py
@@ -4,6 +4,8 @@
import unittest
import gi.overrides
+import gi.module
+
try:
from gi.repository import Regress
Regress # pyflakes
@@ -27,3 +29,30 @@ class TestRegistry(unittest.TestCase):
# Regress override is in tests/gi/overrides, separate from gi/overrides
# https://bugzilla.gnome.org/show_bug.cgi?id=680913
self.assertEqual(Regress.REGRESS_OVERRIDE, 42)
+
+
+class TestModule(unittest.TestCase):
+ # Tests for gi.module
+
+ def test_get_introspection_module_caching(self):
+ # This test attempts to minimize side effects by
+ # using a DynamicModule directly instead of going though:
+ # from gi.repository import Foo
+
+ # Clear out introspection module cache before running this test.
+ old_modules = gi.module._introspection_modules
+ gi.module._introspection_modules = {}
+
+ mod_name = 'GIMarshallingTests'
+ mod1 = gi.module.get_introspection_module(mod_name)
+ mod2 = gi.module.get_introspection_module(mod_name)
+ self.assertTrue(mod1 is mod2)
+
+ # Using a DynamicModule will use get_introspection_module internally
+ # in its _load method.
+ mod_overridden = gi.module.DynamicModule(mod_name)
+ mod_overridden._load()
+ self.assertTrue(mod1 is mod_overridden._introspection_module)
+
+ # Restore the previous cache
+ gi.module._introspection_modules = old_modules
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]