Skip to content

Commit 5324748

Browse files
SONARPY-2313 Fix FN on S6543 when a generic class is defined in another file
1 parent 79f3f29 commit 5324748

File tree

4 files changed

+71
-0
lines changed

4 files changed

+71
-0
lines changed

python-checks/src/test/java/org/sonar/python/checks/GenericTypeWithoutArgumentCheckTest.java

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
*/
2020
package org.sonar.python.checks;
2121

22+
import java.util.List;
2223
import org.junit.jupiter.api.Test;
2324
import org.sonar.python.checks.utils.PythonCheckVerifier;
2425

@@ -28,4 +29,15 @@ class GenericTypeWithoutArgumentCheckTest {
2829
void test() {
2930
PythonCheckVerifier.verify("src/test/resources/checks/genericTypeWithoutArgument.py", new GenericTypeWithoutArgumentCheck());
3031
}
32+
33+
@Test
34+
void test_cross_file() {
35+
PythonCheckVerifier.verify(
36+
List.of(
37+
"src/test/resources/checks/genericTypeWithoutArgumentImported.py",
38+
"src/test/resources/checks/genericTypeWithoutArgumentImporting.py"
39+
),
40+
new GenericTypeWithoutArgumentCheck()
41+
);
42+
}
3143
}

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

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -118,3 +118,21 @@ def typing_tuple_param(param:typing.Tuple[str, int, int]):
118118
pass
119119

120120

121+
class MyGeneric[T](): ...
122+
123+
def returning_type_param_generic() -> MyGeneric: # FN (type parameter syntax not supported in V1)
124+
...
125+
126+
class MyGenericParent(typing.Generic): ...
127+
128+
class MyChild(MyGenericParent[T]): ...
129+
def returning_my_child() -> MyChild: # FN
130+
...
131+
132+
class MyChild2(MyGenericParent): ...
133+
def returning_my_child_2() -> MyChild2: # OK
134+
...
135+
136+
class MyChild3(MyGenericParent[str]): ...
137+
def returning_my_child_3() -> MyChild2: # OK
138+
...
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
from typing import Generic
2+
class SomeGeneric(Generic[T]):
3+
...
4+
5+
class SomeGenericWithTypeParam[T](): ...
6+
7+
class MyImportedGenericTypeVarChild(SomeGeneric[T]): ...
8+
class MyImportedNonGenericChild(SomeGeneric): ...
9+
class MyImportedConcreteChild(SomeGeneric[str]): ...
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
# mod.py
2+
from genericTypeWithoutArgumentImported import SomeGeneric, SomeGenericWithTypeParam, MyImportedGenericTypeVarChild, MyImportedNonGenericChild, MyImportedConcreteChild
3+
4+
def local_generic():
5+
from typing import Generic
6+
class LocalGeneric(Generic[T]):
7+
...
8+
def bar() -> LocalGeneric: # Noncompliant
9+
...
10+
11+
def foo() -> SomeGeneric: # Noncompliant
12+
...
13+
14+
def bar() -> SomeGenericWithTypeParam: # Noncompliant
15+
...
16+
17+
def returning_imported_child() -> MyImportedGenericTypeVarChild: ... # Noncompliant
18+
def returning_imported_non_generic_child() -> MyImportedNonGenericChild: ... # OK
19+
# FP SONARPY-2356: MyImportedConcreteChild is not actually generic (specialized class)
20+
def returning_imported_concrete_child() -> MyImportedConcreteChild: ... # Noncompliant
21+
22+
class MyChild(SomeGeneric[T]): ...
23+
def returning_my_child() -> MyChild: # FN
24+
...
25+
26+
class MyNonGenericChild(SomeGeneric): ...
27+
def returning_my_non_generic_child() -> MyNonGenericChild: # OK
28+
...
29+
30+
class MyConcreteChild(SomeGeneric[str]): ...
31+
def returning_my_concrete_chil3() -> MyConcreteChild: # OK
32+
...

0 commit comments

Comments
 (0)