diff --git a/python/python-psi-impl/src/com/jetbrains/python/codeInsight/completion/PyLiteralTypeCompletionContributor.kt b/python/python-psi-impl/src/com/jetbrains/python/codeInsight/completion/PyLiteralTypeCompletionContributor.kt index bd8f511fbff9..0556134416ba 100644 --- a/python/python-psi-impl/src/com/jetbrains/python/codeInsight/completion/PyLiteralTypeCompletionContributor.kt +++ b/python/python-psi-impl/src/com/jetbrains/python/codeInsight/completion/PyLiteralTypeCompletionContributor.kt @@ -18,6 +18,24 @@ import com.jetbrains.python.psi.types.PyType import com.jetbrains.python.psi.types.PyTypeUtil import com.jetbrains.python.psi.types.TypeEvalContext +/** + * Provides literal type variants in the following cases: + * ```python + * x: Literal["foo", "bar"] + * x = + * x = fo + * x = "fo" + * ``` + * + * or + * + * ```python + * def f(x: Literal["foo", "bar"]): ... + * f() + * f(fo) + * f("fo") + * ``` + */ class PyLiteralTypeCompletionContributor : CompletionContributor() { init { extend(CompletionType.BASIC, psiElement(), PyLiteralTypeCompletionProvider()) @@ -27,6 +45,7 @@ class PyLiteralTypeCompletionContributor : CompletionContributor() { private class PyLiteralTypeCompletionProvider : CompletionProvider() { override fun addCompletions(parameters: CompletionParameters, context: ProcessingContext, result: CompletionResultSet) { val position = parameters.position.parent as? PyExpression ?: return + if (!(position is PyStringLiteralExpression || position is PyReferenceExpression && !position.isQualified)) return val typeEvalContext = TypeEvalContext.codeCompletion(position.project, position.containingFile) val mappedParameters = position.getMappedParameters(PyResolveContext.defaultContext(typeEvalContext)) diff --git a/python/testData/completion/literalType/noLiteralVariantsOnQualifiedReferenceInAssignmentValue.py b/python/testData/completion/literalType/noLiteralVariantsOnQualifiedReferenceInAssignmentValue.py new file mode 100644 index 000000000000..e7e1dba15dc6 --- /dev/null +++ b/python/testData/completion/literalType/noLiteralVariantsOnQualifiedReferenceInAssignmentValue.py @@ -0,0 +1,5 @@ +from typing import Literal + +x: Literal["upper", "lower"] +y = "" +x = y.upp \ No newline at end of file diff --git a/python/testData/completion/literalType/noLiteralVariantsOnQualifiedReferenceInCallArgument.py b/python/testData/completion/literalType/noLiteralVariantsOnQualifiedReferenceInCallArgument.py new file mode 100644 index 000000000000..1c45366b3f9d --- /dev/null +++ b/python/testData/completion/literalType/noLiteralVariantsOnQualifiedReferenceInCallArgument.py @@ -0,0 +1,8 @@ +from typing import Literal + + +def f(x: Literal["upper", "lower"]): + pass + +y = "" +f(y.up) \ No newline at end of file diff --git a/python/testSrc/com/jetbrains/python/PyLiteralTypeCompletionTest.kt b/python/testSrc/com/jetbrains/python/PyLiteralTypeCompletionTest.kt index 0810b1281ae4..94a408639216 100644 --- a/python/testSrc/com/jetbrains/python/PyLiteralTypeCompletionTest.kt +++ b/python/testSrc/com/jetbrains/python/PyLiteralTypeCompletionTest.kt @@ -75,6 +75,16 @@ class PyLiteralTypeCompletionTest : PyTestCase() { myFixture.testCompletionVariants("nestedArgumentLists.py") } + // PY-83039 + fun testNoLiteralVariantsOnQualifiedReferenceInAssignmentValue() { + doTestCompletionVariantsDoesNotContain("noLiteralVariantsOnQualifiedReferenceInAssignmentValue.py", "\"upper\"") + } + + // PY-83039 + fun testNoLiteralVariantsOnQualifiedReferenceInCallArgument() { + doTestCompletionVariantsDoesNotContain("noLiteralVariantsOnQualifiedReferenceInCallArgument.py", "\"upper\"") + } + override fun getTestDataPath(): String { return super.getTestDataPath() + "/completion/literalType" } @@ -84,4 +94,10 @@ class PyLiteralTypeCompletionTest : PyTestCase() { assertNotNull(result) assertContainsElements(result!!, *items) } + + private fun doTestCompletionVariantsDoesNotContain(fileBefore: String, vararg items: String) { + val result = myFixture.getCompletionVariants(fileBefore) + assertNotNull(result) + assertDoesntContain(result!!, *items) + } } \ No newline at end of file