[kupfer/next] core: Reorganize plugin importing, introduce import_plugin_any
- From: Ulrik Sverdrup <usverdrup src gnome org>
- To: svn-commits-list gnome org
- Cc:
- Subject: [kupfer/next] core: Reorganize plugin importing, introduce import_plugin_any
- Date: Mon, 1 Feb 2010 08:38:10 +0000 (UTC)
commit fb55c6bfbdfa7977928856ed06509e89e41da0bf
Author: Ulrik Sverdrup <ulrik sverdrup gmail com>
Date: Sat Jan 23 13:40:35 2010 +0100
core: Reorganize plugin importing, introduce import_plugin_any
kupfer/core/plugins.py | 138 ++++++++++++++++++++++++++++++-----------------
1 files changed, 88 insertions(+), 50 deletions(-)
---
diff --git a/kupfer/core/plugins.py b/kupfer/core/plugins.py
index 47db66d..5016b04 100644
--- a/kupfer/core/plugins.py
+++ b/kupfer/core/plugins.py
@@ -1,3 +1,4 @@
+import os
import sys
from kupfer import pretty, config
from kupfer.core import settings
@@ -15,13 +16,14 @@ info_attributes = [
"__author__",
]
+class NotEnabledError (Exception):
+ "Plugin may not be imported since it is not enabled"
+
def get_plugin_ids():
"""Enumerate possible plugin ids;
return a sequence of possible plugin ids, not
guaranteed to be plugins"""
import pkgutil
- import os
-
from kupfer import plugin
def is_plugname(plug):
@@ -62,7 +64,7 @@ def get_plugin_info():
"""
for plugin_name in sorted(get_plugin_ids()):
try:
- plugin = import_plugin(plugin_name)
+ plugin = import_plugin_any(plugin_name)
if not plugin:
continue
plugin = vars(plugin)
@@ -107,12 +109,14 @@ def get_plugin_desc():
))
return "\n".join(desc)
-imported_plugins = {}
+_imported_plugins = {}
-def import_fake_plugin(modpath):
+def _import_plugin_fake(modpath, error=None):
"""
Return an object that has the plugin info attributes we can rescue
from a plugin raising on import.
+
+ If applicable, write in @error as the exception responsible
"""
import pkgutil
@@ -123,66 +127,97 @@ def import_fake_plugin(modpath):
try:
eval(loader.get_code(), env)
except Exception, exc:
- error = unicode(exc)
- else:
- error = None
- pretty.print_error(__name__, "Fake plugin for good plugin", modpath)
+ pretty.print_debug(__name__, "Loading", modpath, exc)
+ errmsg = error and unicode(error)
attributes = dict((k, env.get(k)) for k in info_attributes)
- return FakePlugin(modpath, attributes, error)
+ return FakePlugin(modpath, attributes, errmsg)
-def import_plugin(name):
+def _import_hook_fake(pathcomps):
+ modpath = ".".join(pathcomps)
+ return _import_plugin_fake(modpath)
+
+def _import_hook_true(pathcomps):
+ """@pathcomps path components to the import"""
+ path = ".".join(pathcomps)
+ fromlist = pathcomps[-1:]
+ try:
+ setctl = settings.GetSettingsController()
+ if not setctl.get_plugin_enabled(pathcomps[-1]):
+ raise NotEnabledError("%s is not enabled" % pathcomps[-1])
+ plugin = __import__(path, fromlist=fromlist)
+ except ImportError, exc:
+ # Try to find a fake plugin if it exists
+ plugin = _import_plugin_fake(path, error=exc)
+ if not plugin:
+ raise
+ pretty.print_error(__name__, "Could not import plugin '%s': %s" %
+ (plugin.__name__, exc))
+ else:
+ pretty.print_debug(__name__, "Loading %s" % plugin.__name__)
+ pretty.print_debug(__name__, " from %s" % plugin.__file__)
+ return plugin
+
+def _import_plugin_true(name):
"""Try to import the plugin from the package,
and then from our plugin directories in $DATADIR
"""
- if name in imported_plugins:
- return imported_plugins[name]
- def importit(pathcomps):
- """@pathcomps path components to the import"""
- path = ".".join(pathcomps)
- fromlist = pathcomps[-1:]
- try:
- plugin = __import__(path, fromlist=fromlist)
- except ImportError, exc:
- # Try to find a fake plugin if it exists
- plugin = import_fake_plugin(path)
- if not plugin:
- raise
- pretty.print_error(__name__, "Could not import plugin '%s': %s" %
- (plugin.__name__, exc))
- else:
- pretty.print_debug(__name__, "Loading %s" % plugin.__name__)
- pretty.print_debug(__name__, " from %s" % plugin.__file__)
- return plugin
-
plugin = None
try:
- try:
- plugin = importit(("kupfer", "plugin", name))
- except ImportError, e:
- if name not in e.args[0]:
- raise
- oldpath = sys.path
- try:
- # Look in datadir kupfer/plugins for plugins
- # (and in current directory)
- extra_paths = list(config.get_data_dirs("plugins"))
- sys.path = extra_paths + sys.path
- plugin = importit((name,))
- finally:
- sys.path = oldpath
- except ImportError, e:
+ plugin = _staged_import(name, _import_hook_true)
+ except ImportError:
# Reraise to send this up
raise
+ except NotEnabledError:
+ raise
except Exception, e:
# catch any other error for plugins and write traceback
import traceback
traceback.print_exc()
pretty.print_error(__name__, "Could not import plugin '%s'" % name)
+ return plugin
+
+def _staged_import(name, import_hook):
+ "Import first from kupfer.plugin, then from plugins data directories"
+ plugin = None
+ try:
+ plugin = import_hook(("kupfer", "plugin", name))
+ except ImportError, e:
+ if name not in e.args[0]:
+ raise
+
+ if not plugin:
+ oldpath = sys.path
+ try:
+ # Look in datadir kupfer/plugins for plugins
+ # (and in current directory)
+ extra_paths = list(config.get_data_dirs("plugins"))
+ sys.path = extra_paths + sys.path
+ plugin = import_hook((name,))
+ finally:
+ sys.path = oldpath
+ return plugin
+
+
+def import_plugin(name):
+ if name in _imported_plugins:
+ return _imported_plugins[name]
+ plugin = None
+ try:
+ plugin = _import_plugin_true(name)
+ except NotEnabledError:
+ plugin = _staged_import(name, _import_hook_fake)
finally:
# store nonexistant plugins as None here
- imported_plugins[name] = plugin
+ _imported_plugins[name] = plugin
return plugin
+def import_plugin_any(name):
+ if name in _imported_plugins:
+ return _imported_plugins[name]
+ return _staged_import(name, _import_hook_fake)
+
+
+# Plugin Attributes
def get_plugin_attributes(plugin_name, attrs, warn=False):
"""Generator of the attributes named @attrs
to be found in plugin @plugin_name
@@ -228,6 +263,12 @@ def load_plugin_sources(plugin_name, attr=sources_attribute, instantiate=True):
else:
pretty.print_info(__name__, "Source not found for %s" % plugin_name)
+
+# Plugin Initialization & Error
+def is_plugin_loaded(plugin_name):
+ return (plugin_name in _imported_plugins and
+ not get_plugin_attribute(plugin_name, "is_fake_plugin"))
+
def initialize_plugin(plugin_name):
"""Initialize plugin.
Find settings attribute if defined, and initialize it
@@ -249,6 +290,3 @@ def get_plugin_error(plugin_name):
except ImportError, e:
return "'%s' is not a plugin" % plugin_name
-def is_plugin_loaded(plugin_name):
- return (plugin_name in imported_plugins and
- not get_plugin_attribute(plugin_name, "is_fake_plugin"))
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]