diff --git a/python/src/com/jetbrains/python/psi/PyUtil.java b/python/src/com/jetbrains/python/psi/PyUtil.java
index f6f0c0703e7f..e135709437fc 100644
--- a/python/src/com/jetbrains/python/psi/PyUtil.java
+++ b/python/src/com/jetbrains/python/psi/PyUtil.java
@@ -24,10 +24,7 @@ import com.intellij.openapi.ui.MessageType;
import com.intellij.openapi.ui.popup.Balloon;
import com.intellij.openapi.ui.popup.JBPopupFactory;
import com.intellij.openapi.wm.WindowManager;
-import com.intellij.psi.PsiDocumentManager;
-import com.intellij.psi.PsiElement;
-import com.intellij.psi.PsiFile;
-import com.intellij.psi.TokenType;
+import com.intellij.psi.*;
import com.intellij.ui.awt.RelativePoint;
import com.intellij.util.IncorrectOperationException;
import com.jetbrains.python.PythonLanguage;
@@ -40,6 +37,7 @@ import java.awt.*;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;
+import java.util.regex.Pattern;
public class PyUtil {
private PyUtil() {
@@ -202,6 +200,14 @@ public class PyUtil {
return node != null && node.getElementType().equals(TokenType.WHITE_SPACE);
}
+
+ @Nullable
+ public static PsiElement getFirstNonCommentAfter(PsiElement start) {
+ PsiElement seeker = start;
+ while (seeker instanceof PsiWhiteSpace || seeker instanceof PsiComment) seeker = seeker.getNextSibling();
+ return seeker;
+ }
+
/**
* @see PyUtil#flattenedParens
*/
@@ -395,4 +401,16 @@ public class PyUtil {
if (! isLast) node.addChild(gen.createComma(project), beforeThis);
}
+
+ private static Pattern IDENTIFIER_PATTERN = Pattern.compile("\\p{javaJavaIdentifierStart}\\p{javaJavaIdentifierPart}*");
+
+ /**
+ * @param name to be tested
+ * @return true iff the name is a valid Python identifier.
+ * Note: it allows unicode names which only Py3k supports.
+ */
+ public static boolean isIdentifier(String name) {
+ return IDENTIFIER_PATTERN.matcher(name).matches();
+ }
+
}
diff --git a/python/src/com/jetbrains/python/psi/impl/PyReferenceExpressionImpl.java b/python/src/com/jetbrains/python/psi/impl/PyReferenceExpressionImpl.java
index 5c6f99e2f103..b59e80a5bc65 100644
--- a/python/src/com/jetbrains/python/psi/impl/PyReferenceExpressionImpl.java
+++ b/python/src/com/jetbrains/python/psi/impl/PyReferenceExpressionImpl.java
@@ -30,6 +30,7 @@ import com.intellij.psi.impl.source.resolve.ResolveCache;
import com.intellij.psi.scope.PsiScopeProcessor;
import com.intellij.psi.util.PsiTreeUtil;
import com.intellij.util.IncorrectOperationException;
+import com.intellij.util.ProcessingContext;
import com.intellij.util.containers.SortedList;
import com.jetbrains.python.PyElementTypes;
import com.jetbrains.python.PyIcons;
@@ -391,15 +392,24 @@ public class PyReferenceExpressionImpl extends PyElementImpl implements PyRefere
final PyExpression qualifier = getQualifier();
if (qualifier != null) {
PyType qualifierType = qualifier.getType();
+ ProcessingContext ctx = new ProcessingContext();
+ final Set names_already = new HashSet();
+ ctx.put(PyType.CTX_NAMES, names_already);
if (qualifierType != null) {
- ArrayList