From 885d17e72a225fbfaedb124bbb9aacaf502688b8 Mon Sep 17 00:00:00 2001 From: "Aleksandr.Govenko" Date: Fri, 14 Mar 2025 01:00:18 +0000 Subject: [PATCH] PY-79743 Assigning to a `Final` variable imported from another module is not reported as an error Merge-request: IJ-MR-157418 Merged-by: Aleksandr Govenko GitOrigin-RevId: da45a9d7f5ff1792c24582315d4b95225025bf7a --- .../com/jetbrains/python/inspections/PyFinalInspection.kt | 6 +++++- .../PyFinalInspection/ImportedModuleFinalReassignment/a.py | 2 +- .../ImportedVariableFinalReassignment/a.py | 5 +++++ .../ImportedVariableFinalReassignment/b.py | 3 +++ .../jetbrains/python/inspections/PyFinalInspectionTest.java | 5 +++++ 5 files changed, 19 insertions(+), 2 deletions(-) create mode 100644 python/testData/inspections/PyFinalInspection/ImportedVariableFinalReassignment/a.py create mode 100644 python/testData/inspections/PyFinalInspection/ImportedVariableFinalReassignment/b.py diff --git a/python/python-psi-impl/src/com/jetbrains/python/inspections/PyFinalInspection.kt b/python/python-psi-impl/src/com/jetbrains/python/inspections/PyFinalInspection.kt index c13214f1b52b..856ee33f0b6c 100644 --- a/python/python-psi-impl/src/com/jetbrains/python/inspections/PyFinalInspection.kt +++ b/python/python-psi-impl/src/com/jetbrains/python/inspections/PyFinalInspection.kt @@ -323,7 +323,11 @@ class PyFinalInspection : PyInspection() { val scopeOwner = ScopeUtil.getScopeOwner(target); if (!target.isQualified && scopeOwner != null) { // multiResolve finds last assignments, but we need all earlier assignments - resolved += ControlFlowCache.getScope(scopeOwner).getNamedElements(target.referencedName, false) + val scope = ControlFlowCache.getScope(scopeOwner) + resolved += scope.getNamedElements(target.referencedName, false) + target.name?.let { name -> + resolved += scope.importedNameDefiners.flatMap { it.multiResolveName(name).mapNotNull { it.element } } + } } diff --git a/python/testData/inspections/PyFinalInspection/ImportedModuleFinalReassignment/a.py b/python/testData/inspections/PyFinalInspection/ImportedModuleFinalReassignment/a.py index a42972ee18ed..a42037d336c3 100644 --- a/python/testData/inspections/PyFinalInspection/ImportedModuleFinalReassignment/a.py +++ b/python/testData/inspections/PyFinalInspection/ImportedModuleFinalReassignment/a.py @@ -2,4 +2,4 @@ import b b.a = 2 from b import a -a = 3 \ No newline at end of file +a = 3 \ No newline at end of file diff --git a/python/testData/inspections/PyFinalInspection/ImportedVariableFinalReassignment/a.py b/python/testData/inspections/PyFinalInspection/ImportedVariableFinalReassignment/a.py new file mode 100644 index 000000000000..40b55ba14cef --- /dev/null +++ b/python/testData/inspections/PyFinalInspection/ImportedVariableFinalReassignment/a.py @@ -0,0 +1,5 @@ +from b import * + +print(BAR) + +BAR = 43 \ No newline at end of file diff --git a/python/testData/inspections/PyFinalInspection/ImportedVariableFinalReassignment/b.py b/python/testData/inspections/PyFinalInspection/ImportedVariableFinalReassignment/b.py new file mode 100644 index 000000000000..0f44cc453c55 --- /dev/null +++ b/python/testData/inspections/PyFinalInspection/ImportedVariableFinalReassignment/b.py @@ -0,0 +1,3 @@ +from typing import Final + +BAR: Final = 42 \ No newline at end of file diff --git a/python/testSrc/com/jetbrains/python/inspections/PyFinalInspectionTest.java b/python/testSrc/com/jetbrains/python/inspections/PyFinalInspectionTest.java index 73ec3daf6eec..66081fe1b3f0 100644 --- a/python/testSrc/com/jetbrains/python/inspections/PyFinalInspectionTest.java +++ b/python/testSrc/com/jetbrains/python/inspections/PyFinalInspectionTest.java @@ -8,6 +8,11 @@ import org.jetbrains.annotations.NotNull; public class PyFinalInspectionTest extends PyInspectionTestCase { + // PY-79743 + public void testImportedVariableFinalReassignment() { + doMultiFileTest(); + } + // PY-34945 public void testSubclassingFinalClass() { doMultiFileTest();