
Всем привет! Меня зовут Иван, я программирую на Python, а в свободное время пишу для блога МТС. В прошлый раз поделился опытом, как я осваивал Go и с чем у меня были сложности. Спасибо всем, кто читал и комментировал! Сегодня хочу обсудить мегабыстрый инструмент для проверки типов данных Python — ty: как он устанавливается и используется, какие есть правила и нюансы, а еще посмотрим, как можно его применять. Приступим!
Что это за покемон?

Начнем с базы: ty — это проект Astral. Как пишут разработчики на GitHub, это супер-пупер быстрый инструмент для проверки типов данных Python, а еще — языковой сервер, написанный на Rust. Про Rust неудивительно, ведь и другие продукты Astral — uv и ruff — тоже написаны с его помощью. Возможно, и следующий проект будет сделан на нем.
У ty уже есть небольшая документация. Функциональность можно изучить онлайн в песочнице, установка на ПК не нужна.
А вот и информация по проекту:
|
Параметр |
Описание |
|
Особенности |
Быстрый, написан на Rust, не готов к проду |
|
Количество звезд на GitHub |
10,6 тыс. |
|
Открытых Issues |
310 |
|
Версия |
0.0.1-alpha.14 |
|
Год релиза |
2025 |
|
Pull Requests (PRs) |
0 открытых и 162 закрытых |
|
Участие в разработке |
Разработчики проекта, комьюнити |
|
Лицензия |
MIT |
Почему он вообще меня заинтересовал? В 2024 году Astral выпустила быстрый пакетный менеджер uv, и он моментально стал популярным. Сейчас у проекта 61 тысяча звезд на GitHub. Подробно о uv и его преимуществах не так давно писал Леша Жиряков из MWS, очень рекомендую почитать: тык. Так почему бы внимательнее не присмотреться к ty?

Возможно, это тоже что-нибудь революционное и в плане скорости, и в плане удобства использования. В целом есть ощущение, что разработчики Astral стремятся создать свою небольшую экосистему инструментов для Python, и наблюдать за этим очень интересно.
Но вернемся к ty. Как я уже сказал выше, это инструмент для проверки типов данных Python и языковой сервер. Давайте немного определений:
Type checker (англ. type — тип, checker — контролер) — это инструмент, который проверяет использование различных типов данных в коде в соответствии с правилами определенного языка программирования. Он помогает убедиться, что действия выполняются с подходящими типами данных. Например, в Python нельзя сложить строку и целое число, в результате выведется ошибка “TypeError: unsupported operand type(s) for +: ‘int’ and ‘str’ “).
Language server (с англ. «языковой сервер») — программа, которая предоставляет редакторам кода и IDE специфичные для языка программирования возможности. Это могут быть:
-
подсветка синтаксиса;
-
проверка ошибок;
-
завершение кода, например, при импорте модуля выводятся подсказки — доступные модули для импорта.
Есть стандартизированный протокол для обеспечения языковых возможностей для редакторов кода и IDE — это LSP (Language Server Protocol).
Галопом по (Европам) ty
Установка
Есть несколько способов:
# 1. pip pip install ty # 2. pipx pipx install ty # 3. uv uv tool install ty@latest
Запуск и доступные команды
Используется ty так:
ty <КОМАНДА>
Доступно четыре команды:
-
check — проверяет проект на ошибки типов данных (type errors);
-
server — запускает языковой сервер;
-
version — выводит версию ty;
-
help — выводит сообщение с информацией о поддерживаемых командах и опциях или вспомогательную информацию об одной из четырех команд.
И две опции:
-
-h, —help — выводит вспомогательную информацию;
-
-V, —version — выводит версию.
Конфигурация
Для ty можно указать конфигурацию при помощи файла pyproject.toml:
[tool.ty.rules] index-out-of-bounds = "ignore"
Или ty.toml:
[rules] index-out-of-bounds = "ignore"
Причем важно заметить, что если в проекте будет два вышеуказанных файла, то приоритет будет у ty.toml. Настройки ty, указанные в pyproject.toml, будут проигнорированы.
Правила и их уровни
В рамках ty правила — это индивидуальные проверки для обнаружения типичных проблем в коде. Каждое правило сфокусировано на определенном паттерне и может быть включено или выключено при необходимости.
У правила есть уровни, которые можно настроить. Всего их три:
-
Error (с англ. «ошибка») — нарушения регистрируются как ошибки, и ty завершается с кодом выхода (exit code) 1.
-
Warn (с англ. «предупреждать») — нарушения регистрируются как предупреждения, и ty завершается с кодом выхода 0. Но если используется опция —error-on-warning, код выхода будет равен 1.
-
Ignore (с англ. «игнорировать») — правило отключено.
Есть два способа настройки правил:
1. В файле:
[tool.ty.rules] unused-ignore-comment = "warn" redundant-cast = "ignore" possibly-unbound-attribute = "error" possibly-unbound-import = "error"
2. В командной строке:
ty check \ --warn unused-ignore-comment \ --ignore redundant-cast \ --error possibly-unbound-attribute \ --error possibly-unbound-import
В документации я насчитал 66 правил. Вот одно из них:

Подавление
Вместо того чтобы полностью отключать правило (уровень ignore), можно сделать это точечно для определенных участков кода.
Один из способов — указание комментария формата # ty: ignore[<rule>]:
a = 42 + "hello" # ty: ignore[unsupported-operator]
Если нарушение правила происходит на нескольких строках, можно указать комментарий на первой или последней строке:
# Создадим функцию def sum_three(a: int, b: int, c: int) -> int: ... # Так как указано три аргумента, а передается два, то сработает правило. # Проигнорируем его. sum_three( 5, 6 ) ### Вариант с первой строкой sum_three( # ty: ignore[missing-argument] 5, 6 ) ### Вариант с последней строкой sum_three( 5, 6 ) # ty: ignore[missing-argument]
Нарушается несколько правил? Тогда можно перечислить их в квадратных скобках:
sum_three("hello", 3) # ty: ignore[missing-argument, invalid-argument-type]
И еще кое-что из интересного — декоратор @no_type_check, который позволяет игнорировать все нарушения внутри функции:
from typing import no_type_check @no_type_check def main(): sum_three(5, 6)
Интеграция с редакторами кода
ty можно встроить в программы для редактирования кода. Сейчас командой разработчиков Astral поддерживается официальный плагин для VS Code, у этого расширения есть документация на GitHub.
Еще ty может взаимодействовать с Neovim — для этого нужно добавить определенные строки в конфигурацию. В качестве примера для версии редактора 0.10 или более ранней с помощью nvim-lspconfig нужно будет указать:
require('lspconfig').ty.setup({ init_options = { settings = { -- Здесь располагаются настройки языкового сервера ty } } })
Что касается других редакторов кода, к ним можно подключить ty, если они поддерживают протокол языкового сервера.
Версия Python
Для ty важно, какая версия Python используется. От этого зависит обнаружение ошибок в коде. Самый яркий пример — это выражение match и атрибут stdlib_module_names для модуля sys:
import sys # Если версия Python 3.9 или ниже, то выведется ошибка `invalid-syntax` match "echo Hello,Habr!".split(): case ["echo", message]: print(message) case _: print("you used unknown command") # То же условие про версию. Ошибка `unresolved-attribute` print(sys.stdlib_module_names) # Однако можно добавить проверку на версию if sys.version_info >= (3, 10): # Ошибки не возникнет, так как выполняется проверка версии print(sys.stdlib_module_names)
Как работает проверка (check)
При выполнении команды:
ty check
Осуществляется проверка всех файлов как в текущей, так и в дочерних директориях. Но если ty используется в рамках проекта, запуск будет выполняться начиная с каталога, в котором расположен файл pyproject.toml.
Еще можно указать конкретный файл:
ty check something.py
ty самостоятельно обнаружит установленные модули в активной виртуальной среде одним из двух путей:
-
при помощи переменных окружения VIRTUAL_ENV или CONDA_PREFIX;
-
будет искать директорию .venv в корне проекта или текущем каталоге.
Если же ty выполняется не в рамках виртуальной среды, придется указывать путь к пакетам вручную при помощи опции —python:
ty check --python .venv/bin/python3 something.py
ty по умолчанию игнорирует файлы, указанные в .ignore или .gitignore. Но эту опцию можно отключить, указав —no-respect-gitignore:
ty check --no-respect-gitignore
Пример использования
Допустим, у нас небольшой проект на FastAPI. Есть файл main.py:
from fastapi import FastAPI from app.models import User app = FastAPI() def old_enough(age: int = None) -> bool: return True if age >= 18 else False @app.get("/") async def root(): return {"hello!": "hello"} @app.post("/user/") def user(data: User) -> User: data.is_adult = old_enough(data.age) return data
И models.py:
from pydantic import BaseModel, ConfigDict class User(BaseModel): model_config = ConfigDict(extra=”allow”) name: str age: int
Теперь выполним проверку:
(venv) Ivans-PC:test iglebov$ ty check WARN ty is pre-release software and not ready for production use. Expect to encounter bugs, missing features, and fatal errors. error[invalid-parameter-default]: Default value of type `None` is not assignable to annotated parameter type `int` --> app/main.py:7:16 | 5 | app = FastAPI() 6 | 7 | def old_enough(age: int = None) -> bool: | ^^^^^^^^^^^^^^^ 8 | return True if age >= 18 else False | info: rule `invalid-parameter-default` is enabled by default error[unresolved-attribute]: Unresolved attribute `is_adult` on type `User`. --> app/main.py:16:5 | 14 | @app.post("/user/") 15 | def user(data: User) -> User: 16 | data.is_adult = old_enough(data.age) | ^^^^^^^^^^^^^ 17 | return data | info: rule `unresolved-attribute` is enabled by default
Found 2 diagnosticsty обнаружил целых две ошибки. Посмотрим подробнее:
1. Default value of type None is not assignable to annotated parameter type int
Тут указано, что нельзя присвоить None для аргумента с типом данных int.
Исправим функцию old_enough:
def old_enough(age: int = 18) -> bool: return True if age >= 18 else False
2. Unresolved attribute is_adult on type User
Для модели User не удалось определить атрибут is_adult. В ней он не описан, но в конфигурации модели указывается extra=”allow”, что позволяет добавлять атрибут «на ходу».
Если логика кода правильная, но ошибка возникает, можно добавить игнорирование при помощи комментария:
@app.post("/user/") def user(data: User) -> User: data.is_adult = old_enough(data.age) # ty: ignore[unresolved-attribute] return data
Снова запустим проверку:
(venv) Ivans-PC:test iglebov$ ty check WARN ty is pre-release software and not ready for production use. Expect to encounter bugs, missing features, and fatal errors. All checks passed!
Ура, все успешно! На такой позитивной ноте перехожу к заключению.

Что в итоге
Мы посмотрели новый проект от компании Astral — ty. Пока он только набирает обороты, но его сильные стороны уже очевидны. В первую очередь это:
-
простота использования: установить, добавить файлик ty.toml или pyproject.toml и let’s go;
-
скорость: проверка выполняется довольно быстро;
-
интеграция с редакторами кода и даже плагин для VS Code.
А как ваши впечатления? Поделитесь, используете ли ty или ждете более стабильную версию? С удовольствием почитаю. И спасибо за внимание!
ссылка на оригинал статьи https://habr.com/ru/articles/935858/
Добавить комментарий