Merge branch 'master' into async-dependencies-optional
This commit is contained in:
commit
40aa60c2c6
2
.github/workflows/publish.yml
vendored
2
.github/workflows/publish.yml
vendored
@ -14,7 +14,7 @@ jobs:
|
||||
name: deploy
|
||||
|
||||
steps:
|
||||
- uses: "actions/checkout@v3"
|
||||
- uses: "actions/checkout@v4"
|
||||
- uses: "actions/setup-python@v4"
|
||||
with:
|
||||
python-version: 3.8
|
||||
|
||||
5
.github/workflows/test-suite.yml
vendored
5
.github/workflows/test-suite.yml
vendored
@ -14,13 +14,14 @@ jobs:
|
||||
|
||||
strategy:
|
||||
matrix:
|
||||
python-version: ["3.8", "3.9", "3.10", "3.11"]
|
||||
python-version: ["3.8", "3.9", "3.10", "3.11", "3.12"]
|
||||
|
||||
steps:
|
||||
- uses: "actions/checkout@v3"
|
||||
- uses: "actions/checkout@v4"
|
||||
- uses: "actions/setup-python@v4"
|
||||
with:
|
||||
python-version: "${{ matrix.python-version }}"
|
||||
allow-prereleases: true
|
||||
- name: "Install dependencies"
|
||||
run: "scripts/install"
|
||||
- name: "Run linting checks"
|
||||
|
||||
@ -6,6 +6,10 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).
|
||||
|
||||
## Unreleased
|
||||
|
||||
### Added
|
||||
|
||||
* Add support for Python 3.12. (#2854)
|
||||
|
||||
### Fixed
|
||||
|
||||
* Raise `ValueError` on `Response.encoding` being set after `Response.text` has been accessed. (#2852)
|
||||
|
||||
@ -201,6 +201,10 @@ Besides, `httpx.Request()` does not support the `auth`, `timeout`, `follow_redir
|
||||
|
||||
If you need to mock HTTPX the same way that test utilities like `responses` and `requests-mock` does for `requests`, see [RESPX](https://github.com/lundberg/respx).
|
||||
|
||||
## Caching
|
||||
|
||||
If you use `cachecontrol` or `requests-cache` to add HTTP Caching support to the `requests` library, you can use [Hishel](https://hishel.com) for HTTPX.
|
||||
|
||||
## Networking layer
|
||||
|
||||
`requests` defers most of its HTTP networking code to the excellent [`urllib3` library](https://urllib3.readthedocs.io/en/latest/).
|
||||
|
||||
@ -16,9 +16,7 @@ except ImportError: # pragma: no cover
|
||||
except ImportError:
|
||||
brotli = None
|
||||
|
||||
if sys.version_info >= (3, 10) or (
|
||||
sys.version_info >= (3, 8) and ssl.OPENSSL_VERSION_INFO >= (1, 1, 0, 7)
|
||||
):
|
||||
if sys.version_info >= (3, 10) or ssl.OPENSSL_VERSION_INFO >= (1, 1, 0, 7):
|
||||
|
||||
def set_minimum_tls_version_1_2(context: ssl.SSLContext) -> None:
|
||||
# The OP_NO_SSL* and OP_NO_TLS* become deprecated in favor of
|
||||
|
||||
@ -1,7 +1,6 @@
|
||||
import logging
|
||||
import os
|
||||
import ssl
|
||||
import sys
|
||||
import typing
|
||||
from pathlib import Path
|
||||
|
||||
@ -128,11 +127,10 @@ class SSLConfig:
|
||||
|
||||
# Signal to server support for PHA in TLS 1.3. Raises an
|
||||
# AttributeError if only read-only access is implemented.
|
||||
if sys.version_info >= (3, 8): # pragma: no cover
|
||||
try:
|
||||
context.post_handshake_auth = True
|
||||
except AttributeError: # pragma: no cover
|
||||
pass
|
||||
try:
|
||||
context.post_handshake_auth = True
|
||||
except AttributeError: # pragma: no cover
|
||||
pass
|
||||
|
||||
# Disable using 'commonName' for SSLContext.check_hostname
|
||||
# when the 'subjectAltName' extension isn't available.
|
||||
@ -168,10 +166,9 @@ class SSLConfig:
|
||||
alpn_idents = ["http/1.1", "h2"] if self.http2 else ["http/1.1"]
|
||||
context.set_alpn_protocols(alpn_idents)
|
||||
|
||||
if sys.version_info >= (3, 8): # pragma: no cover
|
||||
keylogfile = os.environ.get("SSLKEYLOGFILE")
|
||||
if keylogfile and self.trust_env:
|
||||
context.keylog_filename = keylogfile
|
||||
keylogfile = os.environ.get("SSLKEYLOGFILE")
|
||||
if keylogfile and self.trust_env:
|
||||
context.keylog_filename = keylogfile
|
||||
|
||||
return context
|
||||
|
||||
|
||||
@ -87,7 +87,7 @@ COMPONENT_REGEX = {
|
||||
|
||||
# We use these simple regexs as a first pass before handing off to
|
||||
# the stdlib 'ipaddress' module for IP address validation.
|
||||
IPv4_STYLE_HOSTNAME = re.compile(r"^[0-9]+.[0-9]+.[0-9]+.[0-9]+$")
|
||||
IPv4_STYLE_HOSTNAME = re.compile(r"^[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+$")
|
||||
IPv6_STYLE_HOSTNAME = re.compile(r"^\[.*\]$")
|
||||
|
||||
|
||||
|
||||
@ -24,6 +24,7 @@ classifiers = [
|
||||
"Programming Language :: Python :: 3.9",
|
||||
"Programming Language :: Python :: 3.10",
|
||||
"Programming Language :: Python :: 3.11",
|
||||
"Programming Language :: Python :: 3.12",
|
||||
"Topic :: Internet :: WWW/HTTP",
|
||||
]
|
||||
dependencies = [
|
||||
|
||||
@ -10,22 +10,22 @@ chardet==5.2.0
|
||||
types-chardet==5.0.4.5
|
||||
|
||||
# Documentation
|
||||
mkdocs==1.5.2
|
||||
mkdocs==1.5.3
|
||||
mkautodoc==0.2.0
|
||||
mkdocs-material==9.2.6
|
||||
mkdocs-material==9.4.2
|
||||
|
||||
# Packaging
|
||||
build==0.10.0
|
||||
twine==4.0.2
|
||||
|
||||
# Tests & Linting
|
||||
black==23.7.0
|
||||
black==23.9.1
|
||||
coverage[toml]==7.3.0
|
||||
cryptography==41.0.3
|
||||
cryptography==41.0.4
|
||||
mypy==1.5.1
|
||||
types-certifi==2021.10.8.2
|
||||
pytest==7.4.0
|
||||
ruff==0.0.286
|
||||
pytest==7.4.2
|
||||
ruff==0.0.291
|
||||
trio-typing==0.8.0
|
||||
trustme==1.1.0
|
||||
uvicorn==0.22.0
|
||||
|
||||
@ -45,6 +45,12 @@ def test_urlparse_normalized_host():
|
||||
assert url.host == "example.com"
|
||||
|
||||
|
||||
def test_urlparse_ipv4_like_host():
|
||||
"""rare host names used to quality as IPv4"""
|
||||
url = httpx.URL("https://023b76x43144/")
|
||||
assert url.host == "023b76x43144"
|
||||
|
||||
|
||||
def test_urlparse_valid_ipv4():
|
||||
url = httpx.URL("https://1.2.3.4/")
|
||||
assert url.host == "1.2.3.4"
|
||||
|
||||
Loading…
Reference in New Issue
Block a user