diff --git a/python/src/com/jetbrains/python/codeInsight/PyKeywordCompletionContributor.java b/python/src/com/jetbrains/python/codeInsight/PyKeywordCompletionContributor.java index ebabb0183ec3..3f5e90b063f4 100644 --- a/python/src/com/jetbrains/python/codeInsight/PyKeywordCompletionContributor.java +++ b/python/src/com/jetbrains/python/codeInsight/PyKeywordCompletionContributor.java @@ -6,11 +6,13 @@ import com.intellij.codeInsight.lookup.TailTypeDecorator; import com.intellij.lang.ASTNode; import com.intellij.openapi.editor.Document; import com.intellij.openapi.editor.Editor; +import com.intellij.patterns.ElementPattern; import com.intellij.patterns.PsiElementPattern; import com.intellij.patterns.StandardPatterns; import com.intellij.psi.*; import com.intellij.psi.filters.ElementFilter; import com.intellij.psi.filters.position.FilterPattern; +import com.intellij.psi.util.PsiTreeUtil; import com.intellij.util.ProcessingContext; import com.jetbrains.python.PyTokenTypes; import com.jetbrains.python.PythonLanguage; @@ -222,6 +224,39 @@ public class PyKeywordCompletionContributor extends PySeeingOriginalCompletionCo } } + private static class NotParameterOrDefaultValue implements ElementFilter { + + @Override + public boolean isAcceptable(Object element, PsiElement context) { + if (!(element instanceof PsiElement)) { + return false; + } + PsiElement psiElement = (PsiElement) element; + PsiElement definition = PsiTreeUtil.getParentOfType(psiElement, PyDocStringOwner.class, false, PyStatementList.class); + if (definition != null) { + if (PsiTreeUtil.getParentOfType(psiElement, PyParameterList.class) == null) { + return true; + } + PyParameter param = PsiTreeUtil.getParentOfType(psiElement, PyParameter.class); + if (param != null) { + PyExpression defaultValue = param.getDefaultValue(); + if (defaultValue != null && PsiTreeUtil.isAncestor(defaultValue, psiElement, false)) { + return true; + } + } + return false; + } + return true; + } + + @Override + public boolean isClassAcceptable(Class hintClass) { + return true; + } + } + + private static ElementPattern NOT_PARAMETER_OR_DEFAULT_VALUE = new FilterPattern(new NotParameterOrDefaultValue()); + // ====== conditions private static final PsiElementPattern.Capture IN_COMMENT = @@ -556,8 +591,7 @@ public class PyKeywordCompletionContributor extends PySeeingOriginalCompletionCo .and(PY3K) .andNot(IN_COMMENT) .andNot(IN_IMPORT_STMT) - .andNot(IN_PARAM_LIST) - .andNot(IN_DEFINITION) + .and(NOT_PARAMETER_OR_DEFAULT_VALUE) .andNot(AFTER_QUALIFIER) , new PyKeywordCompletionProvider(TailType.NONE, "True", "False", "None") diff --git a/python/testData/completion/noneInArgList.after.py b/python/testData/completion/noneInArgList.after.py new file mode 100644 index 000000000000..e1b3d1a49b0e --- /dev/null +++ b/python/testData/completion/noneInArgList.after.py @@ -0,0 +1 @@ +def foo(x=None): \ No newline at end of file diff --git a/python/testData/completion/noneInArgList.py b/python/testData/completion/noneInArgList.py new file mode 100644 index 000000000000..65b51ba1b705 --- /dev/null +++ b/python/testData/completion/noneInArgList.py @@ -0,0 +1 @@ +def foo(x=Non): \ No newline at end of file diff --git a/python/testSrc/com/jetbrains/python/PythonCompletionTest.java b/python/testSrc/com/jetbrains/python/PythonCompletionTest.java index f57ec561514e..5401090efda1 100644 --- a/python/testSrc/com/jetbrains/python/PythonCompletionTest.java +++ b/python/testSrc/com/jetbrains/python/PythonCompletionTest.java @@ -348,4 +348,8 @@ public class PythonCompletionTest extends PyLightFixtureTestCase { settings.setFormat(DocStringFormat.PLAIN); } } + + public void testNoneInArgList() { // PY-3464 + doTest3K(); + } }