Type narrowing of `target: type[T]` using insinstance seems to fool mypy

Đang mở
#20,690 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ó
4/5
Thời gian dự kiến
3-5 ngày
Mức phù hợp với người mới
35/100
Loại issue
Lỗi
Độ rõ ràng
Khá rõ ràng
Mức độ hoạt động
Đình trệ
Công nghệ
python
Lĩnh vực
compilers, devtools

Hướng nghiên cứu

Bắt đầu bằng cách chạy reproducer được cung cấp với mypy 1.19.1 và so sánh các kiểu được hiển thị cùng các chẩn đoán của nó với hành vi mong đợi. Theo dõi đường đi của việc thu hẹp kiểu đối với isinstance(target_type, int) và target_type is int; hoàn thành khi hàm đầu tiên không hợp lệ bị từ chối và hành vi thu hẹp được hỗ trợ được bao phủ bằng các bài kiểm thử hồi quy.

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

Mô tả

bug topic-type-narrowing

Bug Report
Well, I was writing some sort of converter from unstructured data to a dataclass, so I had a function that uses f[T](obj, target_type: type[T]) -> T and while in the end I stick to typing.cast for that, I also tried several solutions, they are below.

One of them intuitively should(?) work (return_checktype), but mypy refuses to follow them, and one of them is obviously wrong in hindsight (return_checkval), but mypy is happy with it.

To Reproduce

from typing import reveal_type


def return_checkval[T](target_type: type[T]) -> T:
    # runtime check that target_type is int
    if isinstance(target_type, int):
        reveal_type(target_type)
        return 42  # and they lived happily ever after

    raise ValueError("Unsupported type")


x = return_checkval(int)
print(x)


def return_checktype[T](target_type: type[T]) -> T:
    # runtime check that target_type is int
    if target_type is int:
        reveal_type(target_type)
        return 42  # errors here

    raise ValueError("Unsupported type")


# example test
x = return_checktype(int)
print(x)

Expected Behavior

At the very least, it should have two reveal_type outputs, and it should reject the first function completely. That's what (based)pyright.
Ideally, it should also allow the second function, but (based)pyright also rejects it :(

Actual Behavior

t.py:20: note: Revealed type is "type[T`-1]"
t.py:21: error: Incompatible return value type (got "int", expected "T")  [return-value]
Found 1 error in 1 file (checked 1 source file)
Traceback (most recent call last):
  File "/private/tmp/test/t.py", line 13, in <module>
    x = return_checkval(int)
  File "/private/tmp/test/t.py", line 10, in return_checkval
    raise ValueError("Unsupported type")
ValueError: Unsupported type

Your Environment

mypy version 1.19.1 (compiled yes)
python version .. honestly have no idea which one it uses, but python --version is 3.14
just run it mypy . from the folder in /tmp

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.