diff --git a/python/helpers/generator3.py b/python/helpers/generator3.py index a27ff1003ebc..8d23e0bcd11e 100644 --- a/python/helpers/generator3.py +++ b/python/helpers/generator3.py @@ -24,7 +24,7 @@ but seemingly no one uses them in C extensions yet anyway. # * re.search-bound, ~30% time, in likes of builtins and _gtk with complex docstrings. # None of this can seemingly be easily helped. Maybe there's a simpler and faster parser library? -VERSION = "1.115" # Must be a number-dot-number string, updated with each change that affects generated skeletons +VERSION = "1.116" # Must be a number-dot-number string, updated with each change that affects generated skeletons # Note: DON'T FORGET TO UPDATE! VERSION_CONTROL_HEADER_FORMAT = '# from %s by generator %s' @@ -803,6 +803,7 @@ class ModuleRedeclarator(object): (None, "iter"): "(source, sentinel=None)", (None, "getattr"): "(object, name, default=None)", ('frozenset', "__init__"): "(self, seq=())", + ("bytearray", "__init__"): "(self, source=None, encoding=None, errors='strict')", } if version[0] < 3: diff --git a/python/helpers/required_gen_version b/python/helpers/required_gen_version index 2957b9e4cbc7..9fa6f755b33d 100644 --- a/python/helpers/required_gen_version +++ b/python/helpers/required_gen_version @@ -6,7 +6,7 @@ (default) 1.92 # anything not explicitly marked -(built-in) 1.115 # skeletons of all built-in modules are built together +(built-in) 1.116 # skeletons of all built-in modules are built together # Note: modules like itertools, etc are "(built-in)" and are ignored if given separately _fileio 1.101 diff --git a/python/src/com/jetbrains/python/PythonDialectsTokenSetContributor.java b/python/src/com/jetbrains/python/PythonDialectsTokenSetContributor.java index b3e62ac5370b..5a7ef32790ba 100644 --- a/python/src/com/jetbrains/python/PythonDialectsTokenSetContributor.java +++ b/python/src/com/jetbrains/python/PythonDialectsTokenSetContributor.java @@ -14,4 +14,5 @@ public interface PythonDialectsTokenSetContributor { TokenSet getNameDefinerTokens(); TokenSet getKeywordTokens(); TokenSet getParameterTokens(); + TokenSet getFunctionDeclarationTokens(); } diff --git a/python/src/com/jetbrains/python/PythonDialectsTokenSetProvider.java b/python/src/com/jetbrains/python/PythonDialectsTokenSetProvider.java index df7b891e8964..73375523ad99 100644 --- a/python/src/com/jetbrains/python/PythonDialectsTokenSetProvider.java +++ b/python/src/com/jetbrains/python/PythonDialectsTokenSetProvider.java @@ -11,9 +11,10 @@ public class PythonDialectsTokenSetProvider { private final TokenSet myStatementTokens; private final TokenSet myExpressionTokens; - private TokenSet myNameDefinerTokens; - private TokenSet myKeywordTokens; - private TokenSet myParameterTokens; + private final TokenSet myNameDefinerTokens; + private final TokenSet myKeywordTokens; + private final TokenSet myParameterTokens; + private final TokenSet myFunctionDeclarationTokens; private PythonDialectsTokenSetProvider() { TokenSet stmts = TokenSet.EMPTY; @@ -21,18 +22,21 @@ public class PythonDialectsTokenSetProvider { TokenSet definers = TokenSet.EMPTY; TokenSet keywords = TokenSet.EMPTY; TokenSet parameters = TokenSet.EMPTY; + TokenSet functionDeclarations = TokenSet.EMPTY; for(PythonDialectsTokenSetContributor contributor: Extensions.getExtensions(PythonDialectsTokenSetContributor.EP_NAME)) { stmts = TokenSet.orSet(stmts, contributor.getStatementTokens()); exprs = TokenSet.orSet(exprs, contributor.getExpressionTokens()); definers = TokenSet.orSet(definers, contributor.getNameDefinerTokens()); keywords = TokenSet.orSet(keywords, contributor.getKeywordTokens()); parameters = TokenSet.orSet(parameters, contributor.getParameterTokens()); + functionDeclarations = TokenSet.orSet(functionDeclarations, contributor.getFunctionDeclarationTokens()); } myStatementTokens = stmts; myExpressionTokens = exprs; myNameDefinerTokens = definers; myKeywordTokens = keywords; myParameterTokens = parameters; + myFunctionDeclarationTokens = functionDeclarations; } public TokenSet getStatementTokens() { @@ -54,4 +58,8 @@ public class PythonDialectsTokenSetProvider { public TokenSet getParameterTokens() { return myParameterTokens; } + + public TokenSet getFunctionDeclarationTokens() { + return myFunctionDeclarationTokens; + } } diff --git a/python/src/com/jetbrains/python/PythonTokenSetContributor.java b/python/src/com/jetbrains/python/PythonTokenSetContributor.java index a9eb4380b502..9f16cc9534c2 100644 --- a/python/src/com/jetbrains/python/PythonTokenSetContributor.java +++ b/python/src/com/jetbrains/python/PythonTokenSetContributor.java @@ -59,4 +59,9 @@ public class PythonTokenSetContributor implements PythonDialectsTokenSetContribu public TokenSet getParameterTokens() { return TokenSet.create(NAMED_PARAMETER, TUPLE_PARAMETER, SINGLE_STAR_PARAMETER); } + + @Override + public TokenSet getFunctionDeclarationTokens() { + return TokenSet.create(FUNCTION_DECLARATION); + } } diff --git a/python/src/com/jetbrains/python/codeInsight/completion/PyClassNameCompletionContributor.java b/python/src/com/jetbrains/python/codeInsight/completion/PyClassNameCompletionContributor.java index 9beb913a2ab4..db521961863a 100644 --- a/python/src/com/jetbrains/python/codeInsight/completion/PyClassNameCompletionContributor.java +++ b/python/src/com/jetbrains/python/codeInsight/completion/PyClassNameCompletionContributor.java @@ -61,13 +61,7 @@ public class PyClassNameCompletionContributor extends CompletionContributor { final GlobalSearchScope scope = PyClassNameIndex.projectWithLibrariesScope(project); Collection keys = StubIndex.getInstance().getAllKeys(key, project); - final List allNames = new ArrayList(); - for (String s : keys) { - if (resultSet.getPrefixMatcher().prefixMatches(s)) { - allNames.add(s); - } - } - for (final String elementName : CompletionUtil.sortForCompletion(resultSet.getPrefixMatcher(), allNames)) { + for (final String elementName : CompletionUtil.sortMatching(resultSet.getPrefixMatcher(), keys)) { for (T element : StubIndex.getInstance().get(key, elementName, project, scope)) { if (condition.value(element)) { resultSet.addElement(LookupElementBuilder.create(element) diff --git a/python/src/com/jetbrains/python/inspections/PyPackageRequirementsInspection.java b/python/src/com/jetbrains/python/inspections/PyPackageRequirementsInspection.java index 8f6d721dc6bb..0e6cb0d1aa47 100644 --- a/python/src/com/jetbrains/python/inspections/PyPackageRequirementsInspection.java +++ b/python/src/com/jetbrains/python/inspections/PyPackageRequirementsInspection.java @@ -215,7 +215,7 @@ public class PyPackageRequirementsInspection extends PyInspection { final List packages = PyPackageManager.getInstance(sdk).getPackages(); for (PyRequirement req : requirements) { final PyPackage pkg = req.match(packages); - if (pkg != null) { + if (pkg != null && !visited.contains(pkg)) { visited.add(pkg); results.addAll(getTransitiveRequirements(sdk, pkg.getRequirements(), visited)); } diff --git a/python/src/com/jetbrains/python/packaging/PyPackage.java b/python/src/com/jetbrains/python/packaging/PyPackage.java index 2bce5616487b..12a06e1ebbe8 100644 --- a/python/src/com/jetbrains/python/packaging/PyPackage.java +++ b/python/src/com/jetbrains/python/packaging/PyPackage.java @@ -49,4 +49,21 @@ public class PyPackage { public boolean isInstalled() { return myLocation != null; } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + PyPackage aPackage = (PyPackage)o; + if (myName != null ? !myName.equals(aPackage.myName) : aPackage.myName != null) return false; + if (myVersion != null ? !myVersion.equals(aPackage.myVersion) : aPackage.myVersion != null) return false; + return true; + } + + @Override + public int hashCode() { + int result = myName != null ? myName.hashCode() : 0; + result = 31 * result + (myVersion != null ? myVersion.hashCode() : 0); + return result; + } } diff --git a/python/src/com/jetbrains/python/parsing/ExpressionParsing.java b/python/src/com/jetbrains/python/parsing/ExpressionParsing.java index fd009bdefb0a..52d27dc59974 100644 --- a/python/src/com/jetbrains/python/parsing/ExpressionParsing.java +++ b/python/src/com/jetbrains/python/parsing/ExpressionParsing.java @@ -381,7 +381,7 @@ public class ExpressionParsing extends Parsing { private static TokenSet BRACKET_OR_COMMA = TokenSet.create(PyTokenTypes.RBRACKET, PyTokenTypes.COMMA); private static TokenSet BRACKET_COLON_COMMA = TokenSet.create(PyTokenTypes.RBRACKET, PyTokenTypes.COLON, PyTokenTypes.COMMA); - private void parseSliceEnd(PsiBuilder.Marker exprStart, PsiBuilder.Marker sliceItemStart) { + public void parseSliceEnd(PsiBuilder.Marker exprStart, PsiBuilder.Marker sliceItemStart) { myBuilder.advanceLexer(); if (atToken(PyTokenTypes.RBRACKET)) { PsiBuilder.Marker sliceMarker = myBuilder.mark(); diff --git a/python/src/com/jetbrains/python/psi/impl/PyClassImpl.java b/python/src/com/jetbrains/python/psi/impl/PyClassImpl.java index 54efeb1dd7e4..e184ee2f41b0 100644 --- a/python/src/com/jetbrains/python/psi/impl/PyClassImpl.java +++ b/python/src/com/jetbrains/python/psi/impl/PyClassImpl.java @@ -11,14 +11,11 @@ import com.intellij.psi.search.LocalSearchScope; import com.intellij.psi.search.SearchScope; import com.intellij.psi.stubs.IStubElementType; import com.intellij.psi.stubs.StubElement; -import com.intellij.psi.tree.IElementType; +import com.intellij.psi.tree.TokenSet; import com.intellij.psi.util.*; import com.intellij.util.*; import com.intellij.util.containers.ContainerUtil; -import com.jetbrains.python.PyElementTypes; -import com.jetbrains.python.PyNames; -import com.jetbrains.python.PyTokenTypes; -import com.jetbrains.python.PythonDocStringFinder; +import com.jetbrains.python.*; import com.jetbrains.python.codeInsight.controlflow.ControlFlowCache; import com.jetbrains.python.codeInsight.controlflow.ScopeOwner; import com.jetbrains.python.psi.*; @@ -414,24 +411,24 @@ public class PyClassImpl extends PyPresentableElementImpl implement @NotNull public PyFunction[] getMethods() { - return getClassChildren(PyElementTypes.FUNCTION_DECLARATION, PyFunction.ARRAY_FACTORY); + return getClassChildren(PythonDialectsTokenSetProvider.INSTANCE.getFunctionDeclarationTokens(), PyFunction.ARRAY_FACTORY); } @Override public PyClass[] getNestedClasses() { - return getClassChildren(PyElementTypes.CLASS_DECLARATION, PyClass.ARRAY_FACTORY); + return getClassChildren(TokenSet.create(PyElementTypes.CLASS_DECLARATION), PyClass.ARRAY_FACTORY); } - protected T[] getClassChildren(IElementType elementType, ArrayFactory factory) { + protected T[] getClassChildren(TokenSet elementTypes, ArrayFactory factory) { // TODO: gather all top-level functions, maybe within control statements final PyClassStub classStub = getStub(); if (classStub != null) { - return classStub.getChildrenByType(elementType, factory); + return classStub.getChildrenByType(elementTypes, factory); } List result = new ArrayList(); final PyStatementList statementList = getStatementList(); for (PsiElement element : statementList.getChildren()) { - if (element.getNode().getElementType() == elementType) { + if (elementTypes.contains(element.getNode().getElementType())) { //noinspection unchecked result.add((T) element); } diff --git a/python/src/com/jetbrains/python/psi/impl/PyFromImportStatementImpl.java b/python/src/com/jetbrains/python/psi/impl/PyFromImportStatementImpl.java index 16b7e53d4b05..182a3ed46b58 100644 --- a/python/src/com/jetbrains/python/psi/impl/PyFromImportStatementImpl.java +++ b/python/src/com/jetbrains/python/psi/impl/PyFromImportStatementImpl.java @@ -205,6 +205,6 @@ public class PyFromImportStatementImpl extends PyBaseElementImplemptyList() : Collections.singletonList(upper); } } - return ResolveImportUtil.resolveFromImportStatementSource(this, qName); + return ResolveImportUtil.resolveFromOrForeignImportStatementSource(this, qName); } } diff --git a/python/src/com/jetbrains/python/psi/resolve/ResolveImportUtil.java b/python/src/com/jetbrains/python/psi/resolve/ResolveImportUtil.java index fd8649d0861b..b5055d3a80e9 100644 --- a/python/src/com/jetbrains/python/psi/resolve/ResolveImportUtil.java +++ b/python/src/com/jetbrains/python/psi/resolve/ResolveImportUtil.java @@ -151,6 +151,7 @@ public class ResolveImportUtil { return ResolveResultList.to(result); } + @NotNull public static List resolveFromOrForeignImport(PyFromImportStatement fromImportStatement, PyQualifiedName qname) { final List results = resolveFromImportStatementSource(fromImportStatement, qname); if (results.isEmpty() && qname != null && qname.getComponentCount() > 0) { @@ -169,6 +170,18 @@ public class ResolveImportUtil { return resolveModule(qName, file, absolute_import_enabled, from_import_statement.getRelativeLevel()); } + @NotNull + public static List resolveFromOrForeignImportStatementSource(@NotNull PyFromImportStatement fromImportStatement, + @Nullable PyQualifiedName qName) { + final List results = resolveFromImportStatementSource(fromImportStatement, qName); + if (!results.isEmpty()) { + return results; + } + final PsiElement result = qName != null ? resolveForeignImport(fromImportStatement, qName, null) : null; + return result instanceof PsiFileSystemItem ? Collections.singletonList((PsiFileSystemItem)result) + : Collections.emptyList(); + } + /** * Resolves a module reference in a general case. * diff --git a/python/testSrc/com/jetbrains/python/PyMultiFileResolveTest.java b/python/testSrc/com/jetbrains/python/PyMultiFileResolveTest.java index 1d1f9e605105..574229f3b9e0 100644 --- a/python/testSrc/com/jetbrains/python/PyMultiFileResolveTest.java +++ b/python/testSrc/com/jetbrains/python/PyMultiFileResolveTest.java @@ -389,6 +389,11 @@ public class PyMultiFileResolveTest extends PyResolveTestCase { assertResolvesTo(PyFunction.class, "foo"); } + // PY-6289 + public void testCythonIndirectStarImport() { + assertResolvesTo(PyFunction.class, "foo"); + } + private void prepareTestDirectory() { final String testName = getTestName(true); myFixture.copyDirectoryToProject(testName, "");