Phân tích sâu hơn về trạng thái bảo trì của pytest-monkeytype dựa trên nhịp phiên bản PyPI đã phát hành, hoạt động của kho lưu trữ và các điểm dữ liệu khác đã xác định rằng việc bảo trì của nó là Không hoạt động
Một tín hiệu bảo trì dự án quan trọng cần xem xét đối với pytest-monkeytype là nó không thấy bất kỳ phiên bản mới nào được phát hành cho PyPI trong 12 tháng qua và có thể được coi là dự án đã ngừng hoạt động hoặc dự án ít nhận được sự quan tâm từ những người bảo trì dự án.
Trong tháng trước, chúng tôi không tìm thấy bất kỳ hoạt động yêu cầu kéo nào hoặc thay đổi trạng thái vấn đề đã được phát hiện đối với kho lưu trữ GitHub
Gần đây đã có khá nhiều tin đồn xung quanh chú thích loại, vì vậy bạn có thể tự hỏi liệu kiểm tra loại có phải là điều bạn nên làm không. Bài viết này không phải là phần giới thiệu chung về chú thích loại và kiểm tra loại, tôi khuyên bạn nên sử dụng Hypermodern Python. Đánh máy để có cái nhìn tổng quan về nền
Tóm lại trích dẫn bài báo trên.
"Chú thích loại là một cách để chú thích các hàm và biến với các loại. Kết hợp với công cụ hiểu chúng, chúng có thể làm cho chương trình của bạn dễ hiểu, gỡ lỗi và bảo trì hơn. Trình kiểm tra kiểu tĩnh có thể sử dụng chú thích kiểu và suy luận kiểu để xác minh tính đúng đắn của kiểu chương trình của bạn mà không cần thực thi nó, giúp bạn phát hiện ra nhiều lỗi mà lẽ ra không được chú ý. " hoặc Dropbox đặt nó như thế này. "Nếu bạn không sử dụng kiểm tra kiểu trong dự án Python quy mô lớn của mình, thì bây giờ là thời điểm tốt để bắt đầu - không ai đã thực hiện bước nhảy vọt mà tôi từng nói chuyện đã hối tiếc về điều đó. Nó thực sự làm cho Python trở thành một ngôn ngữ tốt hơn cho các dự án lớn. "
Ngoài những điều trên, công cụ xung quanh chú thích loại đang phát triển liên tục và giúp giữ cho mã của bạn KHÔ.
Có các thư viện như Desert hoặc Điển hình để trợ giúp xác thực dữ liệu, Typeguard hoặc Strongtyping để kiểm tra các loại trong thời gian chạy, sphinx-autodoc-typehints để giúp xây dựng tài liệu, Typer để xây dựng CLI, FastAPI một khung web .
Để có danh sách đầy đủ hơn, vui lòng tham khảo Awesome Python Typing
Đừng để mã kế thừa trở thành nợ kỹ thuậtNhư Dropbox mô tả trong Hành trình gõ kiểm tra 4 triệu dòng Python của chúng tôi, khá khó khăn khi gõ chú thích một cơ sở mã hiện có. Bài viết mô tả chi tiết cách bạn có thể tiếp cận các cải tiến dần dần với các chú thích loại cho cơ sở mã của bạn
Nhập MonkeyTypeNhưng tại sao tôi phải viết chú thích của mình theo cách thủ công? . Những người ở Instagram cũng nghĩ như vậy và tạo ra MonkeyType. Một dự án tương tự là PyAnnotate được tạo bởi Dropbox. Pytype tạo các tệp thông tin loại suy luận, được đặt theo mặc định trong
[mypy]
disallow_any_generics = True
disallow_untyped_calls = True
disallow_untyped_defs = True
disallow_untyped_decorators = True
ignore_errors = False
ignore_missing_imports = True
implicit_reexport = False
strict_optional = True
strict_equality = True
no_implicit_optional = True
warn_unused_ignores = True
warn_redundant_casts = True
warn_unused_configs = True
warn_unreachable = True
warn_no_return = True
warn_return_any = True
plugins =
mypy_django_plugin.main,
mypy_drf_plugin.main
[mypy.plugins.django-stubs]
django_settings_module = "test_settings"
[mypy-drfdapc.test_permissions]
ignore_errors = True
0. Pyre có một tính năng mạnh mẽ để di chuyển cơ sở mã sang định dạng đã nhập. Tùy chọn dòng lệnh suy luận nhập một tệp hoặc thư mục, đưa ra các phỏng đoán có giáo dục về các loại được sử dụng và áp dụng các chú thích cho các tệpMonkeyType thu thập các loại đối số hàm và giá trị trả về trong thời gian chạy, đồng thời có thể tự động tạo tệp sơ khai hoặc thậm chí thêm chú thích loại nháp trực tiếp vào mã Python của bạn dựa trên các loại được thu thập trong thời gian chạy
Hãy xem phần Giới thiệu về MonkeyType để biết tổng quan về chức năng của nó hoặc nghe podcast của MonkeyType
Mặc dù bạn có thể chạy MonkeyType trong một môi trường giống như sản xuất và nhận dữ liệu trong thế giới thực về cách mã của bạn được gọi, nhưng trường hợp sử dụng phổ biến nhất có lẽ là lấy dữ liệu này ra khỏi các lần chạy thử nghiệm. Nếu bạn không sử dụng pytest với django Kiểm tra ứng dụng Django của bạn với Pytest sẽ giúp bạn bắt đầu
Cài đặt các phụ thuộc cần thiết bằng cách tạo tệp
[mypy]
disallow_any_generics = True
disallow_untyped_calls = True
disallow_untyped_defs = True
disallow_untyped_decorators = True
ignore_errors = False
ignore_missing_imports = True
implicit_reexport = False
strict_optional = True
strict_equality = True
no_implicit_optional = True
warn_unused_ignores = True
warn_redundant_casts = True
warn_unused_configs = True
warn_unreachable = True
warn_no_return = True
warn_return_any = True
plugins =
mypy_django_plugin.main,
mypy_drf_plugin.main
[mypy.plugins.django-stubs]
django_settings_module = "test_settings"
[mypy-drfdapc.test_permissions]
ignore_errors = True
1 với nội dungmypy
mypy-extensions
MonkeyType
pytest-monkeytype
django-stubs
djangorestframework-stubs
Vào chế độ toàn màn hình Thoát chế độ toàn màn hình
và cài đặt các phụ thuộc với
[mypy]
disallow_any_generics = True
disallow_untyped_calls = True
disallow_untyped_defs = True
disallow_untyped_decorators = True
ignore_errors = False
ignore_missing_imports = True
implicit_reexport = False
strict_optional = True
strict_equality = True
no_implicit_optional = True
warn_unused_ignores = True
warn_redundant_casts = True
warn_unused_configs = True
warn_unreachable = True
warn_no_return = True
warn_return_any = True
plugins =
mypy_django_plugin.main,
mypy_drf_plugin.main
[mypy.plugins.django-stubs]
django_settings_module = "test_settings"
[mypy-drfdapc.test_permissions]
ignore_errors = True
2 Khi viết bài này, [mypy]
disallow_any_generics = True
disallow_untyped_calls = True
disallow_untyped_defs = True
disallow_untyped_decorators = True
ignore_errors = False
ignore_missing_imports = True
implicit_reexport = False
strict_optional = True
strict_equality = True
no_implicit_optional = True
warn_unused_ignores = True
warn_redundant_casts = True
warn_unused_configs = True
warn_unreachable = True
warn_no_return = True
warn_return_any = True
plugins =
mypy_django_plugin.main,
mypy_drf_plugin.main
[mypy.plugins.django-stubs]
django_settings_module = "test_settings"
[mypy-drfdapc.test_permissions]
ignore_errors = True
3 cần [mypy]
disallow_any_generics = True
disallow_untyped_calls = True
disallow_untyped_defs = True
disallow_untyped_decorators = True
ignore_errors = False
ignore_missing_imports = True
implicit_reexport = False
strict_optional = True
strict_equality = True
no_implicit_optional = True
warn_unused_ignores = True
warn_redundant_casts = True
warn_unused_configs = True
warn_unreachable = True
warn_no_return = True
warn_return_any = True
plugins =
mypy_django_plugin.main,
mypy_drf_plugin.main
[mypy.plugins.django-stubs]
django_settings_module = "test_settings"
[mypy-drfdapc.test_permissions]
ignore_errors = True
0, điều này đã được khắc phục trong Yêu cầu kéo nàyĐịnh cấu hình mypy với
[mypy]
disallow_any_generics = True
disallow_untyped_calls = True
disallow_untyped_defs = True
disallow_untyped_decorators = True
ignore_errors = False
ignore_missing_imports = True
implicit_reexport = False
strict_optional = True
strict_equality = True
no_implicit_optional = True
warn_unused_ignores = True
warn_redundant_casts = True
warn_unused_configs = True
warn_unreachable = True
warn_no_return = True
warn_return_any = True
plugins =
mypy_django_plugin.main,
mypy_drf_plugin.main
[mypy.plugins.django-stubs]
django_settings_module = "test_settings"
[mypy-drfdapc.test_permissions]
ignore_errors = True
1 e. g[mypy]
disallow_any_generics = True
disallow_untyped_calls = True
disallow_untyped_defs = True
disallow_untyped_decorators = True
ignore_errors = False
ignore_missing_imports = True
implicit_reexport = False
strict_optional = True
strict_equality = True
no_implicit_optional = True
warn_unused_ignores = True
warn_redundant_casts = True
warn_unused_configs = True
warn_unreachable = True
warn_no_return = True
warn_return_any = True
plugins =
mypy_django_plugin.main,
mypy_drf_plugin.main
[mypy.plugins.django-stubs]
django_settings_module = "test_settings"
[mypy-drfdapc.test_permissions]
ignore_errors = True
Vào chế độ toàn màn hình Thoát chế độ toàn màn hình
Tạo tệp
[mypy]
disallow_any_generics = True
disallow_untyped_calls = True
disallow_untyped_defs = True
disallow_untyped_decorators = True
ignore_errors = False
ignore_missing_imports = True
implicit_reexport = False
strict_optional = True
strict_equality = True
no_implicit_optional = True
warn_unused_ignores = True
warn_redundant_casts = True
warn_unused_configs = True
warn_unreachable = True
warn_no_return = True
warn_return_any = True
plugins =
mypy_django_plugin.main,
mypy_drf_plugin.main
[mypy.plugins.django-stubs]
django_settings_module = "test_settings"
[mypy-drfdapc.test_permissions]
ignore_errors = True
2# Standard Library
import os
from contextlib import contextmanager
from typing import Iterator
# 3rd-party
from monkeytype.config import DefaultConfig
class MonkeyConfig[DefaultConfig]:
@contextmanager
def cli_context[self, command: str] -> Iterator[None]:
os.environ.setdefault["DJANGO_SETTINGS_MODULE", "test_settings"]
import django
django.setup[]
yield
CONFIG = MonkeyConfig[]
Vào chế độ toàn màn hình Thoát chế độ toàn màn hình
Thay đổi
[mypy]
disallow_any_generics = True
disallow_untyped_calls = True
disallow_untyped_defs = True
disallow_untyped_decorators = True
ignore_errors = False
ignore_missing_imports = True
implicit_reexport = False
strict_optional = True
strict_equality = True
no_implicit_optional = True
warn_unused_ignores = True
warn_redundant_casts = True
warn_unused_configs = True
warn_unreachable = True
warn_no_return = True
warn_return_any = True
plugins =
mypy_django_plugin.main,
mypy_drf_plugin.main
[mypy.plugins.django-stubs]
django_settings_module = "test_settings"
[mypy-drfdapc.test_permissions]
ignore_errors = True
3 thành cái được sử dụng trong các bài kiểm tra. Bây giờ bạn có thể chạy thử nghiệm của mình với
[mypy]
disallow_any_generics = True
disallow_untyped_calls = True
disallow_untyped_defs = True
disallow_untyped_decorators = True
ignore_errors = False
ignore_missing_imports = True
implicit_reexport = False
strict_optional = True
strict_equality = True
no_implicit_optional = True
warn_unused_ignores = True
warn_redundant_casts = True
warn_unused_configs = True
warn_unreachable = True
warn_no_return = True
warn_return_any = True
plugins =
mypy_django_plugin.main,
mypy_drf_plugin.main
[mypy.plugins.django-stubs]
django_settings_module = "test_settings"
[mypy-drfdapc.test_permissions]
ignore_errors = True
4 và [mypy]
disallow_any_generics = True
disallow_untyped_calls = True
disallow_untyped_defs = True
disallow_untyped_decorators = True
ignore_errors = False
ignore_missing_imports = True
implicit_reexport = False
strict_optional = True
strict_equality = True
no_implicit_optional = True
warn_unused_ignores = True
warn_redundant_casts = True
warn_unused_configs = True
warn_unreachable = True
warn_no_return = True
warn_return_any = True
plugins =
mypy_django_plugin.main,
mypy_drf_plugin.main
[mypy.plugins.django-stubs]
django_settings_module = "test_settings"
[mypy-drfdapc.test_permissions]
ignore_errors = True
5 trên Bash hoặc [mypy]
disallow_any_generics = True
disallow_untyped_calls = True
disallow_untyped_defs = True
disallow_untyped_decorators = True
ignore_errors = False
ignore_missing_imports = True
implicit_reexport = False
strict_optional = True
strict_equality = True
no_implicit_optional = True
warn_unused_ignores = True
warn_redundant_casts = True
warn_unused_configs = True
warn_unreachable = True
warn_no_return = True
warn_return_any = True
plugins =
mypy_django_plugin.main,
mypy_drf_plugin.main
[mypy.plugins.django-stubs]
django_settings_module = "test_settings"
[mypy-drfdapc.test_permissions]
ignore_errors = True
6 trên C Shell. Kiểm tra những mô-đun mà MonkeyType đã thu thập thông tin với ________ 17
[mypy]
disallow_any_generics = True
disallow_untyped_calls = True
disallow_untyped_defs = True
disallow_untyped_decorators = True
ignore_errors = False
ignore_missing_imports = True
implicit_reexport = False
strict_optional = True
strict_equality = True
no_implicit_optional = True
warn_unused_ignores = True
warn_redundant_casts = True
warn_unused_configs = True
warn_unreachable = True
warn_no_return = True
warn_return_any = True
plugins =
mypy_django_plugin.main,
mypy_drf_plugin.main
[mypy.plugins.django-stubs]
django_settings_module = "test_settings"
[mypy-drfdapc.test_permissions]
ignore_errors = True
1Vào chế độ toàn màn hình Thoát chế độ toàn màn hình
Sau đó, bạn có thể sử dụng lệnh
[mypy]
disallow_any_generics = True
disallow_untyped_calls = True
disallow_untyped_defs = True
disallow_untyped_decorators = True
ignore_errors = False
ignore_missing_imports = True
implicit_reexport = False
strict_optional = True
strict_equality = True
no_implicit_optional = True
warn_unused_ignores = True
warn_redundant_casts = True
warn_unused_configs = True
warn_unreachable = True
warn_no_return = True
warn_return_any = True
plugins =
mypy_django_plugin.main,
mypy_drf_plugin.main
[mypy.plugins.django-stubs]
django_settings_module = "test_settings"
[mypy-drfdapc.test_permissions]
ignore_errors = True
8 để tạo tệp sơ khai cho một mô-đun hoặc áp dụng trực tiếp chú thích loại cho mã của mình với [mypy]
disallow_any_generics = True
disallow_untyped_calls = True
disallow_untyped_defs = True
disallow_untyped_decorators = True
ignore_errors = False
ignore_missing_imports = True
implicit_reexport = False
strict_optional = True
strict_equality = True
no_implicit_optional = True
warn_unused_ignores = True
warn_redundant_casts = True
warn_unused_configs = True
warn_unreachable = True
warn_no_return = True
warn_return_any = True
plugins =
mypy_django_plugin.main,
mypy_drf_plugin.main
[mypy.plugins.django-stubs]
django_settings_module = "test_settings"
[mypy-drfdapc.test_permissions]
ignore_errors = True
9[mypy]
disallow_any_generics = True
disallow_untyped_calls = True
disallow_untyped_defs = True
disallow_untyped_decorators = True
ignore_errors = False
ignore_missing_imports = True
implicit_reexport = False
strict_optional = True
strict_equality = True
no_implicit_optional = True
warn_unused_ignores = True
warn_redundant_casts = True
warn_unused_configs = True
warn_unreachable = True
warn_no_return = True
warn_return_any = True
plugins =
mypy_django_plugin.main,
mypy_drf_plugin.main
[mypy.plugins.django-stubs]
django_settings_module = "test_settings"
[mypy-drfdapc.test_permissions]
ignore_errors = True
4Vào chế độ toàn màn hình Thoát chế độ toàn màn hình
Kiểm tra các chú thích với mypy cho thấy rằng vẫn còn một số việc phải làm và nó thể hiện rõ những lỗi mà mypy bắt được
[mypy]
disallow_any_generics = True
disallow_untyped_calls = True
disallow_untyped_defs = True
disallow_untyped_decorators = True
ignore_errors = False
ignore_missing_imports = True
implicit_reexport = False
strict_optional = True
strict_equality = True
no_implicit_optional = True
warn_unused_ignores = True
warn_redundant_casts = True
warn_unused_configs = True
warn_unreachable = True
warn_no_return = True
warn_return_any = True
plugins =
mypy_django_plugin.main,
mypy_drf_plugin.main
[mypy.plugins.django-stubs]
django_settings_module = "test_settings"
[mypy-drfdapc.test_permissions]
ignore_errors = True
5Vào chế độ toàn màn hình Thoát chế độ toàn màn hình
Hãy nhớ rằng chú thích của MonkeyType là bản nháp đầu tiên cung cấp thông tin, sẽ được nhà phát triển kiểm tra và sửa chữa.
Trong ví dụ trên, chúng tôi không bao giờ chuyển chế độ xem, tất cả các đối tượng đều bị giả định và
# Standard Library
import os
from contextlib import contextmanager
from typing import Iterator
# 3rd-party
from monkeytype.config import DefaultConfig
class MonkeyConfig[DefaultConfig]:
@contextmanager
def cli_context[self, command: str] -> Iterator[None]:
os.environ.setdefault["DJANGO_SETTINGS_MODULE", "test_settings"]
import django
django.setup[]
yield
CONFIG = MonkeyConfig[]
0 quá cụ thể, vì vậy chúng tôi cần điều chỉnh điều này. Đồng thời chạy # Standard Library
import os
from contextlib import contextmanager
from typing import Iterator
# 3rd-party
from monkeytype.config import DefaultConfig
class MonkeyConfig[DefaultConfig]:
@contextmanager
def cli_context[self, command: str] -> Iterator[None]:
os.environ.setdefault["DJANGO_SETTINGS_MODULE", "test_settings"]
import django
django.setup[]
yield
CONFIG = MonkeyConfig[]
1 và # Standard Library
import os
from contextlib import contextmanager
from typing import Iterator
# 3rd-party
from monkeytype.config import DefaultConfig
class MonkeyConfig[DefaultConfig]:
@contextmanager
def cli_context[self, command: str] -> Iterator[None]:
os.environ.setdefault["DJANGO_SETTINGS_MODULE", "test_settings"]
import django
django.setup[]
yield
CONFIG = MonkeyConfig[]
2 trên tệp này để có mã được định dạng độc đáo. Bạn có thể xem quy trình làm việc trong yêu cầu kéo nàyBắt đầu với các mô-đun nhỏ có ít [hoặc thậm chí tốt hơn là không] phụ thuộc vào các phần khác trong mã của bạn, áp dụng các loại, kiểm tra tính chính xác của các chú thích bằng
# Standard Library
import os
from contextlib import contextmanager
from typing import Iterator
# 3rd-party
from monkeytype.config import DefaultConfig
class MonkeyConfig[DefaultConfig]:
@contextmanager
def cli_context[self, command: str] -> Iterator[None]:
os.environ.setdefault["DJANGO_SETTINGS_MODULE", "test_settings"]
import django
django.setup[]
yield
CONFIG = MonkeyConfig[]
3 sửa thông tin nhập và chuyển sang mô-đun tiếp theoNgười giúp việc nhỏBạn sẽ muốn giữ thông tin loại của mình rõ ràng, dễ đọc và nhất quán. Để đạt được điều này, có một số plugin cho flake8
flake8-annotations-complexity báo cáo về các chú thích loại quá phức tạp, khó đọc. Chú thích loại phức tạp thường có nghĩa là sử dụng chú thích không hợp lệ, phân tách mã sai hoặc lựa chọn cấu trúc dữ liệu không phù hợp
flake8-annotations-coverage báo cáo về các tệp có nhiều mã mà không có chú thích loại. Điều này chủ yếu hữu ích khi bạn thêm chú thích loại vào cơ sở mã lớn hiện có và muốn biết liệu mã mới trong mô-đun được chú thích có được chú thích hay không