[pygobject] Allow specifying a version when loading a typelib
- From: Tomeu Vizoso <tomeuv src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [pygobject] Allow specifying a version when loading a typelib
- Date: Tue, 27 Jul 2010 16:29:38 +0000 (UTC)
commit 2082ee35e2a33f52bf1e8ec49cb4a43398e91989
Author: Tomeu Vizoso <tomeu vizoso collabora co uk>
Date: Tue Jul 27 18:25:27 2010 +0200
Allow specifying a version when loading a typelib
* gi/importer.py: Defer loading the typelib until first usage.
* gi/module.py: Load the typelib in IntrospectionModule().
* gi/overrides/*.py: Adapt to API change.
* gi/pygi-repository.c: Add wrappers for g_irepository_enumerate and
g_irepository_get_version.
gi/importer.py | 26 +++++----------
gi/module.py | 58 +++++++++++++++++++++++------------
gi/overrides/GIMarshallingTests.py | 2 +-
gi/overrides/Gdk.py | 2 +-
gi/overrides/Gtk.py | 2 +-
gi/pygi-repository.c | 56 ++++++++++++++++++++++++++++++++++-
6 files changed, 105 insertions(+), 41 deletions(-)
---
diff --git a/gi/importer.py b/gi/importer.py
index 6076692..d18f334 100644
--- a/gi/importer.py
+++ b/gi/importer.py
@@ -27,7 +27,7 @@ import sys
import gobject
from ._gi import Repository, RepositoryError
-from .module import DynamicModule, DynamicGObjectModule, ModuleProxy
+from .module import DynamicModule, DynamicGObjectModule
repository = Repository.get_default()
@@ -48,10 +48,10 @@ class DynamicImporter(object):
path, namespace = fullname.rsplit('.', 1)
if path != self.path:
return
- try:
- repository.require(namespace)
- except RepositoryError, e:
- logging.exception(e)
+
+ if not repository.enumerate(namespace):
+ logging.error('Could not find any typelib for %s', namespace)
+ return None
else:
return self
@@ -69,18 +69,10 @@ class DynamicImporter(object):
dynamic_module = DynamicModule(namespace)
modules[namespace] = dynamic_module
- overrides_modules = __import__('gi.overrides', fromlist=[namespace])
- overrides_module = getattr(overrides_modules, namespace, None)
-
- if overrides_module is not None:
- module = ModuleProxy(fullname, namespace, dynamic_module, overrides_module)
- else:
- module = dynamic_module
-
- module.__file__ = '<%s>' % fullname
- module.__loader__ = self
+ dynamic_module.__file__ = '<%s>' % fullname
+ dynamic_module.__loader__ = self
- sys.modules[fullname] = module
+ sys.modules[fullname] = dynamic_module
- return module
+ return dynamic_module
diff --git a/gi/module.py b/gi/module.py
index e149986..36a5e75 100644
--- a/gi/module.py
+++ b/gi/module.py
@@ -64,6 +64,7 @@ def get_parent_for_object(object_info):
module = __import__('gi.repository.%s' % namespace, fromlist=[name])
return getattr(module, name)
+
def get_interfaces_for_object(object_info):
interfaces = []
for interface_info in object_info.get_interfaces():
@@ -75,12 +76,19 @@ def get_interfaces_for_object(object_info):
return interfaces
-class DynamicModule(object):
+class IntrospectionModule(object):
- def __init__(self, namespace):
+ def __init__(self, namespace, version=None):
+ repository.require(namespace, version)
self._namespace = namespace
+ self.version = version
self.__name__ = 'gi.repository.' + namespace
+ repository.require(self._namespace, self.version)
+
+ if self.version is None:
+ self.version = repository.get_version(self._namespace)
+
def __getattr__(self, name):
info = repository.find_by_name(self._namespace, name)
if not info:
@@ -165,7 +173,7 @@ class DynamicModule(object):
return "<DynamicModule %r from %r>" % (self._namespace, path)
-class DynamicGObjectModule(DynamicModule):
+class DynamicGObjectModule(IntrospectionModule):
"""Wrapper for the GObject module
This class allows us to access both the static PyGObject module and the GI GObject module
@@ -182,12 +190,11 @@ class DynamicGObjectModule(DynamicModule):
"""
def __init__(self):
- self._namespace = 'GObject'
- self._module = gobject
+ IntrospectionModule.__init__(self, namespace='GObject')
def __getattr__(self, name):
# first see if this attr is in the gobject module
- attr = getattr(self._module, name, None)
+ attr = getattr(gobject, name, None)
# if not in module assume request for an attr exported through GI
if attr is None:
@@ -195,23 +202,34 @@ class DynamicGObjectModule(DynamicModule):
return attr
-class ModuleProxy(object):
-
- def __init__(self, name, namespace, dynamic_module, overrides_module):
- self.__name__ = name
+class DynamicModule(object):
+ def __init__(self, namespace):
self._namespace = namespace
- self._dynamic_module = dynamic_module
- self._overrides_module = overrides_module
+ self.introspection_module = None
+ self._version = None
+ self._overrides_module = None
+
+ def require_version(self, version):
+ if self.introspection_module is not None and \
+ self.introspection_module.version != version:
+ raise RuntimeError('Module has been already loaded ')
+ self._version = version
+
+ def _import(self):
+ self.introspection_module = IntrospectionModule(self._namespace,
+ self._version)
+
+ overrides_modules = __import__('gi.overrides', fromlist=[self._namespace])
+ self._overrides_module = getattr(overrides_modules, self._namespace, None)
def __getattr__(self, name):
- override_exports = getattr(self._overrides_module, '__all__', ())
- if (name in override_exports):
- attribute = getattr(self._overrides_module, name, None)
- else:
- attribute = getattr(self._dynamic_module, name)
- return attribute
+ if self.introspection_module is None:
+ self._import()
- def __str__(self):
- return "<ModuleProxy %r>" % self.__name__
+ if self._overrides_module is not None:
+ override_exports = getattr(self._overrides_module, '__all__', ())
+ if name in override_exports:
+ return getattr(self._overrides_module, name, None)
+ return getattr(self.introspection_module, name)
diff --git a/gi/overrides/GIMarshallingTests.py b/gi/overrides/GIMarshallingTests.py
index 768efd7..ee01495 100644
--- a/gi/overrides/GIMarshallingTests.py
+++ b/gi/overrides/GIMarshallingTests.py
@@ -21,7 +21,7 @@
from ..types import override
from ..importer import modules
-GIMarshallingTests = modules['GIMarshallingTests']
+GIMarshallingTests = modules['GIMarshallingTests'].introspection_module
__all__ = []
diff --git a/gi/overrides/Gdk.py b/gi/overrides/Gdk.py
index 4eaff08..f6cc287 100644
--- a/gi/overrides/Gdk.py
+++ b/gi/overrides/Gdk.py
@@ -22,7 +22,7 @@
from ..types import override
from ..importer import modules
-Gdk = modules['Gdk']
+Gdk = modules['Gdk'].introspection_module
__all__ = []
diff --git a/gi/overrides/Gtk.py b/gi/overrides/Gtk.py
index 38a90b3..a655e93 100644
--- a/gi/overrides/Gtk.py
+++ b/gi/overrides/Gtk.py
@@ -25,7 +25,7 @@ from gi.repository import GObject
from ..types import override
from ..importer import modules
-Gtk = modules['Gtk']
+Gtk = modules['Gtk'].introspection_module
__all__ = []
class ActionGroup(Gtk.ActionGroup):
diff --git a/gi/pygi-repository.c b/gi/pygi-repository.c
index 783b4aa..5d3d793 100644
--- a/gi/pygi-repository.c
+++ b/gi/pygi-repository.c
@@ -60,6 +60,35 @@ PyTypeObject PyGIRepository_Type = {
};
static PyObject *
+_wrap_g_irepository_enumerate (PyGIRepository *self,
+ PyObject *args,
+ PyObject *kwargs)
+{
+ static char *kwlist[] = { "namespace", NULL };
+ const char *namespace_;
+ GList *versions, *item;
+ PyObject *ret = NULL;
+
+ if (!PyArg_ParseTupleAndKeywords (args, kwargs, "s:Repository.enumerate",
+ kwlist, &namespace_)) {
+ return NULL;
+ }
+
+ versions = g_irepository_enumerate (self->repository, namespace_);
+ ret = PyList_New(0);
+ for (item = versions; item; item = item->next) {
+ char *version = item->data;
+ PyObject *py_version = PyString_FromString (version);
+ PyList_Append(ret, py_version);
+ Py_DECREF(py_version);
+ g_free (version);
+ }
+ g_list_free(versions);
+
+ return ret;
+}
+
+static PyObject *
_wrap_g_irepository_get_default (PyObject *self)
{
static PyGIRepository *repository = NULL;
@@ -91,7 +120,7 @@ _wrap_g_irepository_require (PyGIRepository *self,
GTypelib *typelib;
GError *error;
- if (!PyArg_ParseTupleAndKeywords (args, kwargs, "s|sO:Repository.require",
+ if (!PyArg_ParseTupleAndKeywords (args, kwargs, "s|zO:Repository.require",
kwlist, &namespace_, &version, &lazy)) {
return NULL;
}
@@ -210,12 +239,37 @@ _wrap_g_irepository_get_typelib_path (PyGIRepository *self,
return PyString_FromString (typelib_path);
}
+static PyObject *
+_wrap_g_irepository_get_version (PyGIRepository *self,
+ PyObject *args,
+ PyObject *kwargs)
+{
+ static char *kwlist[] = { "namespace", NULL };
+ const char *namespace_;
+ const gchar *version;
+
+ if (!PyArg_ParseTupleAndKeywords (args, kwargs,
+ "s:Repository.get_version", kwlist, &namespace_)) {
+ return NULL;
+ }
+
+ version = g_irepository_get_version (self->repository, namespace_);
+ if (version == NULL) {
+ PyErr_Format (PyExc_RuntimeError, "Namespace '%s' not loaded", namespace_);
+ return NULL;
+ }
+
+ return PyString_FromString (version);
+}
+
static PyMethodDef _PyGIRepository_methods[] = {
+ { "enumerate", (PyCFunction) _wrap_g_irepository_enumerate, METH_VARARGS | METH_KEYWORDS },
{ "get_default", (PyCFunction) _wrap_g_irepository_get_default, METH_STATIC | METH_NOARGS },
{ "require", (PyCFunction) _wrap_g_irepository_require, METH_VARARGS | METH_KEYWORDS },
{ "get_infos", (PyCFunction) _wrap_g_irepository_get_infos, METH_VARARGS | METH_KEYWORDS },
{ "find_by_name", (PyCFunction) _wrap_g_irepository_find_by_name, METH_VARARGS | METH_KEYWORDS },
{ "get_typelib_path", (PyCFunction) _wrap_g_irepository_get_typelib_path, METH_VARARGS | METH_KEYWORDS },
+ { "get_version", (PyCFunction) _wrap_g_irepository_get_version, METH_VARARGS | METH_KEYWORDS },
{ NULL, NULL, 0 }
};
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]