diff --git a/juju/client/gocookies.py b/juju/client/gocookies.py index 0c33f0be..f86d4298 100644 --- a/juju/client/gocookies.py +++ b/juju/client/gocookies.py @@ -6,7 +6,7 @@ import json import time -import pyrfc3339 +from backports.datetime_fromisoformat import datetime_fromisoformat 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 = datetime_fromisoformat(go_cookie["Expires"]) expires = t.timestamp() return cookiejar.Cookie( version=0, @@ -101,8 +101,9 @@ def py_to_go_cookie(py_cookie): if py_cookie.path_specified: go_cookie["Path"] = py_cookie.path if py_cookie.expires is not None: - 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"] = datetime.datetime.fromtimestamp( + py_cookie.expires + ).isoformat() return go_cookie diff --git a/juju/machine.py b/juju/machine.py index 3fdd4369..11c4ad8a 100644 --- a/juju/machine.py +++ b/juju/machine.py @@ -6,7 +6,7 @@ import logging import typing -import pyrfc3339 +from backports.datetime_fromisoformat import datetime_fromisoformat 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 datetime_fromisoformat(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 datetime_fromisoformat(self.safe_data["instance-status"]["since"]) @property def dns_name(self): diff --git a/juju/unit.py b/juju/unit.py index 64e14ac6..9dd4b16a 100644 --- a/juju/unit.py +++ b/juju/unit.py @@ -3,7 +3,7 @@ import logging -import pyrfc3339 +from backports.datetime_fromisoformat import datetime_fromisoformat from juju.errors import JujuAPIError, JujuError @@ -27,7 +27,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 datetime_fromisoformat(self.safe_data["agent-status"]["since"]) @property def is_subordinate(self): @@ -54,7 +54,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 datetime_fromisoformat(self.safe_data["workload-status"]["since"]) @property def workload_status_message(self): diff --git a/juju/user.py b/juju/user.py index 7ff0fcc3..204d02b1 100644 --- a/juju/user.py +++ b/juju/user.py @@ -3,7 +3,7 @@ import logging -import pyrfc3339 +from backports.datetime_fromisoformat import datetime_fromisoformat 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 datetime_fromisoformat(self._user_info.last_connection) @property def access(self): diff --git a/pyproject.toml b/pyproject.toml index 228552f0..6de962dd 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"', + "backports-datetime-fromisoformat>=2.0.2", ] [project.optional-dependencies] dev = [ diff --git a/setup.py b/setup.py index f9dd7b57..62b72b43 100644 --- a/setup.py +++ b/setup.py @@ -21,7 +21,6 @@ package_data={"juju": ["py.typed"]}, install_requires=[ "macaroonbakery>=1.1,<2.0", - "pyRFC3339>=1.0,<2.0", "pyyaml>=5.1.2", "websockets>=13.0.1", "paramiko>=2.4.0", @@ -33,6 +32,7 @@ "packaging", "typing-extensions>=4.5.0", 'backports.strenum>=1.3.1; python_version < "3.11"', + "backports-datetime-fromisoformat>=2.0.2", ], extras_require={ "dev": [ diff --git a/tests/unit/test_gocookies.py b/tests/unit/test_gocookies.py index 7f04f67f..44d1e7f3 100644 --- a/tests/unit/test_gocookies.py +++ b/tests/unit/test_gocookies.py @@ -8,13 +8,14 @@ import unittest import urllib.request -import pyrfc3339 +from backports.datetime_fromisoformat import datetime_fromisoformat from juju.client.gocookies import GoCookieJar # cookie_content holds the JSON contents of a Go-produced # cookie file (reformatted so it's not all on one line but # otherwise unchanged). + cookie_content = """ [ { @@ -223,7 +224,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(datetime_fromisoformat("2345-11-15T18:16:08Z").timestamp()) self.assertEqual(got_expires, want_expires) def load_jar(self, content):