diff options
Diffstat (limited to 'manager.py')
-rw-r--r-- | manager.py | 162 |
1 files changed, 27 insertions, 135 deletions
@@ -46,7 +46,7 @@ from logilab.common.modutils import NoSourceFile, is_python_source, \ get_module_files, get_source_file, zipimport from logilab.common.configuration import OptionsProviderMixIn -from logilab.astng._exceptions import ASTNGBuildingException +from logilab.astng.exceptions import ASTNGBuildingException def astng_wrapper(func, modname): """wrapper to give to ASTNGManager.project_from_files""" @@ -55,12 +55,14 @@ def astng_wrapper(func, modname): return func(modname) except ASTNGBuildingException, exc: print exc - except KeyboardInterrupt: - raise except Exception, exc: import traceback traceback.print_exc() +def _silent_no_wrap(func, modname): + """silent wrapper that doesn't do anything; can be used for tests""" + return func(modname) + def safe_repr(obj): try: return repr(obj) @@ -95,15 +97,9 @@ class ASTNGManager(OptionsProviderMixIn): OptionsProviderMixIn.__init__(self) self.load_defaults() # NOTE: cache entries are added by the [re]builder - self._cache = {} + self.astng_cache = {} self._mod_file_cache = {} - def from_directory(self, directory, modname=None): - """given a module name, return the astng object""" - # FIXME : seems to be dead or unused code - modname = modname or basename(directory) - directory = abspath(directory) - return Package(directory, modname, self) def astng_from_file(self, filepath, modname=None, fallback=True, source=False): """given a module name, return the astng object""" @@ -117,21 +113,11 @@ class ASTNGManager(OptionsProviderMixIn): modname = '.'.join(modpath_from_file(filepath)) except ImportError: modname = filepath - if modname in self._cache: - return self._cache[modname] + if modname in self.astng_cache: + return self.astng_cache[modname] if source: - try: - from logilab.astng.builder import ASTNGBuilder - return ASTNGBuilder(self).file_build(filepath, modname) - except (SyntaxError, KeyboardInterrupt, SystemExit): - raise - except Exception, ex: - if __debug__: - print 'error while building astng for', filepath - import traceback - traceback.print_exc() - msg = 'Unable to load module %s (%s)' % (modname, ex) - raise ASTNGBuildingException, msg, sys.exc_info()[-1] + from logilab.astng.builder import ASTNGBuilder + return ASTNGBuilder(self).file_build(filepath, modname) elif fallback and modname: return self.astng_from_module_name(modname) raise ASTNGBuildingException('unable to get astng for file %s' % @@ -139,8 +125,8 @@ class ASTNGManager(OptionsProviderMixIn): def astng_from_module_name(self, modname, context_file=None): """given a module name, return the astng object""" - if modname in self._cache: - return self._cache[modname] + if modname in self.astng_cache: + return self.astng_cache[modname] old_cwd = os.getcwd() if context_file: os.chdir(dirname(context_file)) @@ -153,9 +139,7 @@ class ASTNGManager(OptionsProviderMixIn): if filepath is None or not is_python_source(filepath): try: module = load_module_from_name(modname) - # catch SystemError as well, we may get that on badly - # initialized C-module - except (SystemError, ImportError), ex: + except Exception, ex: msg = 'Unable to load module %s (%s)' % (modname, ex) raise ASTNGBuildingException(msg) return self.astng_from_module(module, modname) @@ -203,8 +187,8 @@ class ASTNGManager(OptionsProviderMixIn): def astng_from_module(self, module, modname=None): """given an imported module, return the astng object""" modname = modname or module.__name__ - if modname in self._cache: - return self._cache[modname] + if modname in self.astng_cache: + return self.astng_cache[modname] try: # some builtin modules don't have __file__ attribute filepath = module.__file__ @@ -227,22 +211,21 @@ class ASTNGManager(OptionsProviderMixIn): return modastng.getattr(klass.__name__)[0] # XXX - def infer_astng_from_something(self, obj, modname=None, context=None): + def infer_astng_from_something(self, obj, context=None): """infer astng for the given class""" if hasattr(obj, '__class__') and not isinstance(obj, type): klass = obj.__class__ else: klass = obj - if modname is None: - try: - modname = klass.__module__ - except AttributeError: - raise ASTNGBuildingException( - 'Unable to get module for %s' % safe_repr(klass)) - except Exception, ex: - raise ASTNGBuildingException( - 'Unexpected error while retrieving module for %s: %s' - % (safe_repr(klass), ex)) + try: + modname = klass.__module__ + except AttributeError: + raise ASTNGBuildingException( + 'Unable to get module for %s' % safe_repr(klass)) + except Exception, ex: + raise ASTNGBuildingException( + 'Unexpected error while retrieving module for %s: %s' + % (safe_repr(klass), ex)) try: name = klass.__name__ except AttributeError: @@ -278,6 +261,7 @@ class ASTNGManager(OptionsProviderMixIn): astng = func_wrapper(self.astng_from_file, fpath) if astng is None: continue + # XXX why is first file defining the project.path ? project.path = project.path or astng.file project.add_module(astng) base_name = astng.name @@ -293,99 +277,6 @@ class ASTNGManager(OptionsProviderMixIn): return project - -# FIXME : seems to be dead or unused code -class Package: - """a package using a dictionary like interface - - load submodules lazily, as they are needed - """ - - def __init__(self, path, name, manager): - self.name = name - self.path = abspath(path) - self.manager = manager - self.parent = None - self.lineno = 0 - self.__keys = None - self.__subobjects = None - - def fullname(self): - """return the full name of the package (i.e. prefix by the full name - of the parent package if any - """ - if self.parent is None: - return self.name - return '%s.%s' % (self.parent.fullname(), self.name) - - def get_subobject(self, name): - """method used to get sub-objects lazily : sub package or module are - only build once they are requested - """ - if self.__subobjects is None: - try: - self.__subobjects = dict.fromkeys(self.keys()) - except AttributeError: - # python <= 2.3 - self.__subobjects = dict([(k, None) for k in self.keys()]) - obj = self.__subobjects[name] - if obj is None: - objpath = join(self.path, name) - if isdir(objpath): - obj = Package(objpath, name, self.manager) - obj.parent = self - else: - modname = '%s.%s' % (self.fullname(), name) - obj = self.manager.astng_from_file(objpath + '.py', modname) - self.__subobjects[name] = obj - return obj - - def get_module(self, modname): - """return the Module or Package object with the given name if any - """ - path = modname.split('.') - if path[0] != self.name: - raise KeyError(modname) - obj = self - for part in path[1:]: - obj = obj.get_subobject(part) - return obj - - def keys(self): - if self.__keys is None: - self.__keys = [] - for fname in os.listdir(self.path): - if fname.endswith('.py'): - self.__keys.append(fname[:-3]) - continue - fpath = join(self.path, fname) - if isdir(fpath) and exists(join(fpath, '__init__.py')): - self.__keys.append(fname) - self.__keys.sort() - return self.__keys[:] - - def values(self): - return [self.get_subobject(name) for name in self.keys()] - - def items(self): - return zip(self.keys(), self.values()) - - def get(self, name, default=None): - try: - return self.get_subobject(name) - except KeyError: - return default - - def __getitem__(self, name): - return self.get_subobject(name) - - def __contains__(self, name): - return bool(self.get(name)) - - def __iter__(self): - return iter(self.keys()) - - class Project: """a project handle a set of modules / packages""" def __init__(self, name=''): @@ -413,3 +304,4 @@ class Project: return '<Project %r at %s (%s modules)>' % (self.name, id(self), len(self.modules)) + |