Development

Environment

Use Python 3.10 or newer.

python -m pip install -e ".[dev,docs]"

The package uses Hatchling with VCS-based dynamic versioning.

Runtime dependencies

The runtime dependencies include:

  • typer

  • rich

  • pydantic>=2

  • tomli-w

  • tomli on Python older than 3.11

  • beautifulsoup4

  • markdown-it-py

  • phrasplit

  • epub2text>=0.2.4

  • text2epub

ebooklib and mypy are included in the dev extra so the documented test/type-check commands run after a single editable install. docs/conf.py (Sphinx, MyST, Read the Docs theme) is covered by the docs extra. To install everything at once:

Docs dependencies

The docs extra installs the packages used by docs/conf.py (Sphinx, MyST, Read the Docs theme):

[project.optional-dependencies]
docs = [
    "sphinx",
    "myst-parser",
    "sphinx-rtd-theme",
]

Test commands

pytest -q
ruff check .
pytest -q
ruff check .
mypy booktx

For docs (requires the docs extra), build with warnings as errors:

sphinx-build -W -b html docs docs/_build/html

Current test clusters

Test file

Area

tests/test_build.py

Markdown/EPUB build behavior

tests/test_chapters.py

Chapter detection

tests/test_chunking.py

Segmentation and packing

tests/test_cli.py

End-to-end CLI behavior

tests/test_cli_chapters.py

Chapter CLI workflows

tests/test_cli_context.py

Context CLI commands

tests/test_config.py

Project config and source discovery

tests/test_context_io.py

Context IO/rendering

tests/test_context_models.py

Context model contracts

tests/test_epub_io.py

EPUB extraction/rebuild

tests/test_html_io.py

XHTML helpers

tests/test_markdown_io.py

Markdown extraction/rebuild

tests/test_models.py

Pydantic contract models

tests/test_placeholders.py

Placeholder protection/restoration

tests/test_acceptance.py

Record-level acceptance gates

tests/test_cli_translate.py

Translate/insert CLI workflows

tests/test_profile_migration.py

Legacy -> profile migration

tests/test_profiles.py

Profile create/list/show/select

tests/test_progress.py

Progress snapshots

tests/test_status.py

Status bundles and overviews

tests/test_tasks_submissions.py

Task paths and submission parsing

tests/test_version.py

Translation version ledgers

tests/test_validate.py

Translation contract validation

tests/test_validate_context.py

Glossary/context validation

Coding standards

  • Keep changes deterministic and local.

  • Do not add network calls to the CLI.

  • Preserve idempotent extraction.

  • Preserve translated files across extraction.

  • Add tests for every behavior change.

  • Keep user-facing errors clear and actionable.

  • Prefer small format-specific adapters over cross-format special cases.

Versioning

Version data is generated by Hatch VCS into booktx/_version.py. Do not hand-edit generated version output.

Fresh-process CLI tests

Some CLI bugs only manifest when each command runs in a fresh Python process. The CliRunner used by most tests runs all commands in the same interpreter, which can mask import-order issues (e.g. Pydantic forward-reference rebuilds).

When a bug involves cross-command state or module initialization, add a test that uses subprocess.run to invoke booktx in separate processes. See tests/test_cli_translate_todo.py::test_todo_commands_work_across_fresh_python_processes for an example.

Durable model import contracts

Persisted JSON boundary models (TranslationTask, TranslationTodo, TranslationStoreV2, TranslationVersionLedger, context JSON models, manifest/config models) must validate without hidden import-order requirements.

Rules:

  • Never use TYPE_CHECKING-gated imports for types referenced in model fields.

  • Never depend on late model_rebuild() side effects for persisted models.

  • If a model references a type from another module, that type must be directly importable at module load time.

  • Add a test in tests/test_models.py that validates minimal payloads for each durable model without importing command-specific modules.