diff --git a/python/src/com/jetbrains/python/psi/impl/PyBlockEvaluator.java b/python/src/com/jetbrains/python/psi/impl/PyBlockEvaluator.java index f23ed3ac06cf..36e67a166765 100644 --- a/python/src/com/jetbrains/python/psi/impl/PyBlockEvaluator.java +++ b/python/src/com/jetbrains/python/psi/impl/PyBlockEvaluator.java @@ -17,6 +17,7 @@ package com.jetbrains.python.psi.impl; import com.intellij.openapi.vfs.VirtualFile; import com.intellij.psi.PsiElement; +import com.intellij.psi.util.QualifiedName; import com.jetbrains.python.PyNames; import com.jetbrains.python.psi.*; import org.jetbrains.annotations.NotNull; @@ -148,19 +149,21 @@ public class PyBlockEvaluator { myDeclarations.putAll(importEvaluator.myDeclarations); } else { - for (PyImportElement element : node.getImportElements()) { - Object value = importEvaluator.myNamespace.get(element.getName()); - String name = element.getAsName(); - if (name == null) { - name = element.getName(); + for (final PyImportElement element : node.getImportElements()) { + final String nameOfVarInOurModule = element.getVisibleName(); + final QualifiedName nameOfVarInExternalModule = element.getImportedQName(); + if ((nameOfVarInOurModule == null) || (nameOfVarInExternalModule == null)) { + continue; } - myNamespace.put(name, value); - List declarations = importEvaluator.getDeclarations(name); - if (myDeclarations.containsKey(name)) { - myDeclarations.get(name).addAll(declarations); + + final Object value = importEvaluator.myNamespace.get(nameOfVarInExternalModule.toString()); + myNamespace.put(nameOfVarInOurModule, value); + final List declarations = importEvaluator.getDeclarations(nameOfVarInOurModule); + if (myDeclarations.containsKey(nameOfVarInOurModule)) { + myDeclarations.get(nameOfVarInOurModule).addAll(declarations); } else { - myDeclarations.put(name, declarations); + myDeclarations.put(nameOfVarInOurModule, declarations); } } } diff --git a/python/src/com/jetbrains/python/psi/impl/PyImportElementImpl.java b/python/src/com/jetbrains/python/psi/impl/PyImportElementImpl.java index 70e3ecf44e9b..de8b51734a13 100644 --- a/python/src/com/jetbrains/python/psi/impl/PyImportElementImpl.java +++ b/python/src/com/jetbrains/python/psi/impl/PyImportElementImpl.java @@ -83,6 +83,7 @@ public class PyImportElementImpl extends PyBaseElementImpl return element != null ? element.getName() : null; } + @Override @Nullable public String getVisibleName() { final PyImportElementStub stub = getStub(); diff --git a/python/testData/blockEvaluator/external_module.py b/python/testData/blockEvaluator/external_module.py new file mode 100644 index 000000000000..9371c18edc0d --- /dev/null +++ b/python/testData/blockEvaluator/external_module.py @@ -0,0 +1,4 @@ +SOME_VARIABLE = "42" +SOME_LIST = ['a', 'b'] + + diff --git a/python/testData/blockEvaluator/my_module.py b/python/testData/blockEvaluator/my_module.py new file mode 100644 index 000000000000..b726b47815a9 --- /dev/null +++ b/python/testData/blockEvaluator/my_module.py @@ -0,0 +1,9 @@ +__author__ = 'Ilya.Kazakevich' +from external_module import SOME_VARIABLE, SOME_LIST +from some_package import VARIABLE_IN_PACKAGE +from some_package.module_in_package import * +from some_package.another_module_in_package import VARIABLE_IN_PACKAGE_MODULE_2 as MY_RENAMED_VAR + + +SOME_LIST += ['c', 'd'] + diff --git a/python/testData/blockEvaluator/some_package/__init__.py b/python/testData/blockEvaluator/some_package/__init__.py new file mode 100644 index 000000000000..7acfca7aabe7 --- /dev/null +++ b/python/testData/blockEvaluator/some_package/__init__.py @@ -0,0 +1,2 @@ +__author__ = 'Ilya.Kazakevich' +VARIABLE_IN_PACKAGE = "foo" \ No newline at end of file diff --git a/python/testData/blockEvaluator/some_package/another_module_in_package.py b/python/testData/blockEvaluator/some_package/another_module_in_package.py new file mode 100644 index 000000000000..a8ef7c9dc279 --- /dev/null +++ b/python/testData/blockEvaluator/some_package/another_module_in_package.py @@ -0,0 +1,2 @@ +__author__ = 'Ilya.Kazakevich' +VARIABLE_IN_PACKAGE_MODULE_2 = "foo" diff --git a/python/testData/blockEvaluator/some_package/module_in_package.py b/python/testData/blockEvaluator/some_package/module_in_package.py new file mode 100644 index 000000000000..1ed3bcb7cff0 --- /dev/null +++ b/python/testData/blockEvaluator/some_package/module_in_package.py @@ -0,0 +1,2 @@ +__author__ = 'Ilya.Kazakevich' +VARIABLE_IN_PACKAGE_MODULE = "foo" diff --git a/python/testSrc/com/jetbrains/python/PyBlockEvaluatorTest.java b/python/testSrc/com/jetbrains/python/PyBlockEvaluatorTest.java index 3fd0a0a60101..368c05556ef0 100644 --- a/python/testSrc/com/jetbrains/python/PyBlockEvaluatorTest.java +++ b/python/testSrc/com/jetbrains/python/PyBlockEvaluatorTest.java @@ -20,7 +20,9 @@ import com.jetbrains.python.fixtures.PyTestCase; import com.jetbrains.python.psi.PyFile; import com.jetbrains.python.psi.PyFunction; import com.jetbrains.python.psi.PyStringLiteralExpression; +import com.jetbrains.python.psi.PyUtil; import com.jetbrains.python.psi.impl.PyBlockEvaluator; +import org.junit.Assert; import java.util.ArrayList; import java.util.Arrays; @@ -64,42 +66,60 @@ public class PyBlockEvaluatorTest extends PyTestCase { public void testDict() { PyBlockEvaluator eval = doEvaluate("a={'b': 'c'}"); - Map map = (Map) eval.getValue("a"); + Map map = (Map)eval.getValue("a"); assertEquals(1, map.size()); assertEquals("c", map.get("b")); } public void testDictNoEvaluate() { PyBlockEvaluator eval = doEvaluate("a={'b': 'c'}", true); - Map map = (Map) eval.getValue("a"); + Map map = (Map)eval.getValue("a"); assertEquals(1, map.size()); assertTrue(map.get("b") instanceof PyStringLiteralExpression); } public void testDictAssign() { PyBlockEvaluator eval = doEvaluate("a={}\na['b']='c'"); - Map map = (Map) eval.getValue("a"); + Map map = (Map)eval.getValue("a"); assertEquals(1, map.size()); assertEquals("c", map.get("b")); } public void testDictAssignNoEvaluate() { PyBlockEvaluator eval = doEvaluate("a={}\na['b']='c'", true); - Map map = (Map) eval.getValue("a"); + Map map = (Map)eval.getValue("a"); assertEquals(1, map.size()); assertTrue(map.get("b") instanceof PyStringLiteralExpression); } public void testDictUpdate() { PyBlockEvaluator eval = doEvaluate("a={}\na.update({'b': 'c'})"); - Map map = (Map) eval.getValue("a"); + Map map = (Map)eval.getValue("a"); assertEquals(1, map.size()); assertEquals("c", map.get("b")); } + /** + * Ensures module has any vars imported from external modules + */ + public void testImport() { + myFixture.copyDirectoryToProject("blockEvaluator", ""); + final PyFile file = PyUtil.as(myFixture.configureByFile("my_module.py"), PyFile.class); + assert file != null : "Failed to read file"; + final PyBlockEvaluator sut = new PyBlockEvaluator(); + sut.evaluate(file); + + Assert.assertEquals("Failed to read var from package module", "foo", sut.getValueAsString("VARIABLE_IN_PACKAGE_MODULE")); + Assert.assertEquals("Failed to read var from package", "foo", sut.getValueAsString("VARIABLE_IN_PACKAGE")); + Assert.assertEquals("Failed to read list from another module", Arrays.asList("a", "b", "c", "d"), sut.getValueAsList("SOME_LIST")); + Assert.assertEquals("Failed to read var from another module", "42", sut.getValueAsString("SOME_VARIABLE")); + Assert.assertEquals("Failed to read var from another module with alias", "foo", sut.getValueAsString("MY_RENAMED_VAR")); + } + public void testFunction() { PyBlockEvaluator eval = new PyBlockEvaluator(); - PyFile file = (PyFile)PsiFileFactory.getInstance(myFixture.getProject()).createFileFromText("a.py", PythonFileType.INSTANCE, "def foo(): return 'a'"); + PyFile file = (PyFile)PsiFileFactory.getInstance(myFixture.getProject()) + .createFileFromText("a.py", PythonFileType.INSTANCE, "def foo(): return 'a'"); PyFunction foo = file.findTopLevelFunction("foo"); eval.evaluate(foo); assertEquals("a", eval.getReturnValue());