diff --git a/python/src/com/jetbrains/python/PythonFileTypeFactory.java b/python/src/com/jetbrains/python/PythonFileTypeFactory.java index 7bfcb4dff75b..7a924bb65208 100644 --- a/python/src/com/jetbrains/python/PythonFileTypeFactory.java +++ b/python/src/com/jetbrains/python/PythonFileTypeFactory.java @@ -1,15 +1,16 @@ package com.jetbrains.python; -import com.intellij.openapi.fileTypes.FileTypeFactory; import com.intellij.openapi.fileTypes.FileType; +import com.intellij.openapi.fileTypes.FileTypeFactory; import com.intellij.util.PairConsumer; +import org.jetbrains.annotations.NonNls; import org.jetbrains.annotations.NotNull; /** * @author yole */ public class PythonFileTypeFactory extends FileTypeFactory { - public void createFileTypes(final @NotNull PairConsumer consumer) { + public void createFileTypes(@NonNls @NotNull final PairConsumer consumer) { consumer.consume(PythonFileType.INSTANCE, "py"); } } diff --git a/python/src/com/jetbrains/python/psi/PyResolveUtil.java b/python/src/com/jetbrains/python/psi/PyResolveUtil.java index 5c76fe3ffed1..c682046ded8b 100644 --- a/python/src/com/jetbrains/python/psi/PyResolveUtil.java +++ b/python/src/com/jetbrains/python/psi/PyResolveUtil.java @@ -135,7 +135,10 @@ public class PyResolveUtil { // maybe we're under cap while (true) { PsiElement local_cap = getConcealingParent(seeker); - if ((local_cap != null) && (local_cap != cap)) { // only look at local cap and above + if ( + (local_cap != null) && (local_cap != cap) && // elt and seeker are under different caps and... + ((cap == null) || !PsiTreeUtil.isAncestor(local_cap, cap, true)) // elt's cap is not under local cap + ) { // only look at local cap and above if (local_cap instanceof NameDefiner) seeker = local_cap; else seeker = getPrevNodeOf(local_cap, NameDefiner.class); } diff --git a/python/src/com/jetbrains/python/psi/PyUtil.java b/python/src/com/jetbrains/python/psi/PyUtil.java index e47546e49ee4..8ae0be126bb6 100644 --- a/python/src/com/jetbrains/python/psi/PyUtil.java +++ b/python/src/com/jetbrains/python/psi/PyUtil.java @@ -194,7 +194,9 @@ public class PyUtil { return node != null && node.getElementType().equals(TokenType.WHITE_SPACE); } - + /** + * @see com.jetbrains.python.psi.PyUtil#flattenedParens(T[]) + */ protected static List _unfoldParenExprs(T[] targets, List receiver) { // NOTE: this proliferation of instanceofs is not very beautiful. Maybe rewrite using a visitor. for (T exp : targets) { @@ -207,7 +209,13 @@ public class PyUtil { } else receiver.add(exp); } - else receiver.add(exp); + else if (exp instanceof PyTupleExpression) { + final PyTupleExpression tupex = (PyTupleExpression)exp; + _unfoldParenExprs((T[])tupex.getElements(), receiver); + } + else { + receiver.add(exp); + } } return receiver; } diff --git a/python/src/com/jetbrains/python/psi/impl/ResolveImportUtil.java b/python/src/com/jetbrains/python/psi/impl/ResolveImportUtil.java index c650c42818af..7a28425e4be9 100644 --- a/python/src/com/jetbrains/python/psi/impl/ResolveImportUtil.java +++ b/python/src/com/jetbrains/python/psi/impl/ResolveImportUtil.java @@ -11,6 +11,7 @@ import com.intellij.psi.PsiFile; import com.intellij.psi.PsiManager; import com.jetbrains.python.psi.*; import org.jetbrains.annotations.Nullable; +import org.jetbrains.annotations.NonNls; import java.util.ArrayList; import java.util.Iterator; @@ -22,8 +23,8 @@ import java.util.List; public class ResolveImportUtil { /** Name of the __init__.py special file. */ - public static final String INIT_PY = "__init__.py"; - public static final String PY_SUFFIX = ".py"; + @NonNls public static final String INIT_PY = "__init__.py"; + @NonNls public static final String PY_SUFFIX = ".py"; private ResolveImportUtil() { } diff --git a/python/src/com/jetbrains/python/sdk/PythonSdkType.java b/python/src/com/jetbrains/python/sdk/PythonSdkType.java index 927b65dfffce..7cb47f49f32d 100644 --- a/python/src/com/jetbrains/python/sdk/PythonSdkType.java +++ b/python/src/com/jetbrains/python/sdk/PythonSdkType.java @@ -9,6 +9,7 @@ import com.intellij.openapi.projectRoots.*; import com.intellij.openapi.roots.OrderRootType; import com.intellij.openapi.util.SystemInfo; import com.intellij.openapi.util.io.FileUtil; +import com.intellij.openapi.vfs.JarFileSystem; import com.intellij.openapi.vfs.LocalFileSystem; import com.intellij.openapi.vfs.VfsUtil; import com.intellij.openapi.vfs.VirtualFile; @@ -181,6 +182,7 @@ public class PythonSdkType extends SdkType { } + @NonNls public String getPresentableName() { return "Python SDK"; } @@ -190,10 +192,10 @@ public class PythonSdkType extends SdkType { final SdkModificator sdkModificator = sdk.getSdkModificator(); String sdk_path = sdk.getHomePath(); String bin_path = getInterpreterPath(sdk_path); - final String stubs_path = + @NonNls final String stubs_path = PathManager.getSystemPath() + File.separator + "python_stubs" + File.separator + sdk_path.hashCode() + File.separator; // we have a number of lib dirs, those listed in python's sys.path - String script = // a script printing sys.path + @NonNls String script = // a script printing sys.path "import sys\n"+ "for x in sys.path:\n"+ " sys.stdout.write(x+chr(10))" @@ -202,12 +204,19 @@ public class PythonSdkType extends SdkType { if ((paths != null) && paths.size() > 0) { // add every path as root. for (String path: paths) { - if (path.indexOf(File.separator) < 0) continue; // TODO: interpret 'special' paths reasonably + if (path.indexOf(File.separator) < 0) continue; // TODO: interpret possible 'special' paths reasonably VirtualFile child = LocalFileSystem.getInstance().findFileByPath(path); if (child != null) { - // NOTE: maybe handle .zip / .egg files specially? - sdkModificator.addRoot(child, OrderRootType.SOURCES); - sdkModificator.addRoot(child, OrderRootType.CLASSES); + @NonNls String suffix = child.getExtension(); + if (suffix != null) suffix = suffix.toLowerCase(); // Why on earth empty suffix is null and not ""? + if ((!child.isDirectory()) && ("zip".equals(suffix) || "egg".equals(suffix))) { + // a .zip / .egg file must have its root extracted first + child = JarFileSystem.getInstance().getJarRootForLocalFile(child); + } + if (child != null) { + sdkModificator.addRoot(child, OrderRootType.SOURCES); + sdkModificator.addRoot(child, OrderRootType.CLASSES); + } } else LOG.info("Bogus sys.path entry "+path); }