Compare commits

..

1 Commits

Author SHA1 Message Date
Ben Beasley
b5addb64f0
Adapt test_response_decode_text_using_autodetect for chardet 6.0 (#3773) 2026-02-23 10:40:42 +00:00
15 changed files with 105 additions and 2052 deletions

View File

@ -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"

View File

@ -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
View 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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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"

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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)

View File

@ -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

View File

@ -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)

1972
uv.lock generated

File diff suppressed because it is too large Load Diff