From 8040de56c074ff62675ff43939860d5a3a8c6866 Mon Sep 17 00:00:00 2001 From: Felipe Reyes Date: Fri, 22 Nov 2024 15:38:40 -0300 Subject: [PATCH 1/3] fix: use newer websockets API to check that connection is open The websockets library has dropped the properties "open" and "closed" since websockets-13.0[0], this patch makes the changes needed to check for the connection's state as suggested by the documentation. [0] https://github.com/python-websockets/websockets/commit/7c8e0b9d6246cd7bdd304f630f719fc55620f89a --- juju/client/connection.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/juju/client/connection.py b/juju/client/connection.py index 88c31c2ab..ea285a14c 100644 --- a/juju/client/connection.py +++ b/juju/client/connection.py @@ -17,6 +17,7 @@ import websockets from dateutil.parser import parse from typing_extensions import Self, TypeAlias, overload +from websockets.protocol import State from juju import errors, jasyncio, tag, utils from juju.client import client @@ -92,7 +93,7 @@ def status(self): and connection._receiver_task.cancelled() ) - if stopped or not connection._ws.open: + if stopped or connection._ws.state is not State.OPEN: return self.ERROR # everything is fine! @@ -357,8 +358,7 @@ async def close(self, to_reconnect: bool = False): tasks_need_to_be_gathered.append(self._debug_log_task) self._debug_log_task.cancel() - if self._ws and not self._ws.closed: - await self._ws.close() + await self._ws.close() if not to_reconnect: try: From 3787ba1e77bdec28b4faca437094af4a3e9fe797 Mon Sep 17 00:00:00 2001 From: Dima Tisnek Date: Tue, 26 Nov 2024 11:35:31 +0900 Subject: [PATCH 2/3] chore: remove the upper bound for websockets --- pyproject.toml | 2 +- setup.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/pyproject.toml b/pyproject.toml index f3c1118ec..eeb170742 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -25,7 +25,7 @@ dependencies = [ "macaroonbakery>=1.1,<2.0", "pyRFC3339>=1.0,<2.0", "pyyaml>=5.1.2", - "websockets>=13.0.1,<14.0", + "websockets>=13.0.1", "paramiko>=2.4.0", "pyasn1>=0.4.4", "toposort>=1.5,<2", diff --git a/setup.py b/setup.py index 5ee1fe8c1..93825375b 100644 --- a/setup.py +++ b/setup.py @@ -23,7 +23,7 @@ "macaroonbakery>=1.1,<2.0", "pyRFC3339>=1.0,<2.0", "pyyaml>=5.1.2", - "websockets>=13.0.1,<14.0", + "websockets>=13.0.1", "paramiko>=2.4.0", "pyasn1>=0.4.4", "toposort>=1.5,<2", From a53ce1e0d5ea42dd0831022dee0bf14500458063 Mon Sep 17 00:00:00 2001 From: Dima Tisnek Date: Tue, 26 Nov 2024 11:47:01 +0900 Subject: [PATCH 3/3] chore: fix unit tests --- juju/client/connection.py | 3 +-- tests/unit/test_connection.py | 7 +++---- 2 files changed, 4 insertions(+), 6 deletions(-) diff --git a/juju/client/connection.py b/juju/client/connection.py index ea285a14c..03eb50961 100644 --- a/juju/client/connection.py +++ b/juju/client/connection.py @@ -17,7 +17,6 @@ import websockets from dateutil.parser import parse from typing_extensions import Self, TypeAlias, overload -from websockets.protocol import State from juju import errors, jasyncio, tag, utils from juju.client import client @@ -93,7 +92,7 @@ def status(self): and connection._receiver_task.cancelled() ) - if stopped or connection._ws.state is not State.OPEN: + if stopped or connection._ws.state is not websockets.protocol.State.OPEN: return self.ERROR # everything is fine! diff --git a/tests/unit/test_connection.py b/tests/unit/test_connection.py index a7cc808cb..9ed876466 100644 --- a/tests/unit/test_connection.py +++ b/tests/unit/test_connection.py @@ -7,6 +7,7 @@ from unittest import mock import pytest +import websockets from websockets.exceptions import ConnectionClosed from juju.client.connection import Connection @@ -17,8 +18,7 @@ class WebsocketMock: def __init__(self, responses): super().__init__() self.responses = deque(responses) - self.open = True - self.closed = False + self.state = websockets.protocol.State.OPEN async def send(self, message): pass @@ -30,8 +30,7 @@ async def recv(self): return json.dumps(self.responses.popleft()) async def close(self): - self.open = False - self.closed = True + pass async def test_out_of_order():