Compare commits
1 Commits
support-3-
...
master
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
b5addb64f0 |
10
.github/workflows/test-suite.yml
vendored
10
.github/workflows/test-suite.yml
vendored
@ -14,16 +14,14 @@ jobs:
|
|||||||
|
|
||||||
strategy:
|
strategy:
|
||||||
matrix:
|
matrix:
|
||||||
python-version: ["3.9", "3.10", "3.11", "3.12", "3.13", "3.14"]
|
python-version: ["3.9", "3.10", "3.11", "3.12", "3.13"]
|
||||||
|
|
||||||
steps:
|
steps:
|
||||||
- uses: "actions/checkout@v4"
|
- uses: "actions/checkout@v4"
|
||||||
- name: Install uv (official Astral action)
|
- uses: "actions/setup-python@v6"
|
||||||
uses: astral-sh/setup-uv@v5
|
|
||||||
with:
|
with:
|
||||||
version: "0.9.13"
|
python-version: "${{ matrix.python-version }}"
|
||||||
enable-cache: true
|
allow-prereleases: true
|
||||||
python-version: ${{ matrix.python-version }}
|
|
||||||
- name: "Install dependencies"
|
- name: "Install dependencies"
|
||||||
run: "scripts/install"
|
run: "scripts/install"
|
||||||
- name: "Run linting checks"
|
- name: "Run linting checks"
|
||||||
|
|||||||
@ -25,7 +25,6 @@ classifiers = [
|
|||||||
"Programming Language :: Python :: 3.11",
|
"Programming Language :: Python :: 3.11",
|
||||||
"Programming Language :: Python :: 3.12",
|
"Programming Language :: Python :: 3.12",
|
||||||
"Programming Language :: Python :: 3.13",
|
"Programming Language :: Python :: 3.13",
|
||||||
"Programming Language :: Python :: 3.14",
|
|
||||||
"Topic :: Internet :: WWW/HTTP",
|
"Topic :: Internet :: WWW/HTTP",
|
||||||
]
|
]
|
||||||
dependencies = [
|
dependencies = [
|
||||||
@ -65,40 +64,6 @@ Documentation = "https://www.python-httpx.org"
|
|||||||
Homepage = "https://github.com/encode/httpx"
|
Homepage = "https://github.com/encode/httpx"
|
||||||
Source = "https://github.com/encode/httpx"
|
Source = "https://github.com/encode/httpx"
|
||||||
|
|
||||||
[dependency-groups]
|
|
||||||
dev = [
|
|
||||||
# Install httpx with all optional dependencies
|
|
||||||
{ include-group = "test" },
|
|
||||||
{ include-group = "docs" },
|
|
||||||
{ include-group = "package" },
|
|
||||||
{ include-group = "lint" },
|
|
||||||
]
|
|
||||||
test = [
|
|
||||||
# Optional charset auto-detection (used in test cases)
|
|
||||||
"chardet==5.2.0",
|
|
||||||
# Testing dependencies
|
|
||||||
"coverage[toml]==7.10.6",
|
|
||||||
"cryptography==45.0.7",
|
|
||||||
"pytest==8.4.1",
|
|
||||||
"trio==0.31.0",
|
|
||||||
"trio-typing==0.10.0",
|
|
||||||
"trustme==1.2.1",
|
|
||||||
"uvicorn==0.38.0",
|
|
||||||
]
|
|
||||||
docs = [
|
|
||||||
"mkdocs==1.6.1",
|
|
||||||
"mkautodoc==0.2.0",
|
|
||||||
"mkdocs-material==9.6.18",
|
|
||||||
]
|
|
||||||
package = [
|
|
||||||
"build==1.3.0",
|
|
||||||
"twine==6.1.0",
|
|
||||||
]
|
|
||||||
lint = [
|
|
||||||
"mypy==1.17.1",
|
|
||||||
"ruff==0.12.11",
|
|
||||||
]
|
|
||||||
|
|
||||||
[tool.hatch.version]
|
[tool.hatch.version]
|
||||||
path = "httpx/__version__.py"
|
path = "httpx/__version__.py"
|
||||||
|
|
||||||
|
|||||||
29
requirements.txt
Normal file
29
requirements.txt
Normal file
@ -0,0 +1,29 @@
|
|||||||
|
# We're pinning our tooling, because it's an environment we can strictly control.
|
||||||
|
# On the other hand, we're not pinning package dependencies, because our tests
|
||||||
|
# needs to pass with the latest version of the packages.
|
||||||
|
# Reference: https://github.com/encode/httpx/pull/1721#discussion_r661241588
|
||||||
|
-e .[brotli,cli,http2,socks,zstd]
|
||||||
|
|
||||||
|
# Optional charset auto-detection
|
||||||
|
# Used in our test cases
|
||||||
|
chardet==5.2.0
|
||||||
|
|
||||||
|
# Documentation
|
||||||
|
mkdocs==1.6.1
|
||||||
|
mkautodoc==0.2.0
|
||||||
|
mkdocs-material==9.6.18
|
||||||
|
|
||||||
|
# Packaging
|
||||||
|
build==1.3.0
|
||||||
|
twine==6.1.0
|
||||||
|
|
||||||
|
# Tests & Linting
|
||||||
|
coverage[toml]==7.10.6
|
||||||
|
cryptography==45.0.7
|
||||||
|
mypy==1.17.1
|
||||||
|
pytest==8.4.1
|
||||||
|
ruff==0.12.11
|
||||||
|
trio==0.31.0
|
||||||
|
trio-typing==0.10.0
|
||||||
|
trustme==1.2.1
|
||||||
|
uvicorn==0.35.0
|
||||||
@ -1,7 +1,13 @@
|
|||||||
#!/bin/sh -e
|
#!/bin/sh -e
|
||||||
|
|
||||||
|
if [ -d 'venv' ] ; then
|
||||||
|
PREFIX="venv/bin/"
|
||||||
|
else
|
||||||
|
PREFIX=""
|
||||||
|
fi
|
||||||
|
|
||||||
set -x
|
set -x
|
||||||
|
|
||||||
uv run python -m build
|
${PREFIX}python -m build
|
||||||
uv run twine check dist/*
|
${PREFIX}twine check dist/*
|
||||||
uv run mkdocs build
|
${PREFIX}mkdocs build
|
||||||
|
|||||||
@ -1,16 +1,14 @@
|
|||||||
#!/bin/sh -e
|
#!/bin/sh -e
|
||||||
|
|
||||||
|
export PREFIX=""
|
||||||
|
if [ -d 'venv' ] ; then
|
||||||
|
export PREFIX="venv/bin/"
|
||||||
|
fi
|
||||||
export SOURCE_FILES="httpx tests"
|
export SOURCE_FILES="httpx tests"
|
||||||
|
|
||||||
set -x
|
set -x
|
||||||
|
|
||||||
./scripts/sync-version
|
./scripts/sync-version
|
||||||
|
${PREFIX}ruff format $SOURCE_FILES --diff
|
||||||
echo "==> Checking formatting…"
|
${PREFIX}mypy $SOURCE_FILES
|
||||||
uv run ruff format $SOURCE_FILES --diff
|
${PREFIX}ruff check $SOURCE_FILES
|
||||||
|
|
||||||
echo "==> Running type checks and linting…"
|
|
||||||
uv run mypy $SOURCE_FILES
|
|
||||||
|
|
||||||
echo "==> Running linting checks…"
|
|
||||||
uv run ruff check $SOURCE_FILES
|
|
||||||
|
|||||||
@ -1,7 +1,11 @@
|
|||||||
#!/bin/sh -e
|
#!/bin/sh -e
|
||||||
|
|
||||||
|
export PREFIX=""
|
||||||
|
if [ -d 'venv' ] ; then
|
||||||
|
export PREFIX="venv/bin/"
|
||||||
|
fi
|
||||||
export SOURCE_FILES="httpx tests"
|
export SOURCE_FILES="httpx tests"
|
||||||
|
|
||||||
set -x
|
set -x
|
||||||
|
|
||||||
uv run coverage report --show-missing --skip-covered --fail-under=100
|
${PREFIX}coverage report --show-missing --skip-covered --fail-under=100
|
||||||
|
|||||||
@ -1,5 +1,10 @@
|
|||||||
#!/bin/sh -e
|
#!/bin/sh -e
|
||||||
|
|
||||||
|
export PREFIX=""
|
||||||
|
if [ -d 'venv' ] ; then
|
||||||
|
export PREFIX="venv/bin/"
|
||||||
|
fi
|
||||||
|
|
||||||
set -x
|
set -x
|
||||||
|
|
||||||
uv run mkdocs serve
|
${PREFIX}mkdocs serve
|
||||||
|
|||||||
@ -1,4 +1,19 @@
|
|||||||
#!/bin/sh -e
|
#!/bin/sh -e
|
||||||
|
|
||||||
echo "==> Installing Python dependencies…"
|
# Use the Python executable provided from the `-p` option, or a default.
|
||||||
uv sync --all-extras
|
[ "$1" = "-p" ] && PYTHON=$2 || PYTHON="python3"
|
||||||
|
|
||||||
|
REQUIREMENTS="requirements.txt"
|
||||||
|
VENV="venv"
|
||||||
|
|
||||||
|
set -x
|
||||||
|
|
||||||
|
if [ -z "$GITHUB_ACTIONS" ]; then
|
||||||
|
"$PYTHON" -m venv "$VENV"
|
||||||
|
PIP="$VENV/bin/pip"
|
||||||
|
else
|
||||||
|
PIP="pip"
|
||||||
|
fi
|
||||||
|
|
||||||
|
"$PIP" install -U pip
|
||||||
|
"$PIP" install -r "$REQUIREMENTS"
|
||||||
|
|||||||
11
scripts/lint
11
scripts/lint
@ -1,11 +1,12 @@
|
|||||||
#!/bin/sh -e
|
#!/bin/sh -e
|
||||||
|
|
||||||
|
export PREFIX=""
|
||||||
|
if [ -d 'venv' ]; then
|
||||||
|
export PREFIX="venv/bin/"
|
||||||
|
fi
|
||||||
export SOURCE_FILES="httpx tests"
|
export SOURCE_FILES="httpx tests"
|
||||||
|
|
||||||
set -x
|
set -x
|
||||||
|
|
||||||
echo "==> Running linting checks…"
|
${PREFIX}ruff check --fix $SOURCE_FILES
|
||||||
uv run ruff check --fix $SOURCE_FILES
|
${PREFIX}ruff format $SOURCE_FILES
|
||||||
|
|
||||||
echo "==> Formatting source code…"
|
|
||||||
uv run ruff format $SOURCE_FILES
|
|
||||||
|
|||||||
@ -2,6 +2,11 @@
|
|||||||
|
|
||||||
VERSION_FILE="httpx/__version__.py"
|
VERSION_FILE="httpx/__version__.py"
|
||||||
|
|
||||||
|
if [ -d 'venv' ] ; then
|
||||||
|
PREFIX="venv/bin/"
|
||||||
|
else
|
||||||
|
PREFIX=""
|
||||||
|
fi
|
||||||
|
|
||||||
if [ ! -z "$GITHUB_ACTIONS" ]; then
|
if [ ! -z "$GITHUB_ACTIONS" ]; then
|
||||||
git config --local user.email "41898282+github-actions[bot]@users.noreply.github.com"
|
git config --local user.email "41898282+github-actions[bot]@users.noreply.github.com"
|
||||||
@ -17,5 +22,5 @@ fi
|
|||||||
|
|
||||||
set -x
|
set -x
|
||||||
|
|
||||||
uv run twine upload dist/*
|
${PREFIX}twine upload dist/*
|
||||||
uv run mkdocs gh-deploy --force
|
${PREFIX}mkdocs gh-deploy --force
|
||||||
|
|||||||
@ -1,12 +1,17 @@
|
|||||||
#!/bin/sh
|
#!/bin/sh
|
||||||
|
|
||||||
|
export PREFIX=""
|
||||||
|
if [ -d 'venv' ] ; then
|
||||||
|
export PREFIX="venv/bin/"
|
||||||
|
fi
|
||||||
|
|
||||||
set -ex
|
set -ex
|
||||||
|
|
||||||
if [ -z $GITHUB_ACTIONS ]; then
|
if [ -z $GITHUB_ACTIONS ]; then
|
||||||
scripts/check
|
scripts/check
|
||||||
fi
|
fi
|
||||||
|
|
||||||
uv run coverage run -m pytest "$@"
|
${PREFIX}coverage run -m pytest "$@"
|
||||||
|
|
||||||
if [ -z $GITHUB_ACTIONS ]; then
|
if [ -z $GITHUB_ACTIONS ]; then
|
||||||
scripts/coverage
|
scripts/coverage
|
||||||
|
|||||||
@ -235,9 +235,10 @@ class TestServer(Server):
|
|||||||
async def serve(self, sockets=None):
|
async def serve(self, sockets=None):
|
||||||
self.restart_requested = asyncio.Event()
|
self.restart_requested = asyncio.Event()
|
||||||
|
|
||||||
|
loop = asyncio.get_event_loop()
|
||||||
tasks = {
|
tasks = {
|
||||||
asyncio.create_task(super().serve(sockets=sockets)),
|
loop.create_task(super().serve(sockets=sockets)),
|
||||||
asyncio.create_task(self.watch_restarts()),
|
loop.create_task(self.watch_restarts()),
|
||||||
}
|
}
|
||||||
await asyncio.wait(tasks)
|
await asyncio.wait(tasks)
|
||||||
|
|
||||||
@ -268,15 +269,7 @@ class TestServer(Server):
|
|||||||
|
|
||||||
|
|
||||||
def serve_in_thread(server: TestServer) -> typing.Iterator[TestServer]:
|
def serve_in_thread(server: TestServer) -> typing.Iterator[TestServer]:
|
||||||
def run_server() -> None:
|
thread = threading.Thread(target=server.run)
|
||||||
loop = asyncio.new_event_loop()
|
|
||||||
asyncio.set_event_loop(loop)
|
|
||||||
try:
|
|
||||||
loop.run_until_complete(server.serve()) # type: ignore
|
|
||||||
finally:
|
|
||||||
loop.close()
|
|
||||||
|
|
||||||
thread = threading.Thread(target=run_server)
|
|
||||||
thread.start()
|
thread.start()
|
||||||
try:
|
try:
|
||||||
while not server.started:
|
while not server.started:
|
||||||
@ -289,6 +282,6 @@ def serve_in_thread(server: TestServer) -> typing.Iterator[TestServer]:
|
|||||||
|
|
||||||
@pytest.fixture(scope="session")
|
@pytest.fixture(scope="session")
|
||||||
def server() -> typing.Iterator[TestServer]:
|
def server() -> typing.Iterator[TestServer]:
|
||||||
config = Config(app=app, lifespan="off")
|
config = Config(app=app, lifespan="off", loop="asyncio")
|
||||||
server = TestServer(config=config)
|
server = TestServer(config=config)
|
||||||
yield from serve_in_thread(server)
|
yield from serve_in_thread(server)
|
||||||
|
|||||||
@ -1011,7 +1011,10 @@ def test_response_decode_text_using_autodetect():
|
|||||||
|
|
||||||
assert response.status_code == 200
|
assert response.status_code == 200
|
||||||
assert response.reason_phrase == "OK"
|
assert response.reason_phrase == "OK"
|
||||||
assert response.encoding == "ISO-8859-1"
|
# The encoded byte string is consistent with either ISO-8859-1 or
|
||||||
|
# WINDOWS-1252. Versions <6.0 of chardet claim the former, while chardet
|
||||||
|
# 6.0 detects the latter.
|
||||||
|
assert response.encoding in ("ISO-8859-1", "WINDOWS-1252")
|
||||||
assert response.text == text
|
assert response.text == text
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@ -12,8 +12,6 @@ async def test_read_timeout(server):
|
|||||||
await client.get(server.url.copy_with(path="/slow_response"))
|
await client.get(server.url.copy_with(path="/slow_response"))
|
||||||
|
|
||||||
|
|
||||||
# TODO: Fix ResourceWarning in this test for Python>=3.14
|
|
||||||
@pytest.mark.filterwarnings("ignore::ResourceWarning")
|
|
||||||
@pytest.mark.anyio
|
@pytest.mark.anyio
|
||||||
async def test_write_timeout(server):
|
async def test_write_timeout(server):
|
||||||
timeout = httpx.Timeout(None, write=1e-6)
|
timeout = httpx.Timeout(None, write=1e-6)
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user