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 <dmuel...@suse.com>
+
+- 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[![build](https://github.com/frankie567/httpx-ws/workflows/Build/badge.svg)](https://github.com/frankie567/httpx-ws/actions)\n[![codecov](https://codecov.io/gh/frankie567/httpx-ws/branch/main/graph/badge.svg?token=fL49kIvrj6)](https://codecov.io/gh/frankie567/httpx-ws)\n[![All
 
Contributors](https://img.shields.io/badge/all_contributors-2-orange.svg?style=flat-square)](#contributors-)\n[![PyPI
 
version](https://badge.fury.io/py/httpx-ws.svg)](https://badge.fury.io/py/httpx-ws)\n[![Downloads](https://pepy.tech/badge/httpx-ws)](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[![build](https://github.com/frankie567/httpx-ws/workflows/Build/badge.svg)](https://github.com/frankie567/httpx-ws/actions)\n[![codecov](https://codecov.io/gh/frankie567/httpx-ws/branch/main/graph/badge.svg?token=fL49kIvrj6)](https://codecov.io/gh/frankie567/httpx-ws)\n[![All
 
Contributors](https://img.shields.io/badge/all_contributors-2-orange.svg?style=flat-square)](#contributors-)\n[![PyPI
 
version](https://badge.fury.io/py/httpx-ws.svg)](https://badge.fury.io/py/httpx-ws)\n[![Downloads](https://pepy.tech/badge/httpx-ws)](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 <fvo...@gmail.com>',
     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
+
+
+@pytest.mark.anyio
+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

Reply via email to