PY-40458 Use overridden method's return type for overrides only if both are async or synchronous

Because async generator methods in ABC and protocols are supposed to be declared as
plain "def" methods so as not to confuse type checkers with their AsyncIterable
return type annotations, it's better to disable such type-hint re-use if methods
async-ness don't match and not wrap anything in typing.Coroutine implicitly.

See also https://mypy.readthedocs.io/en/stable/more_types.html#asynchronous-iterators

(cherry picked from commit 6342f15a7786ec0d02ee1ab2b18fd40fd1ca1430)

IJ-CR-149694

GitOrigin-RevId: 3e19f190d9334e6c8648462ebb5b61abe931b0e6
This commit is contained in:
Mikhail Golubev
2024-11-15 17:42:13 +02:00
committed by intellij-monorepo-bot
parent fae8df34f4
commit 3fdadc1b6b
2 changed files with 27 additions and 7 deletions

View File

@@ -35,7 +35,7 @@ class PyAncestorTypeProvider : PyTypeProviderBase() {
if (callable is PyFunction) {
val typeFromSupertype = getReturnTypeFromSupertype(callable, context)
if (typeFromSupertype != null) {
return Ref.create(PyTypingTypeProvider.toAsyncIfNeeded(callable, typeFromSupertype.get()))
return typeFromSupertype
}
}
return null
@@ -90,8 +90,8 @@ private fun getReturnTypeFromSupertype(function: PyFunction, context: TypeEvalCo
val superFunctionAnnotation = getReturnTypeAnnotation(overriddenFunction, context)
if (superFunctionAnnotation != null) {
val typeRef = PyTypingTypeProvider.getType(superFunctionAnnotation, context)
if (typeRef != null) {
return typeRef
if (typeRef != null && function.isAsync == overriddenFunction.isAsync) {
return Ref.create(PyTypingTypeProvider.toAsyncIfNeeded(function, typeRef.get()))
}
}
}