[pygobject/gsoc2009: 40/160] Change the import strategy
- From: Simon van der Linden <svdlinden src gnome org>
- To: svn-commits-list gnome org
- Cc:
- Subject: [pygobject/gsoc2009: 40/160] Change the import strategy
- Date: Fri, 14 Aug 2009 21:25:27 +0000 (UTC)
commit 7df821f8200db7b64bd0b508f0a2fa6b95900524
Author: Simon van der Linden <svdlinden src gnome org>
Date: Wed Jul 15 11:50:57 2009 +0200
Change the import strategy
Dynamic modules should be loaded with 'from gi.repository import <module>' or
any equivalent form.
gi.repository is a dummy module whose loader is overridden by a dynamic importer.
configure.ac | 1 +
gi/Makefile.am | 2 +-
gi/__init__.py | 6 ------
gi/importer.py | 33 ++++++++++++++++++++-------------
gi/module.py | 16 +++++-----------
gi/pygargument.c | 4 ++--
gi/pygirepository.c | 15 +++++++++++++++
gi/pygirepository.h | 2 ++
gi/repository/Makefile.am | 11 +++++++++++
gi/repository/__init__.py | 28 ++++++++++++++++++++++++++++
tests/test_girepository.py | 3 +--
11 files changed, 86 insertions(+), 35 deletions(-)
---
diff --git a/configure.ac b/configure.ac
index c4126f8..ceac95e 100644
--- a/configure.ac
+++ b/configure.ac
@@ -238,6 +238,7 @@ AC_CONFIG_FILES(
gobject/Makefile
gio/Makefile
gi/Makefile
+ gi/repository/Makefile
gi/overrides/Makefile
examples/Makefile
tests/Makefile
diff --git a/gi/Makefile.am b/gi/Makefile.am
index afad920..d4e1e11 100644
--- a/gi/Makefile.am
+++ b/gi/Makefile.am
@@ -1,6 +1,6 @@
AUTOMAKE_OPTIONS = 1.7
-SUBDIRS = overrides
+SUBDIRS = repository overrides
PLATFORM_VERSION = 2.0
diff --git a/gi/__init__.py b/gi/__init__.py
index b860987..1f6a31e 100644
--- a/gi/__init__.py
+++ b/gi/__init__.py
@@ -18,9 +18,3 @@
# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301
# USA
-from .importer import install_importhook
-
-install_importhook()
-
-del install_importhook
-
diff --git a/gi/importer.py b/gi/importer.py
index 66b6388..dd7f105 100644
--- a/gi/importer.py
+++ b/gi/importer.py
@@ -21,7 +21,6 @@
# USA
import sys
-import new
import gobject
from ._gi import Repository
@@ -29,30 +28,41 @@ from .module import DynamicModule
repository = Repository.get_default()
-sys.modules['GObject'] = gobject
class DynamicImporter(object):
# Note: see PEP302 for the Importer Protocol implemented below.
+ def __init__(self, path):
+ self.path = path
+
def find_module(self, fullname, path=None):
- # Avoid name clashes, and favour static bindings.
- if fullname == 'cairo':
- return None
+ if not fullname.startswith(self.path):
+ return
- if repository.require(fullname):
+ path, namespace = fullname.rsplit('.', 1)
+ if path != self.path:
+ return
+ if repository.require(namespace):
return self
def load_module(self, fullname):
if fullname in sys.modules:
return sys.modules[name]
+ path, namespace = fullname.rsplit('.', 1)
+
+ # Workaround for GObject
+ if namespace == 'GObject':
+ sys.modules[fullname] = gobject
+ return gobject
+
# Look for an overrides module
- overrides_name = 'gi.overrides.%s' % fullname
+ overrides_name = 'gi.overrides.%s' % namespace
try:
- overrides_type_name = '%sModule' % fullname
- overrides_module = __import__(overrides_name, {}, {}, [overrides_type_name])
+ overrides_type_name = '%sModule' % namespace
+ overrides_module = __import__(overrides_name, fromlist=[overrides_type_name])
module_type = getattr(overrides_module, overrides_type_name)
except ImportError, e:
module_type = DynamicModule
@@ -61,6 +71,7 @@ class DynamicImporter(object):
module.__dict__ = {
'__file__': '<%s>' % fullname,
'__name__': fullname,
+ '__namespace__': namespace,
'__loader__': self
}
@@ -70,7 +81,3 @@ class DynamicImporter(object):
return module
-
-def install_importhook():
- sys.meta_path.append(DynamicImporter())
-
diff --git a/gi/module.py b/gi/module.py
index bed17d7..4e4d8d0 100644
--- a/gi/module.py
+++ b/gi/module.py
@@ -43,7 +43,6 @@ from .types import \
GIStruct, \
Function
-
repository = Repository.get_default()
@@ -56,16 +55,11 @@ def get_parent_for_object(object_info):
namespace = parent_object_info.getNamespace()
name = parent_object_info.getName()
- module = __import__(namespace)
-
- if isinstance(parent_object_info, UnresolvedInfo):
- # The module has been imported, try again.
- parent_object_info = object_info.getParent()
-
- # Workaround for gobject.Object and gobject.InitiallyUnowned.
- if module == gobject and name == 'Object' or name == 'InitiallyUnowned':
+ # Workaround for GObject.Object and GObject.InitiallyUnowned.
+ if namespace == 'GObject' and name == 'Object' or name == 'InitiallyUnowned':
return GObject
+ module = __import__('gi.repository.%s' % namespace, fromlist=[name])
return getattr(module, name)
@@ -75,7 +69,7 @@ class DynamicModule(object):
return "<dynamic module %r>" % self.__name__
def __getattr__(self, name):
- info = repository.find_by_name(self.__name__, name)
+ info = repository.find_by_name(self.__namespace__, name)
if not info:
raise AttributeError("%r object has no attribute %r" % (
self.__class__.__name__, name))
@@ -128,7 +122,7 @@ class DynamicModule(object):
@property
def __members__(self):
r = []
- for type_info in repository.get_infos(self.__name__):
+ for type_info in repository.get_infos(self.__namespace__):
if type_info is None:
continue
r.append(type_info.getName())
diff --git a/gi/pygargument.c b/gi/pygargument.c
index bdd000f..cd22d71 100644
--- a/gi/pygargument.c
+++ b/gi/pygargument.c
@@ -886,7 +886,7 @@ pyg_argument_to_pyobject(GArgument *arg, GITypeInfo *type_info)
module_name = g_base_info_get_namespace(interface_info);
type_name = g_base_info_get_name(interface_info);
- module = PyImport_ImportModule(module_name);
+ module = pygi_repository_get_py_module(module_name);
if (module == NULL) {
PyErr_Format(PyExc_TypeError, "Type %s.%s not defined", module_name, type_name);
break;
@@ -935,7 +935,7 @@ pyg_argument_to_pyobject(GArgument *arg, GITypeInfo *type_info)
module_name = g_base_info_get_namespace(interface_info);
type_name = g_base_info_get_name(interface_info);
- module = PyImport_ImportModule(module_name);
+ module = pygi_repository_get_py_module(module_name);
if (module == NULL) {
PyErr_Format(PyExc_TypeError, "Type %s.%s not defined", module_name, type_name);
break;
diff --git a/gi/pygirepository.c b/gi/pygirepository.c
index c640b51..fa8065d 100644
--- a/gi/pygirepository.c
+++ b/gi/pygirepository.c
@@ -227,6 +227,21 @@ static PyMethodDef _PyGIRepository_methods[] = {
{ NULL, NULL, 0 }
};
+PyObject *
+pygi_repository_get_py_module(const char * namespace_)
+{
+ PyObject *py_module;
+ gchar *module_name;
+
+ module_name = g_strconcat("gi.repository.", namespace_, NULL);
+
+ py_module = PyImport_ImportModule(module_name);
+
+ g_free(module_name);
+
+ return py_module;
+}
+
void
pygi_repository_register_types(PyObject *m)
{
diff --git a/gi/pygirepository.h b/gi/pygirepository.h
index 573ecf3..6d519ad 100644
--- a/gi/pygirepository.h
+++ b/gi/pygirepository.h
@@ -26,6 +26,8 @@
G_BEGIN_DECLS
+PyObject * pygi_repository_get_py_module(const char * namespace_);
+
void pygi_repository_register_types(PyObject *m);
G_END_DECLS
diff --git a/gi/repository/Makefile.am b/gi/repository/Makefile.am
new file mode 100644
index 0000000..a95507f
--- /dev/null
+++ b/gi/repository/Makefile.am
@@ -0,0 +1,11 @@
+AUTOMAKE_OPTIONS = 1.7
+PLATFORM_VERSION = 2.0
+
+# gi-repository extension modules
+pkgpyexecdir = $(pyexecdir)/gtk-2.0/gi/repository
+
+# gi-repository python scripts
+pygirepositorydir = $(pkgpyexecdir)
+pygirepository_PYTHON = \
+ __init__.py
+
diff --git a/gi/repository/__init__.py b/gi/repository/__init__.py
new file mode 100644
index 0000000..640fc8e
--- /dev/null
+++ b/gi/repository/__init__.py
@@ -0,0 +1,28 @@
+# -*- Mode: Python; py-indent-offset: 4 -*-
+# vim: tabstop=4 shiftwidth=4 expandtab
+#
+# Copyright (C) 2009 Johan Dahlin <johan gnome org>
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301
+# USA
+
+import sys
+
+from ..importer import DynamicImporter
+
+sys.meta_path.append(DynamicImporter('gi.repository'))
+
+del DynamicImporter
+del sys
diff --git a/tests/test_girepository.py b/tests/test_girepository.py
index 7ddf488..50b9de1 100644
--- a/tests/test_girepository.py
+++ b/tests/test_girepository.py
@@ -6,8 +6,7 @@ import time
import gobject
from gobject import constants
-import gi
-import Everything
+from gi.repository import Everything
INT8_MIN = -128
INT16_MIN = -32768
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]