summaryrefslogtreecommitdiff
path: root/manager.py
diff options
context:
space:
mode:
Diffstat (limited to 'manager.py')
-rw-r--r--manager.py162
1 files changed, 27 insertions, 135 deletions
diff --git a/manager.py b/manager.py
index 836d0c23..5890078c 100644
--- a/manager.py
+++ b/manager.py
@@ -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))
+