# cryptography backs two test arms: the cluster mTLS tests mint throwaway
# certs with it, and the X-Wing push-sealing tests in tests/test_push.py use
# its HPKE module (stock wheels carry working ML-KEM from 48, hence the
# floor). It publishes wheels for a subset of the platforms cronstable
# targets, and a CI runner off that list has neither the Rust toolchain nor
# the OpenSSL headers to build the sdist, so the markers are the same two
# lines the push extra carries: Linux x86_64/aarch64, macOS arm64 and
# Windows amd64 take the newest release; Intel macOS and 32-bit Windows take
# 48.x, the last line with a wheel for them (pyproject.toml says why the cap
# is acceptable). Both test arms importorskip it, so the win-arm64 cell
# self-skips those tests and every other cell keeps full coverage.
#
# `platform_machine` is the raw `uname -m`, so a 32-bit userland on a 64-bit
# kernel passes this marker, finds no i686 wheel, and fails the sdist build
# for want of Rust. Use `linux32 pip install -r requirements_dev.txt` there:
# uname reports 32-bit, dropping cryptography so both test arms self-skip.
cryptography>=48; (sys_platform == "linux" and (platform_machine == "x86_64" or platform_machine == "aarch64")) or (sys_platform == "darwin" and platform_machine == "arm64") or (sys_platform == "win32" and platform_machine == "AMD64")
cryptography>=48,<49; (sys_platform == "darwin" and platform_machine == "x86_64") or (sys_platform == "win32" and platform_machine == "x86")
# 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
