Index: third_party/logilab/astng/manager.py |
diff --git a/third_party/logilab/astroid/manager.py b/third_party/logilab/astng/manager.py |
similarity index 53% |
rename from third_party/logilab/astroid/manager.py |
rename to third_party/logilab/astng/manager.py |
index fde52e2b138c5a0eb59d42125e99416b263799e7..8a4f02bb642ed2e3a348d11eaccd252418574e66 100644 |
--- a/third_party/logilab/astroid/manager.py |
+++ b/third_party/logilab/astng/manager.py |
@@ -1,45 +1,46 @@ |
-# copyright 2003-2013 LOGILAB S.A. (Paris, FRANCE), all rights reserved. |
+# copyright 2003-2011 LOGILAB S.A. (Paris, FRANCE), all rights reserved. |
# contact http://www.logilab.fr/ -- mailto:contact@logilab.fr |
+# copyright 2003-2010 Sylvain Thenault, all rights reserved. |
+# contact mailto:thenault@gmail.com |
# |
-# This file is part of astroid. |
+# This file is part of logilab-astng. |
# |
-# astroid is free software: you can redistribute it and/or modify it |
+# logilab-astng is free software: you can redistribute it and/or modify it |
# under the terms of the GNU Lesser General Public License as published by the |
# Free Software Foundation, either version 2.1 of the License, or (at your |
# option) any later version. |
# |
-# astroid is distributed in the hope that it will be useful, but |
+# logilab-astng 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 Lesser General Public License |
# for more details. |
# |
# You should have received a copy of the GNU Lesser General Public License along |
-# with astroid. If not, see <http://www.gnu.org/licenses/>. |
-"""astroid manager: avoid multiple astroid build of a same module when |
-possible by providing a class responsible to get astroid representation |
+# with logilab-astng. If not, see <http://www.gnu.org/licenses/>. |
+"""astng manager: avoid multiple astng build of a same module when |
+possible by providing a class responsible to get astng representation |
from various source and using a cache of built modules) |
""" |
__docformat__ = "restructuredtext en" |
+import sys |
import os |
-from os.path import dirname, join, isdir, exists |
-from warnings import warn |
+from os.path import dirname, basename, abspath, join, isdir, exists |
-from logilab.common.configuration import OptionsProviderMixIn |
- |
-from astroid.exceptions import AstroidBuildingException |
-from astroid.modutils import NoSourceFile, is_python_source, \ |
+from logilab.common.modutils import NoSourceFile, is_python_source, \ |
file_from_modpath, load_module_from_name, modpath_from_file, \ |
get_module_files, get_source_file, zipimport |
+from logilab.common.configuration import OptionsProviderMixIn |
+from logilab.astng.exceptions import ASTNGBuildingException |
-def astroid_wrapper(func, modname): |
- """wrapper to give to AstroidManager.project_from_files""" |
+def astng_wrapper(func, modname): |
+ """wrapper to give to ASTNGManager.project_from_files""" |
print 'parsing %s...' % modname |
try: |
return func(modname) |
- except AstroidBuildingException, exc: |
+ except ASTNGBuildingException, exc: |
print exc |
except Exception, exc: |
import traceback |
@@ -57,14 +58,14 @@ def safe_repr(obj): |
-class AstroidManager(OptionsProviderMixIn): |
- """the astroid manager, responsible to build astroid from files |
+class ASTNGManager(OptionsProviderMixIn): |
+ """the astng manager, responsible to build astng from files |
or modules. |
Use the Borg pattern. |
""" |
- name = 'astroid loader' |
+ name = 'astng loader' |
options = (("ignore", |
{'type' : "csv", 'metavar' : "<file>", |
'dest' : "black_list", "default" : ('CVS',), |
@@ -75,20 +76,20 @@ class AstroidManager(OptionsProviderMixIn): |
{'default': "No Name", 'type' : 'string', 'short': 'p', |
'metavar' : '<project name>', |
'help' : 'set the project name.'}), |
- ) |
+ ) |
brain = {} |
def __init__(self): |
- self.__dict__ = AstroidManager.brain |
+ self.__dict__ = ASTNGManager.brain |
if not self.__dict__: |
OptionsProviderMixIn.__init__(self) |
self.load_defaults() |
# NOTE: cache entries are added by the [re]builder |
- self.astroid_cache = {} |
+ self.astng_cache = {} |
self._mod_file_cache = {} |
- self.transforms = {} |
+ self.transformers = [] |
- def ast_from_file(self, filepath, modname=None, fallback=True, source=False): |
- """given a module name, return the astroid object""" |
+ def astng_from_file(self, filepath, modname=None, fallback=True, source=False): |
+ """given a module name, return the astng object""" |
try: |
filepath = get_source_file(filepath, include_no_ext=True) |
source = True |
@@ -99,23 +100,23 @@ class AstroidManager(OptionsProviderMixIn): |
modname = '.'.join(modpath_from_file(filepath)) |
except ImportError: |
modname = filepath |
- if modname in self.astroid_cache and self.astroid_cache[modname].file == filepath: |
- return self.astroid_cache[modname] |
+ if modname in self.astng_cache: |
+ return self.astng_cache[modname] |
if source: |
- from astroid.builder import AstroidBuilder |
- return AstroidBuilder(self).file_build(filepath, modname) |
+ from logilab.astng.builder import ASTNGBuilder |
+ return ASTNGBuilder(self).file_build(filepath, modname) |
elif fallback and modname: |
- return self.ast_from_module_name(modname) |
- raise AstroidBuildingException('unable to get astroid for file %s' % |
- filepath) |
- |
- def ast_from_module_name(self, modname, context_file=None): |
- """given a module name, return the astroid object""" |
- if modname in self.astroid_cache: |
- return self.astroid_cache[modname] |
+ return self.astng_from_module_name(modname) |
+ raise ASTNGBuildingException('unable to get astng for file %s' % |
+ filepath) |
+ |
+ def astng_from_module_name(self, modname, context_file=None): |
+ """given a module name, return the astng object""" |
+ if modname in self.astng_cache: |
+ return self.astng_cache[modname] |
if modname == '__main__': |
- from astroid.builder import AstroidBuilder |
- return AstroidBuilder(self).string_build('', modname) |
+ from logilab.astng.builder import ASTNGBuilder |
+ return ASTNGBuilder(self).string_build('', modname) |
old_cwd = os.getcwd() |
if context_file: |
os.chdir(dirname(context_file)) |
@@ -130,17 +131,17 @@ class AstroidManager(OptionsProviderMixIn): |
module = load_module_from_name(modname) |
except Exception, ex: |
msg = 'Unable to load module %s (%s)' % (modname, ex) |
- raise AstroidBuildingException(msg) |
- return self.ast_from_module(module, modname) |
- return self.ast_from_file(filepath, modname, fallback=False) |
+ raise ASTNGBuildingException(msg) |
+ return self.astng_from_module(module, modname) |
+ return self.astng_from_file(filepath, modname, fallback=False) |
finally: |
os.chdir(old_cwd) |
def zip_import_data(self, filepath): |
if zipimport is None: |
return None |
- from astroid.builder import AstroidBuilder |
- builder = AstroidBuilder(self) |
+ from logilab.astng.builder import ASTNGBuilder |
+ builder = ASTNGBuilder(self) |
for ext in ('.zip', '.egg'): |
try: |
eggpath, resource = filepath.rsplit(ext + '/', 1) |
@@ -150,7 +151,7 @@ class AstroidManager(OptionsProviderMixIn): |
importer = zipimport.zipimporter(eggpath + ext) |
zmodname = resource.replace('/', '.') |
if importer.is_package(resource): |
- zmodname = zmodname + '.__init__' |
+ zmodname = zmodname + '.__init__' |
module = builder.string_build(importer.get_source(resource), |
zmodname, filepath) |
return module |
@@ -167,41 +168,41 @@ class AstroidManager(OptionsProviderMixIn): |
context_file=contextfile) |
except ImportError, ex: |
msg = 'Unable to load module %s (%s)' % (modname, ex) |
- value = AstroidBuildingException(msg) |
+ value = ASTNGBuildingException(msg) |
self._mod_file_cache[(modname, contextfile)] = value |
- if isinstance(value, AstroidBuildingException): |
+ if isinstance(value, ASTNGBuildingException): |
raise value |
return value |
- def ast_from_module(self, module, modname=None): |
- """given an imported module, return the astroid object""" |
+ 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.astroid_cache: |
- return self.astroid_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__ |
if is_python_source(filepath): |
- return self.ast_from_file(filepath, modname) |
+ return self.astng_from_file(filepath, modname) |
except AttributeError: |
pass |
- from astroid.builder import AstroidBuilder |
- return AstroidBuilder(self).module_build(module, modname) |
+ from logilab.astng.builder import ASTNGBuilder |
+ return ASTNGBuilder(self).module_build(module, modname) |
- def ast_from_class(self, klass, modname=None): |
- """get astroid for the given class""" |
+ def astng_from_class(self, klass, modname=None): |
+ """get astng for the given class""" |
if modname is None: |
try: |
modname = klass.__module__ |
except AttributeError: |
- raise AstroidBuildingException( |
+ raise ASTNGBuildingException( |
'Unable to get module for class %s' % safe_repr(klass)) |
- modastroid = self.ast_from_module_name(modname) |
- return modastroid.getattr(klass.__name__)[0] # XXX |
+ modastng = self.astng_from_module_name(modname) |
+ return modastng.getattr(klass.__name__)[0] # XXX |
- def infer_ast_from_something(self, obj, context=None): |
- """infer astroid for the given class""" |
+ 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: |
@@ -209,31 +210,31 @@ class AstroidManager(OptionsProviderMixIn): |
try: |
modname = klass.__module__ |
except AttributeError: |
- raise AstroidBuildingException( |
+ raise ASTNGBuildingException( |
'Unable to get module for %s' % safe_repr(klass)) |
except Exception, ex: |
- raise AstroidBuildingException( |
+ raise ASTNGBuildingException( |
'Unexpected error while retrieving module for %s: %s' |
% (safe_repr(klass), ex)) |
try: |
name = klass.__name__ |
except AttributeError: |
- raise AstroidBuildingException( |
+ raise ASTNGBuildingException( |
'Unable to get name for %s' % safe_repr(klass)) |
except Exception, ex: |
- raise AstroidBuildingException( |
+ raise ASTNGBuildingException( |
'Unexpected error while retrieving name for %s: %s' |
% (safe_repr(klass), ex)) |
# take care, on living object __module__ is regularly wrong :( |
- modastroid = self.ast_from_module_name(modname) |
+ modastng = self.astng_from_module_name(modname) |
if klass is obj: |
- for infered in modastroid.igetattr(name, context): |
+ for infered in modastng.igetattr(name, context): |
yield infered |
else: |
- for infered in modastroid.igetattr(name, context): |
+ for infered in modastng.igetattr(name, context): |
yield infered.instanciate_class() |
- def project_from_files(self, files, func_wrapper=astroid_wrapper, |
+ def project_from_files(self, files, func_wrapper=astng_wrapper, |
project_name=None, black_list=None): |
"""return a Project from a list of files or modules""" |
# build the project representation |
@@ -247,77 +248,28 @@ class AstroidManager(OptionsProviderMixIn): |
fpath = join(something, '__init__.py') |
else: |
fpath = something |
- astroid = func_wrapper(self.ast_from_file, fpath) |
- if astroid is None: |
+ 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 astroid.file |
- project.add_module(astroid) |
- base_name = astroid.name |
+ project.path = project.path or astng.file |
+ project.add_module(astng) |
+ base_name = astng.name |
# recurse in package except if __init__ was explicitly given |
- if astroid.package and something.find('__init__') == -1: |
+ if astng.package and something.find('__init__') == -1: |
# recurse on others packages / modules if this is a package |
- for fpath in get_module_files(dirname(astroid.file), |
+ for fpath in get_module_files(dirname(astng.file), |
black_list): |
- astroid = func_wrapper(self.ast_from_file, fpath) |
- if astroid is None or astroid.name == base_name: |
+ astng = func_wrapper(self.astng_from_file, fpath) |
+ if astng is None or astng.name == base_name: |
continue |
- project.add_module(astroid) |
+ project.add_module(astng) |
return project |
- def register_transform(self, node_class, transform, predicate=None): |
- """Register `transform(node)` function to be applied on the given |
- Astroid's `node_class` if `predicate` is None or return a true value |
- when called with the node as argument. |
- |
- The transform function may return a value which is then used to |
- substitute the original node in the tree. |
- """ |
- self.transforms.setdefault(node_class, []).append((transform, predicate)) |
- |
- def unregister_transform(self, node_class, transform, predicate=None): |
- """Unregister the given transform.""" |
- self.transforms[node_class].remove((transform, predicate)) |
- |
- def transform(self, node): |
- """Call matching transforms for the given node if any and return the |
- transformed node. |
- """ |
- cls = node.__class__ |
- if cls not in self.transforms: |
- # no transform registered for this class of node |
- return node |
- |
- transforms = self.transforms[cls] |
- orig_node = node # copy the reference |
- for transform_func, predicate in transforms: |
- if predicate is None or predicate(node): |
- ret = transform_func(node) |
- # if the transformation function returns something, it's |
- # expected to be a replacement for the node |
- if ret is not None: |
- if node is not orig_node: |
- # node has already be modified by some previous |
- # transformation, warn about it |
- warn('node %s substituted multiple times' % node) |
- node = ret |
- return node |
- |
- def cache_module(self, module): |
- """Cache a module if no module with the same name is known yet.""" |
- self.astroid_cache.setdefault(module.name, module) |
- |
- def clear_cache(self): |
- self.astroid_cache.clear() |
- # force bootstrap again, else we may ends up with cache inconsistency |
- # between the manager and CONST_PROXY, making |
- # unittest_lookup.LookupTC.test_builtin_lookup fail depending on the |
- # test order |
- from astroid.raw_building import astroid_bootstrapping |
- astroid_bootstrapping() |
- |
+ def register_transformer(self, transformer): |
+ self.transformers.append(transformer) |
-class Project(object): |
+class Project: |
"""a project handle a set of modules / packages""" |
def __init__(self, name=''): |
self.name = name |