Script 'mail_helper' called by obssrc Hello community, here is the log from the commit of package python-httpcore for openSUSE:Factory checked in at 2023-12-09 22:49:04 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Comparing /work/SRC/openSUSE:Factory/python-httpcore (Old) and /work/SRC/openSUSE:Factory/.python-httpcore.new.25432 (New) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "python-httpcore" Sat Dec 9 22:49:04 2023 rev:13 rq:1131743 version:1.0.2 Changes: -------- --- /work/SRC/openSUSE:Factory/python-httpcore/python-httpcore.changes 2023-10-26 17:11:50.078574000 +0200 +++ /work/SRC/openSUSE:Factory/.python-httpcore.new.25432/python-httpcore.changes 2023-12-09 22:49:10.886693392 +0100 @@ -1,0 +2,19 @@ +Thu Dec 7 22:46:51 UTC 2023 - Dirk Müller <dmuel...@suse.com> + +- update to 1.0.2: + * Fix `float("inf")` timeouts in `Event.wait` function. (#846) + * Fix pool timeout to account for the total time spent + retrying. (#823) + * Raise a neater RuntimeError when the correct async deps are + not installed. (#826) + * Add support for synchronous TLS-in-TLS streams. (#840) + * From version 1.0 our async support is now optional, as the + package has minimal dependencies by default. + * For async support use either `pip install + 'httpcore[asyncio]'` or `pip install 'httpcore[trio]'`. + * The project versioning policy is now explicitly governed by + SEMVER. See https://semver.org/. + * Async support becomes fully optional. (#809) + * Add support for Python 3.12. (#807) + +------------------------------------------------------------------- Old: ---- httpcore-0.18.0.tar.gz New: ---- httpcore-1.0.2.tar.gz ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ python-httpcore.spec ++++++ --- /var/tmp/diff_new_pack.uccAIF/_old 2023-12-09 22:49:12.710759246 +0100 +++ /var/tmp/diff_new_pack.uccAIF/_new 2023-12-09 22:49:12.710759246 +0100 @@ -27,7 +27,7 @@ %{?sle15_python_module_pythons} Name: python-httpcore%{psuffix} -Version: 0.18.0 +Version: 1.0.2 Release: 0 Summary: Minimal low-level Python HTTP client License: BSD-3-Clause ++++++ httpcore-0.18.0.tar.gz -> httpcore-1.0.2.tar.gz ++++++ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/httpcore-0.18.0/.github/workflows/publish.yml new/httpcore-1.0.2/.github/workflows/publish.yml --- old/httpcore-0.18.0/.github/workflows/publish.yml 2023-09-08 15:37:47.000000000 +0200 +++ new/httpcore-1.0.2/.github/workflows/publish.yml 2023-11-10 14:35:57.000000000 +0100 @@ -14,7 +14,7 @@ name: deploy steps: - - uses: "actions/checkout@v3" + - uses: "actions/checkout@v4" - uses: "actions/setup-python@v4" with: python-version: 3.8 diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/httpcore-0.18.0/.github/workflows/test-suite.yml new/httpcore-1.0.2/.github/workflows/test-suite.yml --- old/httpcore-0.18.0/.github/workflows/test-suite.yml 2023-09-08 15:37:47.000000000 +0200 +++ new/httpcore-1.0.2/.github/workflows/test-suite.yml 2023-11-10 14:35:57.000000000 +0100 @@ -14,13 +14,14 @@ 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" diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/httpcore-0.18.0/CHANGELOG.md new/httpcore-1.0.2/CHANGELOG.md --- old/httpcore-0.18.0/CHANGELOG.md 2023-09-08 15:37:47.000000000 +0200 +++ new/httpcore-1.0.2/CHANGELOG.md 2023-11-10 14:35:57.000000000 +0100 @@ -4,6 +4,27 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/). +## 1.0.2 (November 10th, 2023) + +- Fix `float("inf")` timeouts in `Event.wait` function. (#846) + +## 1.0.1 (November 3rd, 2023) + +- Fix pool timeout to account for the total time spent retrying. (#823) +- Raise a neater RuntimeError when the correct async deps are not installed. (#826) +- Add support for synchronous TLS-in-TLS streams. (#840) + +## 1.0.0 (October 6th, 2023) + +From version 1.0 our async support is now optional, as the package has minimal dependencies by default. + +For async support use either `pip install 'httpcore[asyncio]'` or `pip install 'httpcore[trio]'`. + +The project versioning policy is now explicitly governed by SEMVER. See https://semver.org/. + +- Async support becomes fully optional. (#809) +- Add support for Python 3.12. (#807) + ## 0.18.0 (September 8th, 2023) - Add support for HTTPS proxies. (#745, #786) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/httpcore-0.18.0/README.md new/httpcore-1.0.2/README.md --- old/httpcore-0.18.0/README.md 2023-09-08 15:37:47.000000000 +0200 +++ new/httpcore-1.0.2/README.md 2023-11-10 14:35:57.000000000 +0100 @@ -35,16 +35,10 @@ $ pip install httpcore ``` -For HTTP/1.1 and HTTP/2 support, install with: +There are also a number of optional extras available... ```shell -$ pip install httpcore[http2] -``` - -For SOCKS proxy support, install with: - -```shell -$ pip install httpcore[socks] +$ pip install httpcore['asyncio,trio,http2,socks'] ``` # Sending requests @@ -89,3 +83,29 @@ * To provide a reusable low-level client library, that other packages can then build on top of. * To provide a *really clear interface split* between the networking code and client logic, so that each is easier to understand and reason about in isolation. + +## Dependencies + +The `httpcore` package has the following dependencies... + +* `h11` +* `certifi` + +And the following optional extras... + +* `anyio` - Required by `pip install httpcore['asyncio']`. +* `trio` - Required by `pip install httpcore['trio']`. +* `h2` - Required by `pip install httpcore['http2']`. +* `socksio` - Required by `pip install httpcore['socks']`. + +## Versioning + +We use [SEMVER for our versioning policy](https://semver.org/). + +For changes between package versions please see our [project changelog](CHANGELOG.md). + +We recommend pinning your requirements either the most current major version, or a more specific version range: + +```python +pip install 'httpcore==1.*' +``` diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/httpcore-0.18.0/docs/async.md new/httpcore-1.0.2/docs/async.md --- old/httpcore-0.18.0/docs/async.md 2023-09-08 15:37:47.000000000 +0200 +++ new/httpcore-1.0.2/docs/async.md 2023-11-10 14:35:57.000000000 +0100 @@ -8,6 +8,22 @@ Launching concurrent async tasks is far more resource efficient than spawning multiple threads. The Python interpreter should be able to comfortably handle switching between over 1000 concurrent tasks, while a sensible number of threads in a thread pool might be to enable around 10 or 20 concurrent threads. +## Enabling Async support + +If you're using async with [Python's stdlib `asyncio` support](https://docs.python.org/3/library/asyncio.html), install the optional dependencies using: + +```shell +$ pip install 'httpcore[asyncio]' +``` + +Alternatively, if you're working with [the Python `trio` package](https://trio.readthedocs.io/en/stable/): + +```shell +$ pip install 'httpcore[trio]' +``` + +We highly recommend `trio` for async support. The `trio` project [pioneered the principles of structured concurrency](https://en.wikipedia.org/wiki/Structured_concurrency), and has a more carefully constrained API against which to work from. + ## API differences When using async support, you need make sure to use an async connection pool class: diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/httpcore-0.18.0/docs/extensions.md new/httpcore-1.0.2/docs/extensions.md --- old/httpcore-0.18.0/docs/extensions.md 2023-09-08 15:37:47.000000000 +0200 +++ new/httpcore-1.0.2/docs/extensions.md 2023-11-10 14:35:57.000000000 +0100 @@ -147,6 +147,8 @@ * `"http2.receive_response_body"` * `"http2.response_closed"` +The exact set of trace events may be subject to change across different versions of `httpcore`. If you need to rely on a particular set of events it is recommended that you pin installation of the package to a fixed version. + ### `"sni_hostname"` The server's hostname, which is used to confirm the hostname supplied by the SSL certificate. diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/httpcore-0.18.0/docs/http2.md new/httpcore-1.0.2/docs/http2.md --- old/httpcore-0.18.0/docs/http2.md 2023-09-08 15:37:47.000000000 +0200 +++ new/httpcore-1.0.2/docs/http2.md 2023-11-10 14:35:57.000000000 +0100 @@ -15,7 +15,7 @@ If you're issuing highly concurrent requests you might want to consider trying out our HTTP/2 support. You can do so by first making sure to install the optional HTTP/2 dependencies... ```shell -$ pip install httpcore[http2] +$ pip install 'httpcore[http2]' ``` And then instantiating a connection pool with HTTP/2 support enabled: diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/httpcore-0.18.0/docs/proxies.md new/httpcore-1.0.2/docs/proxies.md --- old/httpcore-0.18.0/docs/proxies.md 2023-09-08 15:37:47.000000000 +0200 +++ new/httpcore-1.0.2/docs/proxies.md 2023-11-10 14:35:57.000000000 +0100 @@ -83,7 +83,7 @@ The `httpcore` package also supports proxies using the SOCKS5 protocol. -Make sure to install the optional dependancy using `pip install httpcore[socks]`. +Make sure to install the optional dependancy using `pip install 'httpcore[socks]'`. The `SOCKSProxy` class should be using instead of a standard connection pool: diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/httpcore-0.18.0/httpcore/__init__.py new/httpcore-1.0.2/httpcore/__init__.py --- old/httpcore-0.18.0/httpcore/__init__.py 2023-09-08 15:37:47.000000000 +0200 +++ new/httpcore-1.0.2/httpcore/__init__.py 2023-11-10 14:35:57.000000000 +0100 @@ -130,7 +130,7 @@ "WriteError", ] -__version__ = "0.18.0" +__version__ = "1.0.2" __locals = locals() diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/httpcore-0.18.0/httpcore/_async/connection_pool.py new/httpcore-1.0.2/httpcore/_async/connection_pool.py --- old/httpcore-0.18.0/httpcore/_async/connection_pool.py 2023-09-08 15:37:47.000000000 +0200 +++ new/httpcore-1.0.2/httpcore/_async/connection_pool.py 2023-11-10 14:35:57.000000000 +0100 @@ -1,11 +1,12 @@ import ssl import sys +import time from types import TracebackType from typing import AsyncIterable, AsyncIterator, Iterable, List, Optional, Type from .._backends.auto import AutoBackend from .._backends.base import SOCKET_OPTION, AsyncNetworkBackend -from .._exceptions import ConnectionNotAvailable, UnsupportedProtocol +from .._exceptions import ConnectionNotAvailable, PoolTimeout, UnsupportedProtocol from .._models import Origin, Request, Response from .._synchronization import AsyncEvent, AsyncLock, AsyncShieldCancellation from .connection import AsyncHTTPConnection @@ -220,6 +221,13 @@ ) status = RequestStatus(request) + timeouts = request.extensions.get("timeout", {}) + timeout = timeouts.get("pool", None) + + if timeout is not None: + deadline = time.monotonic() + timeout + else: + deadline = float("inf") async with self._pool_lock: self._requests.append(status) @@ -227,8 +235,6 @@ await self._attempt_to_acquire_connection(status) while True: - timeouts = request.extensions.get("timeout", {}) - timeout = timeouts.get("pool", None) try: connection = await status.wait_for_connection(timeout=timeout) except BaseException as exc: @@ -263,6 +269,10 @@ else: break + timeout = deadline - time.monotonic() + if timeout < 0: + raise PoolTimeout # pragma: nocover + # When we return the response, we wrap the stream in a special class # that handles notifying the connection pool once the response # has been released. @@ -316,6 +326,10 @@ self._requests = [] async def __aenter__(self) -> "AsyncConnectionPool": + # Acquiring the pool lock here ensures that we have the + # correct dependencies installed as early as possible. + async with self._pool_lock: + pass return self async def __aexit__( diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/httpcore-0.18.0/httpcore/_backends/auto.py new/httpcore-1.0.2/httpcore/_backends/auto.py --- old/httpcore-0.18.0/httpcore/_backends/auto.py 2023-09-08 15:37:47.000000000 +0200 +++ new/httpcore-1.0.2/httpcore/_backends/auto.py 2023-11-10 14:35:57.000000000 +0100 @@ -1,15 +1,14 @@ import typing from typing import Optional -import sniffio - +from .._synchronization import current_async_library from .base import SOCKET_OPTION, AsyncNetworkBackend, AsyncNetworkStream class AutoBackend(AsyncNetworkBackend): async def _init_backend(self) -> None: if not (hasattr(self, "_backend")): - backend = sniffio.current_async_library() + backend = current_async_library() if backend == "trio": from .trio import TrioBackend diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/httpcore-0.18.0/httpcore/_backends/sync.py new/httpcore-1.0.2/httpcore/_backends/sync.py --- old/httpcore-0.18.0/httpcore/_backends/sync.py 2023-09-08 15:37:47.000000000 +0200 +++ new/httpcore-1.0.2/httpcore/_backends/sync.py 2023-11-10 14:35:57.000000000 +0100 @@ -145,12 +145,6 @@ server_hostname: typing.Optional[str] = None, timeout: typing.Optional[float] = None, ) -> NetworkStream: - if isinstance(self._sock, ssl.SSLSocket): # pragma: no cover - raise RuntimeError( - "Attempted to add a TLS layer on top of the existing " - "TLS stream, which is not supported by httpcore package" - ) - exc_map: ExceptionMapping = { socket.timeout: ConnectTimeout, OSError: ConnectError, diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/httpcore-0.18.0/httpcore/_sync/connection_pool.py new/httpcore-1.0.2/httpcore/_sync/connection_pool.py --- old/httpcore-0.18.0/httpcore/_sync/connection_pool.py 2023-09-08 15:37:47.000000000 +0200 +++ new/httpcore-1.0.2/httpcore/_sync/connection_pool.py 2023-11-10 14:35:57.000000000 +0100 @@ -1,11 +1,12 @@ import ssl import sys +import time from types import TracebackType from typing import Iterable, Iterator, Iterable, List, Optional, Type from .._backends.sync import SyncBackend from .._backends.base import SOCKET_OPTION, NetworkBackend -from .._exceptions import ConnectionNotAvailable, UnsupportedProtocol +from .._exceptions import ConnectionNotAvailable, PoolTimeout, UnsupportedProtocol from .._models import Origin, Request, Response from .._synchronization import Event, Lock, ShieldCancellation from .connection import HTTPConnection @@ -220,6 +221,13 @@ ) status = RequestStatus(request) + timeouts = request.extensions.get("timeout", {}) + timeout = timeouts.get("pool", None) + + if timeout is not None: + deadline = time.monotonic() + timeout + else: + deadline = float("inf") with self._pool_lock: self._requests.append(status) @@ -227,8 +235,6 @@ self._attempt_to_acquire_connection(status) while True: - timeouts = request.extensions.get("timeout", {}) - timeout = timeouts.get("pool", None) try: connection = status.wait_for_connection(timeout=timeout) except BaseException as exc: @@ -263,6 +269,10 @@ else: break + timeout = deadline - time.monotonic() + if timeout < 0: + raise PoolTimeout # pragma: nocover + # When we return the response, we wrap the stream in a special class # that handles notifying the connection pool once the response # has been released. @@ -316,6 +326,10 @@ self._requests = [] def __enter__(self) -> "ConnectionPool": + # Acquiring the pool lock here ensures that we have the + # correct dependencies installed as early as possible. + with self._pool_lock: + pass return self def __exit__( diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/httpcore-0.18.0/httpcore/_synchronization.py new/httpcore-1.0.2/httpcore/_synchronization.py --- old/httpcore-0.18.0/httpcore/_synchronization.py 2023-09-08 15:37:47.000000000 +0200 +++ new/httpcore-1.0.2/httpcore/_synchronization.py 2023-11-10 14:35:57.000000000 +0100 @@ -2,8 +2,6 @@ from types import TracebackType from typing import Optional, Type -import sniffio - from ._exceptions import ExceptionMapping, PoolTimeout, map_exceptions # Our async synchronization primatives use either 'anyio' or 'trio' depending @@ -20,6 +18,32 @@ anyio = None # type: ignore +def current_async_library() -> str: + # Determine if we're running under trio or asyncio. + # See https://sniffio.readthedocs.io/en/latest/ + try: + import sniffio + except ImportError: # pragma: nocover + environment = "asyncio" + else: + environment = sniffio.current_async_library() + + if environment not in ("asyncio", "trio"): # pragma: nocover + raise RuntimeError("Running under an unsupported async environment.") + + if environment == "asyncio" and anyio is None: # pragma: nocover + raise RuntimeError( + "Running with asyncio requires installation of 'httpcore[asyncio]'." + ) + + if environment == "trio" and trio is None: # pragma: nocover + raise RuntimeError( + "Running with trio requires installation of 'httpcore[trio]'." + ) + + return environment + + class AsyncLock: def __init__(self) -> None: self._backend = "" @@ -29,18 +53,10 @@ Detect if we're running under 'asyncio' or 'trio' and create a lock with the correct implementation. """ - self._backend = sniffio.current_async_library() + self._backend = current_async_library() if self._backend == "trio": - if trio is None: # pragma: nocover - raise RuntimeError( - "Running under trio, requires the 'trio' package to be installed." - ) self._trio_lock = trio.Lock() - else: - if anyio is None: # pragma: nocover - raise RuntimeError( - "Running under asyncio requires the 'anyio' package to be installed." - ) + elif self._backend == "asyncio": self._anyio_lock = anyio.Lock() async def __aenter__(self) -> "AsyncLock": @@ -49,7 +65,7 @@ if self._backend == "trio": await self._trio_lock.acquire() - else: + elif self._backend == "asyncio": await self._anyio_lock.acquire() return self @@ -62,7 +78,7 @@ ) -> None: if self._backend == "trio": self._trio_lock.release() - else: + elif self._backend == "asyncio": self._anyio_lock.release() @@ -75,18 +91,10 @@ Detect if we're running under 'asyncio' or 'trio' and create a lock with the correct implementation. """ - self._backend = sniffio.current_async_library() + self._backend = current_async_library() if self._backend == "trio": - if trio is None: # pragma: nocover - raise RuntimeError( - "Running under trio requires the 'trio' package to be installed." - ) self._trio_event = trio.Event() - else: - if anyio is None: # pragma: nocover - raise RuntimeError( - "Running under asyncio requires the 'anyio' package to be installed." - ) + elif self._backend == "asyncio": self._anyio_event = anyio.Event() def set(self) -> None: @@ -95,7 +103,7 @@ if self._backend == "trio": self._trio_event.set() - else: + elif self._backend == "asyncio": self._anyio_event.set() async def wait(self, timeout: Optional[float] = None) -> None: @@ -103,22 +111,12 @@ self.setup() if self._backend == "trio": - if trio is None: # pragma: nocover - raise RuntimeError( - "Running under trio requires the 'trio' package to be installed." - ) - trio_exc_map: ExceptionMapping = {trio.TooSlowError: PoolTimeout} timeout_or_inf = float("inf") if timeout is None else timeout with map_exceptions(trio_exc_map): with trio.fail_after(timeout_or_inf): await self._trio_event.wait() - else: - if anyio is None: # pragma: nocover - raise RuntimeError( - "Running under asyncio requires the 'anyio' package to be installed." - ) - + elif self._backend == "asyncio": anyio_exc_map: ExceptionMapping = {TimeoutError: PoolTimeout} with map_exceptions(anyio_exc_map): with anyio.fail_after(timeout): @@ -135,22 +133,12 @@ Detect if we're running under 'asyncio' or 'trio' and create a semaphore with the correct implementation. """ - self._backend = sniffio.current_async_library() + self._backend = current_async_library() if self._backend == "trio": - if trio is None: # pragma: nocover - raise RuntimeError( - "Running under trio requires the 'trio' package to be installed." - ) - self._trio_semaphore = trio.Semaphore( initial_value=self._bound, max_value=self._bound ) - else: - if anyio is None: # pragma: nocover - raise RuntimeError( - "Running under asyncio requires the 'anyio' package to be installed." - ) - + elif self._backend == "asyncio": self._anyio_semaphore = anyio.Semaphore( initial_value=self._bound, max_value=self._bound ) @@ -161,13 +149,13 @@ if self._backend == "trio": await self._trio_semaphore.acquire() - else: + elif self._backend == "asyncio": await self._anyio_semaphore.acquire() async def release(self) -> None: if self._backend == "trio": self._trio_semaphore.release() - else: + elif self._backend == "asyncio": self._anyio_semaphore.release() @@ -184,27 +172,17 @@ Detect if we're running under 'asyncio' or 'trio' and create a shielded scope with the correct implementation. """ - self._backend = sniffio.current_async_library() + self._backend = current_async_library() if self._backend == "trio": - if trio is None: # pragma: nocover - raise RuntimeError( - "Running under trio requires the 'trio' package to be installed." - ) - self._trio_shield = trio.CancelScope(shield=True) - else: - if anyio is None: # pragma: nocover - raise RuntimeError( - "Running under asyncio requires the 'anyio' package to be installed." - ) - + elif self._backend == "asyncio": self._anyio_shield = anyio.CancelScope(shield=True) def __enter__(self) -> "AsyncShieldCancellation": if self._backend == "trio": self._trio_shield.__enter__() - else: + elif self._backend == "asyncio": self._anyio_shield.__enter__() return self @@ -216,7 +194,7 @@ ) -> None: if self._backend == "trio": self._trio_shield.__exit__(exc_type, exc_value, traceback) - else: + elif self._backend == "asyncio": self._anyio_shield.__exit__(exc_type, exc_value, traceback) @@ -248,6 +226,8 @@ self._event.set() def wait(self, timeout: Optional[float] = None) -> None: + if timeout == float("inf"): # pragma: no cover + timeout = None if not self._event.wait(timeout=timeout): raise PoolTimeout() # pragma: nocover diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/httpcore-0.18.0/pyproject.toml new/httpcore-1.0.2/pyproject.toml --- old/httpcore-0.18.0/pyproject.toml 2023-09-08 15:37:47.000000000 +0200 +++ new/httpcore-1.0.2/pyproject.toml 2023-11-10 14:35:57.000000000 +0100 @@ -25,13 +25,12 @@ "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 = [ - "anyio>=3.0,<5.0", "certifi", "h11>=0.13,<0.15", - "sniffio==1.*", ] [project.optional-dependencies] @@ -41,6 +40,12 @@ socks = [ "socksio==1.*", ] +trio = [ + "trio>=0.22.0,<0.23.0", +] +asyncio = [ + "anyio>=4.0,<5.0", +] [project.urls] Documentation = "https://www.encode.io/httpcore" @@ -55,6 +60,7 @@ "/httpcore", "/CHANGELOG.md", "/README.md", + "/tests" ] [tool.hatch.metadata.hooks.fancy-pypi-readme] diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/httpcore-0.18.0/requirements.txt new/httpcore-1.0.2/requirements.txt --- old/httpcore-0.18.0/requirements.txt 2023-09-08 15:37:47.000000000 +0200 +++ new/httpcore-1.0.2/requirements.txt 2023-11-10 14:35:57.000000000 +0100 @@ -1,29 +1,25 @@ --e .[http2,socks] - -# Optionals -trio==0.21.0 +-e .[asyncio,trio,http2,socks] # Docs -mkdocs==1.4.2 +mkdocs==1.5.3 mkdocs-autorefs==0.5.0 -mkdocs-material==9.1.15 -mkdocs-material-extensions==1.1.1 +mkdocs-material==9.4.7 +mkdocs-material-extensions==1.3 mkdocstrings[python-legacy]==0.22.0 jinja2==3.1.2 # Packaging -build==0.10.0 +build==1.0.3 twine # Tests & Linting -anyio==3.7.1 -black==23.7.0 +black==23.10.1 coverage[toml]==7.3.0 -ruff==0.0.277 +ruff==0.1.3 mypy==1.5.1 -trio-typing==0.8.0 +trio-typing==0.9.0 types-certifi==2021.10.8.3 -pytest==7.4.0 +pytest==7.4.3 pytest-httpbin==2.0.0 pytest-trio==0.7.0 werkzeug<2.1 # See: https://github.com/postmanlabs/httpbin/issues/673 diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/httpcore-0.18.0/tests/test_cancellations.py new/httpcore-1.0.2/tests/test_cancellations.py --- old/httpcore-0.18.0/tests/test_cancellations.py 2023-09-08 15:37:47.000000000 +0200 +++ new/httpcore-1.0.2/tests/test_cancellations.py 2023-11-10 14:35:57.000000000 +0100 @@ -171,6 +171,7 @@ assert conn.is_closed() +@pytest.mark.xfail @pytest.mark.anyio async def test_h2_timeout_during_handshake(): """ @@ -185,6 +186,7 @@ assert conn.is_closed() +@pytest.mark.xfail @pytest.mark.anyio async def test_h2_timeout_during_request(): """ @@ -205,6 +207,7 @@ assert conn.is_idle() +@pytest.mark.xfail @pytest.mark.anyio async def test_h2_timeout_during_response(): """