python / python/typing

Spec/Conformance: subtyping callables with non-constant parameter mapping.

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

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

topic: typing spec
Ngôn ngữ chính
Python
Star
1.8k
Fork
302
Merge trung bình
23 giờ
Pull request đã merge (30 ngày)
8

Mô tả

Consider the example below, which errors with all tested type checkers (mypy/pyright/ty/pyrefly):

from typing import Protocol

class Interval: ...

class Make(Protocol):
    def __call__(self, /, lower: float, upper: float) -> Interval: ...

def make_impl(
    string_or_lower: str | float | None = None,
    /,
    lower: float | None = None,
    upper: float | None = None,
) -> Interval: ...

def test() -> None:
    _f: Make = make_impl  # ❌️ type checkers error here.

I believe from a pure type theory POV, this assignment should be legal, because all legal arguments to Make are also legal arguments to make_impl. The spec phrases it in the same spirit:

A callable type B is assignable to a callable type A if the return type of B is assignable to the return type of A and the input signature of B accepts all possible combinations of arguments that the input signature of A accepts. All of the specific assignability rules described below derive from this general rule.

And I couldn't find anything else in https://typing.python.org/en/latest/spec/callables.html#assignability-rules-for-callables that would disallow this assignment.

It seems the type-checkers try to match the KEYWORD_OR_POSITIONAL parameters by name, which is incorrect. Make has 3 legal call signatures:

  1. Make(float, float)
  2. Make(float, upper=float)
  3. Make(lower=float, upper=float)

and all these 3 call signatures are supported by make_impl, but the parameter mapping is not constant:

  1. make_impl(float, float) -> {lower:string_or_lower, upper:lower}
  2. make_impl(float, upper=float) -> {lower:string_or_lower, upper:upper}
  3. make_impl(lower=float, upper=float) -> {lower:lower, upper:upper}

So either the spec should demand a constant parameter mapping, or this example should be added to the conformance tests.

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

Chưa lập chỉ mục được hướng dẫn đóng góp cho kho mã nguồn này

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.

Hướng nghiên cứu

Bắt đầu với các quy tắc về tính có thể gán của callable được liên kết trong issue và tái hiện ví dụ bằng mypy, pyright, ty và pyrefly. Issue không nêu tên tệp nào trong repository hoặc đường dẫn conformance-test; việc hoàn tất phụ thuộc vào quyết định nên làm rõ ánh xạ tham số hằng trong đặc tả hay thêm trường hợp này vào các bài kiểm tra conformance.

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

Đánh giá

Công nghệ
python
Lĩnh vực
documentation, testing-qa
Loại issue
Tài liệu
Độ khó
5/5
Thời gian dự kiến
Hơn một tuần
Mức độ hoạt động
Ít trao đổi
Độ rõ ràng
Khá rõ ràng
Mức phù hợp với người mới
35/100

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.