1# _________________________________________________________________________ 2# 3# PyUtilib: A Python utility library. 4# Copyright (c) 2008 Sandia Corporation. 5# This software is distributed under the BSD License. 6# Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation, 7# the U.S. Government retains certain rights in this software. 8# _________________________________________________________________________ 9 10# This software is adapted from the Trac software (specifically, the trac.core 11# module. The Trac copyright statement is included below. 12 13__all__ = ['EggLoader'] 14 15import os 16import sys 17import logging 18from pyutilib.component.config import ManagedPlugin 19from pyutilib.component.core import implements, ExtensionPoint, IPluginLoader 20 21logger = logging.getLogger('pyutilib.component.core.pca') 22pkg_resources_avail = None 23 24def _check_pkg_resources(): 25 # Defer import of pkg_resources until the EggLoader actually needs 26 # it: loading pkg_resources is relatively slow, so this avoids the 27 # time penalty every time pyutilib is imported. 28 global pkg_resources_avail 29 global pkg_resources 30 try: 31 if 'pkg_resources' not in sys.modules: 32 # 33 # Avoid a re-import, which causes setup.py warnings... 34 # 35 import pkg_resources 36 else: 37 pkg_resources = sys.modules['pkg_resources'] 38 pkg_resources_avail = True 39 except ImportError: 40 pkg_resources_avail = False 41 42def pkg_environment(path): 43 if pkg_resources_avail is None: 44 _check_pkg_resources() 45 return pkg_resources.Environment(path) if pkg_resources_avail else None 46 47class EggLoader(ManagedPlugin): 48 """ 49 Loader that looks for Python egg files in the plugins directories. 50 These files get exampled with the pkg_resources package, and 51 Plugin classes are loaded. 52 53 Note: this plugin should not be directly constructed. Instead, 54 the user should employ the PluginFactory_EggLoader function. 55 """ 56 57 implements(IPluginLoader, service=True) 58 59 def __init__(self, **kwds): 60 """EggLoader constructor. The 'namespace' keyword option is 61 required.""" 62 if 'name' not in kwds: 63 kwds['name'] = "EggLoader." + kwds['namespace'] 64 super(EggLoader, self).__init__(**kwds) 65 self.entry_point_name = kwds['namespace'] + ".plugins" 66 if pkg_resources_avail is None: 67 _check_pkg_resources() 68 if not pkg_resources_avail: 69 logger.warning( 70 'A dummy EggLoader service is being constructed, because the pkg_resources package is not available on this machine.') 71 72 def load(self, env, search_path, disable_re, name_re): 73 generate_debug_messages = __debug__ and env.log.isEnabledFor( 74 logging.DEBUG) 75 if not pkg_resources_avail: 76 if generate_debug_messages: 77 env.log.debug( 78 'The EggLoader service is terminating early because the pkg_resources package is not available on this machine.') 79 return 80 81 working_set = pkg_resources.working_set 82 83 env.log.info('BEGIN - Loading plugins with an EggLoader service') 84 distributions, errors = working_set.find_plugins( 85 pkg_resources.Environment(search_path)) 86 for dist in distributions: 87 if name_re.match(str(dist)): 88 if generate_debug_messages: 89 env.log.debug('Adding plugin %r from %r', dist, 90 dist.location) 91 working_set.add(dist) 92 else: 93 if generate_debug_messages: 94 env.log.debug('Ignoring plugin %r from %r', dist, 95 dist.location) 96 97 def _log_error(item, e): 98 gen_debug = __debug__ and env.log.isEnabledFor(logging.DEBUG) 99 if isinstance(e, pkg_resources.DistributionNotFound): 100 if gen_debug: 101 env.log.debug('Skipping "%s": ("%s" not found)', item, e) 102 elif isinstance(e, pkg_resources.VersionConflict): 103 if gen_debug: 104 env.log.debug('Skipping "%s": (version conflict "%s")', 105 item, e) 106 elif isinstance(e, pkg_resources.UnknownExtra): 107 env.log.error('Skipping "%s": (unknown extra "%s")', item, e) 108 elif isinstance(e, ImportError): 109 env.log.error('Skipping "%s": (can\'t import "%s")', item, e) 110 else: 111 env.log.error('Skipping "%s": (error "%s")', item, e) 112 113 for dist, e in errors.items(): 114 _log_error(dist, e) 115 116 for entry in working_set.iter_entry_points(self.entry_point_name): 117 if generate_debug_messages: 118 env.log.debug('Loading %r from %r', entry.name, 119 entry.dist.location) 120 try: 121 entry.load(require=True) 122 except (ImportError, 123 pkg_resources.DistributionNotFound, 124 pkg_resources.VersionConflict, 125 pkg_resources.UnknownExtra): 126 e = sys.exc_info()[1] 127 _log_error(entry, e) 128 else: 129 if not disable_re.match(os.path.dirname( 130 entry.module_name)) is None: 131 #_enable_plugin(env, entry.module_name) 132 pass 133 134 env.log.info('END - Loading plugins with an EggLoader service') 135 136# Copyright (C) 2005-2008 Edgewall Software 137# Copyright (C) 2005-2006 Christopher Lenz <cmlenz@gmx.de> 138# All rights reserved. 139# 140# This software is licensed as described in the file COPYING, which 141# you should have received as part of this distribution. The terms 142# are also available at http://trac.edgewall.org/wiki/TracLicense. 143# 144# This software consists of voluntary contributions made by many 145# individuals. For the exact contribution history, see the revision 146# history and logs, available at http://trac.edgewall.org/log/. 147# 148# Author: Christopher Lenz <cmlenz@gmx.de> 149