Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
38 changes: 38 additions & 0 deletions .github/workflows/test-suite.yml
Original file line number Diff line number Diff line change
Expand Up @@ -45,3 +45,41 @@ jobs:
files: ./coverage.xml
token: ${{ secrets.CODECOV_TOKEN }}
fail_ci_if_error: true

# Tripwire: prove the suite still passes against the community httpx forks.
# Advisory (continue-on-error) — a fork's own breakage shouldn't block PRs;
# flip continue-on-error to false to make compatibility a hard requirement.
fork-compat:
name: "Fork compat: ${{ matrix.backend }}"
runs-on: "ubuntu-latest"
continue-on-error: true

strategy:
fail-fast: false
matrix:
backend: ["httpxyz", "httpx2"]

env:
HTTPX_BACKEND: "${{ matrix.backend }}"

steps:
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
- uses: actions/setup-python@a309ff8b426b58ec0e2a45f0f869d46889d02405 # v6.2.0
with:
python-version: "3.13"
allow-prereleases: true

- name: Install uv
uses: astral-sh/setup-uv@08807647e7069bb48b6ef5acd8ec9567f424441b # v8.1.0
with:
python-version: "3.13"
version: "0.11.7"

- name: "Install dependencies"
run: uv sync --all-extras --dev

- name: "Install the ${{ matrix.backend }} fork"
run: uv pip install "${{ matrix.backend }}"

- name: "Run tests against ${{ matrix.backend }}"
run: "scripts/test-fork"
24 changes: 24 additions & 0 deletions scripts/fork-compat/sitecustomize.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
"""Redirect ``import httpx`` to a community fork, for CI compatibility testing.

This is *only* active when this directory is on ``PYTHONPATH`` **and** the
``HTTPX_BACKEND`` environment variable is set. Python imports ``sitecustomize``
automatically at interpreter startup — before pytest or ``httpx_retries`` import
``httpx`` — so the alias is guaranteed to win regardless of import order.

Used by ``scripts/test-fork``; a no-op in normal runs.
"""

import os
import sys

_backend = os.environ.get("HTTPX_BACKEND")

if _backend == "httpxyz":
# httpxyz registers itself as sys.modules["httpx"] on first import.
import httpxyz # type: ignore[import-not-found] # noqa: F401
elif _backend == "httpx2":
# httpx2 is a rename fork with no auto-alias, so wire it up ourselves.
# It preserves httpx's public API, which is all httpx-retries touches.
import httpx2 # type: ignore[import-not-found]

sys.modules["httpx"] = httpx2
19 changes: 19 additions & 0 deletions scripts/test-fork
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
#!/usr/bin/env bash

# Run the test suite against a community httpx fork (httpxyz or httpx2) to prove
# httpx-retries stays compatible. The fork must already be installed in .venv
# (e.g. `uv pip install httpxyz`). See scripts/fork-compat/sitecustomize.py.

set -euo pipefail

: "${HTTPX_BACKEND:?set HTTPX_BACKEND to httpxyz or httpx2}"

source .venv/bin/activate

# Put the sitecustomize shim on PYTHONPATH so `import httpx` resolves to the fork.
export PYTHONPATH="$(pwd)/scripts/fork-compat${PYTHONPATH:+:$PYTHONPATH}"

# Fail fast with a clear message if the shim didn't take effect.
python -c "import httpx, ${HTTPX_BACKEND} as fork; assert httpx is fork, f'shim inactive: httpx is {httpx.__name__}'; print(f'httpx -> {httpx.__name__} {getattr(httpx, \"__version__\", \"?\")}')"

pytest
Loading