Языки: English · Русский · 简体中文
Когда вы нашли баг, до того, как его исправлять, напишите
воспроизводящий тест — он должен падать на main и проходить
после фикса. И тест, и фикс — в одном PR.
Тесты лежат в tests/:
| Файл | Область |
|---|---|
test_loads.py |
Поведение парсера. |
test_dumps.py |
Поведение сериализатора. |
test_roundtrip.py |
loads(dumps(x)) == x. |
test_errors.py |
Таксономия и распространение исключений. |
test_load_dump.py |
Обёртки под файл-подобные объекты. |
test_module.py |
Экспорты модуля, строки версий. |
test_conformance.py |
Кросс-язычная проверка по спецификации. |
Эти Python-биндинги — намеренно тонкая обёртка. Поведение парсера и
формата принадлежит Rust-крейту
(ktav-lang/rust) — изменение
там обновляет все language-биндинги одновременно. В этот репозиторий
идёт только Python-specific эргономика: обёртки под файлы, типы
исключений, type stubs.
Если ваше изменение требует правки формата — начните с обсуждения в
ktav-lang/spec.
Если вы трогаете что-то экспортируемое из ktav или ktav._core, в
описании PR укажите:
- semver-совместимое (добавления, ослабленные границы, изменения в документации); или
- semver-ломающее (переименование / удаление, изменение сигнатур, ужесточение типов) — в этом случае bump версии попадает в следующий MINOR, пока мы до 1.0.
Обновите CHANGELOG.md и два перевода в том же PR.
Коммиты атомарны: фикс бага и его тест вместе, фича и её тесты вместе,
переименование — отдельным коммитом, рефакторинг — отдельным.
git log --oneline должен читаться как changelog. Не ставьте перед
сообщением префиксы feat: / fix: — никаких conventional commits.
Нужно:
- Python 3.9+ (любая версия, под которую тестируете).
- Rust-toolchain через
rustup. MSRV: 1.70. maturinи тестовый инструментарий:
pip install -e ".[dev]"Раскладка во время разработки — биндинги разрешают Rust-крейт ktav
через path = "../rust" в Cargo.toml. Клонируйте соседний репо
рядом с этим:
ktav-lang/
├── python/ ← этот репо
├── rust/ ← соседний Rust-крейт
└── spec/ ← conformance-фикстуры (опционально, но рекомендовано)Как только ktav опубликуется на crates.io, path-зависимость
уходит и остаётся только version = "0.1". См. комментарий на этой
строке в Cargo.toml.
make dev # debug-сборка (быстрый инкремент)
make install # release-сборка (реалистичная производительность)Или напрямую:
maturin develop
maturin develop --releasematurin develop компилирует Rust-расширение и ставит его в текущее
активное Python-окружение — из него и запускайте тесты.
make test # вся сьюта
pytest -v -k multiline # фильтр по имени
pytest -v tests/test_loads.py # отдельный файлtest_conformance.py запускает кросс-язычные фикстуры из
ktav-lang/spec — путь захардкожен как <repo>/spec/versions/0.1/tests
(git submodule spec). Если submodule не подтянут (например, sdist-
сборка), conformance-тесты скипаются, а не падают.
make lint # ruff check + ruff format --check
make typecheck # mypy --strict
make rust-lint # cargo fmt --check + cargo clippy -D warnings
make all # lint + typecheck + rust-lint + testCI запускает те же команды; прогоните make all локально перед пушем.
pre-commit install
pre-commit run --all-filesЗаведёт ruff, mypy, rustfmt, clippy и стандартные whitespace / EOL
хуки в git commit.
Девиз Ktav: «будь другом конфигу, а не экзаменатором». Прежде чем предлагать Python-specific фичу, спросите себя:
- Добавляет ли это новое правило, которое читатель должен держать в голове?
- Можно ли это жить в пользовательском коде вместо библиотеки?
- Не размывает ли это принцип «никакой магии в типах»?
Новые правила стоят дорого. Отклоняйте всё, что не очевидно на своём месте.
Репо участвует в org-wide политике трёх языков (EN / RU / ZH). Каждый
prose-документ живёт в трёх параллельных версиях — см.
ktav-lang/.github/AGENTS.md
для соглашения об именовании и правила «обновлять все три в одном
коммите».
Если вы не владеете одним из языков — всё равно открывайте PR на
понятном вам языке, поставьте в нетронутых версиях комментарий
<!-- TODO: sync with <name>.md --> в начале, мейнтейнер или
сообщество доведёт перед мерджем.