From 57dc355adabc9ca046e1c952d9b97ecb6cb7d1fb Mon Sep 17 00:00:00 2001 From: chbndrhnns Date: Mon, 3 Nov 2025 15:54:29 +0000 Subject: [PATCH] [python] PY-83215 Renaming a pytest fixture leads to unresolved references Merge-request: IJ-MR-181100 Merged-by: Egor Eliseev GitOrigin-RevId: ed0ae783d8f1caadc1686fde42f4bba27fe35f95 --- .../PyTestFixtureReferenceContributor.kt | 14 +++++++++----- .../after_rename_preserve_qualified_annotation.txt | 11 +++++++++++ .../test_rename_preserve_qualified_annotation.py | 11 +++++++++++ .../testing/PyTestFixtureAndParametrizedTest.kt | 6 ++++++ 4 files changed, 37 insertions(+), 5 deletions(-) create mode 100644 python/testData/testCompletion/after_rename_preserve_qualified_annotation.txt create mode 100644 python/testData/testCompletion/test_rename_preserve_qualified_annotation.py diff --git a/python/src/com/jetbrains/python/testing/pyTestFixtures/PyTestFixtureReferenceContributor.kt b/python/src/com/jetbrains/python/testing/pyTestFixtures/PyTestFixtureReferenceContributor.kt index eb8937beb852..b653e961be68 100644 --- a/python/src/com/jetbrains/python/testing/pyTestFixtures/PyTestFixtureReferenceContributor.kt +++ b/python/src/com/jetbrains/python/testing/pyTestFixtures/PyTestFixtureReferenceContributor.kt @@ -87,9 +87,12 @@ class PyTestFixtureReference(pyElement: PsiElement, fixture: PyTestFixture, priv if (myElement is PyStringLiteralExpression) { return myElement.replace(PyElementGenerator.getInstance(myElement.project).createStringLiteralFromString(newElementName)) } - val annotationString = (myElement as? PyNamedParameter)?.annotation?.value?.name - return myElement.replace(PyElementGenerator.getInstance(myElement.project) - .createParameter(newElementName, null, annotationString, LanguageLevel.getDefault()))!! + (myElement as? PyNamedParameter)?.let { + it.setName(newElementName) + return it + } + + return super.handleElementRename(newElementName) } } @@ -137,8 +140,9 @@ private object PyTestReferenceAsParameterProvider : PyTestReferenceProvider() { val namedParam = element as? PyNamedParameter ?: return emptyArray() val namedFixtureParameterLink = getFixtureLink(namedParam, TypeEvalContext.codeAnalysis(element.project, element.containingFile)) ?: return emptyArray() - val annotationLength = namedParam.annotation?.textLength ?: 0 - return arrayOf(PyTestFixtureReference(namedParam, namedFixtureParameterLink.fixture, namedFixtureParameterLink.importElement, TextRange(0, element.textLength - annotationLength))) + val nameId = namedParam.nameIdentifier + val range = nameId?.textRangeInParent ?: TextRange.from(0, namedParam.textLength) + return arrayOf(PyTestFixtureReference(namedParam, namedFixtureParameterLink.fixture, namedFixtureParameterLink.importElement, range)) } } diff --git a/python/testData/testCompletion/after_rename_preserve_qualified_annotation.txt b/python/testData/testCompletion/after_rename_preserve_qualified_annotation.txt new file mode 100644 index 000000000000..d070d8a20298 --- /dev/null +++ b/python/testData/testCompletion/after_rename_preserve_qualified_annotation.txt @@ -0,0 +1,11 @@ +import types +import pytest + + +@pytest.fixture() +def abc(): + return types.SimpleNamespace(get=lambda: None) + + +def test(abc: types.SimpleNamespace): + assert True diff --git a/python/testData/testCompletion/test_rename_preserve_qualified_annotation.py b/python/testData/testCompletion/test_rename_preserve_qualified_annotation.py new file mode 100644 index 000000000000..6f44e50de00e --- /dev/null +++ b/python/testData/testCompletion/test_rename_preserve_qualified_annotation.py @@ -0,0 +1,11 @@ +import types +import pytest + + +@pytest.fixture() +def client(): + return types.SimpleNamespace(get=lambda: None) + + +def test(client: types.SimpleNamespace): + assert True diff --git a/python/testSrc/com/jetbrains/python/testing/PyTestFixtureAndParametrizedTest.kt b/python/testSrc/com/jetbrains/python/testing/PyTestFixtureAndParametrizedTest.kt index f04634cc18cb..8b49d94bf721 100644 --- a/python/testSrc/com/jetbrains/python/testing/PyTestFixtureAndParametrizedTest.kt +++ b/python/testSrc/com/jetbrains/python/testing/PyTestFixtureAndParametrizedTest.kt @@ -143,4 +143,10 @@ class PyTestFixtureAndParametrizedTest : PyTestCase() { myFixture.renameElementAtCaret("second") myFixture.checkResultByFile("after_rename_multiple_parametrization_second_param.txt") } + + fun testRenamePreserveQualifiedAnnotation() { + myFixture.configureByFile("test_rename_preserve_qualified_annotation.py") + myFixture.renameElementAtCaret("abc") + myFixture.checkResultByFile("after_rename_preserve_qualified_annotation.txt") + } }