Skip to content

Incorrect invalid-return-type for constrained generics in async functions #3583

@Apakottur

Description

@Apakottur

Summary

Consider the following code:

# a.py

from typing import Any, Generic, TypeVar


T = TypeVar("T", bound=tuple[Any, ...])


class Select(Generic[T]):
    pass


def first[T](v: T) -> Select[tuple[T]]:
    raise NotImplementedError


async def second[T](query: Select[tuple[T]]) -> T:
    raise NotImplementedError


async def variant_one() -> int:
    a = await second(first(123))
    return a


async def variant_two() -> int:
    return await second(first(123))

Running ty check a.py gives the following error:

error[invalid-return-type]: Return type does not match returned value
  --> a.py:26:28
   |
26 | async def variant_two() -> int:
   |                            --- Expected `int` because of return type
27 |     return await second(first(123))
   |            ^^^^^^^^^^^^^^^^^^^^^^^^ expected `int`, found `int | None`
   |
info: element `None` of union `int | None` is not assignable to `int`

Found 1 diagnostic

The functions variant_one and variant_two do the exact same thing, but returning the value directly leads to a type error. mypy and pyright both accept this entire file.

This code snippet is based on a real life scenario with SQLAlchemy, figured it's better to not have any dependencies.

Version

0.0.40

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions