diff --git a/python/helpers/pydev/pydev_monkey.py b/python/helpers/pydev/pydev_monkey.py
index 8a5471dd959d..33569151ef56 100644
--- a/python/helpers/pydev/pydev_monkey.py
+++ b/python/helpers/pydev/pydev_monkey.py
@@ -63,7 +63,14 @@ def patch_args(args):
return new_args
def args_to_str(args):
- return ' '.join(x if x.startswith('"') and x.endswith('"') else '"%s"' % x for x in args)
+ quoted_args = []
+ for x in args:
+ if x.startswith('"') and x.endswith('"'):
+ quoted_args.append(x)
+ else:
+ quoted_args.append('"%s"' % x)
+
+ return ' '.join(quoted_args)
def remove_quotes(str):
if str.startswith('"') and str.endswith('"'):
diff --git a/python/main_pycharm.iml b/python/main_pycharm.iml
index a30072725174..598ba4739eb0 100644
--- a/python/main_pycharm.iml
+++ b/python/main_pycharm.iml
@@ -25,6 +25,9 @@
+
+
+
diff --git a/python/src/com/jetbrains/python/codeInsight/PyDunderAllReference.java b/python/src/com/jetbrains/python/codeInsight/PyDunderAllReference.java
index b06a549f2f69..73e987c90e9e 100644
--- a/python/src/com/jetbrains/python/codeInsight/PyDunderAllReference.java
+++ b/python/src/com/jetbrains/python/codeInsight/PyDunderAllReference.java
@@ -1,5 +1,8 @@
package com.jetbrains.python.codeInsight;
+import com.intellij.codeInsight.lookup.LookupElement;
+import com.intellij.codeInsight.lookup.LookupElementBuilder;
+import com.intellij.openapi.util.Iconable;
import com.intellij.openapi.util.Key;
import com.intellij.openapi.util.TextRange;
import com.intellij.psi.PsiElement;
@@ -9,6 +12,7 @@ import com.intellij.psi.ResolveState;
import com.intellij.psi.scope.PsiScopeProcessor;
import com.intellij.util.ArrayUtil;
import com.jetbrains.python.psi.PyFile;
+import com.jetbrains.python.psi.PyImportElement;
import com.jetbrains.python.psi.PyStringLiteralExpression;
import com.jetbrains.python.psi.PyUtil;
import com.jetbrains.python.psi.impl.LightNamedElement;
@@ -41,7 +45,7 @@ public class PyDunderAllReference extends PsiReferenceBase result = new ArrayList();
+ final List result = new ArrayList();
PyFile containingFile = (PyFile) getElement().getContainingFile().getOriginalFile();
final List dunderAll = containingFile.getDunderAll();
containingFile.processDeclarations(new PsiScopeProcessor() {
@@ -50,7 +54,13 @@ public class PyDunderAllReference extends PsiReferenceBase> computeScopeVariables() throws DFALimitExceededException {
+ private synchronized void computeScopeVariables() throws DFALimitExceededException {
computeFlow();
if (myCachedScopeVariables == null) {
final PyReachingDefsDfaInstance dfaInstance = new PyReachingDefsDfaInstance();
@@ -62,7 +62,6 @@ public class ScopeImpl implements Scope {
final DFAMapEngine engine = new DFAMapEngine(myFlow, dfaInstance, semilattice);
myCachedScopeVariables = engine.performDFA();
}
- return myCachedScopeVariables;
}
public boolean isGlobal(final String name) {
@@ -196,6 +195,21 @@ public class ScopeImpl implements Scope {
}
}
});
+
+ Collections.sort(nameDefiners, new Comparator() {
+ @Override
+ public int compare(NameDefiner d1, NameDefiner d2) {
+ return getPriority(d2) - getPriority(d1);
+ };
+
+ private int getPriority(NameDefiner nameDefiner) {
+ if (nameDefiner instanceof PyStarImportElement) {
+ return -10;
+ }
+ return 0;
+ }
+ });
+
myNamedElements = namedElements;
myNameDefiners = nameDefiners;
myNestedScopes = nestedScopes;
diff --git a/python/src/com/jetbrains/python/codeInsight/imports/AddImportHelper.java b/python/src/com/jetbrains/python/codeInsight/imports/AddImportHelper.java
index e76c4ab5f56c..7b4cd06c6d35 100644
--- a/python/src/com/jetbrains/python/codeInsight/imports/AddImportHelper.java
+++ b/python/src/com/jetbrains/python/codeInsight/imports/AddImportHelper.java
@@ -191,6 +191,9 @@ public class AddImportHelper {
if (target != null && existingImport.getTextRange().getStartOffset() > target.getTextRange().getStartOffset()) {
continue;
}
+ if (existingImport.isStarImport()) {
+ continue;
+ }
final PyQualifiedName qName = existingImport.getImportSourceQName();
if (qName != null && qName.toString().equals(path)) {
for (PyImportElement el : existingImport.getImportElements()) {
@@ -220,7 +223,7 @@ public class AddImportHelper {
else if (useQualified) {
addImportStatement(file, path, null, priority);
final PyElementGenerator elementGenerator = PyElementGenerator.getInstance(file.getProject());
- element.replace(elementGenerator.createExpressionFromText(qName + "." + target.getName()));
+ element.replace(elementGenerator.createExpressionFromText(LanguageLevel.forElement(target), qName + "." + target.getName()));
}
else {
addImportFrom(file, null, path, target.getName(), null, priority);
diff --git a/python/src/com/jetbrains/python/findUsages/PyClassFindUsagesHandler.java b/python/src/com/jetbrains/python/findUsages/PyClassFindUsagesHandler.java
index 5ff7942a2228..72d52d3a9e49 100644
--- a/python/src/com/jetbrains/python/findUsages/PyClassFindUsagesHandler.java
+++ b/python/src/com/jetbrains/python/findUsages/PyClassFindUsagesHandler.java
@@ -7,6 +7,9 @@ import com.jetbrains.python.psi.PyClass;
import com.jetbrains.python.psi.PyFunction;
import org.jetbrains.annotations.NotNull;
+import java.util.Collection;
+import java.util.Collections;
+
/**
* @author yole
*/
@@ -32,4 +35,12 @@ public class PyClassFindUsagesHandler extends FindUsagesHandler {
protected boolean isSearchForTextOccurencesAvailable(PsiElement psiElement, boolean isSingleFile) {
return true;
}
+
+ @Override
+ protected Collection getStringsToSearch(PsiElement element) {
+ if (element instanceof PyFunction && PyNames.INIT.equals(((PyFunction) element).getName())) {
+ return Collections.emptyList();
+ }
+ return super.getStringsToSearch(element);
+ }
}
diff --git a/python/src/com/jetbrains/python/inspections/PyUnresolvedReferencesInspection.java b/python/src/com/jetbrains/python/inspections/PyUnresolvedReferencesInspection.java
index 53b14f82241d..676dba6b0d17 100644
--- a/python/src/com/jetbrains/python/inspections/PyUnresolvedReferencesInspection.java
+++ b/python/src/com/jetbrains/python/inspections/PyUnresolvedReferencesInspection.java
@@ -154,10 +154,24 @@ public class PyUnresolvedReferencesInspection extends PyInspection {
final PyClass pyClass = ((PyClassType)type).getPyClass();
if (pyClass != null && pyClass.isNewStyleClass()) {
final List slots = pyClass.getSlots();
- if (slots != null && !slots.contains(node.getReferencedName()) && !slots.contains("__dict__")) {
+ final String attrName = node.getReferencedName();
+ if (slots != null && !slots.contains(attrName) && !slots.contains(PyNames.DICT)) {
+ for (PyClassRef ref : pyClass.iterateAncestors()) {
+ final PyClass ancestor = ref.getPyClass();
+ if (ancestor == null) {
+ return;
+ }
+ if (PyNames.OBJECT.equals(ancestor.getName())) {
+ break;
+ }
+ final List ancestorSlots = ancestor.getSlots();
+ if (ancestorSlots == null || ancestorSlots.contains(attrName) || ancestorSlots.contains(PyNames.DICT)) {
+ return;
+ }
+ }
final ASTNode nameNode = node.getNameElement();
final PsiElement e = nameNode != null ? nameNode.getPsi() : node;
- registerProblem(e, "'" + pyClass.getName() + "' object has no attribute '" + node.getReferencedName() + "'");
+ registerProblem(e, "'" + pyClass.getName() + "' object has no attribute '" + attrName + "'");
}
}
}
diff --git a/python/src/com/jetbrains/python/packaging/PyPackageManager.java b/python/src/com/jetbrains/python/packaging/PyPackageManager.java
index 38cd937e6139..69a45b068993 100644
--- a/python/src/com/jetbrains/python/packaging/PyPackageManager.java
+++ b/python/src/com/jetbrains/python/packaging/PyPackageManager.java
@@ -16,7 +16,6 @@ import com.intellij.openapi.progress.Task;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.projectRoots.Sdk;
import com.intellij.openapi.projectRoots.SdkAdditionalData;
-import com.intellij.openapi.ui.Messages;
import com.intellij.openapi.util.Key;
import com.intellij.openapi.util.Ref;
import com.intellij.openapi.util.SystemInfo;
@@ -28,7 +27,6 @@ import com.intellij.util.ArrayUtil;
import com.intellij.util.Function;
import com.intellij.util.SystemProperties;
import com.intellij.util.net.HttpConfigurable;
-import com.intellij.util.ui.UIUtil;
import com.jetbrains.python.PythonHelpersLocator;
import com.jetbrains.python.psi.PyExpression;
import com.jetbrains.python.psi.PyListLiteralExpression;
@@ -564,19 +562,7 @@ public class PyPackageManager {
do {
processOutput = manager.runRemoteProcess(null, remoteSdkData, ArrayUtil.toStringArray(cmdline), askForSudo);
if (askForSudo && processOutput.getStderr().contains("sudo: 3 incorrect password attempts")) {
- final Ref cont = Ref.create(false);
- UIUtil.invokeAndWaitIfNeeded(new Runnable() {
- @Override
- public void run() {
- if (Messages.showOkCancelDialog("Incorrect sudo password", "Incorrect Password Attempt", Messages.getErrorIcon()) ==
- Messages.OK) {
- cont.set(true);
- }
- }
- });
- if (cont.get()) {
- continue;
- }
+ continue;
}
break;
}
diff --git a/python/src/com/jetbrains/python/packaging/PyRequirement.java b/python/src/com/jetbrains/python/packaging/PyRequirement.java
index feb06b424df8..181b4c7e6d28 100644
--- a/python/src/com/jetbrains/python/packaging/PyRequirement.java
+++ b/python/src/com/jetbrains/python/packaging/PyRequirement.java
@@ -271,7 +271,7 @@ public class PyRequirement {
@Nullable
public PyPackage match(@NotNull List packages) {
for (PyPackage pkg : packages) {
- if (myName.equalsIgnoreCase(pkg.getName())) {
+ if (normalizeName(myName).equalsIgnoreCase(pkg.getName())) {
for (VersionSpec spec : myVersionSpecs) {
final int cmp = VERSION_COMPARATOR.compare(pkg.getVersion(), spec.getVersion());
final Relation relation = spec.getRelation();
diff --git a/python/src/com/jetbrains/python/psi/impl/PyFileImpl.java b/python/src/com/jetbrains/python/psi/impl/PyFileImpl.java
index f7bcb9668701..35512c774fac 100644
--- a/python/src/com/jetbrains/python/psi/impl/PyFileImpl.java
+++ b/python/src/com/jetbrains/python/psi/impl/PyFileImpl.java
@@ -183,9 +183,11 @@ public class PyFileImpl extends PsiFileBase implements PyFile, PyExpression {
return null;
}
+ @Nullable
private PsiElement resolveDeclaration(String name, PsiElement result) {
if (result instanceof PyImportElement) {
- return findNameInImportElement(name, (PyImportElement)result);
+ final PyImportElement importElement = (PyImportElement)result;
+ return findNameInImportElement(name, importElement, importElement.getContainingImportStatement() instanceof PyFromImportStatement);
}
else if (result instanceof PyFromImportStatement) {
return ((PyFromImportStatement) result).resolveImportSource();
@@ -557,7 +559,7 @@ public class PyFileImpl extends PsiFileBase implements PyFile, PyExpression {
@Nullable
private PsiElement findNameInImportStatement(String name, PyImportStatement child) {
for (PyImportElement importElement: child.getImportElements()) {
- final PsiElement result = findNameInImportElement(name, importElement);
+ final PsiElement result = findNameInImportElement(name, importElement, false);
if (result != null) {
return result;
}
@@ -566,8 +568,8 @@ public class PyFileImpl extends PsiFileBase implements PyFile, PyExpression {
}
@Nullable
- private PsiElement findNameInImportElement(String name, PyImportElement importElement) {
- final PsiElement result = importElement.getElementNamed(name, false);
+ private PsiElement findNameInImportElement(String name, PyImportElement importElement, final boolean resolveImportElement) {
+ final PsiElement result = importElement.getElementNamed(name, resolveImportElement);
if (result != null) {
return result;
}
diff --git a/python/src/com/jetbrains/python/psi/impl/references/PyImportReference.java b/python/src/com/jetbrains/python/psi/impl/references/PyImportReference.java
index b7556bc63820..c922230690c5 100644
--- a/python/src/com/jetbrains/python/psi/impl/references/PyImportReference.java
+++ b/python/src/com/jetbrains/python/psi/impl/references/PyImportReference.java
@@ -167,7 +167,7 @@ public class PyImportReference extends PyReferenceImpl {
}
public Object[] execute() {
- int relative_level = -1;
+ int relativeLevel = -1;
InsertHandler insertHandler = null;
// NOTE: could use getPointInImport()
@@ -191,9 +191,9 @@ public class PyImportReference extends PyReferenceImpl {
}
}
else { // null source, must be a "from ... import"
- relative_level = from_import.getRelativeLevel();
- if (relative_level > 0) {
- PsiDirectory relative_dir = ResolveImportUtil.stepBackFrom(myCurrentFile, relative_level);
+ relativeLevel = from_import.getRelativeLevel();
+ if (relativeLevel > 0) {
+ PsiDirectory relative_dir = ResolveImportUtil.stepBackFrom(myCurrentFile, relativeLevel);
if (relative_dir != null) {
addImportedNames(from_import.getImportElements());
fillFromDir(relative_dir, null);
@@ -204,7 +204,7 @@ public class PyImportReference extends PyReferenceImpl {
else { // in "import _" or "from _ import"
ASTNode n = myElement.getNode().getTreePrev();
while (n != null && n.getElementType() == PyTokenTypes.DOT) {
- relative_level += 1;
+ relativeLevel += 1;
n = n.getTreePrev();
}
if (from_import != null) {
@@ -221,21 +221,21 @@ public class PyImportReference extends PyReferenceImpl {
}
}
// look at dir by level
- if (myCurrentFile != null && (relative_level >= 0 || !ResolveImportUtil.isAbsoluteImportEnabledFor(myCurrentFile))) {
+ if (myCurrentFile != null && (relativeLevel >= 0 || !ResolveImportUtil.isAbsoluteImportEnabledFor(myCurrentFile))) {
final PsiDirectory containingDirectory = myCurrentFile.getContainingDirectory();
if (containingDirectory != null) {
PyQualifiedName thisQName = ResolveImportUtil.findShortestImportableQName(containingDirectory);
- if (thisQName == null) {
- fillFromDir(ResolveImportUtil.stepBackFrom(myCurrentFile, relative_level), insertHandler);
+ if (thisQName == null || thisQName.getComponentCount() == relativeLevel) {
+ fillFromDir(ResolveImportUtil.stepBackFrom(myCurrentFile, relativeLevel), insertHandler);
}
- else if (thisQName.getComponentCount() >= relative_level) {
- thisQName = thisQName.removeTail(relative_level);
+ else if (thisQName.getComponentCount() > relativeLevel) {
+ thisQName = thisQName.removeTail(relativeLevel);
fillFromQName(thisQName, insertHandler);
}
}
}
}
- if (relative_level == -1) {
+ if (relativeLevel == -1) {
fillFromQName(PyQualifiedName.fromComponents(), insertHandler);
}
diff --git a/python/src/com/jetbrains/python/psi/impl/references/PyReferenceImpl.java b/python/src/com/jetbrains/python/psi/impl/references/PyReferenceImpl.java
index 0362c6d4d1cf..96ee92a8f3c8 100644
--- a/python/src/com/jetbrains/python/psi/impl/references/PyReferenceImpl.java
+++ b/python/src/com/jetbrains/python/psi/impl/references/PyReferenceImpl.java
@@ -75,6 +75,7 @@ public class PyReferenceImpl implements PsiReferenceEx, PsiPolyVariantReference
}
// it is *not* final so that it can be changed in debug time. if set to false, caching is off
+ @SuppressWarnings("FieldCanBeLocal")
private static boolean USE_CACHE = true;
/**
diff --git a/python/src/com/jetbrains/python/refactoring/move/PyMoveClassOrFunctionProcessor.java b/python/src/com/jetbrains/python/refactoring/move/PyMoveClassOrFunctionProcessor.java
index 05bb77c03268..b627ea1fc73e 100644
--- a/python/src/com/jetbrains/python/refactoring/move/PyMoveClassOrFunctionProcessor.java
+++ b/python/src/com/jetbrains/python/refactoring/move/PyMoveClassOrFunctionProcessor.java
@@ -4,10 +4,7 @@ import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.command.CommandProcessor;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.vfs.VirtualFile;
-import com.intellij.psi.PsiElement;
-import com.intellij.psi.PsiFile;
-import com.intellij.psi.PsiNamedElement;
-import com.intellij.psi.PsiReference;
+import com.intellij.psi.*;
import com.intellij.psi.util.PsiTreeUtil;
import com.intellij.refactoring.BaseRefactoringProcessor;
import com.intellij.refactoring.ui.UsageViewDescriptorAdapter;
@@ -100,10 +97,10 @@ public class PyMoveClassOrFunctionProcessor extends BaseRefactoringProcessor {
PyClassRefactoringUtil.rememberNamedReferences(oldElement);
final PsiNamedElement newElement = (PsiNamedElement)(dest.add(oldElement));
for (UsageInfo usage : usages) {
- final PsiElement oldExpr = usage.getElement();
+ final PsiElement usageElement = usage.getElement();
// TODO: Respect the qualified import style
- if (oldExpr instanceof PyQualifiedExpression) {
- PyQualifiedExpression qexpr = (PyQualifiedExpression)oldExpr;
+ if (usageElement instanceof PyQualifiedExpression) {
+ PyQualifiedExpression qexpr = (PyQualifiedExpression)usageElement;
if (oldElement instanceof PyClass && PyNames.INIT.equals(qexpr.getName())) {
continue;
}
@@ -112,22 +109,25 @@ public class PyMoveClassOrFunctionProcessor extends BaseRefactoringProcessor {
PyClassRefactoringUtil.insertImport(newExpr, newElement, null, true);
}
}
- if (oldExpr instanceof PyStringLiteralExpression) {
- final PsiReference[] references = oldExpr.getReferences();
- for (PsiReference ref : references) {
+ if (usageElement instanceof PyStringLiteralExpression) {
+ for (PsiReference ref : usageElement.getReferences()) {
if (ref instanceof DocStringTypeReference && ref.isReferenceTo(oldElement)) {
ref.bindToElement(newElement);
}
}
}
else {
- final PyImportStatementBase importStmt = PsiTreeUtil.getParentOfType(usage.getElement(), PyImportStatementBase.class);
+ final PyImportStatementBase importStmt = PsiTreeUtil.getParentOfType(usageElement, PyImportStatementBase.class);
if (importStmt != null) {
PyClassRefactoringUtil.updateImportOfElement(importStmt, newElement);
}
- if (usage.getFile() == oldFile && (oldExpr == null || !PsiTreeUtil.isAncestor(oldElement, oldExpr, false))) {
+ if (usage.getFile() == oldFile && (usageElement == null || !PsiTreeUtil.isAncestor(oldElement, usageElement, false))) {
PyClassRefactoringUtil.insertImport(oldElement, newElement);
}
+ if (usageElement != null && resolvesToLocalStarImport(usageElement)) {
+ PyClassRefactoringUtil.insertImport(usageElement, newElement);
+ new PyImportOptimizer().processFile(usageElement.getContainingFile()).run();
+ }
}
}
PyClassRefactoringUtil.restoreNamedReferences(newElement, oldElement);
@@ -141,16 +141,38 @@ public class PyMoveClassOrFunctionProcessor extends BaseRefactoringProcessor {
}, REFACTORING_NAME, null);
}
+ @Override
+ protected String getCommandName() {
+ return REFACTORING_NAME;
+ }
+
+ private boolean resolvesToLocalStarImport(@NotNull PsiElement element) {
+ final PsiReference ref = element.getReference();
+ final List resolvedElements = new ArrayList();
+ if (ref instanceof PsiPolyVariantReference) {
+ for (ResolveResult result : ((PsiPolyVariantReference)ref).multiResolve(false)) {
+ resolvedElements.add(result.getElement());
+ }
+ }
+ else if (ref != null) {
+ resolvedElements.add(ref.resolve());
+ }
+ final PsiFile containingFile = element.getContainingFile();
+ if (containingFile != null) {
+ for (PsiElement resolved : resolvedElements) {
+ if (resolved instanceof PyStarImportElement && resolved.getContainingFile() == containingFile) {
+ return true;
+ }
+ }
+ }
+ return false;
+ }
+
private static void checkValidImportableFile(PsiElement anchor, VirtualFile file) {
final PyQualifiedName qName = ResolveImportUtil.findShortestImportableQName(anchor, file);
if (!PyClassRefactoringUtil.isValidQualifiedName(qName)) {
throw new IncorrectOperationException(PyBundle.message("refactoring.move.class.or.function.error.cannot.use.module.name.$0", qName));
}
}
-
- @Override
- protected String getCommandName() {
- return REFACTORING_NAME;
- }
}
diff --git a/python/src/com/jetbrains/python/refactoring/move/PyMoveFileHandler.java b/python/src/com/jetbrains/python/refactoring/move/PyMoveFileHandler.java
index 6d01082b129c..4940f0018a5b 100644
--- a/python/src/com/jetbrains/python/refactoring/move/PyMoveFileHandler.java
+++ b/python/src/com/jetbrains/python/refactoring/move/PyMoveFileHandler.java
@@ -4,6 +4,7 @@ import com.intellij.openapi.util.Key;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.psi.*;
import com.intellij.psi.util.PsiTreeUtil;
+import com.intellij.refactoring.RefactoringSettings;
import com.intellij.refactoring.move.moveFilesOrDirectories.MoveFileHandler;
import com.intellij.usageView.UsageInfo;
import com.intellij.util.IncorrectOperationException;
@@ -38,7 +39,8 @@ public class PyMoveFileHandler extends MoveFileHandler {
while (root != null && !roots.contains(root.getVirtualFile())) {
root = root.getParentDirectory();
}
- if (moveDestination != root && root != null) {
+ final boolean searchForReferences = RefactoringSettings.getInstance().MOVE_SEARCH_FOR_REFERENCES_FOR_FILE;
+ if (moveDestination != root && root != null && searchForReferences) {
CreatePackageAction.createInitPyInHierarchy(moveDestination, root);
}
}
diff --git a/python/src/com/jetbrains/python/remote/PyRemoteCancelledException.java b/python/src/com/jetbrains/python/remote/PyRemoteCancelledException.java
new file mode 100644
index 000000000000..425747922612
--- /dev/null
+++ b/python/src/com/jetbrains/python/remote/PyRemoteCancelledException.java
@@ -0,0 +1,10 @@
+package com.jetbrains.python.remote;
+
+/**
+ * @author traff
+ */
+public class PyRemoteCancelledException extends PyRemoteInterpreterException {
+ public PyRemoteCancelledException(String s) {
+ super(s);
+ }
+}
diff --git a/python/src/com/jetbrains/python/remote/RemoteFile.java b/python/src/com/jetbrains/python/remote/RemoteFile.java
index 3e80e0a22259..e5585c4a32dd 100644
--- a/python/src/com/jetbrains/python/remote/RemoteFile.java
+++ b/python/src/com/jetbrains/python/remote/RemoteFile.java
@@ -2,16 +2,19 @@ package com.jetbrains.python.remote;
import com.intellij.openapi.util.io.FileUtil;
import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
/**
* @author traff
*/
public class RemoteFile {
+ private final boolean myWin;
private final String myPath;
public RemoteFile(@NotNull String path, boolean isWin) {
myPath = toSystemDependent(path, isWin);
+ myWin = isWin;
}
public RemoteFile(@NotNull String parent, String child) {
@@ -22,14 +25,19 @@ public class RemoteFile {
this(resolveChild(parent, child, isWin), isWin);
}
- private static String resolveChild(@NotNull String parent, @NotNull String child, boolean win) {
- String separator;
- if (win) {
- separator = "\\";
+ @Nullable
+ public String getName() {
+ int ind = myPath.lastIndexOf(getSeparator(myWin));
+ if (ind != -1 && ind < myPath.length() - 1) { //not last char
+ return myPath.substring(ind + 1);
}
else {
- separator = "/";
+ return null;
}
+ }
+
+ private static String resolveChild(@NotNull String parent, @NotNull String child, boolean win) {
+ String separator = getSeparator(win);
String path;
if (parent.endsWith(separator)) {
@@ -41,6 +49,17 @@ public class RemoteFile {
return path;
}
+ private static String getSeparator(boolean win) {
+ String separator;
+ if (win) {
+ separator = "\\";
+ }
+ else {
+ separator = "/";
+ }
+ return separator;
+ }
+
public String getPath() {
return myPath;
diff --git a/python/src/com/jetbrains/python/run/AbstractPythonRunConfiguration.java b/python/src/com/jetbrains/python/run/AbstractPythonRunConfiguration.java
index 4fbc2afe9bbe..ea75bc2f1ba4 100644
--- a/python/src/com/jetbrains/python/run/AbstractPythonRunConfiguration.java
+++ b/python/src/com/jetbrains/python/run/AbstractPythonRunConfiguration.java
@@ -24,7 +24,6 @@ import com.jetbrains.python.PyBundle;
import com.jetbrains.python.PythonModuleTypeBase;
import com.jetbrains.python.debugger.remote.PyPathMappingSettings;
import com.jetbrains.python.sdk.PythonEnvUtil;
-import com.jetbrains.python.sdk.PythonSdkFlavor;
import com.jetbrains.python.sdk.PythonSdkType;
import org.jdom.Element;
import org.jetbrains.annotations.Nullable;
@@ -186,12 +185,6 @@ public abstract class AbstractPythonRunConfiguration suggestHomePaths() {
+ return Lists.newArrayList();
+ }
+
+ @Override
+ public boolean isValidSdkHome(String path) {
+ return StringUtil.isNotEmpty(path) && path.startsWith("ssh:") && checkName(NAMES, getExecutableName(path));
+ }
+
+ private static boolean checkName(String[] names, @Nullable String name) {
+ if (name == null) {
+ return false;
+ }
+ for (String n : names) {
+ if (name.startsWith(n)) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ @Nullable
+ private static String getExecutableName(String path) {
+ return RemoteFile.detectSystemByPath(path).createRemoteFile(path).getName();
+ }
+}
diff --git a/python/src/com/jetbrains/python/sdk/PySkeletonGenerator.java b/python/src/com/jetbrains/python/sdk/PySkeletonGenerator.java
index e7098bb9af0f..64b22c1785ae 100644
--- a/python/src/com/jetbrains/python/sdk/PySkeletonGenerator.java
+++ b/python/src/com/jetbrains/python/sdk/PySkeletonGenerator.java
@@ -4,20 +4,20 @@ import com.google.common.collect.Maps;
import com.intellij.execution.process.ProcessOutput;
import com.intellij.openapi.application.ex.ApplicationManagerEx;
import com.intellij.openapi.diagnostic.Logger;
-import com.intellij.openapi.project.Project;
import com.intellij.openapi.projectRoots.Sdk;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.openapi.vfs.LocalFileSystem;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.util.ArrayUtil;
import com.intellij.util.Consumer;
-import com.intellij.util.Processor;
import com.jetbrains.python.PythonHelpersLocator;
import org.jetbrains.annotations.NotNull;
-import org.jetbrains.annotations.Nullable;
import java.io.File;
-import java.util.*;
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
import static com.jetbrains.python.sdk.SkeletonVersionChecker.fromVersionString;
@@ -36,7 +36,11 @@ public class PySkeletonGenerator {
public void finishSkeletonsGeneration() {
}
- static class ListBinariesResult {
+ public boolean exists(String name) {
+ return new File(name).exists();
+ }
+
+ protected static class ListBinariesResult {
public final int generatorVersion;
public final Map modules;
diff --git a/python/src/com/jetbrains/python/sdk/PySkeletonRefresher.java b/python/src/com/jetbrains/python/sdk/PySkeletonRefresher.java
index b9796826f6ef..b4b620df0a8d 100644
--- a/python/src/com/jetbrains/python/sdk/PySkeletonRefresher.java
+++ b/python/src/com/jetbrains/python/sdk/PySkeletonRefresher.java
@@ -18,7 +18,6 @@ import com.intellij.openapi.vfs.JarFileSystem;
import com.intellij.openapi.vfs.LocalFileSystem;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.util.Consumer;
-import com.intellij.util.Processor;
import com.intellij.util.SmartList;
import com.intellij.util.io.ZipUtil;
import com.jetbrains.python.PyBundle;
@@ -425,7 +424,8 @@ public class PySkeletonRefresher {
boolean canLive = headerMatcher != null && headerMatcher.matches();
if (canLive) {
String sourceName = headerMatcher.group(1);
- canLive = sourceName != null && (SkeletonVersionChecker.BUILTIN_NAME.equals(sourceName) || new File(sourceName).exists());
+ canLive =
+ sourceName != null && (SkeletonVersionChecker.BUILTIN_NAME.equals(sourceName) || mySkeletonsGenerator.exists(sourceName));
}
if (!canLive) {
mySkeletonsGenerator.deleteOrLog(item);
@@ -566,7 +566,7 @@ public class PySkeletonRefresher {
return false;
}
- static class PyBinaryItem {
+ public static class PyBinaryItem {
private String myPath;
private String myModule;
private long myLength;
@@ -647,6 +647,11 @@ public class PySkeletonRefresher {
if (versionString == null) {
return null;
}
+
+ if (PySdkUtil.isRemote(mySdk)) {
+ return null;
+ }
+
String version = versionString.toLowerCase().replace(" ", "-");
File f;
if (SystemInfo.isMac) {
diff --git a/python/src/com/jetbrains/python/sdk/PythonSdkFlavor.java b/python/src/com/jetbrains/python/sdk/PythonSdkFlavor.java
index e93aa40c75f8..13d89bba101d 100644
--- a/python/src/com/jetbrains/python/sdk/PythonSdkFlavor.java
+++ b/python/src/com/jetbrains/python/sdk/PythonSdkFlavor.java
@@ -49,7 +49,7 @@ public abstract class PythonSdkFlavor {
public static List getApplicableFlavors() {
List result = new ArrayList();
- result.add(VirtualEnvSdkFlavor.INSTANCE);
+
if (SystemInfo.isWindows) {
result.add(WinPythonSdkFlavor.INSTANCE);
}
@@ -71,6 +71,9 @@ public abstract class PythonSdkFlavor {
result.add(JythonSdkFlavor.INSTANCE);
result.add(IronPythonSdkFlavor.INSTANCE);
result.add(PyPySdkFlavor.INSTANCE);
+ result.add(VirtualEnvSdkFlavor.INSTANCE);
+ result.add(PyRemoteSdkFlavor.INSTANCE);
+
return result;
}
diff --git a/python/testData/completion/dunderAllReferenceImport.after.py b/python/testData/completion/dunderAllReferenceImport.after.py
new file mode 100644
index 000000000000..2011874196d6
--- /dev/null
+++ b/python/testData/completion/dunderAllReferenceImport.after.py
@@ -0,0 +1,3 @@
+from sys import hexversion
+
+__all__ = ['hexversion']
diff --git a/python/testData/completion/dunderAllReferenceImport.py b/python/testData/completion/dunderAllReferenceImport.py
new file mode 100644
index 000000000000..d091b755ca27
--- /dev/null
+++ b/python/testData/completion/dunderAllReferenceImport.py
@@ -0,0 +1,3 @@
+from sys import hexversion
+
+__all__ = ['hexve']
diff --git a/python/testData/completion/relativeImportExcludeToplevel/pack/__init__.py b/python/testData/completion/relativeImportExcludeToplevel/pack/__init__.py
new file mode 100644
index 000000000000..e69de29bb2d1
diff --git a/python/testData/completion/relativeImportExcludeToplevel/pack/subpack/__init__.py b/python/testData/completion/relativeImportExcludeToplevel/pack/subpack/__init__.py
new file mode 100644
index 000000000000..6509788aae52
--- /dev/null
+++ b/python/testData/completion/relativeImportExcludeToplevel/pack/subpack/__init__.py
@@ -0,0 +1 @@
+__author__ = 'yole'
diff --git a/python/testData/completion/relativeImportExcludeToplevel/pack/subpack/modX.py b/python/testData/completion/relativeImportExcludeToplevel/pack/subpack/modX.py
new file mode 100644
index 000000000000..136608600f80
--- /dev/null
+++ b/python/testData/completion/relativeImportExcludeToplevel/pack/subpack/modX.py
@@ -0,0 +1 @@
+from ... import
\ No newline at end of file
diff --git a/python/testData/inspections/PyUnresolvedReferencesInspection/compoundDunderAll.py b/python/testData/inspections/PyUnresolvedReferencesInspection/compoundDunderAll.py
new file mode 100644
index 000000000000..9533fc64871b
--- /dev/null
+++ b/python/testData/inspections/PyUnresolvedReferencesInspection/compoundDunderAll.py
@@ -0,0 +1,2 @@
+__all__ = [ name for name, obj in locals().items()
+ if not (name.startswith('_')) ]
diff --git a/python/testData/inspections/PyUnresolvedReferencesInspection/slotsSubclass.py b/python/testData/inspections/PyUnresolvedReferencesInspection/slotsSubclass.py
new file mode 100644
index 000000000000..dfd3f5e4cc50
--- /dev/null
+++ b/python/testData/inspections/PyUnresolvedReferencesInspection/slotsSubclass.py
@@ -0,0 +1,15 @@
+class A(object):
+ __slots__ = ['a', 'b']
+ def __init__(self):
+ self.a = None # <- all ok here
+ self.b = None # <- all ok here
+
+class C(A):
+ __slots__ = ['c', 'd']
+
+ def __init__(self, c):
+ super(C, self).__init__()
+ self.c = c
+ self.d = self.b
+ if self.c:
+ self.a = 10
diff --git a/python/testData/inspections/importFromModuleStar/source.py b/python/testData/inspections/importFromModuleStar/source.py
new file mode 100644
index 000000000000..55c27e1fb049
--- /dev/null
+++ b/python/testData/inspections/importFromModuleStar/source.py
@@ -0,0 +1,4 @@
+from target import *
+
+xyzzy
+shazam()
diff --git a/python/testData/inspections/importFromModuleStar/source_after.py b/python/testData/inspections/importFromModuleStar/source_after.py
new file mode 100644
index 000000000000..b118609972b6
--- /dev/null
+++ b/python/testData/inspections/importFromModuleStar/source_after.py
@@ -0,0 +1,5 @@
+from target import *
+from target import xyzzy
+
+xyzzy
+shazam()
diff --git a/python/testData/inspections/importFromModuleStar/target.py b/python/testData/inspections/importFromModuleStar/target.py
new file mode 100644
index 000000000000..2214231d716c
--- /dev/null
+++ b/python/testData/inspections/importFromModuleStar/target.py
@@ -0,0 +1,4 @@
+__all__ = ['shazam']
+
+def shazam(): pass
+def xyzzy(): pass
diff --git a/python/testData/inspections/unusedImport/unusedAfterStarImport/test1.py b/python/testData/inspections/unusedImport/unusedAfterStarImport/test1.py
new file mode 100644
index 000000000000..1cd116611054
--- /dev/null
+++ b/python/testData/inspections/unusedImport/unusedAfterStarImport/test1.py
@@ -0,0 +1,6 @@
+from test2 import *
+from test2 import f #pass
+from test3 import * #pass
+from test4 import *
+
+print(f, g)
diff --git a/python/testData/inspections/unusedImport/unusedAfterStarImport/test2.py b/python/testData/inspections/unusedImport/unusedAfterStarImport/test2.py
new file mode 100644
index 000000000000..001f2e6d84c8
--- /dev/null
+++ b/python/testData/inspections/unusedImport/unusedAfterStarImport/test2.py
@@ -0,0 +1,2 @@
+def f(x):
+ return x
\ No newline at end of file
diff --git a/python/testData/inspections/unusedImport/unusedAfterStarImport/test3.py b/python/testData/inspections/unusedImport/unusedAfterStarImport/test3.py
new file mode 100644
index 000000000000..504363eab9af
--- /dev/null
+++ b/python/testData/inspections/unusedImport/unusedAfterStarImport/test3.py
@@ -0,0 +1,2 @@
+def g():
+ pass
\ No newline at end of file
diff --git a/python/testData/inspections/unusedImport/unusedAfterStarImport/test4.py b/python/testData/inspections/unusedImport/unusedAfterStarImport/test4.py
new file mode 100644
index 000000000000..09d9cea3d574
--- /dev/null
+++ b/python/testData/inspections/unusedImport/unusedAfterStarImport/test4.py
@@ -0,0 +1,2 @@
+def h():
+ pass
\ No newline at end of file
diff --git a/python/testData/refactoring/move/starImportUsage/after/src/a.py b/python/testData/refactoring/move/starImportUsage/after/src/a.py
new file mode 100644
index 000000000000..b51e032b9bbe
--- /dev/null
+++ b/python/testData/refactoring/move/starImportUsage/after/src/a.py
@@ -0,0 +1,3 @@
+from c import f
+
+print(f())
\ No newline at end of file
diff --git a/python/testData/refactoring/move/starImportUsage/after/src/b.py b/python/testData/refactoring/move/starImportUsage/after/src/b.py
new file mode 100644
index 000000000000..e69de29bb2d1
diff --git a/python/testData/refactoring/move/starImportUsage/after/src/c.py b/python/testData/refactoring/move/starImportUsage/after/src/c.py
new file mode 100644
index 000000000000..39e1b2079d04
--- /dev/null
+++ b/python/testData/refactoring/move/starImportUsage/after/src/c.py
@@ -0,0 +1,2 @@
+def f():
+ pass
\ No newline at end of file
diff --git a/python/testData/refactoring/move/starImportUsage/before/src/a.py b/python/testData/refactoring/move/starImportUsage/before/src/a.py
new file mode 100644
index 000000000000..6c3eacab5b29
--- /dev/null
+++ b/python/testData/refactoring/move/starImportUsage/before/src/a.py
@@ -0,0 +1,3 @@
+from b import *
+
+print(f())
\ No newline at end of file
diff --git a/python/testData/refactoring/move/starImportUsage/before/src/b.py b/python/testData/refactoring/move/starImportUsage/before/src/b.py
new file mode 100644
index 000000000000..39e1b2079d04
--- /dev/null
+++ b/python/testData/refactoring/move/starImportUsage/before/src/b.py
@@ -0,0 +1,2 @@
+def f():
+ pass
\ No newline at end of file
diff --git a/python/testData/refactoring/move/starImportUsage/before/src/c.py b/python/testData/refactoring/move/starImportUsage/before/src/c.py
new file mode 100644
index 000000000000..e69de29bb2d1
diff --git a/python/testData/resolve/LambdaParameterInDefaultValue.py b/python/testData/resolve/LambdaParameterInDefaultValue.py
new file mode 100644
index 000000000000..1e0c6c0191cf
--- /dev/null
+++ b/python/testData/resolve/LambdaParameterInDefaultValue.py
@@ -0,0 +1,2 @@
+def f(g=lambda xx: xx):
+ pass # [
\ No newline at end of file
diff --git a/python/testData/resolve/multiFile/fromPackageImportIntoInit/pack/__init__.py b/python/testData/resolve/multiFile/fromPackageImportIntoInit/pack/__init__.py
new file mode 100644
index 000000000000..d84254aa0698
--- /dev/null
+++ b/python/testData/resolve/multiFile/fromPackageImportIntoInit/pack/__init__.py
@@ -0,0 +1,2 @@
+from pack import mod
+# ][
diff --git a/python/testData/resolve/multiFile/fromPackageImportIntoInit/pack/mod.py b/python/testData/resolve/multiFile/fromPackageImportIntoInit/pack/mod.py
new file mode 100644
index 000000000000..e69de29bb2d1
diff --git a/python/testSrc/com/jetbrains/python/PyMultiFileResolveTest.java b/python/testSrc/com/jetbrains/python/PyMultiFileResolveTest.java
index 4540eb1a1480..250977bd7e2f 100644
--- a/python/testSrc/com/jetbrains/python/PyMultiFileResolveTest.java
+++ b/python/testSrc/com/jetbrains/python/PyMultiFileResolveTest.java
@@ -96,6 +96,14 @@ public class PyMultiFileResolveTest extends PyResolveTestCase {
assertTrue("is target?", elt instanceof PyTargetExpression);
}
+ public void testFromPackageImportIntoInit() { // PY-6305
+ myFixture.copyDirectoryToProject("fromPackageImportIntoInit/pack", "pack");
+ final PsiFile psiFile = myFixture.configureByFile("pack/__init__.py");
+ final PsiElement result = doResolve(psiFile);
+ assertInstanceOf(result, PyFile.class);
+ assertEquals("mod.py", ((PyFile) result).getName());
+ }
+
public void testResolveInPkg() {
ResolveResult[] results = doMultiResolve();
assertTrue(results.length == 2); // func and import stmt
diff --git a/python/testSrc/com/jetbrains/python/PyQuickFixTest.java b/python/testSrc/com/jetbrains/python/PyQuickFixTest.java
index dd8aac6b309b..c0758fc44ae9 100644
--- a/python/testSrc/com/jetbrains/python/PyQuickFixTest.java
+++ b/python/testSrc/com/jetbrains/python/PyQuickFixTest.java
@@ -36,6 +36,17 @@ public class PyQuickFixTest extends PyTestCase {
PyUnresolvedReferencesInspection.class, PyBundle.message("ACT.NAME.use.import"), true, true);
}
+ public void testImportFromModuleStar() { // PY-6302
+ myFixture.enableInspections(PyUnresolvedReferencesInspection.class);
+ myFixture.copyDirectoryToProject("importFromModuleStar", "");
+ myFixture.configureFromTempProjectFile("source.py");
+ myFixture.checkHighlighting(true, false, false);
+ final IntentionAction intentionAction = myFixture.findSingleIntention(PyBundle.message("ACT.NAME.use.import"));
+ assertNotNull(intentionAction);
+ myFixture.launchAction(intentionAction);
+ myFixture.checkResultByFile("importFromModuleStar/source_after.py");
+ }
+
public void testQualifyByImport() {
final PyCodeInsightSettings settings = PyCodeInsightSettings.getInstance();
boolean oldPreferFrom = settings.PREFER_FROM_IMPORT;
diff --git a/python/testSrc/com/jetbrains/python/PyResolveTest.java b/python/testSrc/com/jetbrains/python/PyResolveTest.java
index 0331ccfeb0ac..d0fde0cc6b62 100644
--- a/python/testSrc/com/jetbrains/python/PyResolveTest.java
+++ b/python/testSrc/com/jetbrains/python/PyResolveTest.java
@@ -462,4 +462,9 @@ public class PyResolveTest extends PyResolveTestCase {
public void testLambdaParameterInDecorator() {
assertResolvesTo(PyNamedParameter.class, "xx");
}
+
+ // PY-6435
+ public void testLambdaParameterInDefaultValue() {
+ assertResolvesTo(PyNamedParameter.class, "xx");
+ }
}
diff --git a/python/testSrc/com/jetbrains/python/PyStubsTest.java b/python/testSrc/com/jetbrains/python/PyStubsTest.java
index afeeee9be96b..62647916c668 100644
--- a/python/testSrc/com/jetbrains/python/PyStubsTest.java
+++ b/python/testSrc/com/jetbrains/python/PyStubsTest.java
@@ -2,10 +2,15 @@ package com.jetbrains.python;
import com.intellij.openapi.application.Result;
import com.intellij.openapi.command.WriteCommandAction;
+import com.intellij.openapi.editor.Document;
+import com.intellij.openapi.project.DumbServiceImpl;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.vfs.VirtualFile;
+import com.intellij.psi.PsiDocumentManager;
import com.intellij.psi.PsiElement;
import com.intellij.psi.PsiFile;
+import com.intellij.psi.PsiManager;
+import com.intellij.psi.impl.source.PsiFileImpl;
import com.intellij.psi.search.GlobalSearchScope;
import com.intellij.psi.stubs.StubElement;
import com.intellij.psi.stubs.StubUpdatingIndex;
@@ -16,6 +21,7 @@ import com.jetbrains.python.psi.*;
import com.jetbrains.python.psi.impl.PyFileImpl;
import com.jetbrains.python.psi.impl.PyQualifiedName;
import com.jetbrains.python.psi.impl.PythonLanguageLevelPusher;
+import com.jetbrains.python.psi.stubs.PyClassNameIndex;
import com.jetbrains.python.psi.stubs.PyClassStub;
import com.jetbrains.python.psi.stubs.PyVariableNameIndex;
import com.jetbrains.python.toolbox.Maybe;
@@ -365,4 +371,32 @@ public class PyStubsTest extends PyTestCase {
PsiFile psiFile = myFixture.getPsiManager().findFile(sourceFile);
return (PyFile)psiFile;
}
+
+ public void testStubIndexMismatch() {
+ VirtualFile vFile = myFixture.getTempDirFixture().createFile("foo.py");
+ final Project project = myFixture.getProject();
+ PsiFileImpl fooPyFile = (PsiFileImpl) PsiManager.getInstance(project).findFile(vFile);
+ final Document fooDocument = fooPyFile.getViewProvider().getDocument();
+ Collection classes = PyClassNameIndex.find("Foo", project, GlobalSearchScope.allScope(project));
+ assertEquals(classes.size(), 0);
+ new WriteCommandAction.Simple(project, fooPyFile) {
+ public void run() {
+ fooDocument.setText("class Foo: pass");
+ }
+ }.execute();
+ PsiDocumentManager.getInstance(project).commitDocument(fooDocument);
+ fooPyFile.setTreeElementPointer(null);
+ //classes = PyClassNameIndex.find("Foo", project, GlobalSearchScope.allScope(project));
+ //fooPyFile.unloadContent();
+ DumbServiceImpl.getInstance(project).setDumb(true);
+ try {
+ assertEquals(1, ((PyFile) fooPyFile).getTopLevelClasses().size());
+ }
+ finally {
+ DumbServiceImpl.getInstance(project).setDumb(false);
+ }
+ classes = PyClassNameIndex.find("Foo", project, GlobalSearchScope.allScope(project));
+ assertEquals(classes.size(), 1);
+
+ }
}
diff --git a/python/testSrc/com/jetbrains/python/PythonCompletionTest.java b/python/testSrc/com/jetbrains/python/PythonCompletionTest.java
index 92a4a2599df7..9bf9201be865 100644
--- a/python/testSrc/com/jetbrains/python/PythonCompletionTest.java
+++ b/python/testSrc/com/jetbrains/python/PythonCompletionTest.java
@@ -529,6 +529,10 @@ public class PythonCompletionTest extends PyTestCase {
doTest();
}
+ public void testDunderAllReferenceImport() { // PY-6306
+ doTest();
+ }
+
public void testOldStyleClassAttributes() {
doTest();
}
@@ -546,4 +550,17 @@ public class PythonCompletionTest extends PyTestCase {
public void testQualifiedAssignment() { // PY-6121
doTest();
}
+
+ public void testRelativeImportExcludeToplevel() { // PY-6304
+ setLanguageLevel(LanguageLevel.PYTHON27);
+ try {
+ myFixture.copyDirectoryToProject("completion/relativeImportExcludeToplevel", "");
+ myFixture.configureByFile("pack/subpack/modX.py");
+ myFixture.completeBasic();
+ assertFalse(myFixture.getLookupElementStrings().contains("sys"));
+ }
+ finally {
+ setLanguageLevel(null);
+ }
+ }
}
diff --git a/python/testSrc/com/jetbrains/python/inspections/PyUnresolvedReferencesInspectionTest.java b/python/testSrc/com/jetbrains/python/inspections/PyUnresolvedReferencesInspectionTest.java
index 559dd988529d..b74ba65d5de4 100644
--- a/python/testSrc/com/jetbrains/python/inspections/PyUnresolvedReferencesInspectionTest.java
+++ b/python/testSrc/com/jetbrains/python/inspections/PyUnresolvedReferencesInspectionTest.java
@@ -32,6 +32,10 @@ public class PyUnresolvedReferencesInspectionTest extends PyTestCase {
doTest();
}
+ public void testSlotsSubclass() { // PY-5939
+ doTest();
+ }
+
public void testImportExceptImportError() {
doTest();
}
@@ -102,6 +106,10 @@ public class PyUnresolvedReferencesInspectionTest extends PyTestCase {
doTest();
}
+ public void testCompoundDunderAll() { // PY-6370
+ doTest();
+ }
+
private void doMultiFileTest() {
myFixture.copyFileToProject("inspections/PyUnresolvedReferencesInspection/__init__.py", "PyUnresolvedReferencesInspection/__init__.py");
myFixture.copyFileToProject("inspections/PyUnresolvedReferencesInspection/" + getTestName(true) + ".py",
diff --git a/python/testSrc/com/jetbrains/python/inspections/PyUnusedImportTest.java b/python/testSrc/com/jetbrains/python/inspections/PyUnusedImportTest.java
index 820e18277352..5faf7790ba97 100644
--- a/python/testSrc/com/jetbrains/python/inspections/PyUnusedImportTest.java
+++ b/python/testSrc/com/jetbrains/python/inspections/PyUnusedImportTest.java
@@ -1,34 +1,40 @@
package com.jetbrains.python.inspections;
import com.jetbrains.python.fixtures.PyTestCase;
+import org.jetbrains.annotations.NotNull;
/**
* @author yole
*/
public class PyUnusedImportTest extends PyTestCase {
- public void testModuleAndSubmodule() { // PY-3626
- myFixture.copyDirectoryToProject("inspections/unusedImport/moduleAndSubmodule", "");
- myFixture.enableInspections(PyUnresolvedReferencesInspection.class);
- myFixture.testHighlighting(true, false, false, "py3626.py");
+ // PY-3626
+ public void testModuleAndSubmodule() {
+ doTest("py3626.py");
}
- public void testSubpackageInInitPy() { // PY-3201
- myFixture.copyDirectoryToProject("inspections/unusedImport/subpackageInInitPy", "");
- myFixture.enableInspections(PyUnresolvedReferencesInspection.class);
- myFixture.testHighlighting(true, false, false, "package1/__init__.py");
+ // PY-3201
+ public void testSubpackageInInitPy() {
+ doTest("package1/__init__.py");
}
// PY-5589
public void testUnusedPackageAndSubmodule() {
- myFixture.copyDirectoryToProject("inspections/unusedImport/unusedPackageAndSubmodule", "");
- myFixture.enableInspections(PyUnresolvedReferencesInspection.class);
- myFixture.testHighlighting(true, false, false, "test1.py");
+ doTest("test1.py");
}
// PY-5621
public void testUnusedSubmodule() {
- myFixture.copyDirectoryToProject("inspections/unusedImport/unusedSubmodule", "");
+ doTest("test1.py");
+ }
+
+ // PY-6380
+ public void testUnusedAfterStarImport() {
+ doTest("test1.py");
+ }
+
+ private void doTest(@NotNull String filename) {
+ myFixture.copyDirectoryToProject("inspections/unusedImport/" + getTestName(true), "");
myFixture.enableInspections(PyUnresolvedReferencesInspection.class);
- myFixture.testHighlighting(true, false, false, "test1.py");
+ myFixture.testHighlighting(true, false, false, filename);
}
}
diff --git a/python/testSrc/com/jetbrains/python/refactoring/PyMoveTest.java b/python/testSrc/com/jetbrains/python/refactoring/PyMoveTest.java
index 0738e56a286d..cb8645d368f6 100644
--- a/python/testSrc/com/jetbrains/python/refactoring/PyMoveTest.java
+++ b/python/testSrc/com/jetbrains/python/refactoring/PyMoveTest.java
@@ -90,6 +90,11 @@ public class PyMoveTest extends PyTestCase {
doMoveFileTest("p1/p2/m1.py", "nonp3");
}
+ // PY-6432
+ public void testStarImportUsage() {
+ doMoveSymbolTest("f", "c.py");
+ }
+
private void doMoveFileTest(String fileName, String toDirName) {
Project project = myFixture.getProject();
PsiManager manager = PsiManager.getInstance(project);
]