diff --git a/python/helpers/generator3.py b/python/helpers/generator3.py
index 447a63403df7..d5fec4d93472 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.108" # Must be a number-dot-number string, updated with each change that affects generated skeletons
+VERSION = "1.110" # 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'
@@ -1749,7 +1749,7 @@ class ModuleRedeclarator(object):
item = field_source[item_name] # have it raw
except Exception:
continue
- if isCallable(item):
+ if isCallable(item) and not isinstance(item, type):
methods[item_name] = item
elif isProperty(item):
properties[item_name] = item
@@ -2033,14 +2033,13 @@ class ModuleRedeclarator(object):
txt = (
"class ___Classobj:" "\n"
" '''A mock class representing the old style class base.'''" "\n"
- " __module__ = None" "\n"
+ " __module__ = ''" "\n"
" __class__ = None" "\n"
- " #" "\n"
+ "\n"
" def __init__(self):" "\n"
" pass" "\n"
" __dict__ = {}" "\n"
" __doc__ = ''" "\n"
- " __module__ = ''" "\n"
)
self.classes_buf.out(0, txt)
diff --git a/python/helpers/required_gen_version b/python/helpers/required_gen_version
index 6f3efcf4121d..a4042ca98a63 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.108 # skeletons of all built-in modules are built together
+(built-in) 1.110 # 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/META-INF/python-plugin-common.xml b/python/src/META-INF/python-plugin-common.xml
index 26fff826ecab..c8684329a267 100644
--- a/python/src/META-INF/python-plugin-common.xml
+++ b/python/src/META-INF/python-plugin-common.xml
@@ -933,7 +933,7 @@
+ description="Create a new directory and __init__.py inside it" icon="AllIcons.Nodes.PackageClosed">
diff --git a/python/src/com/jetbrains/python/codeInsight/PyDynamicMember.java b/python/src/com/jetbrains/python/codeInsight/PyDynamicMember.java
index a399ef86ecde..c161899633a5 100644
--- a/python/src/com/jetbrains/python/codeInsight/PyDynamicMember.java
+++ b/python/src/com/jetbrains/python/codeInsight/PyDynamicMember.java
@@ -1,6 +1,6 @@
package com.jetbrains.python.codeInsight;
-import com.intellij.openapi.util.IconLoader;
+import com.intellij.icons.AllIcons;
import com.intellij.psi.PsiElement;
import com.intellij.util.Function;
import com.jetbrains.python.psi.PyClass;
@@ -109,7 +109,7 @@ public class PyDynamicMember {
if (myTarget != null) {
return myTarget.getIcon(0);
}
- return IconLoader.getIcon("/nodes/method.png");
+ return AllIcons.Nodes.Method;
}
@Nullable
diff --git a/python/src/com/jetbrains/python/codeInsight/PyLineMarkerProvider.java b/python/src/com/jetbrains/python/codeInsight/PyLineMarkerProvider.java
index ec7da19f3f19..acd8c1a9645a 100644
--- a/python/src/com/jetbrains/python/codeInsight/PyLineMarkerProvider.java
+++ b/python/src/com/jetbrains/python/codeInsight/PyLineMarkerProvider.java
@@ -4,8 +4,8 @@ import com.intellij.codeHighlighting.Pass;
import com.intellij.codeInsight.daemon.DaemonCodeAnalyzerSettings;
import com.intellij.codeInsight.daemon.LineMarkerInfo;
import com.intellij.codeInsight.daemon.LineMarkerProvider;
+import com.intellij.icons.AllIcons;
import com.intellij.lang.ASTNode;
-import com.intellij.openapi.util.IconLoader;
import com.intellij.psi.PsiElement;
import com.intellij.psi.util.PsiTreeUtil;
import com.intellij.util.CollectionQuery;
@@ -34,8 +34,8 @@ import java.util.concurrent.atomic.AtomicInteger;
* @author yole
*/
public class PyLineMarkerProvider implements LineMarkerProvider, PyLineSeparatorUtil.Provider {
- private static final Icon OVERRIDING_METHOD_ICON = IconLoader.getIcon("/gutter/overridingMethod.png");
- private static final Icon OVERRIDDEN_ICON = IconLoader.getIcon("/gutter/overridenMethod.png");
+ private static final Icon OVERRIDING_METHOD_ICON = AllIcons.Gutter.OverridingMethod;
+ private static final Icon OVERRIDDEN_ICON = AllIcons.Gutter.OverridenMethod;
private static class TooltipProvider implements Function {
private final String myText;
diff --git a/python/src/com/jetbrains/python/configuration/ModuleAwareProjectConfigurable.java b/python/src/com/jetbrains/python/configuration/ModuleAwareProjectConfigurable.java
index 995391913989..85bdce6ad9c7 100644
--- a/python/src/com/jetbrains/python/configuration/ModuleAwareProjectConfigurable.java
+++ b/python/src/com/jetbrains/python/configuration/ModuleAwareProjectConfigurable.java
@@ -49,11 +49,6 @@ public abstract class ModuleAwareProjectConfigurable= 0; i--) {
+ if (text.charAt(i) == ' ') {
+ spaces++;
+ }
+ }
+ myCurrentNewLineIndent = spaces;
+ }
+ else if (getTokenType() == PyTokenTypes.TAB) {
+ myCurrentNewLineIndent += 8;
+ }
if (myTokenQueue.size() > 0) {
myTokenQueue.remove(0);
if (myProcessSpecialTokensPending) {
@@ -180,12 +202,30 @@ public class PythonIndentingProcessor extends MergingLexerAdapter {
}
private void adjustBraceLevel() {
- if (PyTokenTypes.OPEN_BRACES.contains(getTokenType())) {
+ final IElementType tokenType = getTokenType();
+ if (PyTokenTypes.OPEN_BRACES.contains(tokenType)) {
myBraceLevel++;
}
- else if (PyTokenTypes.CLOSE_BRACES.contains(getTokenType())) {
+ else if (PyTokenTypes.CLOSE_BRACES.contains(tokenType)) {
myBraceLevel--;
}
+ else if (myBraceLevel != 0 && RECOVERY_TOKENS.contains(tokenType)) {
+ myBraceLevel = 0;
+ final int pos = getTokenStart();
+ pushToken(PyTokenTypes.STATEMENT_BREAK, pos, pos);
+ final int indents = myIndentStack.size();
+ for (int i = 0; i < indents - 1; i++) {
+ final int indent = myIndentStack.peek();
+ if (myCurrentNewLineIndent >= indent) {
+ break;
+ }
+ if (myIndentStack.size() > 1) {
+ myIndentStack.pop();
+ pushToken(PyTokenTypes.DEDENT, pos, pos);
+ }
+ }
+ pushToken(PyTokenTypes.LINE_BREAK, pos, pos);
+ }
}
private void checkSignificantTokens() {
diff --git a/python/src/com/jetbrains/python/packaging/ui/ManagePackagesDialog.java b/python/src/com/jetbrains/python/packaging/ui/ManagePackagesDialog.java
index 15b3c3b8bdf6..6ffbc210e335 100644
--- a/python/src/com/jetbrains/python/packaging/ui/ManagePackagesDialog.java
+++ b/python/src/com/jetbrains/python/packaging/ui/ManagePackagesDialog.java
@@ -1,5 +1,6 @@
package com.jetbrains.python.packaging.ui;
+import com.intellij.icons.AllIcons;
import com.intellij.ide.BrowserUtil;
import com.intellij.openapi.actionSystem.AnActionEvent;
import com.intellij.openapi.application.Application;
@@ -9,7 +10,6 @@ import com.intellij.openapi.project.Project;
import com.intellij.openapi.projectRoots.Sdk;
import com.intellij.openapi.ui.DialogWrapper;
import com.intellij.openapi.ui.Messages;
-import com.intellij.openapi.util.IconLoader;
import com.intellij.openapi.util.Pair;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.ui.AnActionButton;
@@ -97,7 +97,7 @@ public class ManagePackagesDialog extends DialogWrapper {
myNotificationArea = new PyPackagesNotificationPanel(project);
myNotificationsAreaPlaceholder.add(myNotificationArea.getComponent(), BorderLayout.CENTER);
- final AnActionButton reloadButton = new AnActionButton("Reload List of Packages", IconLoader.getIcon("/vcs/refresh.png")) {
+ final AnActionButton reloadButton = new AnActionButton("Reload List of Packages", AllIcons.Vcs.Refresh) {
@Override
public void actionPerformed(AnActionEvent e) {
myPackages.setPaintBusy(true);
@@ -546,4 +546,4 @@ public class ManagePackagesDialog extends DialogWrapper {
return myPanel;
}
}
-}
\ No newline at end of file
+}
diff --git a/python/src/com/jetbrains/python/packaging/ui/PyPackagesPanel.java b/python/src/com/jetbrains/python/packaging/ui/PyPackagesPanel.java
index 57877fd85863..0336c9c7a968 100644
--- a/python/src/com/jetbrains/python/packaging/ui/PyPackagesPanel.java
+++ b/python/src/com/jetbrains/python/packaging/ui/PyPackagesPanel.java
@@ -1,13 +1,13 @@
package com.jetbrains.python.packaging.ui;
import com.google.common.collect.Lists;
+import com.intellij.icons.AllIcons;
import com.intellij.openapi.application.Application;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.application.ModalityState;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.projectRoots.Sdk;
import com.intellij.openapi.ui.Messages;
-import com.intellij.openapi.util.IconLoader;
import com.intellij.ui.ScrollPaneFactory;
import com.intellij.ui.table.JBTable;
import com.intellij.util.Consumer;
@@ -513,7 +513,7 @@ public class PyPackagesPanel extends JPanel {
final String version = (String)table.getValueAt(row, 1);
final String availableVersion = (String)table.getValueAt(row, 2);
cell.setIcon(PyRequirement.VERSION_COMPARATOR.compare(version, availableVersion) < 0 && column == 2 ?
- IconLoader.getIcon("/vcs/arrow_right.png") : null);
+ AllIcons.Vcs.Arrow_right : null);
final Object pyPackage = table.getValueAt(row, 0);
if (pyPackage instanceof PyPackage) {
cell.setToolTipText(PythonSdkType.shortenDirName(((PyPackage)pyPackage).getLocation()));
diff --git a/python/src/com/jetbrains/python/sdk/PySdkListCellRenderer.java b/python/src/com/jetbrains/python/sdk/PySdkListCellRenderer.java
index a0cbaadb41e6..b6c7ae94acfb 100644
--- a/python/src/com/jetbrains/python/sdk/PySdkListCellRenderer.java
+++ b/python/src/com/jetbrains/python/sdk/PySdkListCellRenderer.java
@@ -1,9 +1,9 @@
package com.jetbrains.python.sdk;
+import com.intellij.icons.AllIcons;
import com.intellij.openapi.projectRoots.Sdk;
import com.intellij.openapi.projectRoots.SdkModificator;
import com.intellij.openapi.projectRoots.SdkType;
-import com.intellij.openapi.util.IconLoader;
import com.intellij.ui.HtmlListCellRenderer;
import com.intellij.ui.LayeredIcon;
@@ -35,7 +35,7 @@ public class PySdkListCellRenderer extends HtmlListCellRenderer {
final LayeredIcon layered = new LayeredIcon(2);
layered.setIcon(icon, 0);
// TODO: Create a separate invalid SDK overlay icon
- final Icon overlay = IconLoader.findIcon("/actions/cancel.png");
+ final Icon overlay = AllIcons.Actions.Cancel;
layered.setIcon(overlay, 1);
setIcon(layered);
}
diff --git a/python/src/com/jetbrains/python/structureView/PyInheritedMembersFilter.java b/python/src/com/jetbrains/python/structureView/PyInheritedMembersFilter.java
index 2e9f20c91c5a..5d3c9b07f324 100644
--- a/python/src/com/jetbrains/python/structureView/PyInheritedMembersFilter.java
+++ b/python/src/com/jetbrains/python/structureView/PyInheritedMembersFilter.java
@@ -1,5 +1,6 @@
package com.jetbrains.python.structureView;
+import com.intellij.icons.AllIcons;
import com.intellij.ide.IdeBundle;
import com.intellij.ide.util.FileStructureFilter;
import com.intellij.ide.util.treeView.smartTree.ActionPresentation;
@@ -7,7 +8,6 @@ import com.intellij.ide.util.treeView.smartTree.ActionPresentationData;
import com.intellij.ide.util.treeView.smartTree.TreeElement;
import com.intellij.openapi.actionSystem.Shortcut;
import com.intellij.openapi.keymap.KeymapManager;
-import com.intellij.openapi.util.IconLoader;
import org.jetbrains.annotations.NotNull;
/**
@@ -46,7 +46,7 @@ public class PyInheritedMembersFilter implements FileStructureFilter {
public ActionPresentation getPresentation() {
return new ActionPresentationData(IdeBundle.message("action.structureview.show.inherited"),
null,
- IconLoader.getIcon("/hierarchy/supertypes.png"));
+ AllIcons.Hierarchy.Supertypes);
}
@Override
diff --git a/python/testData/psi/MissingParenInCall.txt b/python/testData/psi/MissingParenInCall.txt
index 1021a7a2cb29..57caa80d8ccf 100644
--- a/python/testData/psi/MissingParenInCall.txt
+++ b/python/testData/psi/MissingParenInCall.txt
@@ -26,20 +26,20 @@ PyFile:MissingParenInCall.py
PsiElement(Py:COMMA)(',')
PsiErrorElement:expression expected
+ PsiWhiteSpace('\n\n')
PsiErrorElement:Colon expected
- PsiWhiteSpace('\n\n')
PyStatementList
- PyFunction('clean')
- PsiElement(Py:DEF_KEYWORD)('def')
- PsiWhiteSpace(' ')
- PsiElement(Py:IDENTIFIER)('clean')
- PyParameterList
- PsiElement(Py:LPAR)('(')
- PsiElement(Py:RPAR)(')')
- PsiElement(Py:COLON)(':')
- PsiWhiteSpace('\n ')
- PyStatementList
- PyPassStatement
- PsiElement(Py:PASS_KEYWORD)('pass')
\ No newline at end of file
+ PyFunction('clean')
+ PsiElement(Py:DEF_KEYWORD)('def')
+ PsiWhiteSpace(' ')
+ PsiElement(Py:IDENTIFIER)('clean')
+ PyParameterList
+ PsiElement(Py:LPAR)('(')
+ PsiElement(Py:RPAR)(')')
+ PsiElement(Py:COLON)(':')
+ PsiWhiteSpace('\n ')
+ PyStatementList
+ PyPassStatement
+ PsiElement(Py:PASS_KEYWORD)('pass')
\ No newline at end of file
diff --git a/python/testSrc/com/jetbrains/python/PyStructureViewTest.java b/python/testSrc/com/jetbrains/python/PyStructureViewTest.java
index 5c4a6fd01100..9931acb5a945 100644
--- a/python/testSrc/com/jetbrains/python/PyStructureViewTest.java
+++ b/python/testSrc/com/jetbrains/python/PyStructureViewTest.java
@@ -73,7 +73,8 @@ public class PyStructureViewTest extends PyTestCase {
" __setattr__(self, name, value)\n" +
" __class__\n" +
" __dict__\n" +
- " __doc__\n",
+ " __doc__\n" +
+ " __module__\n",
true);
}
diff --git a/python/testSrc/com/jetbrains/python/PythonLexerTest.java b/python/testSrc/com/jetbrains/python/PythonLexerTest.java
index 80113d62bb5a..592e1cdcd447 100644
--- a/python/testSrc/com/jetbrains/python/PythonLexerTest.java
+++ b/python/testSrc/com/jetbrains/python/PythonLexerTest.java
@@ -201,6 +201,54 @@ public class PythonLexerTest extends PyLexerTestCase {
doTest(" a", "Py:SPACE", "Py:INDENT", "Py:IDENTIFIER", "Py:STATEMENT_BREAK");
}
+ // PY-3067
+ public void testErrorOpenParInExpr() {
+ doTest("def f():\n" +
+ " (\n" +
+ "\n" +
+ "def g():\n" +
+ " pass\n",
+ "Py:DEF_KEYWORD", "Py:SPACE", "Py:IDENTIFIER", "Py:LPAR", "Py:RPAR", "Py:COLON", "Py:STATEMENT_BREAK", "Py:LINE_BREAK",
+ "Py:INDENT", "Py:LPAR", "Py:LINE_BREAK",
+ "Py:STATEMENT_BREAK", "Py:DEDENT", "Py:LINE_BREAK", // Error recovery
+ "Py:DEF_KEYWORD", "Py:SPACE", "Py:IDENTIFIER", "Py:LPAR", "Py:RPAR", "Py:COLON", "Py:STATEMENT_BREAK", "Py:LINE_BREAK",
+ "Py:INDENT", "Py:PASS_KEYWORD", "Py:STATEMENT_BREAK", "Py:DEDENT", "Py:LINE_BREAK",
+ "Py:STATEMENT_BREAK");
+ }
+
+ // PY-3067
+ public void testErrorOpenParInExprBeforeComment() {
+ doTest("def f():\n" +
+ " (\n" +
+ "#comment\n" +
+ "def g():\n" +
+ " pass\n",
+ "Py:DEF_KEYWORD", "Py:SPACE", "Py:IDENTIFIER", "Py:LPAR", "Py:RPAR", "Py:COLON", "Py:STATEMENT_BREAK", "Py:LINE_BREAK",
+ "Py:INDENT", "Py:LPAR", "Py:LINE_BREAK",
+ "Py:END_OF_LINE_COMMENT", "Py:LINE_BREAK",
+ "Py:STATEMENT_BREAK", "Py:DEDENT", "Py:LINE_BREAK", // Error recovery
+ "Py:DEF_KEYWORD", "Py:SPACE", "Py:IDENTIFIER", "Py:LPAR", "Py:RPAR", "Py:COLON", "Py:STATEMENT_BREAK", "Py:LINE_BREAK",
+ "Py:INDENT", "Py:PASS_KEYWORD", "Py:STATEMENT_BREAK", "Py:DEDENT", "Py:LINE_BREAK",
+ "Py:STATEMENT_BREAK");
+ }
+
+ // PY-3067
+ public void testErrorOpenParInMethod() {
+ doTest("class C:\n" +
+ " def f(self):\n" +
+ " (\n" +
+ "\n" +
+ " def g(self):\n" +
+ " pass\n",
+ "Py:CLASS_KEYWORD", "Py:SPACE", "Py:IDENTIFIER", "Py:COLON", "Py:STATEMENT_BREAK", "Py:LINE_BREAK",
+ "Py:INDENT", "Py:DEF_KEYWORD", "Py:SPACE", "Py:IDENTIFIER", "Py:LPAR", "Py:IDENTIFIER", "Py:RPAR", "Py:COLON", "Py:STATEMENT_BREAK", "Py:LINE_BREAK",
+ "Py:INDENT", "Py:LPAR", "Py:LINE_BREAK",
+ "Py:STATEMENT_BREAK", "Py:DEDENT", "Py:LINE_BREAK", // Error recovery
+ "Py:DEF_KEYWORD", "Py:SPACE", "Py:IDENTIFIER", "Py:LPAR", "Py:IDENTIFIER", "Py:RPAR", "Py:COLON", "Py:STATEMENT_BREAK", "Py:LINE_BREAK",
+ "Py:INDENT", "Py:PASS_KEYWORD", "Py:STATEMENT_BREAK", "Py:DEDENT", "Py:DEDENT", "Py:LINE_BREAK",
+ "Py:STATEMENT_BREAK");
+ }
+
private static void doTest(String text, String... expectedTokens) {
doLexerTest(text, new PythonIndentingLexer(), expectedTokens);
}