From dfb2bcee8319a22803876401787a7f7687aebbed Mon Sep 17 00:00:00 2001 From: Dmitry Jemerov Date: Wed, 5 May 2010 17:09:18 +0400 Subject: [PATCH] check for existence of __init__.py in directories when resolving imports (PY-942) --- .../psi/impl/PyImportReferenceImpl.java | 25 +++++++++++++++++-- .../python/psi/resolve/ResolveImportUtil.java | 14 +++++------ python/testData/completion/__init__.py | 0 .../multiFile/reimportStar/django/__init__.py | 0 .../reimportStar/django/db/__init__.py | 0 .../python/PythonCompletionTest.java | 2 +- 6 files changed, 31 insertions(+), 10 deletions(-) create mode 100644 python/testData/completion/__init__.py create mode 100644 python/testData/resolve/multiFile/reimportStar/django/__init__.py create mode 100644 python/testData/resolve/multiFile/reimportStar/django/db/__init__.py diff --git a/python/src/com/jetbrains/python/psi/impl/PyImportReferenceImpl.java b/python/src/com/jetbrains/python/psi/impl/PyImportReferenceImpl.java index 61c52cadfc84..342a0a8ae816 100644 --- a/python/src/com/jetbrains/python/psi/impl/PyImportReferenceImpl.java +++ b/python/src/com/jetbrains/python/psi/impl/PyImportReferenceImpl.java @@ -4,7 +4,6 @@ import com.intellij.codeInsight.completion.InsertHandler; import com.intellij.codeInsight.completion.InsertionContext; import com.intellij.codeInsight.lookup.LookupElement; import com.intellij.codeInsight.lookup.LookupElementBuilder; -import com.intellij.codeInsight.lookup.LookupItem; import com.intellij.lang.ASTNode; import com.intellij.openapi.editor.Document; import com.intellij.openapi.editor.Editor; @@ -30,7 +29,6 @@ import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import java.util.*; -import java.util.HashSet; /** * @author yole @@ -264,4 +262,27 @@ public class PyImportReferenceImpl extends PyReferenceImpl { editor.getCaretModel().moveToOffset(tailOffset + IMPORT_KWD.length()); } } + + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + if (!super.equals(o)) return false; + + PyImportReferenceImpl that = (PyImportReferenceImpl)o; + + if (!myElement.equals(that.myElement)) return false; + if (!myContext.equals(that.myContext)) return false; + + return true; + } + + @Override + public int hashCode() { + int result = super.hashCode(); + result = 31 * result + myElement.hashCode(); + result = 31 * result + myContext.hashCode(); + return result; + } } diff --git a/python/src/com/jetbrains/python/psi/resolve/ResolveImportUtil.java b/python/src/com/jetbrains/python/psi/resolve/ResolveImportUtil.java index 58a967d996f7..59658367fad8 100644 --- a/python/src/com/jetbrains/python/psi/resolve/ResolveImportUtil.java +++ b/python/src/com/jetbrains/python/psi/resolve/ResolveImportUtil.java @@ -567,7 +567,6 @@ public class ResolveImportUtil { final PsiFile containingFile, boolean fileOnly) { PsiDirectory dir = null; PsiElement ret = null; - ResolveProcessor processor = null; if (parent instanceof PyFile) { if (parent.getCopyableUserData(PyFile.KEY_IS_DIRECTORY) == Boolean.TRUE) { // the file was a fake __init__.py covering a reference to dir @@ -586,13 +585,13 @@ public class ResolveImportUtil { else if (parent instanceof PsiDirectoryContainer) { final PsiDirectoryContainer container = (PsiDirectoryContainer)parent; for(PsiDirectory childDir: container.getDirectories()) { - final PsiElement result = resolveInDirectory(referencedName, containingFile, childDir, processor, fileOnly); + final PsiElement result = resolveInDirectory(referencedName, containingFile, childDir, fileOnly); //if (fileOnly && ! (result instanceof PsiFile) && ! (result instanceof PsiDirectory)) return null; if (result != null) return result; } } if (dir != null) { - final PsiElement result = resolveInDirectory(referencedName, containingFile, dir, processor, fileOnly); + final PsiElement result = resolveInDirectory(referencedName, containingFile, dir, fileOnly); //if (fileOnly && ! (result instanceof PsiFile) && ! (result instanceof PsiDirectory)) return null; return result; } @@ -600,9 +599,8 @@ public class ResolveImportUtil { } @Nullable - private static PsiElement resolveInDirectory( - final String referencedName, final PsiFile containingFile, final PsiDirectory dir, ResolveProcessor processor, boolean isFileOnly - ) { + private static PsiElement resolveInDirectory(final String referencedName, final PsiFile containingFile, + final PsiDirectory dir, boolean isFileOnly) { if (referencedName == null) return null; final PsiFile file = dir.findFile(referencedName + PyNames.DOT_PY); // findFile() does case-insensitive search, and we need exactly matching case (see PY-381) @@ -610,7 +608,9 @@ public class ResolveImportUtil { return file; } final PsiDirectory subdir = dir.findSubdirectory(referencedName); - if (subdir != null) return subdir; + if (subdir != null && subdir.findFile(PyNames.INIT_DOT_PY) != null) { + return subdir; + } else if (! isFileOnly) { // not a subdir, not a file; could be a name in parent/__init__.py final PsiFile initPy = dir.findFile(PyNames.INIT_DOT_PY); diff --git a/python/testData/completion/__init__.py b/python/testData/completion/__init__.py new file mode 100644 index 000000000000..e69de29bb2d1 diff --git a/python/testData/resolve/multiFile/reimportStar/django/__init__.py b/python/testData/resolve/multiFile/reimportStar/django/__init__.py new file mode 100644 index 000000000000..e69de29bb2d1 diff --git a/python/testData/resolve/multiFile/reimportStar/django/db/__init__.py b/python/testData/resolve/multiFile/reimportStar/django/db/__init__.py new file mode 100644 index 000000000000..e69de29bb2d1 diff --git a/python/testSrc/com/jetbrains/python/PythonCompletionTest.java b/python/testSrc/com/jetbrains/python/PythonCompletionTest.java index 9795702315d2..e706bf5ca717 100644 --- a/python/testSrc/com/jetbrains/python/PythonCompletionTest.java +++ b/python/testSrc/com/jetbrains/python/PythonCompletionTest.java @@ -89,7 +89,7 @@ public class PythonCompletionTest extends PyLightFixtureTestCase { public void testPy255() throws Exception { final String dirname = "completion/"; final String testName = dirname + "moduleClass"; - myFixture.configureByFile(testName + ".py"); + myFixture.configureByFiles(testName + ".py", dirname + "__init__.py"); myFixture.copyDirectoryToProject(dirname + "mymodule", dirname + "mymodule"); myFixture.copyDirectoryToProject(dirname + "mymodule/mysubmodule", dirname + "mymodule/mysubmodule"); myFixture.completeBasic();