From 8116a97e704caaefd3a508ecf12a41fc48f7cb36 Mon Sep 17 00:00:00 2001 From: Edmilson Monteiro Rodrigues Neto Date: Tue, 17 Dec 2024 05:52:31 +0000 Subject: [PATCH 1/2] refactor: change use of pyrfc3339 to use ciso8601 --- juju/client/gocookies.py | 24 +++++++++++++++++++++--- juju/machine.py | 6 +++--- juju/unit.py | 6 +++--- juju/user.py | 4 ++-- pyproject.toml | 2 +- setup.py | 2 +- tests/unit/test_gocookies.py | 4 ++-- 7 files changed, 33 insertions(+), 15 deletions(-) diff --git a/juju/client/gocookies.py b/juju/client/gocookies.py index 0c33f0be6..c8905f327 100644 --- a/juju/client/gocookies.py +++ b/juju/client/gocookies.py @@ -6,7 +6,7 @@ import json import time -import pyrfc3339 +import ciso8601 class GoCookieJar(cookiejar.FileCookieJar): @@ -52,7 +52,7 @@ def go_to_py_cookie(go_cookie): """Convert a Go-style JSON-unmarshaled cookie into a Python cookie""" expires = None if go_cookie.get("Expires") is not None: - t = pyrfc3339.parse(go_cookie["Expires"]) + t = ciso8601.parse_rfc3339(go_cookie["Expires"]) expires = t.timestamp() return cookiejar.Cookie( version=0, @@ -104,5 +104,23 @@ def py_to_go_cookie(py_cookie): unix_time = datetime.datetime.fromtimestamp(py_cookie.expires) # Note: fromtimestamp bizarrely produces a time without # a time zone, so we need to use accept_naive. - go_cookie["Expires"] = pyrfc3339.generate(unix_time, accept_naive=True) + go_cookie["Expires"] = generate_rfc3339_from_unix_time(unix_time) return go_cookie + + +def generate_rfc3339_from_unix_time(unix_time: datetime.datetime) -> str: + rfc, discard = unix_time.isoformat().split(".") + discard = discard.split("+") + if len(discard) > 1: + rfc = datetime.datetime.fromisoformat(rfc) + hours, minutes = discard[1].split(":") + rfc -= datetime.timedelta(hours=int(hours), minutes=int(minutes)) + rfc = rfc.isoformat() + else: + discard = discard[0].split("-") + if len(discard) > 1: + rfc = datetime.datetime.fromisoformat(rfc) + hours, minutes = discard[1].split(":") + rfc += datetime.timedelta(hours=int(hours), minutes=int(minutes)) + rfc = rfc.isoformat() + return f"{rfc}Z" diff --git a/juju/machine.py b/juju/machine.py index 3fdd43692..ffde2a402 100644 --- a/juju/machine.py +++ b/juju/machine.py @@ -6,7 +6,7 @@ import logging import typing -import pyrfc3339 +import ciso8601 from juju.utils import block_until, juju_ssh_key_paths @@ -239,7 +239,7 @@ def agent_status(self): @property def agent_status_since(self): """Get the time when the `agent_status` was last updated.""" - return pyrfc3339.parse(self.safe_data["agent-status"]["since"]) + return ciso8601.parse_rfc3339(self.safe_data["agent-status"]["since"]) @property def agent_version(self): @@ -266,7 +266,7 @@ def status_message(self): @property def status_since(self): """Get the time when the `status` was last updated.""" - return pyrfc3339.parse(self.safe_data["instance-status"]["since"]) + return ciso8601.parse_rfc3339(self.safe_data["instance-status"]["since"]) @property def dns_name(self): diff --git a/juju/unit.py b/juju/unit.py index 4cb8e2591..ce9337ce5 100644 --- a/juju/unit.py +++ b/juju/unit.py @@ -3,7 +3,7 @@ import logging -import pyrfc3339 +import ciso8601 from juju.errors import JujuAPIError, JujuError @@ -25,7 +25,7 @@ def agent_status(self): @property def agent_status_since(self): """Get the time when the `agent_status` was last updated.""" - return pyrfc3339.parse(self.safe_data["agent-status"]["since"]) + return ciso8601.parse_rfc3339(self.safe_data["agent-status"]["since"]) @property def is_subordinate(self): @@ -52,7 +52,7 @@ def workload_status(self): @property def workload_status_since(self): """Get the time when the `workload_status` was last updated.""" - return pyrfc3339.parse(self.safe_data["workload-status"]["since"]) + return ciso8601.parse_rfc3339(self.safe_data["workload-status"]["since"]) @property def workload_status_message(self): diff --git a/juju/user.py b/juju/user.py index 7ff0fcc32..44adb4c59 100644 --- a/juju/user.py +++ b/juju/user.py @@ -3,7 +3,7 @@ import logging -import pyrfc3339 +import ciso8601 from . import errors, tag from .client import client @@ -31,7 +31,7 @@ def display_name(self): @property def last_connection(self): - return pyrfc3339.parse(self._user_info.last_connection) + return ciso8601.parse_rfc3339(self._user_info.last_connection) @property def access(self): diff --git a/pyproject.toml b/pyproject.toml index b3c2d4277..1d8614128 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -23,7 +23,6 @@ classifiers = [ ] dependencies = [ "macaroonbakery>=1.1,<2.0", - "pyRFC3339>=1.0,<2.0", "pyyaml>=5.1.2", "websockets>=13.0.1", "paramiko>=2.4.0", @@ -35,6 +34,7 @@ dependencies = [ "packaging", "typing-extensions>=4.5.0", 'backports.strenum>=1.3.1; python_version < "3.11"', + "ciso8601>=2.3.2", ] [project.optional-dependencies] dev = [ diff --git a/setup.py b/setup.py index 93825375b..8863632c4 100644 --- a/setup.py +++ b/setup.py @@ -21,7 +21,7 @@ package_data={"juju": ["py.typed"]}, install_requires=[ "macaroonbakery>=1.1,<2.0", - "pyRFC3339>=1.0,<2.0", + "ciso8601>=2.3.2", "pyyaml>=5.1.2", "websockets>=13.0.1", "paramiko>=2.4.0", diff --git a/tests/unit/test_gocookies.py b/tests/unit/test_gocookies.py index 7f04f67fa..2b5d0c1e8 100644 --- a/tests/unit/test_gocookies.py +++ b/tests/unit/test_gocookies.py @@ -8,7 +8,7 @@ import unittest import urllib.request -import pyrfc3339 +import ciso8601 from juju.client.gocookies import GoCookieJar @@ -223,7 +223,7 @@ def test_expiry_time(self): ]""" jar = self.load_jar(content) got_expires = tuple(jar)[0].expires - want_expires = int(pyrfc3339.parse("2345-11-15T18:16:08Z").timestamp()) + want_expires = int(ciso8601.parse_rfc3339("2345-11-15T18:16:08Z").timestamp()) self.assertEqual(got_expires, want_expires) def load_jar(self, content): From de772290a4582083fbd5f431efabada8374b12d4 Mon Sep 17 00:00:00 2001 From: Edmilson Monteiro Rodrigues Neto Date: Tue, 17 Dec 2024 09:53:44 +0000 Subject: [PATCH 2/2] chore: fix the malfunction so the tests pass --- juju/client/gocookies.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/juju/client/gocookies.py b/juju/client/gocookies.py index c8905f327..699abb8ce 100644 --- a/juju/client/gocookies.py +++ b/juju/client/gocookies.py @@ -109,7 +109,10 @@ def py_to_go_cookie(py_cookie): def generate_rfc3339_from_unix_time(unix_time: datetime.datetime) -> str: - rfc, discard = unix_time.isoformat().split(".") + splitted_rfc = unix_time.isoformat().split(".") + if len(splitted_rfc) == 1: + return f"{splitted_rfc[0]}Z" + rfc, discard = splitted_rfc discard = discard.split("+") if len(discard) > 1: rfc = datetime.datetime.fromisoformat(rfc)