mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
PY-18791 Fixed: False positive in type information when returning callable from property
Consider property call in PyCallExpressionHelper.getCallTargetReturnType.
This commit is contained in:
@@ -584,6 +584,10 @@ public class PyCallExpressionHelper {
|
||||
if (providedType instanceof PyCallableType) {
|
||||
return Ref.create(((PyCallableType)providedType).getCallType(context, call));
|
||||
}
|
||||
final Ref<PyType> propertyCallType = getPropertyCallType(call, target, context);
|
||||
if (propertyCallType != null) {
|
||||
return propertyCallType;
|
||||
}
|
||||
if (target instanceof PyCallable) {
|
||||
final PyCallable callable = (PyCallable)target;
|
||||
return Ref.create(callable.getCallType(context, call));
|
||||
@@ -591,6 +595,26 @@ public class PyCallExpressionHelper {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private static Ref<PyType> getPropertyCallType(@NotNull PyCallExpression call,
|
||||
@NotNull PsiElement target,
|
||||
@NotNull TypeEvalContext context) {
|
||||
if (target instanceof PyCallable && target instanceof PyPossibleClassMember) {
|
||||
final PyClass containingClass = ((PyPossibleClassMember)target).getContainingClass();
|
||||
if (containingClass != null) {
|
||||
final PyCallable callable = (PyCallable)target;
|
||||
final Property property = containingClass.findPropertyByCallable(callable);
|
||||
if (property != null) {
|
||||
final PyType propertyType = property.getType(call.getReceiver(callable), context);
|
||||
if (propertyType instanceof PyCallableType) {
|
||||
return Ref.create(((PyCallableType)propertyType).getCallType(context, call));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private static Maybe<PyType> getSuperCallType(@NotNull PyCallExpression call, TypeEvalContext context) {
|
||||
final PyExpression callee = call.getCallee();
|
||||
|
||||
@@ -2221,6 +2221,22 @@ public class PyTypeTest extends PyTestCase {
|
||||
);
|
||||
}
|
||||
|
||||
// PY-18791
|
||||
public void testCallOnProperty() {
|
||||
runWithLanguageLevel(
|
||||
LanguageLevel.PYTHON35,
|
||||
() -> doTest("Iterator[int]",
|
||||
"from typing import Iterator, Callable\n" +
|
||||
"class Foo:\n" +
|
||||
" def iterate(self) -> Iterator[int]:\n" +
|
||||
" pass\n" +
|
||||
" @property\n" +
|
||||
" def foo(self) -> Callable[[], Iterator[int]]:\n" +
|
||||
" return self.iterate\n" +
|
||||
"expr = Foo().foo()")
|
||||
);
|
||||
}
|
||||
|
||||
private static List<TypeEvalContext> getTypeEvalContexts(@NotNull PyExpression element) {
|
||||
return ImmutableList.of(TypeEvalContext.codeAnalysis(element.getProject(), element.getContainingFile()).withTracing(),
|
||||
TypeEvalContext.userInitiated(element.getProject(), element.getContainingFile()).withTracing());
|
||||
|
||||
Reference in New Issue
Block a user