Merge remote-tracking branch 'origin/master'

This commit is contained in:
Ekaterina Tuzova
2012-08-31 19:30:46 +04:00
35 changed files with 316 additions and 45 deletions
@@ -18,6 +18,7 @@ package com.jetbrains.python.templateLanguages;
import com.intellij.codeInsight.lookup.LookupElement;
import com.intellij.openapi.extensions.ExtensionPointName;
import com.intellij.psi.PsiFile;
import org.jetbrains.annotations.Nullable;
import java.util.Collection;
@@ -34,7 +35,8 @@ public interface TemplateContextProvider {
* name of the variable; the object is the PsiElement declaring the variable.
*
* @param template the template file
* @return the list of variables
* @return the list of variables, or null if the template is not used in the context handled by this processor.
*/
@Nullable
Collection<LookupElement> getTemplateContext(PsiFile template);
}
@@ -240,6 +240,11 @@
<category>Python</category>
</intentionAction>
<intentionAction>
<className>com.jetbrains.python.codeInsight.intentions.PyYieldFromIntention</className>
<category>Python</category>
</intentionAction>
<testFinder implementation="com.jetbrains.python.codeInsight.testIntegration.PyTestFinder"/>
<testCreator language="Python" implementationClass="com.jetbrains.python.codeInsight.testIntegration.PyTestCreator"/>
@@ -193,6 +193,9 @@ INTN.specify.returt.type.in.annotation=Specify return type using annotation
#TypeAssertionIntention
INTN.insert.assertion=Insert type assertion
#PyYieldFromIntention
INTN.yield.from=Transform explicit iteration with 'yield' into 'yield from' expression
# Conflict checker
CONFLICT.name.$0.obscured=Name ''{0}'' obscured by local definitions
CONFLICT.name.$0.obscured.cannot.convert=Name ''{0}'' obscured. Cannot convert.
@@ -10,15 +10,18 @@ import java.util.Set;
public class PyCodeFragment extends CodeFragment {
private final Set<String> myGlobalWrites;
private final Set<String> myNonlocalWrites;
private final boolean myYieldInside;
public PyCodeFragment(final Set<String> input,
final Set<String> output,
final Set<String> globalWrites,
final Set<String> nonlocalWrites,
final boolean returnInside) {
final boolean returnInside,
final boolean yieldInside) {
super(input, output, returnInside);
myGlobalWrites = globalWrites;
myNonlocalWrites = nonlocalWrites;
myYieldInside = yieldInside;
}
public Set<String> getGlobalWrites() {
@@ -28,4 +31,8 @@ public class PyCodeFragment extends CodeFragment {
public Set<String> getNonlocalWrites() {
return myNonlocalWrites;
}
public boolean isYieldInside() {
return myYieldInside;
}
}
@@ -82,7 +82,13 @@ public class PyCodeFragmentUtil {
}
}
return new PyCodeFragment(inputNames, outputNames, globalWrites, nonlocalWrites, subGraphAnalysis.returns > 0);
final boolean yieldsFound = subGraphAnalysis.yieldExpressions > 0;
if (yieldsFound && LanguageLevel.forElement(owner).isOlderThan(LanguageLevel.PYTHON33)) {
throw new CannotCreateCodeFragmentException("Cannot perform refactoring with 'yield' statement inside code block");
}
return new PyCodeFragment(inputNames, outputNames, globalWrites, nonlocalWrites, subGraphAnalysis.returns > 0, yieldsFound);
}
private static boolean resolvesToBoundMethodParameter(@NotNull PsiElement element) {
@@ -164,13 +170,15 @@ public class PyCodeFragmentUtil {
private final int regularExits;
private final int returns;
private final int outerLoopBreaks;
private final int yieldExpressions;
public AnalysisResult(int starImports, int targetInstructions, int returns, int regularExits, int outerLoopBreaks) {
public AnalysisResult(int starImports, int targetInstructions, int returns, int regularExits, int outerLoopBreaks, int yieldExpressions) {
this.starImports = starImports;
this.targetInstructions = targetInstructions;
this.regularExits = regularExits;
this.returns = returns;
this.outerLoopBreaks = outerLoopBreaks;
this.yieldExpressions = yieldExpressions;
}
}
@@ -181,6 +189,7 @@ public class PyCodeFragmentUtil {
final Set<Instruction> targetInstructions = new HashSet<Instruction>();
int starImports = 0;
int outerLoopBreaks = 0;
int yieldExpressions = 0;
for (Pair<Instruction, Instruction> edge : getOutgoingEdges(subGraph)) {
final Instruction sourceInstruction = edge.getFirst();
@@ -218,9 +227,12 @@ public class PyCodeFragmentUtil {
outerLoopBreaks++;
}
}
if (element instanceof PyYieldExpression) {
yieldExpressions++;
}
}
return new AnalysisResult(starImports, targetInstructions.size(), returnSources, regularSources, outerLoopBreaks);
return new AnalysisResult(starImports, targetInstructions.size(), returnSources, regularSources, outerLoopBreaks, yieldExpressions);
}
@NotNull
@@ -216,7 +216,7 @@ public class PyKeywordCompletionContributor extends CompletionContributor {
psiElement().inside(PyStringLiteralExpression.class);
private static final PsiElementPattern.Capture<PsiElement> IN_FUNCTION_HEADER =
psiElement().inside(PyFunction.class).andNot(psiElement().inside(PyStatementList.class));
psiElement().inside(PyFunction.class).andNot(psiElement().inside(false, psiElement(PyStatementList.class), psiElement(PyFunction.class)));
public static final PsiElementPattern.Capture<PsiElement> AFTER_QUALIFIER =
psiElement().afterLeaf(psiElement().withText(".").inside(PyReferenceExpression.class));
@@ -289,13 +289,8 @@ public class PyKeywordCompletionContributor extends CompletionContributor {
private static final PsiElementPattern.Capture<PsiElement> AFTER_IF = afterStatement(psiElement(PyIfStatement.class));
private static final PsiElementPattern.Capture<PsiElement> AFTER_TRY = afterStatement(psiElement(PyTryExceptStatement.class));
/*
private static final FilterPattern AFTER_LOOP_NO_ELSE = new FilterPattern(new PrecededByFilter(
psiElement()
.withChild(StandardPatterns.or(psiElement(PyWhileStatement.class), psiElement(PyForStatement.class)))
.withLastChild(StandardPatterns.not(psiElement(PyElsePart.class)))
));
*/
private static final PsiElementPattern.Capture<PsiElement> AFTER_LOOP_NO_ELSE =
afterStatement(psiElement(PyLoopStatement.class).withLastChild(StandardPatterns.not(psiElement(PyElsePart.class))));
private static final PsiElementPattern.Capture<PsiElement> AFTER_COND_STMT_NO_ELSE =
afterStatement(psiElement().withChild(psiElement(PyConditionalStatementPart.class))
@@ -485,7 +480,7 @@ public class PyKeywordCompletionContributor extends CompletionContributor {
CompletionType.BASIC, psiElement()
.withLanguage(PythonLanguage.getInstance())
.and(FIRST_ON_LINE)
.andOr(IN_COND_STMT, IN_TRY_BODY, IN_EXCEPT_BODY, AFTER_COND_STMT_NO_ELSE, AFTER_TRY_NO_ELSE)
.andOr(IN_COND_STMT, IN_TRY_BODY, IN_EXCEPT_BODY, AFTER_COND_STMT_NO_ELSE, AFTER_LOOP_NO_ELSE, AFTER_TRY_NO_ELSE)
//.andNot(RIGHT_AFTER_COLON)
.andNot(AFTER_QUALIFIER).andNot(IN_STRING_LITERAL)
,
@@ -425,6 +425,15 @@ public class PyControlFlowBuilder extends PyRecursiveElementVisitor {
myBuilder.flowAbrupted();
}
@Override
public void visitPyYieldExpression(PyYieldExpression node) {
myBuilder.startNode(node);
final PyExpression expression = node.getExpression();
if (expression != null) {
expression.accept(this);
}
}
@Override
public void visitPyRaiseStatement(final PyRaiseStatement node) {
myBuilder.startNode(node);
@@ -0,0 +1,108 @@
package com.jetbrains.python.codeInsight.intentions;
import com.intellij.codeInsight.intention.impl.BaseIntentionAction;
import com.intellij.openapi.editor.Editor;
import com.intellij.openapi.project.Project;
import com.intellij.psi.PsiElement;
import com.intellij.psi.PsiFile;
import com.intellij.psi.util.PsiTreeUtil;
import com.intellij.util.IncorrectOperationException;
import com.jetbrains.python.PyBundle;
import com.jetbrains.python.psi.*;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
/**
* @author vlan
*/
public class PyYieldFromIntention extends BaseIntentionAction {
@NotNull
@Override
public String getFamilyName() {
return PyBundle.message("INTN.yield.from");
}
@NotNull
@Override
public String getText() {
return PyBundle.message("INTN.yield.from");
}
@Override
public boolean isAvailable(@NotNull Project project, Editor editor, PsiFile file) {
if (LanguageLevel.forElement(file).isAtLeast(LanguageLevel.PYTHON33)) {
final PyForStatement forLoop = findForStatementAtCaret(editor, file);
if (forLoop != null) {
final PyTargetExpression forTarget = findSingleForLoopTarget(forLoop);
final PyReferenceExpression yieldValue = findSingleYieldValue(forLoop);
if (forTarget != null && yieldValue != null) {
final String targetName = forTarget.getName();
if (targetName != null && targetName.equals(yieldValue.getName())) {
return true;
}
}
}
}
return false;
}
@Override
public void invoke(@NotNull Project project, Editor editor, PsiFile file) throws IncorrectOperationException {
final PyForStatement forLoop = findForStatementAtCaret(editor, file);
if (forLoop != null) {
final PyExpression source = forLoop.getForPart().getSource();
if (source != null) {
final PyElementGenerator generator = PyElementGenerator.getInstance(project);
final String text = "yield from foo";
final PyExpressionStatement exprStmt = generator.createFromText(LanguageLevel.forElement(file), PyExpressionStatement.class, text);
final PyExpression expr = exprStmt.getExpression();
if (expr instanceof PyYieldExpression) {
final PyExpression yieldValue = ((PyYieldExpression)expr).getExpression();
if (yieldValue != null) {
yieldValue.replace(source);
forLoop.replace(exprStmt);
}
}
}
}
}
@Nullable
private static PyForStatement findForStatementAtCaret(@NotNull Editor editor, @NotNull PsiFile file) {
final PsiElement elementAtCaret = file.findElementAt(editor.getCaretModel().getOffset());
return PsiTreeUtil.getParentOfType(elementAtCaret, PyForStatement.class);
}
@Nullable
private static PyTargetExpression findSingleForLoopTarget(@NotNull PyForStatement forLoop) {
final PyForPart forPart = forLoop.getForPart();
final PyExpression forTarget = forPart.getTarget();
if (forTarget instanceof PyTargetExpression) {
return (PyTargetExpression)forTarget;
}
return null;
}
@Nullable
private static PyReferenceExpression findSingleYieldValue(@NotNull PyForStatement forLoop) {
final PyForPart forPart = forLoop.getForPart();
final PyStatementList stmtList = forPart.getStatementList();
if (stmtList != null && forLoop.getElsePart() == null) {
final PyStatement[] statements = stmtList.getStatements();
if (statements.length == 1) {
final PyStatement firstStmt = statements[0];
if (firstStmt instanceof PyExpressionStatement) {
final PyExpression firstExpr = ((PyExpressionStatement)firstStmt).getExpression();
if (firstExpr instanceof PyYieldExpression) {
final PyYieldExpression yieldExpr = (PyYieldExpression)firstExpr;
final PyExpression yieldValue = yieldExpr.getExpression();
if (yieldValue instanceof PyReferenceExpression) {
return (PyReferenceExpression)yieldValue;
}
}
}
}
}
return null;
}
}
@@ -183,7 +183,7 @@ public class PyOverrideImplementUtil {
statementBody.append(PyNames.PASS);
}
else {
if (baseFunction.getReturnType(TypeEvalContext.slow(), null) != PyNoneType.INSTANCE) {
if (!PyNames.INIT.equals(baseFunction.getName()) && baseFunction.getReturnType(TypeEvalContext.slow(), null) != PyNoneType.INSTANCE) {
statementBody.append("return ");
}
if (baseClass.isNewStyleClass()) {
@@ -32,7 +32,7 @@ public class PyClassFindUsagesHandler extends FindUsagesHandler {
}
@Override
protected boolean isSearchForTextOccurencesAvailable(PsiElement psiElement, boolean isSingleFile) {
protected boolean isSearchForTextOccurencesAvailable(@NotNull PsiElement psiElement, boolean isSingleFile) {
return true;
}
@@ -23,7 +23,7 @@ public class PyFunctionFindUsagesHandler extends FindUsagesHandler {
}
@Override
protected boolean isSearchForTextOccurencesAvailable(PsiElement psiElement, boolean isSingleFile) {
protected boolean isSearchForTextOccurencesAvailable(@NotNull PsiElement psiElement, boolean isSingleFile) {
return true;
}
@@ -6,11 +6,20 @@ import com.intellij.find.findUsages.FindUsagesHandler;
import com.intellij.psi.PsiDirectory;
import com.intellij.psi.PsiElement;
import com.intellij.psi.PsiFileSystemItem;
import com.intellij.psi.PsiReference;
import com.intellij.psi.search.SearchScope;
import com.intellij.psi.search.searches.ReferencesSearch;
import com.intellij.ui.SimpleColoredComponent;
import com.intellij.ui.SimpleTextAttributes;
import com.jetbrains.python.PyNames;
import com.jetbrains.python.psi.PyFile;
import com.jetbrains.python.psi.PyUtil;
import org.jetbrains.annotations.NotNull;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
/**
* @author yole
*/
@@ -40,10 +49,21 @@ public class PyModuleFindUsagesHandler extends FindUsagesHandler {
isSingleFile,
this) {
@Override
public void configureLabelComponent(final SimpleColoredComponent coloredComponent) {
public void configureLabelComponent(@NotNull final SimpleColoredComponent coloredComponent) {
coloredComponent.append(myElement instanceof PsiDirectory ? "Package " : "Module ");
coloredComponent.append(myElement.getName(), SimpleTextAttributes.REGULAR_BOLD_ATTRIBUTES);
}
};
}
@Override
public Collection<PsiReference> findReferencesToHighlight(PsiElement target, SearchScope searchScope) {
if (target instanceof PyFile && PyNames.INIT_DOT_PY.equals(((PyFile)target).getName())) {
List<PsiReference> result = new ArrayList<PsiReference>();
result.addAll(super.findReferencesToHighlight(target, searchScope));
result.addAll(ReferencesSearch.search(PyUtil.turnInitIntoDir(target), searchScope, false).findAll());
return result;
}
return super.findReferencesToHighlight(target, searchScope);
}
}
@@ -549,11 +549,19 @@ public class PyBlock implements ASTBlock {
}
ASTNode lastChild = getLastNonSpaceChild(_node, false);
if (lastChild != null && lastChild.getElementType() == PyElementTypes.STATEMENT_LIST) {
// only multiline statement lists are considered incomplete
ASTNode statementListPrev = lastChild.getTreePrev();
if (statementListPrev != null && statementListPrev.getText().indexOf('\n') >= 0) {
return true;
if (lastChild != null) {
if (lastChild.getElementType() == PyElementTypes.STATEMENT_LIST) {
// only multiline statement lists are considered incomplete
ASTNode statementListPrev = lastChild.getTreePrev();
if (statementListPrev != null && statementListPrev.getText().indexOf('\n') >= 0) {
return true;
}
}
if (lastChild.getElementType() == PyElementTypes.BINARY_EXPRESSION) {
PyBinaryExpression binaryExpression = (PyBinaryExpression) lastChild.getPsi();
if (binaryExpression.getRightExpression() == null) {
return true;
}
}
}
@@ -77,6 +77,7 @@ public class PythonFormattingModelBuilder implements FormattingModelBuilderEx, C
.before(COLON).spaceIf(pySettings.SPACE_BEFORE_PY_COLON)
.after(COMMA).spaceIf(commonSettings.SPACE_AFTER_COMMA)
.before(COMMA).spaceIf(commonSettings.SPACE_BEFORE_COMMA)
.between(FROM_KEYWORD, DOT).spaces(1)
.around(DOT).spaces(0)
.before(SEMICOLON).spaceIf(commonSettings.SPACE_BEFORE_SEMICOLON)
.withinPairInside(LPAR, RPAR, ARGUMENT_LIST).spaceIf(commonSettings.SPACE_WITHIN_METHOD_CALL_PARENTHESES)
@@ -5,6 +5,8 @@ import com.intellij.psi.PsiElementResolveResult;
import com.intellij.psi.ResolveResult;
import com.intellij.psi.util.PsiTreeUtil;
import com.intellij.util.ArrayUtil;
import com.jetbrains.python.psi.PyClass;
import com.jetbrains.python.psi.PyFunction;
import com.jetbrains.python.psi.PyImportElement;
import com.jetbrains.python.psi.PyQualifiedExpression;
import com.jetbrains.python.psi.resolve.PyResolveContext;
@@ -22,15 +24,16 @@ public class PyTargetReference extends PyReferenceImpl {
@Override
public ResolveResult[] multiResolve(boolean incompleteCode) {
final ResolveResult[] results = super.multiResolve(incompleteCode);
boolean resolvedToAnotherFile = false;
boolean shadowed = false;
for (ResolveResult result : results) {
final PsiElement element = result.getElement();
if (element != null && element.getContainingFile() != myElement.getContainingFile()) {
resolvedToAnotherFile = true;
if (element != null && (element.getContainingFile() != myElement.getContainingFile() ||
element instanceof PyFunction || element instanceof PyClass)) {
shadowed = true;
break;
}
}
if (results.length > 0 && !resolvedToAnotherFile) {
if (results.length > 0 && !shadowed) {
return results;
}
// resolve to self if no other target found
@@ -1,7 +1,6 @@
package com.jetbrains.python.refactoring.extractmethod;
import com.intellij.codeInsight.codeFragment.CannotCreateCodeFragmentException;
import com.intellij.codeInsight.codeFragment.CodeFragment;
import com.intellij.openapi.actionSystem.DataContext;
import com.intellij.openapi.editor.*;
import com.intellij.openapi.project.Project;
@@ -93,7 +92,7 @@ public class PyExtractMethodHandler implements RefactoringActionHandler {
if (owner == null) {
return;
}
final CodeFragment fragment;
final PyCodeFragment fragment;
try {
fragment = PyCodeFragmentUtil.createCodeFragment(owner, element1, element2);
}
@@ -110,6 +110,9 @@ public class PyExtractMethodUtil {
if (fragment.isReturnInstructionInside()) {
builder.append("return ");
}
if (fragment.isYieldInside()) {
builder.append("yield from ");
}
if (isMethod) {
appendSelf(firstElement, builder, isStaticMethod);
}
@@ -158,6 +161,9 @@ public class PyExtractMethodUtil {
// Generate call element
builder.append(" = ");
if (fragment.isYieldInside()) {
builder.append("yield from ");
}
if (isMethod){
appendSelf(elementsRange.get(0), builder, isStaticMethod);
}
@@ -234,7 +240,7 @@ public class PyExtractMethodUtil {
public static void extractFromExpression(final Project project,
final Editor editor,
final CodeFragment fragment,
final PyCodeFragment fragment,
final PsiElement expression) {
if (!fragment.getOutputVariables().isEmpty()){
CommonRefactoringUtil.showErrorHint(project, editor,
@@ -281,6 +287,9 @@ public class PyExtractMethodUtil {
// Generating call element
final StringBuilder builder = new StringBuilder();
builder.append("return ");
if (fragment.isYieldInside()) {
builder.append("yield from ");
}
if (isMethod){
appendSelf(expression, builder, isStaticMethod);
}
@@ -295,14 +295,14 @@ public class PythonRemoteSdkAdditionalData extends PythonSdkAdditionalData imple
if (element != null) {
data.setHost(element.getAttributeValue(HOST));
data.setPort(Integer.parseInt(element.getAttributeValue(PORT)));
data.setAnonymous(Boolean.parseBoolean(element.getAttributeValue(ANONYMOUS)));
data.setPort(StringUtil.parseInt(element.getAttributeValue(PORT), 22));
data.setAnonymous(StringUtil.parseBoolean(element.getAttributeValue(ANONYMOUS), false));
data.setSerializedUserName(element.getAttributeValue(USERNAME));
data.setSerializedPassword(element.getAttributeValue(PASSWORD));
data.setPrivateKeyFile(StringUtil.nullize(element.getAttributeValue(PRIVATE_KEY_FILE)));
data.setKnownHostsFile(StringUtil.nullize(element.getAttributeValue(KNOWN_HOSTS_FILE)));
data.setSerializedPassphrase(element.getAttributeValue(PASSPHRASE));
data.setUseKeyPair(Boolean.parseBoolean(element.getAttributeValue(USE_KEY_PAIR)));
data.setUseKeyPair(StringUtil.parseBoolean(element.getAttributeValue(USE_KEY_PAIR), false));
data.setInterpreterPath(StringUtil.nullize(element.getAttributeValue(INTERPRETER_PATH)));
data.setPyCharmTempFilesPath(StringUtil.nullize(element.getAttributeValue(PYCHARM_HELPERS_PATH)));
@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<form xmlns="http://www.intellij.com/uidesigner/form/" version="1" bind-to-class="com.jetbrains.python.sdk.CreateVirtualEnvDialog">
<grid id="cbd77" binding="myMainPanel" layout-manager="GridLayoutManager" row-count="6" column-count="2" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1">
<grid id="cbd77" binding="myMainPanel" layout-manager="GridLayoutManager" row-count="7" column-count="2" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1">
<margin top="0" left="0" bottom="0" right="0"/>
<constraints>
<xy x="48" y="54" width="550" height="342"/>
@@ -16,7 +16,7 @@
</component>
<vspacer id="b277d">
<constraints>
<grid row="5" column="1" row-span="1" col-span="1" vsize-policy="6" hsize-policy="1" anchor="0" fill="2" indent="0" use-parent-layout="false"/>
<grid row="6" column="1" row-span="1" col-span="1" vsize-policy="6" hsize-policy="1" anchor="0" fill="2" indent="0" use-parent-layout="false"/>
</constraints>
</vspacer>
<component id="48fd" class="com.intellij.ui.components.JBLabel">
@@ -58,13 +58,13 @@
<text value="&amp;Location:"/>
</properties>
</component>
<component id="41e08" class="com.intellij.ui.components.JBCheckBox" binding="myAssociateCheckbox">
<component id="41e08" class="com.intellij.ui.components.JBCheckBox" binding="myMakeAvailableToAllProjectsCheckbox">
<constraints>
<grid row="4" column="0" row-span="1" col-span="2" vsize-policy="0" hsize-policy="0" anchor="0" fill="1" indent="0" use-parent-layout="false"/>
<grid row="5" column="0" row-span="1" col-span="2" vsize-policy="0" hsize-policy="0" anchor="0" fill="1" indent="0" use-parent-layout="false"/>
</constraints>
<properties>
<selected value="true"/>
<text value="&amp;Associate this virtual environment with current project"/>
<selected value="false"/>
<text value="Make available to &amp;all projects"/>
</properties>
</component>
<component id="9835d" class="com.intellij.ui.components.JBCheckBox" binding="mySitePackagesCheckBox">
@@ -75,6 +75,15 @@
<text value="&amp;Inherit global site-packages"/>
</properties>
</component>
<component id="fd5f3" class="com.intellij.ui.components.JBCheckBox" binding="mySetAsProjectInterpreterCheckbox" default-binding="true">
<constraints>
<grid row="4" column="0" row-span="1" col-span="2" vsize-policy="0" hsize-policy="0" anchor="0" fill="1" indent="0" use-parent-layout="false"/>
</constraints>
<properties>
<selected value="true"/>
<text value="&amp;Set as project interpreter for this project"/>
</properties>
</component>
</children>
</grid>
</form>
@@ -34,7 +34,8 @@ public class CreateVirtualEnvDialog extends IdeaDialog {
private TextFieldWithBrowseButton myDestination;
private JTextField myName;
private JBCheckBox mySitePackagesCheckBox;
private JBCheckBox myAssociateCheckbox;
private JBCheckBox myMakeAvailableToAllProjectsCheckbox;
private JBCheckBox mySetAsProjectInterpreterCheckbox;
private Project myProject;
private String myInitialPath;
@@ -45,13 +46,13 @@ public class CreateVirtualEnvDialog extends IdeaDialog {
setTitle("Create Virtual Environment");
updateSdkList(sdk, allSdks);
myAssociateCheckbox.setBorder(BorderFactory.createEmptyBorder(8, 0, 0, 0));
myMakeAvailableToAllProjectsCheckbox.setBorder(BorderFactory.createEmptyBorder(8, 0, 0, 0));
if (project.isDefault()) {
myAssociateCheckbox.setSelected(false);
myAssociateCheckbox.setVisible(false);
myMakeAvailableToAllProjectsCheckbox.setSelected(true);
myMakeAvailableToAllProjectsCheckbox.setVisible(false);
}
else if (isNewProject) {
myAssociateCheckbox.setText("Associate this virtual environment with the project being created");
mySetAsProjectInterpreterCheckbox.setText("Set as project interpreter for the project being created");
}
setOKActionEnabled(false);
@@ -206,7 +207,11 @@ public class CreateVirtualEnvDialog extends IdeaDialog {
}
public boolean associateWithProject() {
return myAssociateCheckbox.isSelected();
return !myMakeAvailableToAllProjectsCheckbox.isSelected();
}
public boolean setAsProjectInterpreter() {
return mySetAsProjectInterpreterCheckbox.isSelected();
}
@Override
@@ -484,6 +484,7 @@ public abstract class CompatibilityVisitor extends PyAnnotator {
if (level.isOlderThan(LanguageLevel.PYTHON33)) {
registerProblem(node, "Python versions < 3.3 do not support this syntax. Delegating to a subgenerator is available since " +
"Python 3.3; use explicit iteration over subgenerator instead.");
break;
}
}
}
@@ -0,0 +1 @@
from..foo import foo2
@@ -0,0 +1 @@
from ..foo import foo2
@@ -0,0 +1,4 @@
def f(g):
yield 'begin'
yield from g()
print('end')
@@ -0,0 +1,5 @@
def f(g):
yield 'begin'
for x in g():
yield <caret>x
print('end')
@@ -0,0 +1,6 @@
def f(xs):
found = False
<selection>for x in xs:
yield x
found = True</selection>
print(found)
@@ -0,0 +1,11 @@
def bar(found_new, xs_new):
for x in xs_new:
yield x
found_new = True
return found_new
def f(xs):
found = False
found = yield from bar(found, xs)
print(found)
@@ -0,0 +1,6 @@
def f(xs):
found = False
<selection>for x in xs:
yield x
found = True</selection>
print(found)
@@ -0,0 +1,4 @@
def lab(): pass
lab = 1
# <ref>
print(lab)
@@ -171,6 +171,10 @@ public class PyFormatterTest extends PyTestCase {
doTest();
}
public void testFromImportRelative() {
doTest();
}
public void testPsiFormatting() { // IDEA-69724
String initial =
"def method_name(\n" +
@@ -313,6 +313,14 @@ public class PyIndentTest extends PyTestCase {
"<caret>");
}
public void testIndentOnBackslash() { // PY-7360
doTest("def index():\n" +
" return 'some string' + \\<caret>",
"def index():\n" +
" return 'some string' + \\\n" +
" <caret>");
}
/*
TODO: formatter core problem?
public void testAlignListBeforeEquals() throws Exception {
@@ -269,6 +269,11 @@ public class PyIntentionTest extends PyTestCase {
doDocStubTest();
}
// PY-7383
public void testYieldFrom() {
doTest(PyBundle.message("INTN.yield.from"), LanguageLevel.PYTHON33);
}
private void doDocStubTest() {
CodeInsightSettings codeInsightSettings = CodeInsightSettings.getInstance();
codeInsightSettings.JAVADOC_STUB_ON_ENTER = true;
@@ -477,6 +477,10 @@ public class PyResolveTest extends PyResolveTestCase {
assertResolvesTo(PyClass.class, "timedelta");
}
public void testShadowingTargetExpression() {
assertResolvesTo(PyTargetExpression.class, "lab");
}
public void testReferenceInDocstring() {
assertResolvesTo(PyClass.class, "datetime");
}
@@ -606,4 +606,10 @@ public class PythonCompletionTest extends PyTestCase {
" pass\n" +
"except IOError <caret>").contains("as"));
}
public void testElseInFor() { // PY-6755
assertTrue(doTestByText("for item in range(10):\n" +
" pass\n" +
"el<caret>").contains("else"));
}
}
@@ -235,4 +235,14 @@ public class PyExtractMethodTest extends LightMarkedTestCase {
public void testNonlocal() {
doTest("baz", LanguageLevel.PYTHON30);
}
// PY-7381
public void testYield() {
doFail("bar", "Cannot perform refactoring with 'yield' statement inside code block");
}
// PY-7382
public void testYield33() {
doTest("bar", LanguageLevel.PYTHON33);
}
}