Skip to content

Commit e946c69

Browse files
ghislainpiotguillaume-dequenne
authored andcommitted
SONARPY-2167 Function return type in V2 model should always be an ObjectType
1 parent b6a91d2 commit e946c69

File tree

7 files changed

+15
-8
lines changed

7 files changed

+15
-8
lines changed

python-checks/src/test/resources/checks/nonCallableCalled.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -257,7 +257,7 @@ def my_rec(x):
257257

258258
def call_non_callable_property():
259259
e = OSError()
260-
e.errno() # FN
260+
e.errno() # Noncompliant
261261

262262
class MyClass:
263263
x = 42

python-frontend/src/main/java/org/sonar/python/semantic/v2/converter/FunctionDescriptorToPythonTypeConverter.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@
2727
import org.sonar.python.types.v2.ParameterV2;
2828
import org.sonar.python.types.v2.PythonType;
2929
import org.sonar.python.types.v2.TypeOrigin;
30+
import org.sonar.python.types.v2.TypeUtils;
3031

3132
public class FunctionDescriptorToPythonTypeConverter implements DescriptorToPythonTypeConverter {
3233

@@ -44,6 +45,7 @@ public PythonType convert(ConversionContext ctx, FunctionDescriptor from) {
4445

4546
var returnType = Optional.ofNullable(from.annotatedReturnTypeName())
4647
.map(fqn -> (PythonType) ctx.lazyTypesContext().getOrCreateLazyType(fqn))
48+
.map(TypeUtils::ensureWrappedObjectType)
4749
.orElse(PythonType.UNKNOWN);
4850

4951
var typeOrigin = TypeOrigin.STUB;

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@ public ObjectType(TypeWrapper typeWrapper, List<PythonType> attributes, List<Mem
4141
}
4242

4343
public ObjectType(PythonType type, List<PythonType> attributes, List<Member> members, TypeSource typeSource) {
44-
this(new SimpleTypeWrapper(type), attributes, members, typeSource);
44+
this(TypeWrapper.of(type), attributes, members, typeSource);
4545
}
4646

4747
public ObjectType(PythonType type) {

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

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,4 +31,11 @@ static PythonType resolved(PythonType pythonType) {
3131
}
3232
return pythonType;
3333
}
34+
35+
public static PythonType ensureWrappedObjectType(PythonType pythonType) {
36+
if (!(pythonType instanceof ObjectType)) {
37+
return new ObjectType(pythonType);
38+
}
39+
return pythonType;
40+
}
3441
}

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

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,4 +24,8 @@ public interface TypeWrapper {
2424
PythonType type();
2525

2626
TypeWrapper UNKNOWN_TYPE_WRAPPER = new SimpleTypeWrapper(PythonType.UNKNOWN);
27+
28+
static TypeWrapper of(PythonType type) {
29+
return type instanceof LazyType ? new LazyTypeWrapper(type) : new SimpleTypeWrapper(type);
30+
}
2731
}

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

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -380,7 +380,6 @@ def foo(param: int):
380380
}
381381

382382
@Test
383-
@Disabled
384383
void typeSourceOfCallExpressionResultDependsOnTypeSourceOfQualifier() {
385384
FileInput root = inferTypes("""
386385
def foo(x: int):
@@ -404,7 +403,6 @@ def foo(x: int):
404403
}
405404

406405
@Test
407-
@Disabled
408406
void typeSourceOfCallExpressionResultDependsOnTypeSourceOfName() {
409407
FileInput fileInput = inferTypes("""
410408
from pyasn1.debug import Printer
@@ -2278,7 +2276,6 @@ void resolvedTypingLazyType() {
22782276
}
22792277

22802278
@Test
2281-
@Disabled
22822279
void resolveCustomTypeLazyType() {
22832280
FileInput fileInput = inferTypes("""
22842281
import ldap

python-frontend/src/test/java/org/sonar/python/types/v2/LazyTypeTest.java

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,6 @@
2424
import org.sonar.python.semantic.ProjectLevelSymbolTable;
2525
import org.sonar.python.semantic.v2.LazyTypesContext;
2626
import org.sonar.python.semantic.v2.ProjectLevelTypeTable;
27-
import org.sonar.python.semantic.v2.TypeShed;
2827

2928
import static org.assertj.core.api.Assertions.assertThat;
3029
import static org.assertj.core.api.Assertions.assertThatThrownBy;
@@ -42,8 +41,6 @@ void lazyTypeThrowExceptionsWhenInteractedWith() {
4241
assertThat(lazyType.resolve()).isEqualTo(INT_TYPE);
4342
assertThatThrownBy(lazyType::unwrappedType).isInstanceOf(IllegalStateException.class).hasMessage("Lazy types should not be interacted with.");
4443
assertThatThrownBy(() -> lazyType.hasMember("__bool__")).isInstanceOf(IllegalStateException.class).hasMessage("Lazy types should not be interacted with.");
45-
ObjectType objectContainingLazyType = new ObjectType(lazyType, TypeSource.EXACT);
46-
assertThatThrownBy(() -> objectContainingLazyType.hasMember("__bool__")).isInstanceOf(IllegalStateException.class).hasMessage("Lazy types should not be interacted with.");
4744
assertThatThrownBy(lazyType::name).isInstanceOf(IllegalStateException.class).hasMessage("Lazy types should not be interacted with.");
4845
assertThatThrownBy(lazyType::instanceDisplayName).isInstanceOf(IllegalStateException.class).hasMessage("Lazy types should not be interacted with.");
4946
assertThatThrownBy(() -> lazyType.resolveMember("__bool__")).isInstanceOf(IllegalStateException.class).hasMessage("Lazy types should not be interacted with.");

0 commit comments

Comments
 (0)