[pygobject] Load typelibs at import time, add gi.require_version()



commit 76758efb6579752237a0dc4d56cf9518de6c6e55
Author: Tomeu Vizoso <tomeu vizoso collabora co uk>
Date:   Wed Feb 16 11:53:18 2011 +0100

    Load typelibs at import time, add gi.require_version()
    
    also adds Repository.get_loaded_namespaces()
    
    https://bugzilla.gnome.org/show_bug.cgi?id=642305

 gi/__init__.py       |   29 ++++++++++++++++++++++++++++-
 gi/importer.py       |    1 +
 gi/module.py         |   21 ++++-----------------
 gi/pygi-repository.c |   23 +++++++++++++++++++++++
 4 files changed, 56 insertions(+), 18 deletions(-)
---
diff --git a/gi/__init__.py b/gi/__init__.py
index fb711c3..ed20606 100644
--- a/gi/__init__.py
+++ b/gi/__init__.py
@@ -20,8 +20,35 @@
 
 from __future__ import absolute_import
 
-from ._gi import _API
+from ._gi import _API, Repository
 
 # Force loading the GObject typelib so we have available the wrappers for
 # base classes such as GInitiallyUnowned
 from gi.repository import GObject
+
+_versions = {}
+
+def require_version(namespace, version):
+    repository = Repository.get_default()
+
+    if namespace in repository.get_loaded_namespaces():
+        if repository.get_version(namespace) != version:
+            raise ValueError('Namespace %s is already loaded with version %s' % \
+                             (namespace, loaded_version))
+
+    if namespace in _versions and _versions[namespace] != version:
+        raise ValueError('Namespace %s already requires version %s' % \
+                         (namespace, _versions[namespace]))
+
+    available_versions = repository.enumerate_versions(namespace)
+    if not available_versions:
+        raise ValueError('Namespace %s not available' % namespace)
+
+    if version not in available_versions:
+        raise ValueError('Namespace %s not available for version %s' % \
+                         (namespace, version))
+
+    _versions[namespace] = version
+
+def get_required_version(namespace):
+    return _versions.get(namespace, None)
diff --git a/gi/importer.py b/gi/importer.py
index 1cb9b92..e5733e4 100644
--- a/gi/importer.py
+++ b/gi/importer.py
@@ -68,6 +68,7 @@ class DynamicImporter(object):
 
         dynamic_module = DynamicModule(namespace)
         modules[namespace] = dynamic_module
+        dynamic_module.load()
 
         dynamic_module.__file__ = '<%s>' % fullname
         dynamic_module.__loader__ = self
diff --git a/gi/module.py b/gi/module.py
index 133f3ed..43010e8 100644
--- a/gi/module.py
+++ b/gi/module.py
@@ -25,6 +25,7 @@ from __future__ import absolute_import
 import os
 import gobject
 
+import gi
 from .overrides import registry
 
 from ._gi import \
@@ -230,28 +231,19 @@ class DynamicModule(object):
     def __init__(self, namespace):
         self._namespace = namespace
         self._introspection_module = None
-        self._version = None
         self._overrides_module = None
         self.__path__ = 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):
+    def load(self):
+        version = gi.get_required_version(self._namespace)
         self._introspection_module = IntrospectionModule(self._namespace,
-                                                         self._version)
+                                                         version)
 
         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:
-            self._import()
-
         if self._overrides_module is not None:
             override_exports = getattr(self._overrides_module, '__all__', ())
             if name in override_exports:
@@ -269,9 +261,6 @@ class DynamicModule(object):
         return getattr(self._introspection_module, name)
 
     def __dir__ (self):
-        if self._introspection_module is None:
-            self._import()
-            
         # Python's default dir() is just dir(self.__class__) + self.__dict__.keys()
         result = set(dir(self.__class__))
         result.update(self.__dict__.keys())
@@ -282,8 +271,6 @@ class DynamicModule(object):
         return list(result)
 
     def __repr__(self):
-        repository.require(self._namespace, self._version)
-
         path = repository.get_typelib_path(self._namespace)
         return "<%s.%s %r from %r>" % (self.__class__.__module__,
                                       self.__class__.__name__,
diff --git a/gi/pygi-repository.c b/gi/pygi-repository.c
index 9b22eae..c48d2ce 100644
--- a/gi/pygi-repository.c
+++ b/gi/pygi-repository.c
@@ -234,6 +234,28 @@ _wrap_g_irepository_get_version (PyGIRepository *self,
     return PYGLIB_PyUnicode_FromString (version);
 }
 
+static PyObject *
+_wrap_g_irepository_get_loaded_namespaces (PyGIRepository *self)
+{
+    char **namespaces;
+    PyObject *py_namespaces;
+    gssize i;
+
+    namespaces = g_irepository_get_loaded_namespaces (self->repository);
+
+    py_namespaces = PyList_New (0);
+    for (i = 0; namespaces[i] != NULL; i++) {
+        PyObject *py_namespace = PYGLIB_PyUnicode_FromString (namespaces[i]);
+        PyList_Append (py_namespaces, py_namespace);
+        Py_DECREF(py_namespace);
+        g_free (namespaces[i]);
+    }
+
+    g_free (namespaces);
+
+    return py_namespaces;
+}
+
 static PyMethodDef _PyGIRepository_methods[] = {
     { "enumerate_versions", (PyCFunction) _wrap_g_irepository_enumerate_versions, METH_VARARGS | METH_KEYWORDS },
     { "get_default", (PyCFunction) _wrap_g_irepository_get_default, METH_STATIC | METH_NOARGS },
@@ -242,6 +264,7 @@ static PyMethodDef _PyGIRepository_methods[] = {
     { "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 },
+    { "get_loaded_namespaces", (PyCFunction) _wrap_g_irepository_get_loaded_namespaces, METH_NOARGS },
     { NULL, NULL, 0 }
 };
 



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]