diff --git a/acme/acme/_internal/tests/fields_test.py b/acme/acme/_internal/tests/fields_test.py index a45bdc47b..0c2b8c4a0 100644 --- a/acme/acme/_internal/tests/fields_test.py +++ b/acme/acme/_internal/tests/fields_test.py @@ -34,7 +34,7 @@ class RFC3339FieldTest(unittest.TestCase): """Tests for acme.fields.RFC3339Field.""" def setUp(self): - self.decoded = datetime.datetime(2015, 3, 27, tzinfo=pytz.utc) + self.decoded = datetime.datetime(2015, 3, 27, tzinfo=pytz.UTC) self.encoded = '2015-03-27T00:00:00Z' def test_default_encoder(self): diff --git a/acme/acme/fields.py b/acme/acme/fields.py index bcd0346d8..2ff5da419 100644 --- a/acme/acme/fields.py +++ b/acme/acme/fields.py @@ -34,7 +34,7 @@ class RFC3339Field(jose.Field): Handles decoding/encoding between RFC3339 strings and aware (not naive) `datetime.datetime` objects - (e.g. ``datetime.datetime.now(pytz.utc)``). + (e.g. ``datetime.datetime.now(pytz.UTC)``). """ diff --git a/certbot-ci/certbot_integration_tests/utils/pebble_ocsp_server.py b/certbot-ci/certbot_integration_tests/utils/pebble_ocsp_server.py index 72520bd8b..f01332fed 100755 --- a/certbot-ci/certbot_integration_tests/utils/pebble_ocsp_server.py +++ b/certbot-ci/certbot_integration_tests/utils/pebble_ocsp_server.py @@ -5,6 +5,7 @@ to serve a mock OCSP responder during integration tests against Pebble. """ import datetime import http.server as BaseHTTPServer +import pytz import re from typing import cast from typing import Union @@ -54,7 +55,7 @@ class _ProxyHandler(BaseHTTPServer.BaseHTTPRequestHandler): else: data = response.json() - now = datetime.datetime.utcnow() + now = datetime.datetime.now(pytz.UTC) cert = x509.load_pem_x509_certificate(data['Certificate'].encode(), default_backend()) if data['Status'] != 'Revoked': ocsp_status = ocsp.OCSPCertStatus.GOOD diff --git a/certbot/CHANGELOG.md b/certbot/CHANGELOG.md index 20cc0fb25..7eae5a0a3 100644 --- a/certbot/CHANGELOG.md +++ b/certbot/CHANGELOG.md @@ -17,7 +17,7 @@ Certbot adheres to [Semantic Versioning](https://semver.org/). ### Fixed -* +* Do not call deprecated datetime.utcnow() and datetime.utcfromtimestamp() More details about these changes can be found on our GitHub repo. diff --git a/certbot/certbot/_internal/cert_manager.py b/certbot/certbot/_internal/cert_manager.py index c7205c304..0b6115d26 100644 --- a/certbot/certbot/_internal/cert_manager.py +++ b/certbot/certbot/_internal/cert_manager.py @@ -301,7 +301,7 @@ def human_readable_cert_info(config: configuration.NamespaceConfig, cert: storag return None if config.domains and not set(config.domains).issubset(cert.names()): return None - now = pytz.UTC.fromutc(datetime.datetime.utcnow()) + now = datetime.datetime.now(pytz.UTC) reasons = [] if cert.is_test_cert: diff --git a/certbot/certbot/_internal/storage.py b/certbot/certbot/_internal/storage.py index 7ddc5e929..a535ac336 100644 --- a/certbot/certbot/_internal/storage.py +++ b/certbot/certbot/_internal/storage.py @@ -1023,7 +1023,7 @@ class RenewableCert(interfaces.RenewableCert): interval = self.configuration.get("renew_before_expiry", default_interval) expiry = crypto_util.notAfter(self.version( "cert", self.latest_common_version())) - now = pytz.UTC.fromutc(datetime.datetime.utcnow()) + now = datetime.datetime.now(pytz.UTC) if expiry < add_time_interval(now, interval): logger.debug("Should renew, less than %s before certificate " "expiry %s.", interval, diff --git a/certbot/certbot/_internal/tests/cert_manager_test.py b/certbot/certbot/_internal/tests/cert_manager_test.py index c8483efa7..d5e3b2cc5 100644 --- a/certbot/certbot/_internal/tests/cert_manager_test.py +++ b/certbot/certbot/_internal/tests/cert_manager_test.py @@ -254,7 +254,7 @@ class CertificatesTest(BaseCertManagerTest): import pytz from certbot._internal import cert_manager - expiry = pytz.UTC.fromutc(datetime.datetime.utcnow()) + expiry = datetime.datetime.now(pytz.UTC) cert = mock.MagicMock(lineagename="nameone") cert.target_expiry = expiry diff --git a/certbot/certbot/_internal/tests/main_test.py b/certbot/certbot/_internal/tests/main_test.py index b2b715ea8..c7e8d2167 100644 --- a/certbot/certbot/_internal/tests/main_test.py +++ b/certbot/certbot/_internal/tests/main_test.py @@ -2081,13 +2081,12 @@ class ReportNewCertTest(unittest.TestCase): """ def setUp(self): - from datetime import datetime self.notify_patch = mock.patch('certbot._internal.main.display_util.notify') self.mock_notify = self.notify_patch.start() self.notafter_patch = mock.patch('certbot._internal.main.crypto_util.notAfter') self.mock_notafter = self.notafter_patch.start() - self.mock_notafter.return_value = datetime.utcfromtimestamp(0) + self.mock_notafter.return_value = datetime.datetime(1970, 1, 1, 0, 0) def tearDown(self): self.notify_patch.stop() diff --git a/certbot/certbot/_internal/tests/ocsp_test.py b/certbot/certbot/_internal/tests/ocsp_test.py index 0d1404fcb..86abf8bf4 100644 --- a/certbot/certbot/_internal/tests/ocsp_test.py +++ b/certbot/certbot/_internal/tests/ocsp_test.py @@ -65,7 +65,7 @@ class OCSPTestOpenSSL(unittest.TestCase): @mock.patch('certbot.ocsp.crypto_util.notAfter') @mock.patch('certbot.util.run_script') def test_ocsp_revoked(self, mock_run, mock_na, mock_determine): - now = pytz.UTC.fromutc(datetime.utcnow()) + now = datetime.now(pytz.UTC) cert_obj = mock.MagicMock() cert_obj.cert_path = "x" cert_obj.chain_path = "y" @@ -138,7 +138,7 @@ class OSCPTestCryptography(unittest.TestCase): self.cert_obj = mock.MagicMock() self.cert_obj.cert_path = self.cert_path self.cert_obj.chain_path = self.chain_path - now = pytz.UTC.fromutc(datetime.utcnow()) + now = datetime.now(pytz.UTC) self.mock_notAfter = mock.patch('certbot.ocsp.crypto_util.notAfter', return_value=now + timedelta(hours=2)) self.mock_notAfter.start() @@ -324,8 +324,8 @@ def _construct_mock_ocsp_response(certificate_status, response_status): responder_name=responder.subject, certificates=[responder], hash_algorithm=hashes.SHA1(), - next_update=datetime.now() + timedelta(days=1), - this_update=datetime.now() - timedelta(days=1), + next_update=datetime.now(pytz.UTC).replace(tzinfo=None) + timedelta(days=1), + this_update=datetime.now(pytz.UTC).replace(tzinfo=None) - timedelta(days=1), signature_algorithm_oid=x509.oid.SignatureAlgorithmOID.RSA_WITH_SHA1, ) diff --git a/certbot/certbot/_internal/tests/storage_test.py b/certbot/certbot/_internal/tests/storage_test.py index 3b4075478..020a7062a 100644 --- a/certbot/certbot/_internal/tests/storage_test.py +++ b/certbot/certbot/_internal/tests/storage_test.py @@ -481,8 +481,8 @@ class RenewableCertTests(BaseRenewableCertTest): (1420070400, "10 weeks", True), (1420070400, "10 months", True), (1420070400, "10 years", True), (1420070400, "99 months", True), ]: - sometime = datetime.datetime.utcfromtimestamp(current_time) - mock_datetime.datetime.utcnow.return_value = sometime + sometime = datetime.datetime.fromtimestamp(current_time, pytz.UTC) + mock_datetime.datetime.now.return_value = sometime self.test_rc.configuration["renew_before_expiry"] = interval assert self.test_rc.should_autorenew() == result @@ -739,10 +739,10 @@ class RenewableCertTests(BaseRenewableCertTest): from certbot._internal import storage # this month has 30 days, and the next year is a leap year - time_1 = pytz.UTC.fromutc(datetime.datetime(2003, 11, 20, 11, 59, 21)) + time_1 = datetime.datetime(2003, 11, 20, 11, 59, 21, tzinfo=pytz.UTC) # this month has 31 days, and the next year is not a leap year - time_2 = pytz.UTC.fromutc(datetime.datetime(2012, 10, 18, 21, 31, 16)) + time_2 = datetime.datetime(2012, 10, 18, 21, 31, 16, tzinfo=pytz.UTC) # in different time zone (GMT+8) time_3 = pytz.timezone('Asia/Shanghai').fromutc( diff --git a/certbot/certbot/ocsp.py b/certbot/certbot/ocsp.py index 8f558eb7b..a24f04f0d 100644 --- a/certbot/certbot/ocsp.py +++ b/certbot/certbot/ocsp.py @@ -78,7 +78,7 @@ class RevocationChecker: # Let's Encrypt doesn't update OCSP for expired certificates, # so don't check OCSP if the cert is expired. # https://github.com/certbot/certbot/issues/7152 - now = pytz.UTC.fromutc(datetime.utcnow()) + now = datetime.now(pytz.UTC) if crypto_util.notAfter(cert_path) <= now: return False @@ -233,7 +233,8 @@ def _check_ocsp_response(response_ocsp: 'ocsp.OCSPResponse', request_ocsp: 'ocsp # for OpenSSL, so we do not do it here. # See OpenSSL implementation as a reference: # https://github.com/openssl/openssl/blob/ef45aa14c5af024fcb8bef1c9007f3d1c115bd85/crypto/ocsp/ocsp_cl.c#L338-L391 - now = datetime.utcnow() # thisUpdate/nextUpdate are expressed in UTC/GMT time zone + # thisUpdate/nextUpdate are expressed in UTC/GMT time zone + now = datetime.now(pytz.UTC).replace(tzinfo=None) if not response_ocsp.this_update: raise AssertionError('param thisUpdate is not set.') if response_ocsp.this_update > now + timedelta(minutes=5): diff --git a/pytest.ini b/pytest.ini index 672e2c054..8d06655ff 100644 --- a/pytest.ini +++ b/pytest.ini @@ -26,7 +26,11 @@ # It is also is used in sphinxcontrib-devhelp 1.0.2 which as of writing this # is the latest version of that library. See # https://github.com/sphinx-doc/sphinxcontrib-devhelp/blob/1.0.2/setup.py#L69. +# 6) Ignore DeprecationWarning from using pkg_resources API # 7) Ignore our own PendingDeprecationWarning about Python 3.7 soon to be dropped. +# 8) Ignore DeprecationWarning for datetime.utcfromtimestamp() triggered +# when importing the pytz.tzinfo module +# https://github.com/stub42/pytz/issues/105 filterwarnings = error ignore:decodestring\(\) is a deprecated alias:DeprecationWarning:dns @@ -34,4 +38,6 @@ filterwarnings = ignore:'urllib3.contrib.pyopenssl:DeprecationWarning:requests_toolbelt ignore:update_symlinks is deprecated:PendingDeprecationWarning ignore:.*declare_namespace\(':DeprecationWarning + ignore:pkg_resources is deprecated as an API:DeprecationWarning:pkg_resources ignore:Python 3.7 support will be dropped:PendingDeprecationWarning + ignore:datetime.utcfromtimestamp\(\) is deprecated:DeprecationWarning:pytz.tzinfo