stubgen generates stubs for `@asynccontextmanager` functions that mypy itself rejects

Đang mở
#21,869 3 bình luận 0 reaction 0 người được giao Xem trên GitHub

Chưa có ai nhận issue này.

Đánh giá

Độ khó
3/5
Thời gian dự kiến
1-2 ngày
Mức phù hợp với người mới
72/100
Loại issue
Lỗi
Độ rõ ràng
Đặc tả rõ ràng
Mức độ hoạt động
Ít trao đổi
Công nghệ
python
Lĩnh vực
cli, tooling

Hướng nghiên cứu

Bắt đầu từ điểm vào của stubgen và tái hiện vấn đề bằng cm.py, ví dụ @asynccontextmanager trong báo cáo. So sánh đầu ra .pyi được tạo cho các hàm và phương thức generator bất đồng bộ, sau đó chạy mypy trên stub đã tạo. Hoàn thành khi stub được tạo cho trường hợp này kiểm tra kiểu mà không có lỗi, đồng thời vẫn giữ nguyên kiểu dự kiến của context manager.

Do mô hình lập chỉ mục viết ra từ nội dung của issue.

Mô tả

bug topic-stubgen

Bug Report

stubgen copies @asynccontextmanager and the async def keyword verbatim into the generated .pyi. Because a stub body has no yield, mypy then classifies the stubbed function as a coroutine function returning AsyncIterator[T] rather than as an async generator function, and rejects the decorator application.

The result is that stubgen emits a stub which mypy — the same version, with default settings — reports an error on. Source that type-checks cleanly produces a stub that does not.

To Reproduce

# cm.py
from collections.abc import AsyncIterator
from contextlib import asynccontextmanager


@asynccontextmanager
async def ctx() -> AsyncIterator[int]:
    yield 1
$ mypy cm.py
Success: no issues found in 1 source file

$ stubgen -o out cm.py
Processed 1 modules
Generated out/cm.pyi

$ cat out/cm.pyi
from collections.abc import AsyncIterator
from contextlib import asynccontextmanager

@asynccontextmanager
async def ctx() -> AsyncIterator[int]: ...

$ mypy out/cm.pyi
out/cm.pyi:4: error: Argument 1 to "asynccontextmanager" has incompatible type "Callable[[], Coroutine[Any, Any, AsyncIterator[int]]]"; expected "Callable[[], AsyncIterator[Never]]"  [arg-type]
Found 1 error in 1 file (checked 1 source file)

The same happens for methods, and with AsyncGenerator[T, None] in place of AsyncIterator[T].

Expected Behavior

stubgen output should type-check under the mypy version that produced it. For an @asynccontextmanager-decorated async generator, that means emitting one of the two spellings the typing docs sanction for stubs — either dropping async:

@asynccontextmanager
def ctx() -> AsyncIterator[int]: ...

or dropping the decorator and declaring the decorated result, as typeshed does:

from contextlib import AbstractAsyncContextManager

def ctx() -> AbstractAsyncContextManager[int]: ...

Both of these are accepted by mypy 2.3.0.

Actual Behavior

out/cm.pyi:4: error: Argument 1 to "asynccontextmanager" has incompatible type "Callable[[], Coroutine[Any, Any, AsyncIterator[int]]]"; expected "Callable[[], AsyncIterator[Never]]"  [arg-type]

Your Environment

  • Mypy version used: 2.3.0 (compiled: yes)
  • Mypy command-line flags: none (mypy out/cm.pyi); stub produced with stubgen -o out cm.py
  • Mypy configuration options from mypy.ini (and other config files): none
  • Python version used: 3.11.15

Additional notes

This is a change in behaviour from 1.15.0. That version's stubgen omitted the decorator entirely:

# stubgen 1.15.0
async def ctx() -> AsyncIterator[int]: ...

which is also lossy, but happens to type-check, so the problem only becomes visible on 2.3.0 once the decorator is preserved.

The synchronous case is unaffected — @contextmanager over def f() -> Iterator[T] round-trips through stubgen and type-checks on 2.3.0, because there is no async keyword to change how the return type is interpreted.

Ngôn ngữ chính
Python
Star
20.6k
Fork
3.3k
Merge trung bình
1 ngày 18 giờ
Pull request đã merge (30 ngày)
54

Hướng dẫn đóng góp

Mở hướng dẫn đóng góp

Bắt đầu từ đâu

  1. Đọc hết issue, rồi đọc hướng dẫn đóng góp của dự án.
  2. Bình luận trên issue rằng bạn sẽ nhận — tránh hai người làm cùng một việc.
  3. Fork repository và làm thay đổi trên một nhánh.
  4. Mở pull request có tham chiếu số hiệu của issue.

Issue khác của python/mypy

Tất cả issue của python/mypy

Issue tương tự

Thêm issue về Python

Nhận issue mới trong hộp thư của bạn

Bản tóm tắt ngắn những issue GitHub phù hợp với người mới.