python / python/mypy

mypy doesn't like when I use type variables to subscript generic type

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

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

bug
Ngôn ngữ chính
Python
Star
20.6k
Fork
3.3k
Chỉ số merge pull request
Chỉ số pull request đang chờ

Mô tả

Bug Report

Hey, I'm trying to figure out if this mypy output is a bug or if I'm doing something incorrectly. I need to pass a type variable to a function to properly deserialize my model class. Versions 1 & 2 of my build_generic_* function work correctly, as visible in the code output, but mypy doesn't like what I'm doing there saying that I can't use a type variable this way. I created versions of this function both with Type and TypeAlias annotation just to check if mypy will be fine with either one.

from typing import Generic, Type, TypeAlias, TypeVar
from pydantic import BaseModel
from pydantic.generics import GenericModel


class SomeModel(BaseModel):
    a: int


T = TypeVar("T", bound=BaseModel)


class SomeGenericModel(GenericModel, Generic[T]):
    some_model_instance: T


def build_generic_type_from_str_1(some_generic_model_str: str,
                                  t_type: Type[T]) -> SomeGenericModel[T]:
    return SomeGenericModel[t_type].parse_raw(some_generic_model_str)


def build_generic_type_from_str_2(some_generic_model_str: str,
                                  t_type: TypeAlias) -> SomeGenericModel[T]:
    return SomeGenericModel[t_type].parse_raw(some_generic_model_str)


def build_generic_type_from_str_3(
        some_generic_model_str: str) -> SomeGenericModel[T]:
    return SomeGenericModel.parse_raw(some_generic_model_str)


def main():
    print(
        build_generic_type_from_str_1('{"some_model_instance": {"a": 1}}',
                                      SomeModel))
    print(
        build_generic_type_from_str_2('{"some_model_instance": {"a": 1}}',
                                      SomeModel))
    print(build_generic_type_from_str_3('{"some_model_instance": {"a": 1}}'))


if __name__ == "__main__":
    main()

carbon

Output from running this code & mypy:

$ python tests/mypy_typealias_problem.py
some_model_instance=SomeModel(a=1)
some_model_instance=SomeModel(a=1)
some_model_instance=BaseModel()

$ mypy tests/mypy_typealias_problem.py  
tests/mypy_typealias_problem.py:19: error: Variable "t_type" is not valid as a type
tests/mypy_typealias_problem.py:19: note: See https://mypy.readthedocs.io/en/stable/common_issues.html#variables-vs-type-aliases
tests/mypy_typealias_problem.py:24: error: Variable "t_type" is not valid as a type
tests/mypy_typealias_problem.py:24: note: See https://mypy.readthedocs.io/en/stable/common_issues.html#variables-vs-type-aliases
Found 2 errors in 1 file (checked 1 source file)

For comparison, pyright seems to suggest that the second approach with TypeAlias is incorrect.

$ pyright tests/mypy_typealias_problem.py                              
WARNING: there is a new pyright version available (v1.1.269 -> v1.1.274).
Please install the new version or set PYRIGHT_PYTHON_FORCE_VERSION to `latest`

No configuration file found.
pyproject.toml file found at /Users/dominikderen/dev/qomplx/argo-workflows/iostation-responders-client.
Loading pyproject.toml file at /Users/dominikderen/dev/qomplx/argo-workflows/iostation-responders-client/pyproject.toml
Assuming Python version 3.10
Assuming Python platform Darwin
Auto-excluding **/node_modules
Auto-excluding **/__pycache__
Auto-excluding **/.*
stubPath /Users/dominikderen/dev/qomplx/argo-workflows/iostation-responders-client/typings is not a valid directory.
Searching for source files
Found 1 source file
pyright 1.1.269
/Users/dominikderen/dev/qomplx/argo-workflows/iostation-responders-client/tests/mypy_typealias_problem.py
  /Users/dominikderen/dev/qomplx/argo-workflows/iostation-responders-client/tests/mypy_typealias_problem.py:24:29 - error: Expected class type but received "TypeAlias" (reportGeneralTypeIssues)
  /Users/dominikderen/dev/qomplx/argo-workflows/iostation-responders-client/tests/mypy_typealias_problem.py:23:74 - warning: TypeVar "T" appears only once in generic function signature (reportInvalidTypeVarUse)
  /Users/dominikderen/dev/qomplx/argo-workflows/iostation-responders-client/tests/mypy_typealias_problem.py:28:58 - warning: TypeVar "T" appears only once in generic function signature (reportInvalidTypeVarUse)
  /Users/dominikderen/dev/qomplx/argo-workflows/iostation-responders-client/tests/mypy_typealias_problem.py:38:39 - error: Argument of type "Type[SomeModel]" cannot be assigned to parameter "t_type" of type "TypeAlias" in function "build_generic_type_from_str_2"
    "Type[ModelMetaclass]" is incompatible with "Type[TypeAlias]" (reportGeneralTypeIssues)
2 errors, 2 warnings, 0 informations
Completed in 0.77sec

Versions:
Any suggestions on this would be greatly appreciated!

To Reproduce

Run the script provided above.

Expected Behavior

Either of the two approaches should not raise a mypy validation error.

Actual Behavior

Mypy is making case 1 & 2 as errors.

Your Environment

  • Mypy version used: mypy 0.971 (compiled: yes)

  • Mypy command-line flags: none, just providing a directory.

  • Mypy configuration options from mypy.ini (and other config files): none.

  • Python version used: 3.10.5

  • Operating system and version: MacOS Monterey 12.5.1

  • Pyright: 1.1.269

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.

Hướng nghiên cứu

Bắt đầu với reproducer trong tests/mypy_typealias_problem.py và chạy lệnh mypy được hiển thị đối với ba biến thể của build_generic_type_from_str. Đọc cách xử lý việc áp dụng kiểu generic và các biểu thức TypeVar, sau đó so sánh các chẩn đoán với hành vi mong đợi được mô tả trong issue. Hoàn thành nghĩa là đưa ra được một quyết định về hành vi và ghi lại quyết định đó, đồng thời thêm hoặc cập nhật một regression test nếu xác nhận hành vi này là bug.

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
devtools
Loại issue
Lỗi
Độ khó
4/5
Thời gian dự kiến
3-5 ngày
Mức độ hoạt động
Đình trệ
Độ rõ ràng
Khá rõ ràng
Mức phù hợp với người mới
25/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.