diff --git a/python/pluginSrc/com/jetbrains/python/psi/impl/PyJavaClassType.java b/python/pluginSrc/com/jetbrains/python/psi/impl/PyJavaClassType.java index 87cbdaf9ab10..b1df4c6f4dff 100644 --- a/python/pluginSrc/com/jetbrains/python/psi/impl/PyJavaClassType.java +++ b/python/pluginSrc/com/jetbrains/python/psi/impl/PyJavaClassType.java @@ -113,7 +113,7 @@ public class PyJavaClassType implements PyClassLikeType { @Nullable @Override - public PyType getCallType(@NotNull TypeEvalContext context, @Nullable PyQualifiedExpression callSite) { + public PyType getCallType(@NotNull TypeEvalContext context, @NotNull PyQualifiedExpression callSite) { return getReturnType(); } diff --git a/python/pluginSrc/com/jetbrains/python/psi/impl/PyJavaMethodType.java b/python/pluginSrc/com/jetbrains/python/psi/impl/PyJavaMethodType.java index 247e5e9ad9b2..b12fa1cb06ba 100644 --- a/python/pluginSrc/com/jetbrains/python/psi/impl/PyJavaMethodType.java +++ b/python/pluginSrc/com/jetbrains/python/psi/impl/PyJavaMethodType.java @@ -58,7 +58,7 @@ public class PyJavaMethodType implements PyCallableType { @Nullable @Override - public PyType getCallType(@NotNull TypeEvalContext context, @Nullable PyQualifiedExpression callSite) { + public PyType getCallType(@NotNull TypeEvalContext context, @NotNull PyQualifiedExpression callSite) { return getReturnType(); } diff --git a/python/psi-api/src/com/jetbrains/python/psi/Callable.java b/python/psi-api/src/com/jetbrains/python/psi/Callable.java index 7eb9727ebbb4..2dbded6faae7 100644 --- a/python/psi-api/src/com/jetbrains/python/psi/Callable.java +++ b/python/psi-api/src/com/jetbrains/python/psi/Callable.java @@ -45,7 +45,7 @@ public interface Callable extends PyTypedElement, PyQualifiedNameOwner { * Returns the type of the call to the callable. */ @Nullable - PyType getCallType(@NotNull TypeEvalContext context, @Nullable PyQualifiedExpression callSite); + PyType getCallType(@NotNull TypeEvalContext context, @NotNull PyQualifiedExpression callSite); /** * Returns the type of the call to the callable where the call site is specified by the optional receiver and the arguments to parameters diff --git a/python/psi-api/src/com/jetbrains/python/psi/types/PyCallableType.java b/python/psi-api/src/com/jetbrains/python/psi/types/PyCallableType.java index 109a20e6c60d..6797ca69e4a5 100644 --- a/python/psi-api/src/com/jetbrains/python/psi/types/PyCallableType.java +++ b/python/psi-api/src/com/jetbrains/python/psi/types/PyCallableType.java @@ -45,7 +45,7 @@ public interface PyCallableType extends PyType { * Returns the type which is the result of calling an instance of this type. */ @Nullable - PyType getCallType(@NotNull TypeEvalContext context, @Nullable PyQualifiedExpression callSite); + PyType getCallType(@NotNull TypeEvalContext context, @NotNull PyQualifiedExpression callSite); /** * Returns the list of parameter types. diff --git a/python/src/com/jetbrains/python/codeInsight/stdlib/PyNamedTupleType.java b/python/src/com/jetbrains/python/codeInsight/stdlib/PyNamedTupleType.java index 9ffb86d2b090..f70a18b9aa39 100644 --- a/python/src/com/jetbrains/python/codeInsight/stdlib/PyNamedTupleType.java +++ b/python/src/com/jetbrains/python/codeInsight/stdlib/PyNamedTupleType.java @@ -95,7 +95,7 @@ public class PyNamedTupleType extends PyClassTypeImpl implements PyCallableType @Nullable @Override - public PyType getCallType(@NotNull TypeEvalContext context, @Nullable PyQualifiedExpression callSite) { + public PyType getCallType(@NotNull TypeEvalContext context, @NotNull PyQualifiedExpression callSite) { if (myDefinitionLevel > 0) { return new PyNamedTupleType(myClass, myDeclaration, myName, myFields, myDefinitionLevel-1); } diff --git a/python/src/com/jetbrains/python/documentation/PyTypeModelBuilder.java b/python/src/com/jetbrains/python/documentation/PyTypeModelBuilder.java index ad1fa2d7f5a2..519e6a4afb2c 100644 --- a/python/src/com/jetbrains/python/documentation/PyTypeModelBuilder.java +++ b/python/src/com/jetbrains/python/documentation/PyTypeModelBuilder.java @@ -226,7 +226,7 @@ public class PyTypeModelBuilder { parameterModels.add(new ParamType(parameter.getName(), build(parameter.getType(myContext), true))); } } - final PyType ret = type.getCallType(myContext, null); + final PyType ret = type.getReturnType(); final TypeModel returnType = build(ret, true); return new FunctionType(returnType, parameterModels); } diff --git a/python/src/com/jetbrains/python/inspections/PyPropertyDefinitionInspection.java b/python/src/com/jetbrains/python/inspections/PyPropertyDefinitionInspection.java index 33d9b0bf20a1..945929e866d6 100644 --- a/python/src/com/jetbrains/python/inspections/PyPropertyDefinitionInspection.java +++ b/python/src/com/jetbrains/python/inspections/PyPropertyDefinitionInspection.java @@ -301,7 +301,9 @@ public class PyPropertyDefinitionInspection extends PyInspection { } else { PyReferenceExpression callSite = being_checked instanceof PyReferenceExpression ? (PyReferenceExpression) being_checked : null; - hasReturns = !(callable.getCallType(myTypeEvalContext, callSite) instanceof PyNoneType); + final PyType type = callSite != null ? callable.getCallType(myTypeEvalContext, callSite) + : callable.getReturnType(myTypeEvalContext); + hasReturns = !(type instanceof PyNoneType); } if (allowed ^ hasReturns) { if (allowed && callable instanceof PyFunction) { diff --git a/python/src/com/jetbrains/python/psi/impl/PyCallExpressionHelper.java b/python/src/com/jetbrains/python/psi/impl/PyCallExpressionHelper.java index 4928bc6305e6..7eae40ba90c9 100644 --- a/python/src/com/jetbrains/python/psi/impl/PyCallExpressionHelper.java +++ b/python/src/com/jetbrains/python/psi/impl/PyCallExpressionHelper.java @@ -463,8 +463,14 @@ public class PyCallExpressionHelper { else { final PyType type = context.getType(callee); if (type instanceof PyCallableType) { + final PyCallableType callableType = (PyCallableType)type; final PyQualifiedExpression callSite = callee instanceof PyQualifiedExpression ? (PyQualifiedExpression)callee : null; - return ((PyCallableType) type).getCallType(context, callSite); + if (callSite != null) { + return callableType.getCallType(context, callSite); + } + else { + return callableType.getReturnType(); + } } return null; } diff --git a/python/src/com/jetbrains/python/psi/impl/PyFunctionImpl.java b/python/src/com/jetbrains/python/psi/impl/PyFunctionImpl.java index 62776f013af1..1c29810d6f1a 100644 --- a/python/src/com/jetbrains/python/psi/impl/PyFunctionImpl.java +++ b/python/src/com/jetbrains/python/psi/impl/PyFunctionImpl.java @@ -176,7 +176,11 @@ public class PyFunctionImpl extends PyPresentableElementImpl imp @Nullable @Override public PyType getReturnType(@NotNull TypeEvalContext context) { - final PyType type = context.getType(this); + PyType type = context.getType(this); + if (type instanceof PyUnionType) { + final PyUnionType unionType = (PyUnionType)type; + type = unionType.excludeNull(); + } if (type instanceof PyCallableType) { return ((PyCallableType)type).getReturnType(); } @@ -218,7 +222,7 @@ public class PyFunctionImpl extends PyPresentableElementImpl imp @Nullable @Override - public PyType getCallType(@NotNull TypeEvalContext context, @Nullable PyQualifiedExpression callSite) { + public PyType getCallType(@NotNull TypeEvalContext context, @NotNull PyQualifiedExpression callSite) { PyType type = null; for (PyTypeProvider typeProvider : Extensions.getExtensions(PyTypeProvider.EP_NAME)) { type = typeProvider.getCallType(this, callSite, context); @@ -230,9 +234,6 @@ public class PyFunctionImpl extends PyPresentableElementImpl imp if (type == null) { type = getReturnType(context); } - if (callSite == null) { - return type; - } final PyTypeChecker.AnalyzeCallResults results = PyTypeChecker.analyzeCallSite(callSite, context); if (results != null) { return analyzeCallType(type, results.getReceiver(), results.getArguments(), context); @@ -249,8 +250,10 @@ public class PyFunctionImpl extends PyPresentableElementImpl imp } @Nullable - private PyType analyzeCallType(@Nullable PyType type, @Nullable PyExpression receiver, - @NotNull Map parameters, @NotNull TypeEvalContext context) { + private PyType analyzeCallType(@Nullable PyType type, + @Nullable PyExpression receiver, + @NotNull Map parameters, + @NotNull TypeEvalContext context) { if (PyTypeChecker.hasGenerics(type, context)) { final Map substitutions = PyTypeChecker.unifyGenericCall(receiver, parameters, context); if (substitutions != null) { @@ -400,8 +403,10 @@ public class PyFunctionImpl extends PyPresentableElementImpl imp return type; } } - final PyFunctionType type = new PyFunctionType(this, calculateReturnType(context)); - if (PyUtil.hasCustomDecorators(this) && !PyUtil.isDecoratedAsAbstract(this) && getProperty() == null) { + final boolean hasCustomDecorators = PyUtil.hasCustomDecorators(this) && !PyUtil.isDecoratedAsAbstract(this) && getProperty() == null; + final PyType returnType = calculateReturnType(context); + final PyFunctionType type = new PyFunctionType(this, hasCustomDecorators ? PyUnionType.createWeakType(returnType) : returnType); + if (hasCustomDecorators) { return PyUnionType.createWeakType(type); } return type; diff --git a/python/src/com/jetbrains/python/psi/impl/PyLambdaExpressionImpl.java b/python/src/com/jetbrains/python/psi/impl/PyLambdaExpressionImpl.java index 97f1303cb24e..87d081050f12 100644 --- a/python/src/com/jetbrains/python/psi/impl/PyLambdaExpressionImpl.java +++ b/python/src/com/jetbrains/python/psi/impl/PyLambdaExpressionImpl.java @@ -80,7 +80,7 @@ public class PyLambdaExpressionImpl extends PyElementImpl implements PyLambdaExp @Nullable @Override - public PyType getCallType(@NotNull TypeEvalContext context, @Nullable PyQualifiedExpression callSite) { + public PyType getCallType(@NotNull TypeEvalContext context, @NotNull PyQualifiedExpression callSite) { return getReturnType(context); } diff --git a/python/src/com/jetbrains/python/psi/types/PyCallableTypeImpl.java b/python/src/com/jetbrains/python/psi/types/PyCallableTypeImpl.java index 2c37790558c1..2a488c3a53ea 100644 --- a/python/src/com/jetbrains/python/psi/types/PyCallableTypeImpl.java +++ b/python/src/com/jetbrains/python/psi/types/PyCallableTypeImpl.java @@ -55,7 +55,7 @@ public class PyCallableTypeImpl implements PyCallableType { @Nullable @Override - public PyType getCallType(@NotNull TypeEvalContext context, @Nullable PyQualifiedExpression callSite) { + public PyType getCallType(@NotNull TypeEvalContext context, @NotNull PyQualifiedExpression callSite) { return myReturnType; } diff --git a/python/src/com/jetbrains/python/psi/types/PyClassTypeImpl.java b/python/src/com/jetbrains/python/psi/types/PyClassTypeImpl.java index c557c63c9603..592ee9a1881b 100644 --- a/python/src/com/jetbrains/python/psi/types/PyClassTypeImpl.java +++ b/python/src/com/jetbrains/python/psi/types/PyClassTypeImpl.java @@ -316,7 +316,7 @@ public class PyClassTypeImpl extends UserDataHolderBase implements PyClassType { @Nullable @Override - public PyType getCallType(@NotNull TypeEvalContext context, @Nullable PyQualifiedExpression callSite) { + public PyType getCallType(@NotNull TypeEvalContext context, @NotNull PyQualifiedExpression callSite) { return getReturnType(); } diff --git a/python/src/com/jetbrains/python/psi/types/PyFunctionType.java b/python/src/com/jetbrains/python/psi/types/PyFunctionType.java index 804f19b63b89..acd18cf7018b 100644 --- a/python/src/com/jetbrains/python/psi/types/PyFunctionType.java +++ b/python/src/com/jetbrains/python/psi/types/PyFunctionType.java @@ -54,7 +54,7 @@ public class PyFunctionType implements PyCallableType { @Nullable @Override - public PyType getCallType(@NotNull TypeEvalContext context, @Nullable PyQualifiedExpression callSite) { + public PyType getCallType(@NotNull TypeEvalContext context, @NotNull PyQualifiedExpression callSite) { return myCallable.getCallType(context, callSite); } diff --git a/python/src/com/jetbrains/python/psi/types/PyTypeChecker.java b/python/src/com/jetbrains/python/psi/types/PyTypeChecker.java index b698869ea379..6050bb58e643 100644 --- a/python/src/com/jetbrains/python/psi/types/PyTypeChecker.java +++ b/python/src/com/jetbrains/python/psi/types/PyTypeChecker.java @@ -171,8 +171,7 @@ public class PyTypeChecker { } } } - if (!match(expectedCallable.getCallType(context, null), actualCallable.getCallType(context, null), context, substitutions, - recursive)) { + if (!match(expectedCallable.getReturnType(), actualCallable.getReturnType(), context, substitutions, recursive)) { return false; } return true; @@ -258,7 +257,7 @@ public class PyTypeChecker { } } } - collectGenerics(callable.getCallType(context, null), context, collected, visited); + collectGenerics(callable.getReturnType(), context, collected, visited); } } @@ -308,7 +307,7 @@ public class PyTypeChecker { substParams.add(subst); } } - final PyType substResult = substitute(callable.getCallType(context, null), substitutions, context); + final PyType substResult = substitute(callable.getReturnType(), substitutions, context); return new PyCallableTypeImpl(substParams, substResult); } } diff --git a/python/testData/quickdoc/Method.html b/python/testData/quickdoc/Method.html index db6787aadafe..c99d4b3cbd1b 100644 --- a/python/testData/quickdoc/Method.html +++ b/python/testData/quickdoc/Method.html @@ -1 +1 @@ -class Foo

@deco
def meth(self)
Inferred type: (self: Foo) -> unknown


Doc of meth.
\ No newline at end of file +class Foo

@deco
def meth(self)
Inferred type: (self: Foo) -> None


Doc of meth.
\ No newline at end of file diff --git a/python/testSrc/com/jetbrains/python/PyTypeParserTest.java b/python/testSrc/com/jetbrains/python/PyTypeParserTest.java index 30dc43404a3c..8a34c5e31ae6 100644 --- a/python/testSrc/com/jetbrains/python/PyTypeParserTest.java +++ b/python/testSrc/com/jetbrains/python/PyTypeParserTest.java @@ -252,7 +252,7 @@ public class PyTypeParserTest extends PyTestCase { final PyCallableType callableType = (PyCallableType)type; assertNotNull(callableType); final TypeEvalContext context = getTypeEvalContext(); - final PyType returnType = callableType.getCallType(context, null); + final PyType returnType = callableType.getReturnType(); assertInstanceOf(returnType, PyGenericType.class); final List parameterTypes = callableType.getParameters(context); assertNotNull(parameterTypes); @@ -271,7 +271,7 @@ public class PyTypeParserTest extends PyTestCase { assertInstanceOf(type, PyCallableType.class); final PyCallableType callableType = (PyCallableType)type; assertNotNull(callableType); - final PyType returnType = callableType.getCallType(getTypeEvalContext(), null); + final PyType returnType = callableType.getReturnType(); assertNotNull(returnType); assertEquals("int", returnType.getName()); final List parameterTypes = callableType.getParameters(getTypeEvalContext());