commit-gnue
[Top][All Lists]
Advanced

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

[gnue] r9937 - in trunk/gnue-common: src/apps src/base src/datasources s


From: reinhard
Subject: [gnue] r9937 - in trunk/gnue-common: src/apps src/base src/datasources src/datasources/drivers/Base src/rpc src/utils utils/helpers
Date: Tue, 6 Oct 2009 08:48:23 -0500 (CDT)

Author: reinhard
Date: 2009-10-06 08:48:22 -0500 (Tue, 06 Oct 2009)
New Revision: 9937

Added:
   trunk/gnue-common/src/base/plugin.py
Removed:
   trunk/gnue-common/src/apps/plugin.py
   trunk/gnue-common/src/utils/plugin.py
Modified:
   trunk/gnue-common/src/datasources/GConnections.py
   trunk/gnue-common/src/datasources/drivers/Base/Connection.py
   trunk/gnue-common/src/rpc/client.py
   trunk/gnue-common/src/rpc/server.py
   trunk/gnue-common/utils/helpers/info.py
Log:
Some work on plugin loader library.


Deleted: trunk/gnue-common/src/apps/plugin.py
===================================================================
--- trunk/gnue-common/src/apps/plugin.py        2009-10-06 13:42:11 UTC (rev 
9936)
+++ trunk/gnue-common/src/apps/plugin.py        2009-10-06 13:48:22 UTC (rev 
9937)
@@ -1,29 +0,0 @@
-# GNU Enterprise Common Library - Plugin support
-#
-# This file is part of GNU Enterprise.
-#
-# GNU Enterprise is free software; you can redistribute it
-# and/or modify it under the terms of the GNU General Public
-# License as published by the Free Software Foundation; either
-# version 2, or (at your option) any later version.
-#
-# GNU Enterprise 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 General Public License for more details.
-#
-# You should have received a copy of the GNU General Public
-# License along with program; see the file COPYING. If not,
-# write to the Free Software Foundation, Inc., 59 Temple Place
-# - Suite 330, Boston, MA 02111-1307, USA.
-#
-# Copyright 2001-2009 Free Software Foundation
-#
-# $Id$
-
-"""
-This module is *DEPRECATED*. Please use gnue.common.utils.plugin instead
-"""
-
-from gnue.common.utils.plugin import *
-

Copied: trunk/gnue-common/src/base/plugin.py (from rev 9928, 
trunk/gnue-common/src/utils/plugin.py)
===================================================================
--- trunk/gnue-common/src/base/plugin.py                                (rev 0)
+++ trunk/gnue-common/src/base/plugin.py        2009-10-06 13:48:22 UTC (rev 
9937)
@@ -0,0 +1,443 @@
+# GNU Enterprise Common Library - Plugin support
+#
+# Copyright 2001-2009 Free Software Foundation
+#
+# This file is part of GNU Enterprise.
+#
+# GNU Enterprise is free software; you can redistribute it
+# and/or modify it under the terms of the GNU General Public
+# License as published by the Free Software Foundation; either
+# version 2, or (at your option) any later version.
+#
+# GNU Enterprise 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 General Public License for more details.
+#
+# You should have received a copy of the GNU General Public
+# License along with program; see the file COPYING. If not,
+# write to the Free Software Foundation, Inc., 59 Temple Place
+# - Suite 330, Boston, MA 02111-1307, USA.
+#
+# $Id$
+
+"""
+Functions to list and load avaliable plugins dynamically.
+
+Plugin handling in GNU Enterprise
+=================================
+
+Plugins are Python modules that implement a defined API and are loaded on
+demand.  Usually, there are several plugins of the same type (that means they
+implement the same API) that can be used interchangeable.  The user can select
+which plugin he wants to use.
+
+All plugins of a specific type must be Python modules in a defined package.
+For example, all database drivers must be modules in the
+gnue.common.datasources.drivers package.
+
+Any plugin must define a specific symbol (usually a class definition like
+LanguageAdapter, ClientAdapter or Connection) to qualify itself as valid.
+
+Any plugin must immediately check whether it is functional (especially whether
+all dependencies are installed), and import must fail with a meaningful
+exception otherwise.  Optionally, a module can also define a function with the
+name __initplugin__ that initializes the module and raises an exception if the
+plugin cannot be initialized.
+
+Plugins can be organized in a tree structure.  To load a plugin, any point in
+the tree may be specified.  For example, consider there are three plugins named
+base.group.foo, base.group.bar and base.group.baz.  "foo" will specify the foo
+plugin, as well as "group.foo".  Loading the plugin "group" means to load the
+first available functional plugin in the group.
+
+Modules and packages located within the plugin tree but not being valid plugins
+can define a symbol with the name __noplugin__ to indicate that they are no
+valid plugin.  Note that the module defining the __noplugin__ symbol is still
+imported, but no submodules of it. This is useful to exclude, for example,
+abstract base drivers.
+"""
+
+import os
+
+from types import ModuleType
+from gnue.common.base import errors
+
+__all__ = ['LoadError', 'list_plugins', 'find']
+
+# =============================================================================
+# Exceptions
+# =============================================================================
+
+# -----------------------------------------------------------------------------
+# Module loading error
+# -----------------------------------------------------------------------------
+
+class LoadError(errors.AdminError):
+    """
+    Indicates a failure to load a given module.  Raised by L{find}.
+
+    If e is an Exception of this class, e.exceptions gives a dictionary with
+    the keys being the modules that were trying to be imported and the values
+    being the exception info tuples for the exception that happened trying, and
+    e.detail is a string containing basically the same info.
+    """
+    def __init__(self, name, exceptions):
+
+        self.name = name
+        self.exceptions = exceptions
+
+        if self.exceptions:
+            message = u_("Cannot load plugin '%s'") % self.name
+            detail = u_("The following plugins failed:\n")
+            for (name, exc) in self.exceptions.items():
+                detail += u"* %s: %s" % (name, exc)
+        else:
+            message = u_("Cannot find plugin '%s'") % self.name
+            detail = None
+
+        errors.AdminError.__init__(self, message)
+
+        if detail:
+            self.detail = detail
+
+
+# -----------------------------------------------------------------------------
+# List all available plugins
+# -----------------------------------------------------------------------------
+
+def list_plugins(base, identifier, try_to_init=True):
+    """
+    List all available plugins.
+
+    @param base: Name of the package that contains the plugins.
+    @param identifier: Identifier that a plugin must define to qualify as
+        module.
+    @param try_to_init: If set to False, __initplugin__ is not called.
+    @return: A dictionary with the available plugin module names as keys and
+        either the loaded module or the exception info tuple of the exception
+        raised when trying to import the module as values.
+    """
+    checktype(base, [basestring])
+    checktype(identifier, [basestring])
+
+    # Make sure everything is a string. Non-ASCII characters are not allowed in
+    # Python module names anyway.
+    _base = base.encode()
+    _identifier = identifier.encode()
+
+    # Now recursively list the plugins
+    return __list(_base, _identifier, try_to_init, True)
+
+
+# -----------------------------------------------------------------------------
+# Find a plugin
+# -----------------------------------------------------------------------------
+
+def find(name, base, identifier):
+    """
+    Find a plugin by name. If no plugin is functional, a LoadError is raised.
+
+    @param name: Name of the plugin to find.  If the plugin is foo.bar, name 
can
+        be bar, or foo.bar, or foo, where the last one returns the first
+        functional plugin in the foo group.
+    @param base: Name of the package that contains the plugins.
+    @param identifier: Identifier that a plugin must define to qualify as
+        module.
+    @return: The loaded module of the plugin.
+    """
+    checktype(name, [basestring])
+    checktype(base, [basestring])
+    checktype(identifier, [basestring])
+
+    # Make sure everything is a string. Non-ASCII characters are not allowed in
+    # Python module names anyway.
+    _name = name.encode()
+    _base = base.encode()
+    _identifier = identifier.encode()
+
+    # First, see if we've already found this module previously
+    try:
+        result = __FIND_CACHE[(_base, _name)]
+    except KeyError:
+        # If not, search for the plugin
+        __FIND_CACHE[(_base, _name)] = __find(_base, _name, _identifier)
+        result = __FIND_CACHE[(_base, _name)]
+
+    if isinstance(result, ModuleType):
+        return result
+    else:
+        raise LoadError, (name, result)
+
+
+# -----------------------------------------------------------------------------
+# A list of all previously failed modules
+# -----------------------------------------------------------------------------
+
+# This dictionary remembers all previous failure of module imports/inits. That
+# is necessary because module initialization code is only run at first import
+# attempt.
+__FAILED_CACHE = {}
+
+
+# -----------------------------------------------------------------------------
+# Mapping of previously found plugins
+# -----------------------------------------------------------------------------
+
+__FIND_CACHE = {}
+
+
+# -----------------------------------------------------------------------------
+# Find all modules and subpackages in a package
+# -----------------------------------------------------------------------------
+
+def __modules(package, want_packages):
+
+    # package.__file__ is a directory if GImportLogger is in use. This makes it
+    # necessary to 'simulate' a package, otherwise stepping down subpackages
+    # won't work.
+    if os.path.isdir(package.__file__):
+        (basedir, basefile) = (package.__file__, '__init__.py')
+    else:
+        (basedir, basefile) = os.path.split(package.__file__)
+
+    basename = os.path.splitext(basefile)[0]
+
+    if basename != '__init__':
+        # This is not a package, so no need to go deeper
+        return []
+
+    # Find all submodules
+    result = {}
+    for subfile in os.listdir(basedir):
+        (subname, subext) = os.path.splitext(subfile)
+        subpath = os.path.join(basedir, subfile)
+        # We are only interested in Python modules or packages
+        if (not want_packages and subext in ['.py', '.pyc', '.pyo'] and \
+            subname != '__init__') or \
+           (os.path.isdir(subpath) and \
+            os.path.isfile(os.path.join(subpath, '__init__.py')) or \
+            os.path.isfile(os.path.join(subpath, '__init__.pyc')) or \
+            os.path.isfile(os.path.join(subpath, '__init__.pyo'))):
+            result[subname] = True
+
+    return result.keys()
+
+
+# -----------------------------------------------------------------------------
+# Recursively list all plugins
+# -----------------------------------------------------------------------------
+
+def __list(base, identifier, try_to_init, top):
+
+    if __FAILED_CACHE.has_key(base):
+        # This has already failed in previous attempt
+        return {base: __FAILED_CACHE[base]}
+
+    try:
+        mod = __import__(base, None, None, '*')
+    except StandardError, e:
+        __FAILED_CACHE[base] = e
+        return {base: __FAILED_CACHE[base]}
+
+    if hasattr(mod, '__noplugin__'):
+        # This is not a plugin, ignore it
+        return {}
+
+    if not top:
+        if hasattr(mod, identifier):
+            # This is already a plugin, no need to go deeper
+            if try_to_init and hasattr(mod, '__initplugin__'):
+                try:
+                    mod.__initplugin__()
+                except StandardError, e:
+                    __FAILED_CACHE[base] = e
+                    return {base: __FAILED_CACHE[base]}
+            return {base: mod}
+
+    # List all submodules
+    result = {}
+    for sub in __modules(mod, False):
+        result.update(__list(base + '.' + sub, identifier, try_to_init, False))
+    return result
+
+
+# -----------------------------------------------------------------------------
+# Recursively find first available plugin and return the module or a dictionary
+# with the exceptions that occured
+# -----------------------------------------------------------------------------
+
+def __first(base, identifier):
+
+    if __FAILED_CACHE.has_key(base):
+        # This has already failed in previous attempt
+        return {base: __FAILED_CACHE[base]}
+
+    try:
+        mod = __import__(base, None, None, '*')
+    except StandardError, e:
+        __FAILED_CACHE[base] = e
+        return {base: __FAILED_CACHE[base]}
+
+    if hasattr(mod, '__noplugin__'):
+        # This is not a plugin, ignore it
+        return {}
+
+    if hasattr(mod, identifier):
+        # This is already a plugin, no need to go deeper
+        if hasattr(mod, '__initplugin__'):
+            try:
+                mod.__initplugin__()
+            except StandardError, e:
+                __FAILED_CACHE[base] = e
+                return {base: __FAILED_CACHE[base]}
+        return mod
+
+    # Search all submodules
+    exceptions = {}
+    for sub in __modules(mod, False):
+        result = __first(base + '.' + sub, identifier)
+        if isinstance(result, ModuleType):
+            return result
+        exceptions.update(result)
+    return exceptions
+
+
+# -----------------------------------------------------------------------------
+# Recursively search for a plugin and return the module or the exceptions that
+# occured
+# -----------------------------------------------------------------------------
+
+def __find(base, name, identifier):
+
+    if __FAILED_CACHE.has_key(base):
+        # This has already failed in previous attempt
+        return {base: __FAILED_CACHE[base]}
+
+    try:
+        mod = __import__(base, None, None, '*')
+    except StandardError, e:
+        __FAILED_CACHE[base] = e
+        return {base: __FAILED_CACHE[base]}
+
+    if hasattr(mod, '__noplugin__'):
+        # This is not a plugin, ignore it
+        return {}
+
+    # Is the searched driver an alias of this module?
+    if hasattr(mod, '__pluginalias__'):
+        if name in mod.__pluginalias__:
+            return __first(base, identifier)
+
+    if __FAILED_CACHE.has_key(base + '.' + name):
+        # This has already failed in previous attempt
+        return {base + '.' + name: __FAILED_CACHE[base + '.' + name]}
+
+    try:
+        mod = __import__(base + '.' + name, None, None, '*')
+    except ImportError:
+        pass
+    except StandardError, e:
+        __FAILED_CACHE[base + '.' + name] = e
+        return {base + '.' + name: __FAILED_CACHE[base + '.' + name]}
+    else:
+        return __first(base + '.' + name, identifier)
+
+    # Search all submodules
+    exceptions = {}
+    for sub in __modules(mod, False):
+        result = __find(base + '.' + sub, name, identifier)
+        if isinstance(result, ModuleType):
+            return result
+        exceptions.update(result)
+
+    return exceptions
+
+
+# =============================================================================
+# Self test code
+# =============================================================================
+
+if __name__ == '__main__':
+
+    # -------------------------------------------------------------------------
+    # list_plugins
+    # -------------------------------------------------------------------------
+
+    def __test_list_plugins():
+
+        base = 'gnue.common.datasources.drivers'
+
+        for (iname, iresult) in (list_plugins(base, 'Connection')).items():
+            print iname[len(base)+1:]  + ":",
+            if isinstance(iresult, ModuleType):
+                print "ok"
+            else:
+                print unicode(iresult)
+        print
+
+
+    # -------------------------------------------------------------------------
+    # find
+    # -------------------------------------------------------------------------
+
+    def __test_find():
+
+        base = 'gnue.common.datasources.drivers'
+
+        try:
+            print 'find "postgresql.psycopg2drv":',
+            fmod = find('postgresql.psycopg2drv', base, 'Connection')
+            print fmod.__name__
+        except LoadError, e:
+            print e
+            print "Detail:"
+            print o(e.detail)
+        print
+
+        try:
+            print 'find "pygresql":',
+            fmod = find('pygresql', base, 'Connection')
+            print fmod.__name__
+        except LoadError, e:
+            print e
+            print "Detail:"
+            print o(e.detail)
+        print
+
+        try:
+            print 'find "mysql":',
+            fmod = find('mysql', base, 'Connection')
+            print fmod.__name__
+        except LoadError, e:
+            print e
+            print "Detail:"
+            print o(e.detail)
+        print
+
+        try:
+            print 'find "oracle":',
+            fmod = find('oracle', base, 'Connection')
+            print fmod.__name__
+        except LoadError, e:
+            print e
+            print "Detail:"
+            print o(e.detail)
+        print
+
+        try:
+            print 'find "nonexistent":',
+            fmod = find('nonexistent', base, 'Connection')
+            print fmod.__name__
+        except LoadError, e:
+            print e
+            print "Detail:"
+            print o(e.detail)
+
+
+    # -------------------------------------------------------------------------
+    # Call all tests
+    # -------------------------------------------------------------------------
+
+    __test_list_plugins()
+    __test_find()

Modified: trunk/gnue-common/src/datasources/GConnections.py
===================================================================
--- trunk/gnue-common/src/datasources/GConnections.py   2009-10-06 13:42:11 UTC 
(rev 9936)
+++ trunk/gnue-common/src/datasources/GConnections.py   2009-10-06 13:48:22 UTC 
(rev 9937)
@@ -29,7 +29,8 @@
 
 import copy, netrc
 
-from gnue.common.apps import plugin, errors, i18n
+from gnue.common.base import errors, plugin
+from gnue.common.apps import i18n
 from gnue.common.utils.FileUtils import openResource, dyn_import
 from gnue.common.datasources import Exceptions, GLoginHandler
 

Modified: trunk/gnue-common/src/datasources/drivers/Base/Connection.py
===================================================================
--- trunk/gnue-common/src/datasources/drivers/Base/Connection.py        
2009-10-06 13:42:11 UTC (rev 9936)
+++ trunk/gnue-common/src/datasources/drivers/Base/Connection.py        
2009-10-06 13:48:22 UTC (rev 9937)
@@ -27,8 +27,7 @@
 
 __all__ = ['Connection']
 
-from gnue.common.base import log
-from gnue.common.apps import GDebug, plugin
+from gnue.common.base import log, plugin
 from gnue.common.datasources import GConnections, GSchema
 
 

Modified: trunk/gnue-common/src/rpc/client.py
===================================================================
--- trunk/gnue-common/src/rpc/client.py 2009-10-06 13:42:11 UTC (rev 9936)
+++ trunk/gnue-common/src/rpc/client.py 2009-10-06 13:48:22 UTC (rev 9937)
@@ -28,8 +28,7 @@
 __all__ = ['attach', 'InvalidAdapter', 'AdapterInitializationError',
            'AdapterConfigurationError', 'ProgrammingError', 
'AccessDeniedError']
 
-from gnue.common.apps import plugin
-from gnue.common.base import errors
+from gnue.common.base import errors, plugin
 
 # =============================================================================
 # Public functions

Modified: trunk/gnue-common/src/rpc/server.py
===================================================================
--- trunk/gnue-common/src/rpc/server.py 2009-10-06 13:42:11 UTC (rev 9936)
+++ trunk/gnue-common/src/rpc/server.py 2009-10-06 13:48:22 UTC (rev 9937)
@@ -28,7 +28,7 @@
 __all__ = ['bind', 'AdapterInitializationError', 'AdapterConfigurationError',
            'ProgrammingError', 'InvalidParameter']
 
-from gnue.common.apps import errors, plugin
+from gnue.common.base import errors, plugin
 
 
 # =============================================================================

Deleted: trunk/gnue-common/src/utils/plugin.py
===================================================================
--- trunk/gnue-common/src/utils/plugin.py       2009-10-06 13:42:11 UTC (rev 
9936)
+++ trunk/gnue-common/src/utils/plugin.py       2009-10-06 13:48:22 UTC (rev 
9937)
@@ -1,441 +0,0 @@
-# GNU Enterprise Common Library - Plugin support
-#
-# This file is part of GNU Enterprise.
-#
-# GNU Enterprise is free software; you can redistribute it
-# and/or modify it under the terms of the GNU General Public
-# License as published by the Free Software Foundation; either
-# version 2, or (at your option) any later version.
-#
-# GNU Enterprise 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 General Public License for more details.
-#
-# You should have received a copy of the GNU General Public
-# License along with program; see the file COPYING. If not,
-# write to the Free Software Foundation, Inc., 59 Temple Place
-# - Suite 330, Boston, MA 02111-1307, USA.
-#
-# Copyright 2001-2009 Free Software Foundation
-#
-# $Id$
-
-"""
-Functions to list and load avaliable plugins dynamically.
-
-Plugins are Python modules that implement a defined API and are loaded on
-demand.  Usually, there are several plugins of the same type (that means they
-implement the same API) that can be used interchangeable.  The user can select
-which plugin he wants to use.
-
-All plugins of a specific type must be Python modules in a defined package.
-For example, all database drivers must be modules in the
-gnue.common.datasources.drivers package.
-
-Any plugin must define a specific symbol (usually a class definition like
-LanguageAdapter, ClientAdapter or Connection) to qualify itself as valid.
-
-Any plugin must immediately check whether it is functional (especially whether
-all dependencies are installed), and import must fail with a meaningful
-exception otherwise.  Optionally, a module can also define a function with the
-name __initplugin__ that initializes the module and raises an exception if the
-plugin cannot be initialized.
-
-Plugins can be organized in a tree structure.  To load a plugin, any point in
-the tree may be specified.  For example, consider there are three plugins named
-base.group.foo, base.group.bar and base.group.baz.  "foo" will specify the foo
-plugin, as well as "group.foo".  Loading the plugin "group" means to load the
-first available functional plugin in the group.
-
-Modules and packages located within the plugin tree but not being valid plugins
-can define a symbol with the name __noplugin__ to indicate that they are no
-valid plugin.  Note that the module defining the __noplugin__ symbol is still
-imported, but no submodules of it. This is useful to exclude, for example,
-abstract base drivers.
-"""
-
-import os
-import sys
-
-from types import ModuleType
-from gnue.common.base import errors
-
-__all__ = ['LoadError', 'list_plugins', 'find']
-
-# =============================================================================
-# Exceptions
-# =============================================================================
-
-# -----------------------------------------------------------------------------
-# Module loading error
-# -----------------------------------------------------------------------------
-
-class LoadError(errors.AdminError):
-    """
-    Indicates a failure to load a given module.  Raised by L{find}.
-
-    If e is an Exception of this class, e.exceptions gives a dictionary with
-    the keys being the modules that were trying to be imported and the values
-    being the exception info tuples for the exception that happened trying, and
-    e.detail is a string containing basically the same info.
-    """
-    def __init__(self, name, exceptions):
-
-        self.name = name
-        self.exceptions = exceptions
-
-        if self.exceptions:
-            message = u_("Cannot load plugin '%s'") % self.name
-            detail = u_("The following plugins failed:\n")
-            for (name, exc) in self.exceptions.items():
-                detail += u"* %s: %s" % (name, exc)
-        else:
-            message = u_("Cannot find plugin '%s'") % self.name
-            detail = None
-
-        errors.AdminError.__init__(self, message)
-
-        if detail:
-            self.detail = detail
-
-
-# -----------------------------------------------------------------------------
-# List all available plugins
-# -----------------------------------------------------------------------------
-
-def list_plugins(base, identifier, try_to_init=True):
-    """
-    List all available plugins.
-
-    @param base: Name of the package that contains the plugins.
-    @param identifier: Identifier that a plugin must define to qualify as
-        module.
-    @param try_to_init: If set to False, __initplugin__ is not called.
-    @return: A dictionary with the available plugin module names as keys and
-        either the loaded module or the exception info tuple of the exception
-        raised when trying to import the module as values.
-    """
-    checktype(base, [basestring])
-    checktype(identifier, [basestring])
-
-    # Make sure everything is a string. Non-ASCII characters are not allowed in
-    # Python module names anyway.
-    _base = base.encode()
-    _identifier = identifier.encode()
-
-    # Now recursively list the plugins
-    return __list(_base, _identifier, try_to_init, True)
-
-
-# -----------------------------------------------------------------------------
-# Find a plugin
-# -----------------------------------------------------------------------------
-
-def find(name, base, identifier):
-    """
-    Find a plugin by name. If no plugin is functional, a LoadError is raised.
-
-    @param name: Name of the plugin to find.  If the plugin is foo.bar, name 
can
-        be bar, or foo.bar, or foo, where the last one returns the first
-        functional plugin in the foo group.
-    @param base: Name of the package that contains the plugins.
-    @param identifier: Identifier that a plugin must define to qualify as
-        module.
-    @return: The loaded module of the plugin.
-    """
-    checktype(name, [basestring])
-    checktype(base, [basestring])
-    checktype(identifier, [basestring])
-
-    # Make sure everything is a string. Non-ASCII characters are not allowed in
-    # Python module names anyway.
-    _name = name.encode()
-    _base = base.encode()
-    _identifier = identifier.encode()
-
-    # First, see if we've already found this module previously
-    global __findCache
-    try:
-        result = __findCache[(_base, _name)]
-    except KeyError:
-        # If not, search for the plugin
-        result = __findCache[(_base, _name)] = __find(_base, _name, 
_identifier)
-
-    if isinstance(result, ModuleType):
-        return result
-    else:
-        raise LoadError, (name, result)
-
-
-# -----------------------------------------------------------------------------
-# A list of all previously failed modules
-# -----------------------------------------------------------------------------
-
-# This dictionary remembers all previous failure of module imports/inits. That
-# is necessary because module initialization code is only run at first import
-# attempt.
-__failed = {}
-
-
-# -----------------------------------------------------------------------------
-# Mapping of previously found plugins
-# -----------------------------------------------------------------------------
-
-__findCache = {}
-
-
-# -----------------------------------------------------------------------------
-# Find all modules and subpackages in a package
-# -----------------------------------------------------------------------------
-
-def __modules(package, want_packages):
-
-    # package.__file__ is a directory if GImportLogger is in use. This makes it
-    # necessary to 'simulate' a package, otherwise stepping down subpackages
-    # won't work.
-    if os.path.isdir(package.__file__):
-        (basedir, basefile) = (package.__file__, '__init__.py')
-    else:
-        (basedir, basefile) = os.path.split(package.__file__)
-
-    (basename, baseext) = os.path.splitext(basefile)
-
-    if basename != '__init__':
-        # This is not a package, so no need to go deeper
-        return []
-
-    # Find all submodules
-    result = {}
-    for subfile in os.listdir(basedir):
-        (subname, subext) = os.path.splitext(subfile)
-        subpath = os.path.join(basedir, subfile)
-        # We are only interested in Python modules or packages
-        if (not want_packages and subext in ['.py', '.pyc', '.pyo'] and \
-            subname != '__init__') or \
-           (os.path.isdir(subpath) and \
-            os.path.isfile(os.path.join(subpath, '__init__.py')) or \
-            os.path.isfile(os.path.join(subpath, '__init__.pyc')) or \
-            os.path.isfile(os.path.join(subpath, '__init__.pyo'))):
-            result[subname] = True
-
-    return result.keys()
-
-
-# -----------------------------------------------------------------------------
-# Recursively list all plugins
-# -----------------------------------------------------------------------------
-
-def __list(base, identifier, try_to_init, top):
-
-    global __failed
-
-    if __failed.has_key(base):
-        # This has already failed in previous attempt
-        return {base: __failed[base]}
-
-    try:
-        mod = __import__(base, None, None, '*')
-    except Exception, e:
-        __failed[base] = e
-        return {base: __failed[base]}
-
-    if hasattr(mod, '__noplugin__'):
-        # This is not a plugin, ignore it
-        return {}
-
-    if not top:
-        if hasattr(mod, identifier):
-            # This is already a plugin, no need to go deeper
-            if try_to_init and hasattr(mod, '__initplugin__'):
-                try:
-                    mod.__initplugin__()
-                except Exception, e:
-                    __failed[base] = e
-                    return {base: __failed[base]}
-            return {base: mod}
-
-    # List all submodules
-    result = {}
-    for sub in __modules(mod, False):
-        result.update(__list(base + '.' + sub, identifier, try_to_init, False))
-    return result
-
-
-# -----------------------------------------------------------------------------
-# Recursively find first available plugin and return the module or a dictionary
-# with the exceptions that occured
-# -----------------------------------------------------------------------------
-
-def __first(base, identifier):
-
-    global __failed
-
-    if __failed.has_key(base):
-        # This has already failed in previous attempt
-        return {base: __failed[base]}
-
-    try:
-        mod = __import__(base, None, None, '*')
-    except Exception, e:
-        __failed[base] = e
-        return {base: __failed[base]}
-
-    if hasattr(mod, '__noplugin__'):
-        # This is not a plugin, ignore it
-        return {}
-
-    if hasattr(mod, identifier):
-        # This is already a plugin, no need to go deeper
-        if hasattr(mod, '__initplugin__'):
-            try:
-                mod.__initplugin__()
-            except Exception, e:
-                __failed[base] = e
-                return {base: __failed[base]}
-        return mod
-
-    # Search all submodules
-    exceptions = {}
-    for sub in __modules(mod, False):
-        result = __first(base + '.' + sub, identifier)
-        if isinstance(result, ModuleType):
-            return result
-        exceptions.update(result)
-    return exceptions
-
-
-# -----------------------------------------------------------------------------
-# Recursively search for a plugin and return the module or the exceptions that
-# occured
-# -----------------------------------------------------------------------------
-
-def __find(base, name, identifier):
-
-    if __failed.has_key(base):
-        # This has already failed in previous attempt
-        return {base: __failed[base]}
-
-    try:
-        mod = __import__(base, None, None, '*')
-    except Exception, e:
-        __failed[base] = e
-        return {base: __failed[base]}
-
-    if hasattr(mod, '__noplugin__'):
-        # This is not a plugin, ignore it
-        return {}
-
-    # Is the searched driver an alias of this module?
-    if hasattr(mod, '__pluginalias__'):
-        if name in mod.__pluginalias__:
-            return __first(base, identifier)
-
-    if __failed.has_key(base + '.' + name):
-        # This has already failed in previous attempt
-        return {base + '.' + name: __failed[base + '.' + name]}
-
-    try:
-        mod = __import__(base + '.' + name, None, None, '*')
-    except ImportError:
-        pass
-    except Exception, e:
-        __failed[base + '.' + name] = e
-        return {base + '.' + name: __failed[base + '.' + name]}
-    else:
-        return __first(base + '.' + name, identifier)
-
-    # Search all submodules
-    exceptions = {}
-    for sub in __modules(mod, False):
-        result = __find(base + '.' + sub, name, identifier)
-        if isinstance(result, ModuleType):
-            return result
-        exceptions.update(result)
-
-    return exceptions
-
-
-# =============================================================================
-# Self test code
-# =============================================================================
-
-if __name__ == '__main__':
-
-    basep = 'gnue.common.datasources.drivers'
-
-    if len(sys.argv) == 1:
-
-        # List all modules
-        for (iname, iresult) in(list_plugins(basep, 'Connection')).items():
-            print iname[len(basep)+1:]  + ":",
-            if isinstance(iresult, ModuleType):
-                print "ok"
-            else:
-                print unicode(iresult)
-
-    elif sys.argv[1] == 'test':
-
-        try:
-            print 'find "postgresql.popy":',
-            fmod = find('postgresql.popy', basep, 'Connection')
-            print fmod.__name__
-        except LoadError, e:
-            print e
-            print "Detail:"
-            print o(e.detail),
-
-        print
-
-        try:
-            print 'find "pygresql":',
-            fmod = find('pygresql', basep, 'Connection')
-            print fmod.__name__
-        except LoadError, e:
-            print e
-            print "Detail:"
-            print o(e.detail),
-
-        print
-
-        try:
-            print 'find "mysql":',
-            fmod = find('mysql', basep, 'Connection')
-            print fmod.__name__
-        except LoadError, e:
-            print e
-            print "Detail:"
-            print o(e.detail),
-
-        print
-
-        try:
-            print 'find "oracle":',
-            fmod = find('oracle', basep, 'Connection')
-            print fmod.__name__
-        except LoadError, e:
-            print e
-            print "Detail:"
-            print o(e.detail),
-
-        print
-
-        try:
-            print 'find "nonexistent":',
-            fmod = find('nonexistent', basep, 'Connection')
-            print fmod.__name__
-        except LoadError, e:
-            print e
-            print "Detail:"
-            print o(e.detail),
-
-    else:
-
-        try:
-            print 'find %s:' % sys.argv[1],
-            fmod = find(sys.argv[1], basep, 'Connection')
-            print fmod.__name__
-        except LoadError, e:
-            print e
-            print "Detail:"
-            print o(e.detail),

Modified: trunk/gnue-common/utils/helpers/info.py
===================================================================
--- trunk/gnue-common/utils/helpers/info.py     2009-10-06 13:42:11 UTC (rev 
9936)
+++ trunk/gnue-common/utils/helpers/info.py     2009-10-06 13:48:22 UTC (rev 
9937)
@@ -1,7 +1,7 @@
 import sys, os, string, time, gnue
 from files import openModuleFile, importModule, SubheadedFile, SVN_BASE
 from StringIO import StringIO
-from gnue.common.apps import plugin
+from gnue.common.base import plugin
 
 ##
 ##





reply via email to

[Prev in Thread] Current Thread [Next in Thread]