
Всем привет! Меня зовут Иван, я программирую на 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 или ждете более стабильную версию? С удовольствием почитаю. И спасибо за внимание!
Комментарии (2)
Antra
11.08.2025 09:02Интересно было бы взглянуть на ваш шаблон для нового проекта.
pyproject.toml, .ruff.toml, ty.toml, может pytest.ini и т.п.
Andrey_Solomatin
Довольно круто.