summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorcpopa <devnull@localhost>2014-04-29 22:39:35 +0300
committercpopa <devnull@localhost>2014-04-29 22:39:35 +0300
commit495951ce43a6eb572d52b9e0f22b51104321c1b8 (patch)
treed9dd604341805d2e0cc7ca9847343305e444e2aa
parent29fb5b02b3f120e98c815eeda5c31cff2d4f2bfb (diff)
parentee970b32970ce02e7a1ebd719a5513939db7256f (diff)
downloadastroid-495951ce43a6eb572d52b9e0f22b51104321c1b8.tar.gz
Merge with default.
-rw-r--r--ChangeLog6
-rw-r--r--builder.py5
-rw-r--r--manager.py5
-rw-r--r--raw_building.py3
-rw-r--r--scoped_nodes.py4
-rw-r--r--test/unittest_builder.py16
6 files changed, 36 insertions, 3 deletions
diff --git a/ChangeLog b/ChangeLog
index 5c2c659..d6d34c9 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -2,9 +2,15 @@ Change log for the astroid package (used to be astng)
=====================================================
--
+
+ * Do not cache modules if a module with the same qname is already
+ known, and only return cached modules if both name and filepath
+ match. Fixes pylint Bitbucket issue #136.
+
* `Class.metaclass()` looks in ancestors when the current class
does not define explicitly a metaclass.
+
2014-04-18 -- 1.1.0
* All class nodes are marked as new style classes for Py3k.
diff --git a/builder.py b/builder.py
index 0271f71..b6ceff8 100644
--- a/builder.py
+++ b/builder.py
@@ -145,9 +145,12 @@ class AstroidBuilder(InspectBuilder):
after a module has been built
"""
module.file_encoding = encoding
- self._manager.astroid_cache[module.name] = module
+ self._manager.cache_module(module)
# post tree building steps after we stored the module in the cache:
for from_node in module._from_nodes:
+ if from_node.modname == '__future__':
+ for symbol, _ in from_node.names:
+ module.future_imports.add(symbol)
self.add_from_names_to_locals(from_node)
# handle delayed assattr nodes
for delayed in module._delayed_assattr:
diff --git a/manager.py b/manager.py
index 273bf06..058e845 100644
--- a/manager.py
+++ b/manager.py
@@ -97,7 +97,7 @@ class AstroidManager(OptionsProviderMixIn):
modname = '.'.join(modpath_from_file(filepath))
except ImportError:
modname = filepath
- if modname in self.astroid_cache:
+ if modname in self.astroid_cache and self.astroid_cache[modname].file == filepath:
return self.astroid_cache[modname]
if source:
from astroid.builder import AstroidBuilder
@@ -301,6 +301,9 @@ class AstroidManager(OptionsProviderMixIn):
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)
class Project(object):
diff --git a/raw_building.py b/raw_building.py
index 720cdce..bb685a9 100644
--- a/raw_building.py
+++ b/raw_building.py
@@ -225,7 +225,8 @@ class InspectBuilder(object):
# in jython, java modules have no __doc__ (see #109562)
node = build_module(modname)
node.file = node.path = path and abspath(path) or path
- MANAGER.astroid_cache[modname] = node
+ node.name = modname
+ MANAGER.cache_module(node)
node.package = hasattr(module, '__path__')
self._done = {}
self.object_build(node, module)
diff --git a/scoped_nodes.py b/scoped_nodes.py
index c306538..067f01f 100644
--- a/scoped_nodes.py
+++ b/scoped_nodes.py
@@ -236,6 +236,9 @@ class Module(LocalsDictNodeNG):
# as value
globals = None
+ # Future imports
+ future_imports = None
+
# names of python special attributes (handled by getattr impl.)
special_attributes = set(('__name__', '__doc__', '__file__', '__path__',
'__dict__'))
@@ -248,6 +251,7 @@ class Module(LocalsDictNodeNG):
self.pure_python = pure_python
self.locals = self.globals = {}
self.body = []
+ self.future_imports = set()
@property
def file_stream(self):
diff --git a/test/unittest_builder.py b/test/unittest_builder.py
index e4022ff..a0d8d7d 100644
--- a/test/unittest_builder.py
+++ b/test/unittest_builder.py
@@ -28,6 +28,7 @@ from astroid import builder, nodes, InferenceError, NotFoundError
from astroid.nodes import Module
from astroid.bases import YES, BUILTINS
from astroid.manager import AstroidManager
+from astroid import test_utils
MANAGER = AstroidManager()
PY3K = sys.version_info >= (3, 0)
@@ -474,6 +475,21 @@ def global_no_effect():
self.assertEqual([i.__class__ for i in n.infer()],
[YES.__class__])
+ def test_no_future_imports(self):
+ mod = test_utils.build_module("import sys")
+ self.assertEqual(set(), mod.future_imports)
+
+ def test_future_imports(self):
+ mod = test_utils.build_module("from __future__ import print_function")
+ self.assertEqual(set(['print_function']), mod.future_imports)
+
+ def test_two_future_imports(self):
+ mod = test_utils.build_module("""
+ from __future__ import print_function
+ from __future__ import absolute_import
+ """)
+ self.assertEqual(set(['print_function', 'absolute_import']), mod.future_imports)
+
class FileBuildTC(TestCase):
module = builder.AstroidBuilder().file_build(join(DATA, 'module.py'), 'data.module')