PY-22730 Properly render Union and Optional types containing TypeVars

Namely, don't consider them "unknown" wrapping them in another
weak Union and rendering using PyType#getName() rather than
PyTypeModelBuilder.
This commit is contained in:
Mikhail Golubev
2017-03-06 15:20:44 +03:00
parent 2c79c98d22
commit 05951d275f
5 changed files with 25 additions and 3 deletions
@@ -266,7 +266,7 @@ public class PyTypeModelBuilder {
}
else if (type instanceof PyUnionType && allowUnions) {
final PyUnionType unionType = (PyUnionType)type;
if (type instanceof PyDynamicallyEvaluatedType || PyTypeChecker.isUnknown(type)) {
if (type instanceof PyDynamicallyEvaluatedType || PyTypeChecker.isUnknown(type, false)) {
result = new UnknownType(build(unionType.excludeNull(myContext), true));
}
else {
@@ -346,13 +346,17 @@ public class PyTypeChecker {
}
public static boolean isUnknown(@Nullable PyType type) {
if (type == null || type instanceof PyGenericType) {
return isUnknown(type, true);
}
public static boolean isUnknown(@Nullable PyType type, boolean genericsAreUnknown) {
if (type == null || (genericsAreUnknown && type instanceof PyGenericType)) {
return true;
}
if (type instanceof PyUnionType) {
final PyUnionType union = (PyUnionType)type;
for (PyType t : union.getMembers()) {
if (isUnknown(t)) {
if (isUnknown(t, genericsAreUnknown)) {
return true;
}
}
@@ -0,0 +1 @@
<html><body><code>def <b>f</b>(x1:&nbsp;Optional[T],&nbsp;x2:&nbsp;Union[T,&nbsp;Tuple[Any,&nbsp;Any]])<br>Inferred&nbsp;type:&nbsp;(x1:&nbsp;Optional[TypeVar('T',&nbsp;<a href="psi_element://#typename#int">int</a>)],&nbsp;x2:&nbsp;Union[TypeVar('T',&nbsp;<a href="psi_element://#typename#int">int</a>),&nbsp;Tuple[Any,&nbsp;Any]])&nbsp;-&gt;&nbsp;None<br></code></body></html>
@@ -0,0 +1,11 @@
from typing import TypeVar, Optional, Union, Tuple, Any
T = TypeVar('T', int)
def f(x1: Optional[T], x2: Union[T, Tuple[Any, Any]]):
print(x1, x2)
<the_ref>f
@@ -282,4 +282,10 @@ public class PyQuickDocTest extends LightMarkedTestCase {
myFixture.copyDirectoryToProject("typing", "");
runWithLanguageLevel(LanguageLevel.PYTHON35, this::checkHTMLOnly);
}
// PY-22730
public void testOptionalAndUnionTypesContainingTypeVars() {
myFixture.copyDirectoryToProject("typing", "");
runWithLanguageLevel(LanguageLevel.PYTHON36, this::checkHTMLOnly);
}
}