PY-80936 Don't hide generic type arguments if they all are Any

GitOrigin-RevId: d3354c68617a8176f9ef2f78b0c37afed56add51
This commit is contained in:
Mikhail Golubev
2025-05-14 09:51:56 +00:00
committed by intellij-monorepo-bot
parent d55a206af8
commit a2bacfa2ad
11 changed files with 29 additions and 41 deletions
@@ -114,11 +114,6 @@ public abstract class PyTypeRenderer extends PyTypeVisitorExt<@NotNull HtmlChunk
return false;
}
@Override
protected boolean hideAllAnyTypeArguments() {
return false;
}
@Override
public HtmlChunk visitPyCallableType(@NotNull PyCallableType callableType) {
HtmlBuilder result = new HtmlBuilder();
@@ -191,10 +186,6 @@ public abstract class PyTypeRenderer extends PyTypeVisitorExt<@NotNull HtmlChunk
return origin == null || PythonLanguageLevelPusher.getLanguageLevelForFile(origin).isAtLeast(LanguageLevel.PYTHON39);
}
protected boolean hideAllAnyTypeArguments() {
return true;
}
@Override
public HtmlChunk visitPyGenericType(@NotNull PyCollectionType collectionOf) {
HtmlChunk genericTypeRender = renderGenericType(collectionOf);
@@ -203,10 +194,7 @@ public abstract class PyTypeRenderer extends PyTypeVisitorExt<@NotNull HtmlChunk
private @NotNull HtmlChunk renderGenericType(@NotNull PyCollectionType genericType) {
HtmlBuilder result = new HtmlBuilder();
// TODO get rid of that behavior
boolean allTypeParamsAreAny = ContainerUtil.and(genericType.getElementTypes(), t -> t == null);
boolean renderTypeArgumentList = !genericType.getElementTypes().isEmpty() &&
!(hideAllAnyTypeArguments() && allTypeParamsAreAny);
boolean renderTypeArgumentList = !genericType.getElementTypes().isEmpty();
String className = genericType.getPyClass().getName();
if (renderTypeArgumentList && !isGenericBuiltinsAvailable() && PyTypingTypeProvider.TYPING_COLLECTION_CLASSES.containsKey(className)) {
result.append(className(PyTypingTypeProvider.TYPING_COLLECTION_CLASSES.get(className))); // NON-NLS
@@ -30,7 +30,7 @@ async def coro():
else:
print('end')
async for i in <warning descr="Expected type 'collections.AsyncIterable', got 'list' instead">[]</warning>:
async for i in <warning descr="Expected type 'collections.AsyncIterable', got 'list[Any]' instead">[]</warning>:
pass
@@ -8,5 +8,5 @@ def test():
x = f(10)
y = f('foo')
z = f(<warning descr="Expected type 'T ≤: Union[int, str]', got 'list' instead">[]</warning>)
z = f(<warning descr="Expected type 'T ≤: Union[int, str]', got 'List[Any]' instead">[]</warning>)
return x + <warning descr="Expected type 'int', got 'str' instead">y</warning>
@@ -14,6 +14,6 @@ def test():
f(<warning descr="Expected type 'str', got 'bool' instead">o >= o</warning>)
f(<warning descr="Expected type 'str', got 'bool' instead">'foo' > 'bar'</warning>)
f(<warning descr="Expected type 'str', got 'bool' instead"><warning descr="Expected type 'int', got 'C' instead">c</warning> < 1</warning>)
f(<warning descr="Expected type 'str', got 'list' instead">c > 1</warning>)
f(<warning descr="Expected type 'str', got 'List[Any]' instead">c > 1</warning>)
f(<warning descr="Expected type 'str', got 'bool' instead">c == 1</warning>)
f(<warning descr="Expected type 'str', got 'bool' instead">c in [1, 2, 3]</warning>)
@@ -28,7 +28,7 @@ def g(x) -> int:
if x:
return <warning descr="Expected type 'int', got 'str' instead">'abc'</warning>
else:
return <warning descr="Expected type 'int', got 'dict' instead">{}</warning>
return <warning descr="Expected type 'int', got 'dict[Any, Any]' instead">{}</warning>
def h(x) -> int:
<warning descr="Expected type 'int', got 'None' instead">return</warning>
@@ -29,4 +29,4 @@ cllbl_c = baz()
cllbl_c(1, "2")
cllbl_c(1, <warning descr="Expected type 'str', got 'int' instead">2</warning>)
cllbl_c(<warning descr="Expected type 'int', got 'str' instead">"1"</warning>, "2")
cllbl_c(<warning descr="Expected type 'int', got 'list' instead">[]</warning>, <warning descr="Expected type 'str', got 'list' instead">[]</warning>)
cllbl_c(<warning descr="Expected type 'int', got 'list[Any]' instead">[]</warning>, <warning descr="Expected type 'str', got 'list[Any]' instead">[]</warning>)
@@ -17,7 +17,7 @@ def test(c):
"""
x1 = f1(c)
f2(x1) # Weaker union types
f3(<warning descr="Expected type 'int', got 'Union[list, str, None]' instead">x1</warning>)
f3(<warning descr="Expected type 'int', got 'Union[List[Any], str, None]' instead">x1</warning>)
f2(<warning descr="Expected type 'str', got 'int' instead">x1.count('')</warning>)
f3(x1.count(''))
@@ -686,7 +686,7 @@ public class PyTypeTest extends PyTestCase {
// EA-40207
public void testRecursion() {
doTest("list",
doTest("List[Any]",
"""
def f():
return [f()]
@@ -1244,7 +1244,7 @@ public class PyTypeTest extends PyTestCase {
}
public void testUnionTypeAttributeOfDifferentTypes() {
doTest("Union[list, int]",
doTest("Union[List[Any], int]",
"""
class Foo:
x = []
@@ -1640,7 +1640,7 @@ public class PyTypeTest extends PyTestCase {
}
public void testListLiteral() {
doTest("list", "expr = []");
doTest("List[Any]", "expr = []");
doTest("List[int]", "expr = [1, 2, 3]");
@@ -1658,7 +1658,7 @@ public class PyTypeTest extends PyTestCase {
}
public void testDictLiteral() {
doTest("dict", "expr = {}");
doTest("Dict[Any, Any]", "expr = {}");
doTest("Dict[int, bool]", "expr = {1: False}");
@@ -1712,7 +1712,7 @@ public class PyTypeTest extends PyTestCase {
// PY-20797
public void testValueOfEmptyDefaultDict() {
doTest("list",
doTest("List[Any]",
"""
from collections import defaultdict
expr = defaultdict(lambda: [])['x']
@@ -1894,7 +1894,7 @@ public class PyTypeTest extends PyTestCase {
// PY-21474
public void testReassigningOptionalListWithDefaultValue() {
doTest("Union[List[str], list]",
doTest("Union[List[str], List[Any]]",
"""
def x(things):
""\"
@@ -2034,7 +2034,7 @@ public class PyTypeTest extends PyTestCase {
// PY-37755
public void testGlobalType() {
doTest("list",
doTest("List[Any]",
"""
expr = []
@@ -2042,7 +2042,7 @@ public class PyTypeTest extends PyTestCase {
global expr
expr""");
doTest("list",
doTest("List[Any]",
"""
expr = []
@@ -2051,7 +2051,7 @@ public class PyTypeTest extends PyTestCase {
global expr
expr""");
doTest("list",
doTest("List[Any]",
"""
expr = []
@@ -2928,7 +2928,7 @@ public class PyTypeTest extends PyTestCase {
// PY-26061
public void testUnknownDictValues() {
doTest("list",
doTest("List[Any]",
"expr = dict().values()");
}
@@ -1699,7 +1699,7 @@ public class PyTypingTest extends PyTestCase {
// PY-31004
public void testRecursiveTypeAliasInAnotherFile() {
doMultiFileStubAwareTest("list | int",
doMultiFileStubAwareTest("list[Any] | int",
"""
from other import MyType
@@ -2512,7 +2512,7 @@ public class PyTypingTest extends PyTestCase {
// PY-53105
public void testGenericVariadicStarArgsPrefixSuffix() {
doTest("tuple[str, list, dict, bool, int]",
doTest("tuple[str, list[Any], dict[Any, Any], bool, int]",
"""
from typing import TypeVarTuple, Tuple
@@ -4233,7 +4233,7 @@ public class PyTypingTest extends PyTestCase {
// PY-61883
public void testRecursiveTypeAliasInAnotherFilePEP695Syntax() {
doMultiFileStubAwareTest("list | int",
doMultiFileStubAwareTest("list[Any] | int",
"""
from a import MyType
@@ -4721,7 +4721,7 @@ public class PyTypingTest extends PyTestCase {
// PY-71002
public void testTypeVarDefaultsClassWithInitMethodReference() {
doTest("type[Bar[Any, list]]", """
doTest("type[Bar[Any, list[Any]]]", """
from typing import TypeVar, Generic
Z1 = TypeVar("Z1")
ListDefaultT = TypeVar("ListDefaultT", default=list[Z1])
@@ -4733,7 +4733,7 @@ public class PyTypingTest extends PyTestCase {
// PY-71002
public void testTypeVarDefaultsClassWithInitMethodReferenceNewSyntax() {
doTest("type[Bar[Any, list]]", """
doTest("type[Bar[Any, list[Any]]]", """
from typing import TypeVar, Generic
class Bar[Z1, ListDefaultT = list[Z1]]:
def __init__(self, x: Z1, y: ListDefaultT): ...
@@ -1435,13 +1435,13 @@ public class PyTypeCheckerInspectionTest extends PyInspectionTestCase {
y = {}
z = {'foo': 'bar'}
n = {"foo": "", "quux": 3}
f(<warning descr="Expected type 'C', got 'dict' instead">y</warning>)
f(<warning descr="Expected type 'C', got 'dict[Any, Any]' instead">y</warning>)
f(<warning descr="Expected type 'C', got 'dict[str, str | int]' instead">n</warning>)
f(<warning descr="Expected type 'C', got 'dict[str, str]' instead">z</warning>)
f(<warning descr="Expected type 'C', got 'dict' instead">x=y</warning>)
f(<warning descr="Expected type 'C', got 'dict[Any, Any]' instead">x=y</warning>)
f(<warning descr="Expected type 'C', got 'dict[str, str | int]' instead">x=n</warning>)
f(<warning descr="Expected type 'C', got 'dict[str, str]' instead">x=z</warning>)
z2: C = <warning descr="Expected type 'C', got 'dict' instead">y</warning>
z2: C = <warning descr="Expected type 'C', got 'dict[Any, Any]' instead">y</warning>
z2: C = <warning descr="Expected type 'C', got 'dict[str, str | int]' instead">n</warning>
z2: C = <warning descr="Expected type 'C', got 'dict[str, str]' instead">z</warning>
""")
@@ -1505,8 +1505,8 @@ public class PyTypeCheckerInspectionTest extends PyInspectionTestCase {
'd': {}
}
}
s2: HardDict = {'a': 'xx', 'd': <warning descr="Expected type 'NotSoHardDict', got 'dict[str, str | dict[str, int | dict]]' instead">t1</warning>}
s3: HardDict = <warning descr="Expected type 'HardDict', got 'dict[str, str | dict[str, int | dict]]' instead">t1</warning>
s2: HardDict = {'a': 'xx', 'd': <warning descr="Expected type 'NotSoHardDict', got 'dict[str, str | dict[str, int | dict[Any, Any]]]' instead">t1</warning>}
s3: HardDict = <warning descr="Expected type 'HardDict', got 'dict[str, str | dict[str, int | dict[Any, Any]]]' instead">t1</warning>
s4: HardDict = <warning descr="TypedDict 'HardDict' has missing key: 'a'">{
'd': {
'a': 'a',
@@ -111,12 +111,12 @@ public class PyiTypeTest extends PyTestCase {
// PY-22808
public void testOverloadedNotMatchedType() {
doTest("list | Any");
doTest("list[Any] | Any");
}
// PY-22808
public void testOverloadedNotMatchedGenericType() {
doTest("dict[str, Any] | list");
doTest("dict[str, Any] | list[Any]");
}
public void testGenericClassDefinitionInOtherFile() {