Script 'mail_helper' called by obssrc
Hello community,
here is the log from the commit of package python-httpx-ws for openSUSE:Factory
checked in at 2024-11-14 16:08:56
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/python-httpx-ws (Old)
and /work/SRC/openSUSE:Factory/.python-httpx-ws.new.2017 (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "python-httpx-ws"
Thu Nov 14 16:08:56 2024 rev:2 rq:1223990 version:0.6.2
Changes:
--------
--- /work/SRC/openSUSE:Factory/python-httpx-ws/python-httpx-ws.changes
2024-09-05 15:47:09.884014619 +0200
+++
/work/SRC/openSUSE:Factory/.python-httpx-ws.new.2017/python-httpx-ws.changes
2024-11-14 16:09:55.077856788 +0100
@@ -1,0 +2,10 @@
+Wed Nov 13 15:14:59 UTC 2024 - Dirk Müller <[email protected]>
+
+- update to 0.6.2:
+ * Improve efficiency of WebSocketSession by reusing a single
+ thread pool when waiting for messages
+ * Fix (#73) anyio misusages
+ * Fix (#74) unclosed anyio streams
+ * Fix (#76) memory leak with non-async WebSocketSession
+
+-------------------------------------------------------------------
Old:
----
httpx_ws-0.6.0.tar.gz
New:
----
httpx_ws-0.6.2.tar.gz
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Other differences:
------------------
++++++ python-httpx-ws.spec ++++++
--- /var/tmp/diff_new_pack.hFRY0w/_old 2024-11-14 16:09:58.157985419 +0100
+++ /var/tmp/diff_new_pack.hFRY0w/_new 2024-11-14 16:09:58.157985419 +0100
@@ -17,7 +17,7 @@
Name: python-httpx-ws
-Version: 0.6.0
+Version: 0.6.2
Release: 0
Summary: WebSockets support for HTTPX
License: MIT
++++++ httpx_ws-0.6.0.tar.gz -> httpx_ws-0.6.2.tar.gz ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/httpx_ws-0.6.0/.all-contributorsrc
new/httpx_ws-0.6.2/.all-contributorsrc
--- old/httpx_ws-0.6.0/.all-contributorsrc 2020-02-02 01:00:00.000000000
+0100
+++ new/httpx_ws-0.6.2/.all-contributorsrc 2020-02-02 01:00:00.000000000
+0100
@@ -31,7 +31,8 @@
"avatar_url": "https://avatars.githubusercontent.com/u/4711805?v=4",
"profile": "https://github.com/davidbrochart",
"contributions": [
- "platform"
+ "platform",
+ "code"
]
},
{
@@ -109,6 +110,26 @@
"contributions": [
"code"
]
+ },
+ {
+ "login": "agronholm",
+ "name": "Alex Grönholm",
+ "avatar_url": "https://avatars.githubusercontent.com/u/130003?v=4",
+ "profile": "https://github.com/agronholm",
+ "contributions": [
+ "bug",
+ "code"
+ ]
+ },
+ {
+ "login": "ro-oliveira95",
+ "name": "Rodrigo de Oliveira Neto",
+ "avatar_url": "https://avatars.githubusercontent.com/u/27009864?v=4",
+ "profile": "https://github.com/ro-oliveira95",
+ "contributions": [
+ "bug",
+ "code"
+ ]
}
],
"contributorsPerLine": 7,
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/httpx_ws-0.6.0/PKG-INFO new/httpx_ws-0.6.2/PKG-INFO
--- old/httpx_ws-0.6.0/PKG-INFO 2020-02-02 01:00:00.000000000 +0100
+++ new/httpx_ws-0.6.2/PKG-INFO 2020-02-02 01:00:00.000000000 +0100
@@ -1,6 +1,6 @@
Metadata-Version: 2.3
Name: httpx-ws
-Version: 0.6.0
+Version: 0.6.2
Summary: WebSockets support for HTTPX
Project-URL: Documentation, https://frankie567.github.io/httpx-ws/
Project-URL: Source, https://github.com/frankie567/httpx-ws
@@ -81,7 +81,7 @@
<tr>
<td align="center" valign="top" width="14.28%"><a
href="http://francoisvoron.com"><img
src="https://avatars.githubusercontent.com/u/1144727?v=4?s=100" width="100px;"
alt="François Voron"/><br /><sub><b>François Voron</b></sub></a><br /><a
href="#maintenance-frankie567" title="Maintenance">ð§</a> <a
href="https://github.com/frankie567/httpx-ws/commits?author=frankie567"
title="Code">ð»</a></td>
<td align="center" valign="top" width="14.28%"><a
href="http://kousikmitra.github.io"><img
src="https://avatars.githubusercontent.com/u/15109533?v=4?s=100" width="100px;"
alt="Kousik Mitra"/><br /><sub><b>Kousik Mitra</b></sub></a><br /><a
href="https://github.com/frankie567/httpx-ws/commits?author=kousikmitra"
title="Code">ð»</a></td>
- <td align="center" valign="top" width="14.28%"><a
href="https://github.com/davidbrochart"><img
src="https://avatars.githubusercontent.com/u/4711805?v=4?s=100" width="100px;"
alt="David Brochart"/><br /><sub><b>David Brochart</b></sub></a><br /><a
href="#platform-davidbrochart" title="Packaging/porting to new
platform">ð¦</a></td>
+ <td align="center" valign="top" width="14.28%"><a
href="https://github.com/davidbrochart"><img
src="https://avatars.githubusercontent.com/u/4711805?v=4?s=100" width="100px;"
alt="David Brochart"/><br /><sub><b>David Brochart</b></sub></a><br /><a
href="#platform-davidbrochart" title="Packaging/porting to new
platform">ð¦</a> <a
href="https://github.com/frankie567/httpx-ws/commits?author=davidbrochart"
title="Code">ð»</a></td>
<td align="center" valign="top" width="14.28%"><a
href="https://github.com/ysmu"><img
src="https://avatars.githubusercontent.com/u/17018576?v=4?s=100" width="100px;"
alt="ysmu"/><br /><sub><b>ysmu</b></sub></a><br /><a
href="https://github.com/frankie567/httpx-ws/issues?q=author%3Aysmu" title="Bug
reports">ð</a></td>
<td align="center" valign="top" width="14.28%"><a
href="https://samforeman.me"><img
src="https://avatars.githubusercontent.com/u/5234251?v=4?s=100" width="100px;"
alt="Sam Foreman"/><br /><sub><b>Sam Foreman</b></sub></a><br /><a
href="https://github.com/frankie567/httpx-ws/issues?q=author%3Asaforem2"
title="Bug reports">ð</a></td>
<td align="center" valign="top" width="14.28%"><a
href="http://maparent.ca/"><img
src="https://avatars.githubusercontent.com/u/202691?v=4?s=100" width="100px;"
alt="Marc-Antoine Parent"/><br /><sub><b>Marc-Antoine Parent</b></sub></a><br
/><a href="https://github.com/frankie567/httpx-ws/issues?q=author%3Amaparent"
title="Bug reports">ð</a> <a
href="https://github.com/frankie567/httpx-ws/commits?author=maparent"
title="Code">ð»</a></td>
@@ -92,6 +92,8 @@
<td align="center" valign="top" width="14.28%"><a
href="http://www.tomchristie.com/"><img
src="https://avatars.githubusercontent.com/u/647359?v=4?s=100" width="100px;"
alt="Tom Christie"/><br /><sub><b>Tom Christie</b></sub></a><br /><a
href="https://github.com/frankie567/httpx-ws/issues?q=author%3Atomchristie"
title="Bug reports">ð</a> <a href="#research-tomchristie"
title="Research">ð¬</a></td>
<td align="center" valign="top" width="14.28%"><a
href="https://github.com/dmontagu"><img
src="https://avatars.githubusercontent.com/u/35119617?v=4?s=100" width="100px;"
alt="David Montague"/><br /><sub><b>David Montague</b></sub></a><br /><a
href="https://github.com/frankie567/httpx-ws/issues?q=author%3Admontagu"
title="Bug reports">ð</a></td>
<td align="center" valign="top" width="14.28%"><a
href="https://github.com/WSH032"><img
src="https://avatars.githubusercontent.com/u/126865849?v=4?s=100"
width="100px;" alt="Sean Wang"/><br /><sub><b>Sean Wang</b></sub></a><br /><a
href="https://github.com/frankie567/httpx-ws/commits?author=WSH032"
title="Code">ð»</a></td>
+ <td align="center" valign="top" width="14.28%"><a
href="https://github.com/agronholm"><img
src="https://avatars.githubusercontent.com/u/130003?v=4?s=100" width="100px;"
alt="Alex Grönholm"/><br /><sub><b>Alex Grönholm</b></sub></a><br /><a
href="https://github.com/frankie567/httpx-ws/issues?q=author%3Aagronholm"
title="Bug reports">ð</a> <a
href="https://github.com/frankie567/httpx-ws/commits?author=agronholm"
title="Code">ð»</a></td>
+ <td align="center" valign="top" width="14.28%"><a
href="https://github.com/ro-oliveira95"><img
src="https://avatars.githubusercontent.com/u/27009864?v=4?s=100" width="100px;"
alt="Rodrigo de Oliveira Neto"/><br /><sub><b>Rodrigo de Oliveira
Neto</b></sub></a><br /><a
href="https://github.com/frankie567/httpx-ws/issues?q=author%3Aro-oliveira95"
title="Bug reports">ð</a> <a
href="https://github.com/frankie567/httpx-ws/commits?author=ro-oliveira95"
title="Code">ð»</a></td>
</tr>
</tbody>
</table>
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/httpx_ws-0.6.0/README.md new/httpx_ws-0.6.2/README.md
--- old/httpx_ws-0.6.0/README.md 2020-02-02 01:00:00.000000000 +0100
+++ new/httpx_ws-0.6.2/README.md 2020-02-02 01:00:00.000000000 +0100
@@ -55,7 +55,7 @@
<tr>
<td align="center" valign="top" width="14.28%"><a
href="http://francoisvoron.com"><img
src="https://avatars.githubusercontent.com/u/1144727?v=4?s=100" width="100px;"
alt="François Voron"/><br /><sub><b>François Voron</b></sub></a><br /><a
href="#maintenance-frankie567" title="Maintenance">ð§</a> <a
href="https://github.com/frankie567/httpx-ws/commits?author=frankie567"
title="Code">ð»</a></td>
<td align="center" valign="top" width="14.28%"><a
href="http://kousikmitra.github.io"><img
src="https://avatars.githubusercontent.com/u/15109533?v=4?s=100" width="100px;"
alt="Kousik Mitra"/><br /><sub><b>Kousik Mitra</b></sub></a><br /><a
href="https://github.com/frankie567/httpx-ws/commits?author=kousikmitra"
title="Code">ð»</a></td>
- <td align="center" valign="top" width="14.28%"><a
href="https://github.com/davidbrochart"><img
src="https://avatars.githubusercontent.com/u/4711805?v=4?s=100" width="100px;"
alt="David Brochart"/><br /><sub><b>David Brochart</b></sub></a><br /><a
href="#platform-davidbrochart" title="Packaging/porting to new
platform">ð¦</a></td>
+ <td align="center" valign="top" width="14.28%"><a
href="https://github.com/davidbrochart"><img
src="https://avatars.githubusercontent.com/u/4711805?v=4?s=100" width="100px;"
alt="David Brochart"/><br /><sub><b>David Brochart</b></sub></a><br /><a
href="#platform-davidbrochart" title="Packaging/porting to new
platform">ð¦</a> <a
href="https://github.com/frankie567/httpx-ws/commits?author=davidbrochart"
title="Code">ð»</a></td>
<td align="center" valign="top" width="14.28%"><a
href="https://github.com/ysmu"><img
src="https://avatars.githubusercontent.com/u/17018576?v=4?s=100" width="100px;"
alt="ysmu"/><br /><sub><b>ysmu</b></sub></a><br /><a
href="https://github.com/frankie567/httpx-ws/issues?q=author%3Aysmu" title="Bug
reports">ð</a></td>
<td align="center" valign="top" width="14.28%"><a
href="https://samforeman.me"><img
src="https://avatars.githubusercontent.com/u/5234251?v=4?s=100" width="100px;"
alt="Sam Foreman"/><br /><sub><b>Sam Foreman</b></sub></a><br /><a
href="https://github.com/frankie567/httpx-ws/issues?q=author%3Asaforem2"
title="Bug reports">ð</a></td>
<td align="center" valign="top" width="14.28%"><a
href="http://maparent.ca/"><img
src="https://avatars.githubusercontent.com/u/202691?v=4?s=100" width="100px;"
alt="Marc-Antoine Parent"/><br /><sub><b>Marc-Antoine Parent</b></sub></a><br
/><a href="https://github.com/frankie567/httpx-ws/issues?q=author%3Amaparent"
title="Bug reports">ð</a> <a
href="https://github.com/frankie567/httpx-ws/commits?author=maparent"
title="Code">ð»</a></td>
@@ -66,6 +66,8 @@
<td align="center" valign="top" width="14.28%"><a
href="http://www.tomchristie.com/"><img
src="https://avatars.githubusercontent.com/u/647359?v=4?s=100" width="100px;"
alt="Tom Christie"/><br /><sub><b>Tom Christie</b></sub></a><br /><a
href="https://github.com/frankie567/httpx-ws/issues?q=author%3Atomchristie"
title="Bug reports">ð</a> <a href="#research-tomchristie"
title="Research">ð¬</a></td>
<td align="center" valign="top" width="14.28%"><a
href="https://github.com/dmontagu"><img
src="https://avatars.githubusercontent.com/u/35119617?v=4?s=100" width="100px;"
alt="David Montague"/><br /><sub><b>David Montague</b></sub></a><br /><a
href="https://github.com/frankie567/httpx-ws/issues?q=author%3Admontagu"
title="Bug reports">ð</a></td>
<td align="center" valign="top" width="14.28%"><a
href="https://github.com/WSH032"><img
src="https://avatars.githubusercontent.com/u/126865849?v=4?s=100"
width="100px;" alt="Sean Wang"/><br /><sub><b>Sean Wang</b></sub></a><br /><a
href="https://github.com/frankie567/httpx-ws/commits?author=WSH032"
title="Code">ð»</a></td>
+ <td align="center" valign="top" width="14.28%"><a
href="https://github.com/agronholm"><img
src="https://avatars.githubusercontent.com/u/130003?v=4?s=100" width="100px;"
alt="Alex Grönholm"/><br /><sub><b>Alex Grönholm</b></sub></a><br /><a
href="https://github.com/frankie567/httpx-ws/issues?q=author%3Aagronholm"
title="Bug reports">ð</a> <a
href="https://github.com/frankie567/httpx-ws/commits?author=agronholm"
title="Code">ð»</a></td>
+ <td align="center" valign="top" width="14.28%"><a
href="https://github.com/ro-oliveira95"><img
src="https://avatars.githubusercontent.com/u/27009864?v=4?s=100" width="100px;"
alt="Rodrigo de Oliveira Neto"/><br /><sub><b>Rodrigo de Oliveira
Neto</b></sub></a><br /><a
href="https://github.com/frankie567/httpx-ws/issues?q=author%3Aro-oliveira95"
title="Bug reports">ð</a> <a
href="https://github.com/frankie567/httpx-ws/commits?author=ro-oliveira95"
title="Code">ð»</a></td>
</tr>
</tbody>
</table>
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/httpx_ws-0.6.0/httpx_ws/__init__.py
new/httpx_ws-0.6.2/httpx_ws/__init__.py
--- old/httpx_ws-0.6.0/httpx_ws/__init__.py 2020-02-02 01:00:00.000000000
+0100
+++ new/httpx_ws-0.6.2/httpx_ws/__init__.py 2020-02-02 01:00:00.000000000
+0100
@@ -1,4 +1,4 @@
-__version__ = "0.6.0"
+__version__ = "0.6.2"
from ._api import (
AsyncWebSocketSession,
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/httpx_ws-0.6.0/httpx_ws/_api.py
new/httpx_ws-0.6.2/httpx_ws/_api.py
--- old/httpx_ws-0.6.0/httpx_ws/_api.py 2020-02-02 01:00:00.000000000 +0100
+++ new/httpx_ws-0.6.2/httpx_ws/_api.py 2020-02-02 01:00:00.000000000 +0100
@@ -6,11 +6,13 @@
import secrets
import threading
import typing
+from types import TracebackType
import anyio
import httpcore
import httpx
import wsproto
+from anyio.streams.memory import MemoryObjectReceiveStream,
MemoryObjectSendStream
from httpcore import AsyncNetworkStream, NetworkStream
from wsproto.frame_protocol import CloseReason
@@ -80,12 +82,25 @@
self._ping_manager = PingManager()
self._should_close = threading.Event()
+ self._should_close_task:
typing.Optional[concurrent.futures.Future[bool]] = None
+ self._executor: typing.Optional[concurrent.futures.ThreadPoolExecutor]
= None
self._max_message_size_bytes = max_message_size_bytes
self._queue_size = queue_size
self._keepalive_ping_interval_seconds = keepalive_ping_interval_seconds
self._keepalive_ping_timeout_seconds = keepalive_ping_timeout_seconds
+ def _get_executor_should_close_task(
+ self,
+ ) -> typing.Tuple[
+ concurrent.futures.ThreadPoolExecutor,
"concurrent.futures.Future[bool]"
+ ]:
+ if self._should_close_task is None:
+ self._executor = concurrent.futures.ThreadPoolExecutor()
+ self._should_close_task =
self._executor.submit(self._should_close.wait)
+ assert self._executor is not None
+ return self._executor, self._should_close_task
+
def __enter__(self) -> "WebSocketSession":
self._background_receive_task = threading.Thread(
target=self._background_receive,
args=(self._max_message_size_bytes,)
@@ -424,6 +439,8 @@
ws.close()
"""
self._should_close.set()
+ if self._executor is not None:
+ self._executor.shutdown(False)
if self.connection.state not in {
wsproto.connection.ConnectionState.LOCAL_CLOSING,
wsproto.connection.ConnectionState.CLOSED,
@@ -516,20 +533,19 @@
self, callable: typing.Callable[..., TaskResult], *args, **kwargs
) -> TaskResult:
try:
- executor = concurrent.futures.ThreadPoolExecutor(max_workers=2)
- wait_close_task = executor.submit(self._should_close.wait)
+ executor, should_close_task =
self._get_executor_should_close_task()
todo_task = executor.submit(callable, *args, **kwargs)
except RuntimeError as e:
raise ShouldClose() from e
- done, pending = concurrent.futures.wait( # type: ignore
- (todo_task, wait_close_task),
return_when=concurrent.futures.FIRST_COMPLETED
- )
- for task in pending:
- task.cancel()
- if wait_close_task in done and todo_task not in done:
- raise ShouldClose()
- result = todo_task.result()
- executor.shutdown(False)
+ else:
+ done, _ = concurrent.futures.wait(
+ (todo_task, should_close_task), # type: ignore[misc]
+ return_when=concurrent.futures.FIRST_COMPLETED,
+ )
+ if should_close_task in done:
+ raise ShouldClose()
+ assert todo_task in done
+ result = todo_task.result()
return result
@@ -546,6 +562,12 @@
subprotocol: typing.Optional[str]
response: typing.Optional[httpx.Response]
+ _send_event: MemoryObjectSendStream[
+ typing.Union[wsproto.events.Event, HTTPXWSException]
+ ]
+ _receive_event: MemoryObjectReceiveStream[
+ typing.Union[wsproto.events.Event, HTTPXWSException]
+ ]
def __init__(
self,
@@ -569,10 +591,6 @@
else:
self.subprotocol = None
- self._send_event, self._receive_event =
anyio.create_memory_object_stream[
- typing.Union[wsproto.events.Event, HTTPXWSException]
- ]()
-
self._ping_manager = AsyncPingManager()
self._should_close = anyio.Event()
@@ -587,26 +605,39 @@
self._keepalive_ping_interval_seconds =
keepalive_ping_interval_seconds
self._keepalive_ping_timeout_seconds =
keepalive_ping_timeout_seconds
- async def __aenter__(self):
- self._exit_stack = contextlib.AsyncExitStack()
- self._background_task_group = anyio.create_task_group()
- await self._exit_stack.enter_async_context(self._background_task_group)
+ async def __aenter__(self) -> "AsyncWebSocketSession":
+ async with contextlib.AsyncExitStack() as exit_stack:
+ self._send_event, self._receive_event =
anyio.create_memory_object_stream[
+ typing.Union[wsproto.events.Event, HTTPXWSException]
+ ]()
+ exit_stack.enter_context(self._send_event)
+ exit_stack.enter_context(self._receive_event)
+
+ self._background_task_group = anyio.create_task_group()
+ await exit_stack.enter_async_context(self._background_task_group)
- self._background_task_group.start_soon(
- self._background_receive, self._max_message_size_bytes
- )
- if self._keepalive_ping_interval_seconds is not None:
self._background_task_group.start_soon(
- self._background_keepalive_ping,
- self._keepalive_ping_interval_seconds,
- self._keepalive_ping_timeout_seconds,
+ self._background_receive, self._max_message_size_bytes
)
+ if self._keepalive_ping_interval_seconds is not None:
+ self._background_task_group.start_soon(
+ self._background_keepalive_ping,
+ self._keepalive_ping_interval_seconds,
+ self._keepalive_ping_timeout_seconds,
+ )
+
+
exit_stack.callback(self._background_task_group.cancel_scope.cancel)
+ exit_stack.push_async_callback(self.close)
+ self._exit_stack = exit_stack.pop_all()
return self
- async def __aexit__(self, exc_type, exc, tb):
- await self.close()
- self._background_task_group.cancel_scope.cancel()
+ async def __aexit__(
+ self,
+ exc_type: typing.Optional[typing.Type[BaseException]],
+ exc: typing.Optional[BaseException],
+ tb: typing.Optional[TracebackType],
+ ) -> None:
await self._exit_stack.aclose()
async def ping(self, payload: bytes = b"") -> anyio.Event:
@@ -989,27 +1020,22 @@
except (httpcore.ReadError, httpcore.WriteError):
await self.close(CloseReason.INTERNAL_ERROR, "Stream error")
await self._send_event.send(WebSocketNetworkError())
- except anyio.get_cancelled_exc_class():
- pass
async def _background_keepalive_ping(
self, interval_seconds: float, timeout_seconds: typing.Optional[float]
= None
) -> None:
- try:
- while not self._should_close.is_set():
- await anyio.sleep(interval_seconds)
- pong_callback = await self.ping()
- if timeout_seconds is not None:
- try:
- with anyio.fail_after(timeout_seconds):
- await pong_callback.wait()
- except TimeoutError:
- await self.close(
- CloseReason.INTERNAL_ERROR, "Keepalive ping
timeout"
- )
- await self._send_event.send(WebSocketNetworkError())
- except anyio.get_cancelled_exc_class():
- pass
+ while not self._should_close.is_set():
+ await anyio.sleep(interval_seconds)
+ pong_callback = await self.ping()
+ if timeout_seconds is not None:
+ try:
+ with anyio.fail_after(timeout_seconds):
+ await pong_callback.wait()
+ except TimeoutError:
+ await self.close(
+ CloseReason.INTERNAL_ERROR, "Keepalive ping timeout"
+ )
+ await self._send_event.send(WebSocketNetworkError())
def _get_headers(
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/httpx_ws-0.6.0/httpx_ws/transport.py
new/httpx_ws-0.6.2/httpx_ws/transport.py
--- old/httpx_ws-0.6.0/httpx_ws/transport.py 2020-02-02 01:00:00.000000000
+0100
+++ new/httpx_ws-0.6.2/httpx_ws/transport.py 2020-02-02 01:00:00.000000000
+0100
@@ -48,7 +48,7 @@
self.portal = self.exit_stack.enter_context(
anyio.from_thread.start_blocking_portal("asyncio")
)
- _: "Future[None]" = self.portal.start_task_soon(self._run)
+ _: Future[None] = self.portal.start_task_soon(self._run)
await self.send({"type": "websocket.connect"})
message = await self.receive()
@@ -197,7 +197,7 @@
self.scope = scope
self.exit_stack = contextlib.AsyncExitStack()
stream, accept_response = await self.exit_stack.enter_async_context(
- ASGIWebSocketAsyncNetworkStream(self.app, self.scope)
+ ASGIWebSocketAsyncNetworkStream(self.app, self.scope) # type:
ignore[arg-type]
)
accept_response_lines = accept_response.decode("utf-8").splitlines()
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/httpx_ws-0.6.0/pyproject.toml
new/httpx_ws-0.6.2/pyproject.toml
--- old/httpx_ws-0.6.0/pyproject.toml 2020-02-02 01:00:00.000000000 +0100
+++ new/httpx_ws-0.6.2/pyproject.toml 2020-02-02 01:00:00.000000000 +0100
@@ -18,6 +18,7 @@
path = "httpx_ws/__init__.py"
[tool.hatch.envs.default]
+installer = "uv"
dependencies = [
"mypy",
"ruff",
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/httpx_ws-0.6.0/setup.py new/httpx_ws-0.6.2/setup.py
--- old/httpx_ws-0.6.0/setup.py 2020-02-02 01:00:00.000000000 +0100
+++ new/httpx_ws-0.6.2/setup.py 2020-02-02 01:00:00.000000000 +0100
@@ -3,9 +3,9 @@
setup(
name='httpx-ws',
- version='0.6.0',
+ version='0.6.2',
description='WebSockets support for HTTPX',
- long_description='# HTTPX WS\n\n<p align="center">\n <em>WebSockets
support for
HTTPX</em>\n</p>\n\n[](https://github.com/frankie567/httpx-ws/actions)\n[](https://codecov.io/gh/frankie567/httpx-ws)\n[](#contributors-)\n[](https://badge.fury.io/py/httpx-ws)\n[](https://pepy.tech/project/httpx-ws)\n\n<p
align="center">\n<a href="https://polar.sh/frankie567">\n<picture>\n <source
media="(prefers-color-scheme: dark)"
srcset="https://polar.sh/embed/subscribe.svg?org=frankie567&darkmode=1">\n
<img alt="Subscribe"
src="https://polar.sh/embed/subscribe.svg?org=frankie567">\n</picture>\n</a>\n</p>\n\n---\n\n**Documentati
on**: <a href="https://frankie567.github.io/httpx-ws/"
target="_blank">https://frankie567.github.io/httpx-ws/</a>\n\n**Source Code**:
<a href="https://github.com/frankie567/httpx-ws"
target="_blank">https://github.com/frankie567/httpx-ws</a>\n\n---\n\n##
Installation\n\n```bash\npip install httpx-ws\n```\n\n## Features\n\n* [X] Sync
and async client\n* [X] Helper methods to send text, binary and JSON data\n*
[X] Helper methods to receive text, binary and JSON data\n* [X] Automatic
ping/pong answers\n* [X] HTTPX transport to test WebSockets defined in ASGI
apps\n* [X] Automatic keepalive ping\n* [X] `asyncio` and
[Trio](https://trio.readthedocs.io/) support through
[AnyIO](https://anyio.readthedocs.io/)\n\n## Contributors â¨\n\nThanks goes to
these wonderful people ([emoji
key](https://allcontributors.org/docs/en/emoji-key)):\n\n<!--
ALL-CONTRIBUTORS-LIST:START - Do not remove or modify this section -->\n<!--
prettier-ignore-start -->\n<!-- markdownlint-disable -->\n<table>\n <tbod
y>\n <tr>\n <td align="center" valign="top" width="14.28%"><a
href="http://francoisvoron.com"><img
src="https://avatars.githubusercontent.com/u/1144727?v=4?s=100" width="100px;"
alt="François Voron"/><br /><sub><b>François Voron</b></sub></a><br /><a
href="#maintenance-frankie567" title="Maintenance">ð§</a> <a
href="https://github.com/frankie567/httpx-ws/commits?author=frankie567"
title="Code">ð»</a></td>\n <td align="center" valign="top"
width="14.28%"><a href="http://kousikmitra.github.io"><img
src="https://avatars.githubusercontent.com/u/15109533?v=4?s=100" width="100px;"
alt="Kousik Mitra"/><br /><sub><b>Kousik Mitra</b></sub></a><br /><a
href="https://github.com/frankie567/httpx-ws/commits?author=kousikmitra"
title="Code">ð»</a></td>\n <td align="center" valign="top"
width="14.28%"><a href="https://github.com/davidbrochart"><img
src="https://avatars.githubusercontent.com/u/4711805?v=4?s=100" width="100px;"
alt="David Brochart"/><br /><sub><b>David Broc
hart</b></sub></a><br /><a href="#platform-davidbrochart"
title="Packaging/porting to new platform">ð¦</a></td>\n <td
align="center" valign="top" width="14.28%"><a
href="https://github.com/ysmu"><img
src="https://avatars.githubusercontent.com/u/17018576?v=4?s=100" width="100px;"
alt="ysmu"/><br /><sub><b>ysmu</b></sub></a><br /><a
href="https://github.com/frankie567/httpx-ws/issues?q=author%3Aysmu" title="Bug
reports">ð</a></td>\n <td align="center" valign="top" width="14.28%"><a
href="https://samforeman.me"><img
src="https://avatars.githubusercontent.com/u/5234251?v=4?s=100" width="100px;"
alt="Sam Foreman"/><br /><sub><b>Sam Foreman</b></sub></a><br /><a
href="https://github.com/frankie567/httpx-ws/issues?q=author%3Asaforem2"
title="Bug reports">ð</a></td>\n <td align="center" valign="top"
width="14.28%"><a href="http://maparent.ca/"><img
src="https://avatars.githubusercontent.com/u/202691?v=4?s=100" width="100px;"
alt="Marc-Antoine Parent"/><br /><sub><b>Ma
rc-Antoine Parent</b></sub></a><br /><a
href="https://github.com/frankie567/httpx-ws/issues?q=author%3Amaparent"
title="Bug reports">ð</a> <a
href="https://github.com/frankie567/httpx-ws/commits?author=maparent"
title="Code">ð»</a></td>\n <td align="center" valign="top"
width="14.28%"><a href="https://www.fastapiexpert.com/"><img
src="https://avatars.githubusercontent.com/u/7353520?v=4?s=100" width="100px;"
alt="Marcelo Trylesinski"/><br /><sub><b>Marcelo Trylesinski</b></sub></a><br
/><a href="https://github.com/frankie567/httpx-ws/issues?q=author%3AKludex"
title="Bug reports">ð</a> <a href="#research-Kludex"
title="Research">ð¬</a></td>\n </tr>\n <tr>\n <td align="center"
valign="top" width="14.28%"><a href="https://lit.link/MtkN1"><img
src="https://avatars.githubusercontent.com/u/51289448?v=4?s=100" width="100px;"
alt="MtkN1"/><br /><sub><b>MtkN1</b></sub></a><br /><a
href="https://github.com/frankie567/httpx-ws/issues?q=author%3AMtkN1"
title="Bug report
s">ð</a> <a href="#research-MtkN1" title="Research">ð¬</a></td>\n
<td align="center" valign="top" width="14.28%"><a
href="http://www.tomchristie.com/"><img
src="https://avatars.githubusercontent.com/u/647359?v=4?s=100" width="100px;"
alt="Tom Christie"/><br /><sub><b>Tom Christie</b></sub></a><br /><a
href="https://github.com/frankie567/httpx-ws/issues?q=author%3Atomchristie"
title="Bug reports">ð</a> <a href="#research-tomchristie"
title="Research">ð¬</a></td>\n <td align="center" valign="top"
width="14.28%"><a href="https://github.com/dmontagu"><img
src="https://avatars.githubusercontent.com/u/35119617?v=4?s=100" width="100px;"
alt="David Montague"/><br /><sub><b>David Montague</b></sub></a><br /><a
href="https://github.com/frankie567/httpx-ws/issues?q=author%3Admontagu"
title="Bug reports">ð</a></td>\n <td align="center" valign="top"
width="14.28%"><a href="https://github.com/WSH032"><img
src="https://avatars.githubusercontent.com/u/126865849?v=4?s=100
" width="100px;" alt="Sean Wang"/><br /><sub><b>Sean Wang</b></sub></a><br
/><a href="https://github.com/frankie567/httpx-ws/commits?author=WSH032"
title="Code">ð»</a></td>\n </tr>\n </tbody>\n</table>\n\n<!--
markdownlint-restore -->\n<!-- prettier-ignore-end -->\n\n<!--
ALL-CONTRIBUTORS-LIST:END -->\n\nThis project follows the
[all-contributors](https://github.com/all-contributors/all-contributors)
specification. Contributions of any kind welcome!\n\n## Development\n\n###
Setup environment\n\nWe use [Hatch](https://hatch.pypa.io/latest/install/) to
manage the development environment and production build. Ensure it\'s installed
on your system.\n\n### Run unit tests\n\nYou can run all the tests
with:\n\n```bash\nhatch run test\n```\n\n### Format the code\n\nExecute the
following command to apply linting and check typing:\n\n```bash\nhatch run
lint\n```\n\n## License\n\nThis project is licensed under the terms of the MIT
license.\n',
+ long_description='# HTTPX WS\n\n<p align="center">\n <em>WebSockets
support for
HTTPX</em>\n</p>\n\n[](https://github.com/frankie567/httpx-ws/actions)\n[](https://codecov.io/gh/frankie567/httpx-ws)\n[](#contributors-)\n[](https://badge.fury.io/py/httpx-ws)\n[](https://pepy.tech/project/httpx-ws)\n\n<p
align="center">\n<a href="https://polar.sh/frankie567">\n<picture>\n <source
media="(prefers-color-scheme: dark)"
srcset="https://polar.sh/embed/subscribe.svg?org=frankie567&darkmode=1">\n
<img alt="Subscribe"
src="https://polar.sh/embed/subscribe.svg?org=frankie567">\n</picture>\n</a>\n</p>\n\n---\n\n**Documentati
on**: <a href="https://frankie567.github.io/httpx-ws/"
target="_blank">https://frankie567.github.io/httpx-ws/</a>\n\n**Source Code**:
<a href="https://github.com/frankie567/httpx-ws"
target="_blank">https://github.com/frankie567/httpx-ws</a>\n\n---\n\n##
Installation\n\n```bash\npip install httpx-ws\n```\n\n## Features\n\n* [X] Sync
and async client\n* [X] Helper methods to send text, binary and JSON data\n*
[X] Helper methods to receive text, binary and JSON data\n* [X] Automatic
ping/pong answers\n* [X] HTTPX transport to test WebSockets defined in ASGI
apps\n* [X] Automatic keepalive ping\n* [X] `asyncio` and
[Trio](https://trio.readthedocs.io/) support through
[AnyIO](https://anyio.readthedocs.io/)\n\n## Contributors â¨\n\nThanks goes to
these wonderful people ([emoji
key](https://allcontributors.org/docs/en/emoji-key)):\n\n<!--
ALL-CONTRIBUTORS-LIST:START - Do not remove or modify this section -->\n<!--
prettier-ignore-start -->\n<!-- markdownlint-disable -->\n<table>\n <tbod
y>\n <tr>\n <td align="center" valign="top" width="14.28%"><a
href="http://francoisvoron.com"><img
src="https://avatars.githubusercontent.com/u/1144727?v=4?s=100" width="100px;"
alt="François Voron"/><br /><sub><b>François Voron</b></sub></a><br /><a
href="#maintenance-frankie567" title="Maintenance">ð§</a> <a
href="https://github.com/frankie567/httpx-ws/commits?author=frankie567"
title="Code">ð»</a></td>\n <td align="center" valign="top"
width="14.28%"><a href="http://kousikmitra.github.io"><img
src="https://avatars.githubusercontent.com/u/15109533?v=4?s=100" width="100px;"
alt="Kousik Mitra"/><br /><sub><b>Kousik Mitra</b></sub></a><br /><a
href="https://github.com/frankie567/httpx-ws/commits?author=kousikmitra"
title="Code">ð»</a></td>\n <td align="center" valign="top"
width="14.28%"><a href="https://github.com/davidbrochart"><img
src="https://avatars.githubusercontent.com/u/4711805?v=4?s=100" width="100px;"
alt="David Brochart"/><br /><sub><b>David Broc
hart</b></sub></a><br /><a href="#platform-davidbrochart"
title="Packaging/porting to new platform">ð¦</a> <a
href="https://github.com/frankie567/httpx-ws/commits?author=davidbrochart"
title="Code">ð»</a></td>\n <td align="center" valign="top"
width="14.28%"><a href="https://github.com/ysmu"><img
src="https://avatars.githubusercontent.com/u/17018576?v=4?s=100" width="100px;"
alt="ysmu"/><br /><sub><b>ysmu</b></sub></a><br /><a
href="https://github.com/frankie567/httpx-ws/issues?q=author%3Aysmu" title="Bug
reports">ð</a></td>\n <td align="center" valign="top" width="14.28%"><a
href="https://samforeman.me"><img
src="https://avatars.githubusercontent.com/u/5234251?v=4?s=100" width="100px;"
alt="Sam Foreman"/><br /><sub><b>Sam Foreman</b></sub></a><br /><a
href="https://github.com/frankie567/httpx-ws/issues?q=author%3Asaforem2"
title="Bug reports">ð</a></td>\n <td align="center" valign="top"
width="14.28%"><a href="http://maparent.ca/"><img src="https://avatars.
githubusercontent.com/u/202691?v=4?s=100" width="100px;" alt="Marc-Antoine
Parent"/><br /><sub><b>Marc-Antoine Parent</b></sub></a><br /><a
href="https://github.com/frankie567/httpx-ws/issues?q=author%3Amaparent"
title="Bug reports">ð</a> <a
href="https://github.com/frankie567/httpx-ws/commits?author=maparent"
title="Code">ð»</a></td>\n <td align="center" valign="top"
width="14.28%"><a href="https://www.fastapiexpert.com/"><img
src="https://avatars.githubusercontent.com/u/7353520?v=4?s=100" width="100px;"
alt="Marcelo Trylesinski"/><br /><sub><b>Marcelo Trylesinski</b></sub></a><br
/><a href="https://github.com/frankie567/httpx-ws/issues?q=author%3AKludex"
title="Bug reports">ð</a> <a href="#research-Kludex"
title="Research">ð¬</a></td>\n </tr>\n <tr>\n <td align="center"
valign="top" width="14.28%"><a href="https://lit.link/MtkN1"><img
src="https://avatars.githubusercontent.com/u/51289448?v=4?s=100" width="100px;"
alt="MtkN1"/><br /><sub><b>MtkN1</b></sub>
</a><br /><a
href="https://github.com/frankie567/httpx-ws/issues?q=author%3AMtkN1"
title="Bug reports">ð</a> <a href="#research-MtkN1"
title="Research">ð¬</a></td>\n <td align="center" valign="top"
width="14.28%"><a href="http://www.tomchristie.com/"><img
src="https://avatars.githubusercontent.com/u/647359?v=4?s=100" width="100px;"
alt="Tom Christie"/><br /><sub><b>Tom Christie</b></sub></a><br /><a
href="https://github.com/frankie567/httpx-ws/issues?q=author%3Atomchristie"
title="Bug reports">ð</a> <a href="#research-tomchristie"
title="Research">ð¬</a></td>\n <td align="center" valign="top"
width="14.28%"><a href="https://github.com/dmontagu"><img
src="https://avatars.githubusercontent.com/u/35119617?v=4?s=100" width="100px;"
alt="David Montague"/><br /><sub><b>David Montague</b></sub></a><br /><a
href="https://github.com/frankie567/httpx-ws/issues?q=author%3Admontagu"
title="Bug reports">ð</a></td>\n <td align="center" valign="top"
width="14.28%"><a hr
ef="https://github.com/WSH032"><img
src="https://avatars.githubusercontent.com/u/126865849?v=4?s=100"
width="100px;" alt="Sean Wang"/><br /><sub><b>Sean Wang</b></sub></a><br /><a
href="https://github.com/frankie567/httpx-ws/commits?author=WSH032"
title="Code">ð»</a></td>\n <td align="center" valign="top"
width="14.28%"><a href="https://github.com/agronholm"><img
src="https://avatars.githubusercontent.com/u/130003?v=4?s=100" width="100px;"
alt="Alex Grönholm"/><br /><sub><b>Alex Grönholm</b></sub></a><br /><a
href="https://github.com/frankie567/httpx-ws/issues?q=author%3Aagronholm"
title="Bug reports">ð</a> <a
href="https://github.com/frankie567/httpx-ws/commits?author=agronholm"
title="Code">ð»</a></td>\n <td align="center" valign="top"
width="14.28%"><a href="https://github.com/ro-oliveira95"><img
src="https://avatars.githubusercontent.com/u/27009864?v=4?s=100" width="100px;"
alt="Rodrigo de Oliveira Neto"/><br /><sub><b>Rodrigo de Oliveira
Neto</b></sub></a><br
/><a
href="https://github.com/frankie567/httpx-ws/issues?q=author%3Aro-oliveira95"
title="Bug reports">ð</a> <a
href="https://github.com/frankie567/httpx-ws/commits?author=ro-oliveira95"
title="Code">ð»</a></td>\n </tr>\n </tbody>\n</table>\n\n<!--
markdownlint-restore -->\n<!-- prettier-ignore-end -->\n\n<!--
ALL-CONTRIBUTORS-LIST:END -->\n\nThis project follows the
[all-contributors](https://github.com/all-contributors/all-contributors)
specification. Contributions of any kind welcome!\n\n## Development\n\n###
Setup environment\n\nWe use [Hatch](https://hatch.pypa.io/latest/install/) to
manage the development environment and production build. Ensure it\'s installed
on your system.\n\n### Run unit tests\n\nYou can run all the tests
with:\n\n```bash\nhatch run test\n```\n\n### Format the code\n\nExecute the
following command to apply linting and check typing:\n\n```bash\nhatch run
lint\n```\n\n## License\n\nThis project is licensed under the terms of the MIT
license.\n',
author_email='François Voron <[email protected]>',
classifiers=[
'Development Status :: 4 - Beta',
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/httpx_ws-0.6.0/tests/test_api.py
new/httpx_ws-0.6.2/tests/test_api.py
--- old/httpx_ws-0.6.0/tests/test_api.py 2020-02-02 01:00:00.000000000
+0100
+++ new/httpx_ws-0.6.2/tests/test_api.py 2020-02-02 01:00:00.000000000
+0100
@@ -1,5 +1,6 @@
import contextlib
import queue
+import threading
import time
import typing
from unittest.mock import MagicMock, call, patch
@@ -330,8 +331,8 @@
@pytest.mark.parametrize(
"full_message,send_method",
[
- (b"A" * 1024 * 4, "send_bytes"),
- ("A" * 1024 * 4, "send_text"),
+ pytest.param(b"A" * 1024 * 4, "send_bytes", id="bytes"),
+ pytest.param("A" * 1024 * 4, "send_text", id="text"),
],
)
async def test_receive_oversized_message(
@@ -780,24 +781,31 @@
@pytest.mark.anyio
-async def test_send_close(server_factory: ServerFactoryFixture):
+async def test_send_close(
+ server_factory: ServerFactoryFixture, on_receive_message: MagicMock
+):
async def websocket_endpoint(websocket: WebSocket):
await websocket.accept()
try:
await websocket.receive_text()
- except StarletteWebSocketDisconnect:
- pass
+ except StarletteWebSocketDisconnect as e:
+ print(e)
+ on_receive_message(e.code, e.reason)
with server_factory(websocket_endpoint) as socket:
with httpx.Client(transport=httpx.HTTPTransport(uds=socket)) as client:
- with connect_ws("http://socket/ws", client):
- pass
+ with connect_ws("http://socket/ws", client) as ws:
+ ws.close(code=1001, reason="CLOSE_REASON")
async with httpx.AsyncClient(
transport=httpx.AsyncHTTPTransport(uds=socket)
) as aclient:
- async with aconnect_ws("http://socket/ws", aclient):
- pass
+ async with aconnect_ws("http://socket/ws", aclient) as aws:
+ await aws.close(code=1001, reason="CLOSE_REASON")
+
+ on_receive_message.assert_has_calls(
+ [call(1001, "CLOSE_REASON"), call(1001, "CLOSE_REASON")]
+ )
@pytest.mark.anyio
@@ -894,3 +902,35 @@
assert isinstance(aws.response, httpx.Response)
assert aws.subprotocol == "custom_protocol"
assert aws.response.headers["sec-websocket-protocol"] ==
aws.subprotocol
+
+
[email protected]
+async def test_threads_wont_hang(server_factory: ServerFactoryFixture) -> None:
+ """
+ Check that all threads spawned in WebSocketSession are properly terminated
during
+ a series of messages exchange. This used to be the cause of a memory leak
in the
+ connect_ws client, see https://github.com/frankie567/httpx-ws/issues/76.
+ """
+
+ async def websocket_endpoint(websocket: WebSocket) -> None:
+ await websocket.accept()
+ for _ in range(50):
+ await websocket.send_text("SERVER_MESSAGE")
+ await websocket.receive_text()
+ await websocket.close()
+
+ with server_factory(websocket_endpoint) as socket:
+ with httpx.Client(transport=httpx.HTTPTransport(uds=socket)) as client:
+ initial_threads_count = threading.active_count()
+ with connect_ws(
+ "http://socket/ws", client,
keepalive_ping_interval_seconds=None
+ ) as ws:
+ for _ in range(50):
+ ws.receive()
+ ws.send_text("CLIENT_MESSAGE")
+ time.sleep(0.1) # Let the websocket endpoint finish its
handling.
+ threads_count = threading.active_count()
+ assert initial_threads_count + 2 == threads_count
+ time.sleep(0.1)
+ final_threads_count = threading.active_count()
+ assert initial_threads_count == final_threads_count