Skip to content

Commit 85d3d9b

Browse files
Seppli11sonartech
authored andcommitted
SONARPY-3575 Use QualifiedExpression for function return type (#712)
GitOrigin-RevId: 8c4f92335925cf1d2ab2be94698dde37995b78c5
1 parent 2e6c7c3 commit 85d3d9b

File tree

2 files changed

+24
-3
lines changed

2 files changed

+24
-3
lines changed

python-frontend/src/main/java/org/sonar/python/semantic/v2/types/TrivialTypeInferenceVisitor.java

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -36,9 +36,9 @@
3636
import org.sonar.plugins.python.api.tree.AliasedName;
3737
import org.sonar.plugins.python.api.tree.AnnotatedAssignment;
3838
import org.sonar.plugins.python.api.tree.ArgList;
39-
import org.sonar.plugins.python.api.tree.AwaitExpression;
4039
import org.sonar.plugins.python.api.tree.AssignmentExpression;
4140
import org.sonar.plugins.python.api.tree.AssignmentStatement;
41+
import org.sonar.plugins.python.api.tree.AwaitExpression;
4242
import org.sonar.plugins.python.api.tree.BaseTreeVisitor;
4343
import org.sonar.plugins.python.api.tree.BinaryExpression;
4444
import org.sonar.plugins.python.api.tree.CallExpression;
@@ -730,8 +730,8 @@ private ClassType computeDirectClassOwner() {
730730
}
731731

732732
private PythonType resolveTypeAnnotationExpressionType(Expression expression, @Nullable ClassType enclosingClassType) {
733-
if (expression instanceof Name name && name.typeV2() != PythonType.UNKNOWN) {
734-
PythonType resolvedType = resolveSelfType(name.typeV2(), enclosingClassType);
733+
if ((expression instanceof Name || expression instanceof QualifiedExpression) && expression.typeV2() != PythonType.UNKNOWN) {
734+
PythonType resolvedType = resolveSelfType(expression.typeV2(), enclosingClassType);
735735
return ObjectType.Builder.fromType(resolvedType).withTypeSource(TypeSource.TYPE_HINT).build();
736736
} else if (expression instanceof SubscriptionExpression subscriptionExpression && subscriptionExpression.object().typeV2() != PythonType.UNKNOWN) {
737737
var candidateTypes = subscriptionExpression.subscripts()

python-frontend/src/test/java/org/sonar/python/semantic/v2/TypeInferenceV2Test.java

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4316,6 +4316,27 @@ class B(datetime.datetime): pass
43164316
.isEqualTo(bType);
43174317
}
43184318

4319+
@Test
4320+
void self_type_as_return_type_on_inherited_methods_with_qualified_expression() {
4321+
FileInput fileInput = inferTypes("""
4322+
import typing
4323+
class A:
4324+
def foo() -> typing.Self: ...
4325+
4326+
class B(A):
4327+
...
4328+
resultB = B().foo()
4329+
""");
4330+
4331+
PythonType resultB = PythonTestUtils.<Name>getFirstChild(fileInput, t -> t instanceof Name name && "resultB".equals(name.name())).typeV2();
4332+
PythonType classTypeB = PythonTestUtils.<ClassDef>getFirstChild(fileInput, t -> t instanceof ClassDef cd && "B".equals(cd.name().name())).name().typeV2();
4333+
4334+
assertThat(resultB)
4335+
.isInstanceOf(ObjectType.class)
4336+
.extracting(PythonType::unwrappedType)
4337+
.isEqualTo(classTypeB);
4338+
}
4339+
43194340
@Test
43204341
void self_type_as_return_type_on_inherited_methods() {
43214342
FileInput fileInput = inferTypes("""

0 commit comments

Comments
 (0)