# cryptography is only used by the cluster mTLS tests, to mint throwaway certs.
# It ships no win-arm64 wheel and can't build from source on that CI runner (no
# OpenSSL), so don't install it there; those tests importorskip it and self-skip
# when it's absent. Every other platform keeps full coverage.
cryptography; platform_machine != "ARM64" or sys_platform != "win32"
# orjson is the optional `speedups` extra, but the tests that cover the
# accelerated durable-state/gossip JSON paths are worthless if no CI cell ever
# installs it: they were importorskip-guarded and therefore skipped in all 12
# matrix cells, so the orjson arm of cronstable._json shipped unexercised.
# Installed here so `tox -e py` really runs it. Excluded where a wheel is not
# reliably available (win-arm64; a just-released Python that orjson has not
# built for yet) since it needs a Rust toolchain to build from source; those
# cells still self-skip via importorskip, and
# test_orjson_is_installed_where_a_wheel_exists fails if this line ever stops
# covering the cells that DO have wheels.
orjson>=3.11.6; python_version < "3.15" and (platform_machine != "ARM64" or sys_platform != "win32")
# pynacl backs the optional `push` extra (E2E-encrypted push alerts). Installed
# in dev unconditionally so the sealing/round-trip tests in tests/test_push.py
# really run in every CI cell: its cp38-abi3 wheels cover every runner we use
# (including win-arm64, unlike cryptography above), so no marker is needed;
# the tests still importorskip so a bare `pip install -e .` checkout can run
# the rest of the suite.
pynacl>=1.6.2
# zeroconf backs the optional `discovery` extra (the web.bonjour mDNS advert).
# Installed in dev for the same reason as pynacl above: without it every
# discovery test runs against hand-rolled fakes and a real-library signature
# change (ServiceInfo arguments, name validation) would ship with green CI,
# the exact optional-dep blind spot the orjson note above describes. It is
# pure Python with optional prebuilt speedups, so no platform marker is
# needed; the tests still importorskip so a bare checkout runs the rest.
zeroconf>=0.149.16
# playwright drives a real Chromium for the client/daemon cron-engine
# differential (tests/test_web_engine_parity.py), which replays the whole
# golden corpus through both the dashboard's own JavaScript schedule engine
# and the daemon's, and requires byte-identical fire instants and
# descriptions. It was in NEITHER dependency list, so that test
# importorskipped itself in every environment including all 12 CI cells, and
# the page's second engine shipped with nothing comparing it to the first:
# the same optional-dep blind spot the orjson note above describes. Excluded
# on win-arm64, the one runner with no playwright wheel; there is no sdist to
# fall back to, so an unmarked line would fail to resolve there rather than
# skip.
#
# pip installs the LIBRARY, not the browser. Chromium arrives only from a
# separate `playwright install chromium` step, so an environment that has this
# line but never ran that step still skips the differential (the test catches
# the launch failure and skips rather than erroring). This line covers only
# what pip can do; test_playwright_is_installed_where_a_wheel_exists in
# tests/test_dev_deps_parity.py fails if it is dropped or its marker stops
# covering the cells that DO have wheels.
playwright; platform_machine != "ARM64" or sys_platform != "win32"
# security linter; bandit[toml] reads its config from pyproject.toml.
bandit[toml]
mypy
mypy-extensions
# validates docs/openapi.yaml (see .github/scripts/check_openapi.py, tox -e openapi).
openapi-spec-validator
pytest
pytest-asyncio
pytest-cov
ruff
tox
# tox-uv makes tox provision envs and install deps with uv (see tox.ini).
tox-uv
