diff --git a/b2sdk/_internal/b2http.py b/b2sdk/_internal/b2http.py index 8deb3fc0..0d0fe031 100644 --- a/b2sdk/_internal/b2http.py +++ b/b2sdk/_internal/b2http.py @@ -145,15 +145,20 @@ def post_request(self, method, url, headers, response): # Convert the server time to a datetime object try: with setlocale("C"): + # "%Z" always creates naive datetimes, even though the timezone + # is specified. https://github.com/python/cpython/issues/76678 + # Anyway, thankfully, HTTP/1.1 spec requires the string + # to always say "GMT", and provide UTC time. + # https://datatracker.ietf.org/doc/html/rfc2616#section-3.3.1 server_time = datetime.datetime.strptime( - server_date_str, '%a, %d %b %Y %H:%M:%S %Z' - ) + server_date_str, '%a, %d %b %Y %H:%M:%S GMT' + ).replace(tzinfo=datetime.timezone.utc) except ValueError: logger.exception('server returned date in an inappropriate format') raise BadDateFormat(server_date_str) # Get the local time - local_time = datetime.datetime.utcnow() + local_time = datetime.datetime.now(datetime.timezone.utc) # Check the difference. max_allowed = 10 * 60 # ten minutes, in seconds diff --git a/changelog.d/+datetime.utcnow_deprecation.fixed.md b/changelog.d/+datetime.utcnow_deprecation.fixed.md new file mode 100644 index 00000000..ceb598f6 --- /dev/null +++ b/changelog.d/+datetime.utcnow_deprecation.fixed.md @@ -0,0 +1 @@ +Fixed datetime.utcnow() deprecation warnings in Python 3.12. diff --git a/test/unit/b2http/test_b2http.py b/test/unit/b2http/test_b2http.py index f8f7602c..40079ea4 100644 --- a/test/unit/b2http/test_b2http.py +++ b/test/unit/b2http/test_b2http.py @@ -402,14 +402,14 @@ def test_bad_month(self): ClockSkewHook().post_request('POST', 'http://example.com', {}, response) def test_no_skew(self): - now = datetime.datetime.utcnow() + now = datetime.datetime.now(datetime.timezone.utc) now_str = now.strftime('%a, %d %b %Y %H:%M:%S GMT') response = MagicMock() response.headers = {'Date': now_str} ClockSkewHook().post_request('POST', 'http://example.com', {}, response) def test_positive_skew(self): - now = datetime.datetime.utcnow() + datetime.timedelta(minutes=11) + now = datetime.datetime.now(datetime.timezone.utc) + datetime.timedelta(minutes=11) now_str = now.strftime('%a, %d %b %Y %H:%M:%S GMT') response = MagicMock() response.headers = {'Date': now_str} @@ -417,7 +417,7 @@ def test_positive_skew(self): ClockSkewHook().post_request('POST', 'http://example.com', {}, response) def test_negative_skew(self): - now = datetime.datetime.utcnow() + datetime.timedelta(minutes=-11) + now = datetime.datetime.now(datetime.timezone.utc) + datetime.timedelta(minutes=-11) now_str = now.strftime('%a, %d %b %Y %H:%M:%S GMT') response = MagicMock() response.headers = {'Date': now_str}