diff --git a/awscli/bcdoc/docstringparser.py b/awscli/bcdoc/docstringparser.py index 868bd5d..3eaf662 100644 --- a/awscli/bcdoc/docstringparser.py +++ b/awscli/bcdoc/docstringparser.py @@ -11,9 +11,10 @@ # ANY KIND, either express or implied. See the License for the specific # language governing permissions and limitations under the License. from botocore.compat import six +from html import parser as html_parser -class DocStringParser(six.moves.html_parser.HTMLParser): +class DocStringParser(html_parser.HTMLParser): """ A simple HTML parser. Focused on converting the subset of HTML that appears in the documentation strings of the JSON models into @@ -23,20 +24,20 @@ class DocStringParser(six.moves.html_parser.HTMLParser): def __init__(self, doc): self.tree = None self.doc = doc - six.moves.html_parser.HTMLParser.__init__(self) + html_parser.HTMLParser.__init__(self) def reset(self): - six.moves.html_parser.HTMLParser.reset(self) + html_parser.HTMLParser.reset(self) self.tree = HTMLTree(self.doc) def feed(self, data): # HTMLParser is an old style class, so the super() method will not work. - six.moves.html_parser.HTMLParser.feed(self, data) + html_parser.HTMLParser.feed(self, data) self.tree.write() self.tree = HTMLTree(self.doc) def close(self): - six.moves.html_parser.HTMLParser.close(self) + html_parser.HTMLParser.close(self) # Write if there is anything remaining. self.tree.write() self.tree = HTMLTree(self.doc) diff --git a/awscli/botocore/auth.py b/awscli/botocore/auth.py index edae233..2483b32 100644 --- a/awscli/botocore/auth.py +++ b/awscli/botocore/auth.py @@ -396,7 +396,7 @@ class SigV4Auth(BaseSigner): def add_auth(self, request): if self.credentials is None: raise NoCredentialsError() - datetime_now = datetime.datetime.utcnow() + datetime_now = datetime.datetime.now(datetime.UTC) request.context['timestamp'] = datetime_now.strftime(SIGV4_TIMESTAMP) # This could be a retry. Make sure the previous # authorization header is removed first. @@ -611,7 +611,7 @@ class S3SigV4PostAuth(SigV4Auth): http://docs.aws.amazon.com/AmazonS3/latest/API/sigv4-UsingHTTPPOST.html """ def add_auth(self, request): - datetime_now = datetime.datetime.utcnow() + datetime_now = datetime.datetime.now(datetime.UTC) request.context['timestamp'] = datetime_now.strftime(SIGV4_TIMESTAMP) fields = {} diff --git a/awscli/botocore/compat.py b/awscli/botocore/compat.py index b189271..de182f4 100644 --- a/awscli/botocore/compat.py +++ b/awscli/botocore/compat.py @@ -33,7 +33,7 @@ from urllib3 import exceptions logger = logging.getLogger(__name__) -from botocore.vendored.six.moves import http_client +from http import client as http_client class HTTPHeaders(http_client.HTTPMessage): pass diff --git a/awscli/botocore/configloader.py b/awscli/botocore/configloader.py index 3d1de2f..d8120c6 100644 --- a/awscli/botocore/configloader.py +++ b/awscli/botocore/configloader.py @@ -18,6 +18,7 @@ import sys import botocore.exceptions from botocore.compat import six +import configparser def multi_file_load_config(*filenames): @@ -143,10 +144,10 @@ def raw_config_parse(config_filename, parse_subsections=True): path = os.path.expanduser(path) if not os.path.isfile(path): raise botocore.exceptions.ConfigNotFound(path=_unicode_path(path)) - cp = six.moves.configparser.RawConfigParser() + cp = configparser.RawConfigParser() try: cp.read([path]) - except (six.moves.configparser.Error, UnicodeDecodeError): + except (configparser.Error, UnicodeDecodeError): raise botocore.exceptions.ConfigParseError( path=_unicode_path(path)) else: diff --git a/awscli/botocore/crt/auth.py b/awscli/botocore/crt/auth.py index 534a7f8..474e675 100644 --- a/awscli/botocore/crt/auth.py +++ b/awscli/botocore/crt/auth.py @@ -57,8 +57,7 @@ class CrtSigV4Auth(BaseSigner): # Use utcnow() because that's what gets mocked by tests, but set # timezone because CRT assumes naive datetime is local time. - datetime_now = datetime.datetime.utcnow().replace( - tzinfo=datetime.timezone.utc) + datetime_now = datetime.datetime.now(datetime.UTC) # Use existing 'X-Amz-Content-SHA256' header if able existing_sha256 = self._get_existing_sha256(request) @@ -247,8 +246,7 @@ class CrtSigV4AsymAuth(BaseSigner): # Use utcnow() because that's what gets mocked by tests, but set # timezone because CRT assumes naive datetime is local time. - datetime_now = datetime.datetime.utcnow().replace( - tzinfo=datetime.timezone.utc) + datetime_now = datetime.datetime.now(datetime.UTC) # Use existing 'X-Amz-Content-SHA256' header if able existing_sha256 = self._get_existing_sha256(request) diff --git a/awscli/botocore/docs/bcdoc/docstringparser.py b/awscli/botocore/docs/bcdoc/docstringparser.py index 868bd5d..3eaf662 100644 --- a/awscli/botocore/docs/bcdoc/docstringparser.py +++ b/awscli/botocore/docs/bcdoc/docstringparser.py @@ -11,9 +11,10 @@ # ANY KIND, either express or implied. See the License for the specific # language governing permissions and limitations under the License. from botocore.compat import six +from html import parser as html_parser -class DocStringParser(six.moves.html_parser.HTMLParser): +class DocStringParser(html_parser.HTMLParser): """ A simple HTML parser. Focused on converting the subset of HTML that appears in the documentation strings of the JSON models into @@ -23,20 +24,20 @@ class DocStringParser(six.moves.html_parser.HTMLParser): def __init__(self, doc): self.tree = None self.doc = doc - six.moves.html_parser.HTMLParser.__init__(self) + html_parser.HTMLParser.__init__(self) def reset(self): - six.moves.html_parser.HTMLParser.reset(self) + html_parser.HTMLParser.reset(self) self.tree = HTMLTree(self.doc) def feed(self, data): # HTMLParser is an old style class, so the super() method will not work. - six.moves.html_parser.HTMLParser.feed(self, data) + html_parser.HTMLParser.feed(self, data) self.tree.write() self.tree = HTMLTree(self.doc) def close(self): - six.moves.html_parser.HTMLParser.close(self) + html_parser.HTMLParser.close(self) # Write if there is anything remaining. self.tree.write() self.tree = HTMLTree(self.doc) diff --git a/awscli/botocore/httpsession.py b/awscli/botocore/httpsession.py index 29b2103..d51dfdd 100644 --- a/awscli/botocore/httpsession.py +++ b/awscli/botocore/httpsession.py @@ -59,7 +59,7 @@ from botocore.exceptions import ( ReadTimeoutError, SSLError, ) -from botocore.vendored.six.moves.urllib_parse import unquote +from urllib.parse import unquote filter_ssl_warnings() logger = logging.getLogger(__name__) diff --git a/awscli/botocore/parsers.py b/awscli/botocore/parsers.py index ffca974..367c867 100644 --- a/awscli/botocore/parsers.py +++ b/awscli/botocore/parsers.py @@ -119,7 +119,8 @@ import json import logging import re -from botocore.compat import ETree, XMLParseError, six +from botocore.compat import ETree, XMLParseError +from http import client as http_client from botocore.eventstream import EventStream, NoInitialResponseError from botocore.utils import ( is_json_value_header, @@ -300,7 +301,7 @@ class ResponseParser(object): "service, unable to populate error code and message.") return { 'Error': {'Code': str(response['status_code']), - 'Message': six.moves.http_client.responses.get( + 'Message': http_client.responses.get( response['status_code'], '')}, 'ResponseMetadata': {}, } @@ -1035,7 +1036,7 @@ class RestXMLParser(BaseRestParser, BaseXMLResponseParser): return { 'Error': { 'Code': str(response['status_code']), - 'Message': six.moves.http_client.responses.get( + 'Message': http_client.responses.get( response['status_code'], ''), }, 'ResponseMetadata': { diff --git a/awscli/botocore/signers.py b/awscli/botocore/signers.py index 77a9346..93b8af0 100644 --- a/awscli/botocore/signers.py +++ b/awscli/botocore/signers.py @@ -532,7 +532,7 @@ class S3PostPresigner(object): policy = {} # Create an expiration date for the policy - datetime_now = datetime.datetime.utcnow() + datetime_now = datetime.datetime.now(datetime.UTC) expire_date = datetime_now + datetime.timedelta(seconds=expires_in) policy['expiration'] = expire_date.strftime(botocore.auth.ISO8601) diff --git a/awscli/botocore/utils.py b/awscli/botocore/utils.py index 81b41dc..0740339 100644 --- a/awscli/botocore/utils.py +++ b/awscli/botocore/utils.py @@ -70,7 +70,7 @@ from botocore.exceptions import ( UnsupportedS3ControlArnError, UnsupportedS3ControlConfigurationError, ) -from botocore.vendored.six.moves.urllib.request import getproxies, proxy_bypass +from urllib.request import getproxies, proxy_bypass from dateutil.tz import tzutc from urllib3.exceptions import LocationParseError @@ -577,7 +577,7 @@ class InstanceMetadataFetcher(IMDSFetcher): "ec2_credential_refresh_window", 60 * 10 ) refresh_interval_with_jitter = refresh_interval + random.randint(120, 600) - current_time = datetime.datetime.utcnow() + current_time = datetime.datetime.now(datetime.UTC) refresh_offset = datetime.timedelta(seconds=refresh_interval_with_jitter) extension_time = expiration - refresh_offset if current_time >= extension_time: diff --git a/awscli/compat.py b/awscli/compat.py index 705255d..b418c19 100644 --- a/awscli/compat.py +++ b/awscli/compat.py @@ -25,6 +25,8 @@ from functools import partial import urllib.parse as urlparse from urllib.error import URLError +import queue +import urllib.request from botocore.compat import six from botocore.compat import OrderedDict @@ -33,11 +35,10 @@ from botocore.compat import OrderedDict # This may get large. advance_iterator = six.advance_iterator PY3 = six.PY3 -queue = six.moves.queue -shlex_quote = six.moves.shlex_quote +shlex_quote = shlex.quote StringIO = six.StringIO BytesIO = six.BytesIO -urlopen = six.moves.urllib.request.urlopen +urlopen = urllib.request.urlopen binary_type = six.binary_type # Most, but not all, python installations will have zlib. This is required to diff --git a/awscli/customizations/cloudformation/deployer.py b/awscli/customizations/cloudformation/deployer.py index 3733c55..48e69a6 100644 --- a/awscli/customizations/cloudformation/deployer.py +++ b/awscli/customizations/cloudformation/deployer.py @@ -20,7 +20,7 @@ import collections from awscli.customizations.cloudformation import exceptions from awscli.customizations.cloudformation.artifact_exporter import mktempfile, parse_s3_url -from datetime import datetime +from datetime import datetime, UTC LOG = logging.getLogger(__name__) @@ -85,7 +85,7 @@ class Deployer(object): :return: """ - now = datetime.utcnow().isoformat() + now = datetime.now(UTC).isoformat() description = "Created by AWS CLI at {0} UTC".format(now) # Each changeset will get a unique name based on time diff --git a/awscli/customizations/cloudtrail/validation.py b/awscli/customizations/cloudtrail/validation.py index 78e2540..9a515e0 100644 --- a/awscli/customizations/cloudtrail/validation.py +++ b/awscli/customizations/cloudtrail/validation.py @@ -19,7 +19,7 @@ import re import sys import zlib from zlib import error as ZLibError -from datetime import datetime, timedelta +from datetime import datetime, timedelta, UTC from dateutil import tz, parser import cryptography @@ -401,7 +401,7 @@ class DigestTraverser(object): :param end_date: Date to stop validating at (inclusive). """ if end_date is None: - end_date = datetime.utcnow() + end_date = datetime.now(UTC) end_date = normalize_date(end_date) start_date = normalize_date(start_date) bucket = self.starting_bucket @@ -703,7 +703,7 @@ class CloudTrailValidateLogs(BasicCommand): if args.end_time: self.end_time = normalize_date(parse_date(args.end_time)) else: - self.end_time = normalize_date(datetime.utcnow()) + self.end_time = datetime.now(UTC) if self.start_time > self.end_time: raise ParamValidationError( 'Invalid time range specified: start-time must ' diff --git a/awscli/customizations/codecommit.py b/awscli/customizations/codecommit.py index 6b30e83..935f27b 100644 --- a/awscli/customizations/codecommit.py +++ b/awscli/customizations/codecommit.py @@ -150,7 +150,7 @@ class CodeCommitGetCommand(BasicCommand): request = AWSRequest() request.url = url_to_sign request.method = 'GIT' - now = datetime.datetime.utcnow() + now = datetime.datetime.now(datetime.UTC) request.context['timestamp'] = now.strftime('%Y%m%dT%H%M%S') split = urlsplit(request.url) # we don't want to include the port number in the signature diff --git a/awscli/customizations/codedeploy/push.py b/awscli/customizations/codedeploy/push.py index 4c08664..8531c03 100644 --- a/awscli/customizations/codedeploy/push.py +++ b/awscli/customizations/codedeploy/push.py @@ -16,7 +16,7 @@ import sys import zipfile import tempfile import contextlib -from datetime import datetime +from datetime import datetime, UTC from botocore.exceptions import ClientError @@ -133,7 +133,7 @@ class Push(BasicCommand): if not parsed_args.description: parsed_args.description = ( 'Uploaded by AWS CLI {0} UTC'.format( - datetime.utcnow().isoformat() + datetime.now(UTC).isoformat() ) ) diff --git a/awscli/customizations/configure/__init__.py b/awscli/customizations/configure/__init__.py index ab06305..55f11a9 100644 --- a/awscli/customizations/configure/__init__.py +++ b/awscli/customizations/configure/__init__.py @@ -11,7 +11,7 @@ # ANY KIND, either express or implied. See the License for the specific # language governing permissions and limitations under the License. import string -from botocore.vendored.six.moves import shlex_quote +from shlex import quote as shlex_quote NOT_SET = '' PREDEFINED_SECTION_NAMES = ('plugins') diff --git a/awscli/customizations/datapipeline/__init__.py b/awscli/customizations/datapipeline/__init__.py index c47ca94..309406c 100644 --- a/awscli/customizations/datapipeline/__init__.py +++ b/awscli/customizations/datapipeline/__init__.py @@ -12,7 +12,7 @@ # language governing permissions and limitations under the License. import json -from datetime import datetime, timedelta +from datetime import datetime, timedelta, UTC from awscli.formatter import get_formatter from awscli.arguments import CustomArgument @@ -186,7 +186,7 @@ class QueryArgBuilder(object): """ def __init__(self, current_time=None): if current_time is None: - current_time = datetime.utcnow() + current_time = datetime.now(UTC) self.current_time = current_time def build_query(self, parsed_args): diff --git a/awscli/customizations/ec2/bundleinstance.py b/awscli/customizations/ec2/bundleinstance.py index 96d9ece..31a4962 100644 --- a/awscli/customizations/ec2/bundleinstance.py +++ b/awscli/customizations/ec2/bundleinstance.py @@ -120,7 +120,7 @@ def _generate_policy(params): # Called if there is no policy supplied by the user. # Creates a policy that provides access for 24 hours. delta = datetime.timedelta(hours=24) - expires = datetime.datetime.utcnow() + delta + expires = datetime.datetime.now(datetime.UTC) + delta expires_iso = expires.strftime("%Y-%m-%dT%H:%M:%S.%fZ") policy = POLICY.format(expires=expires_iso, bucket=params['Bucket'], diff --git a/awscli/customizations/eks/get_token.py b/awscli/customizations/eks/get_token.py index c85b86d..4d12661 100644 --- a/awscli/customizations/eks/get_token.py +++ b/awscli/customizations/eks/get_token.py @@ -16,7 +16,7 @@ import json import os import sys -from datetime import datetime, timedelta +from datetime import datetime, timedelta, UTC from botocore.signers import RequestSigner from botocore.model import ServiceId @@ -106,7 +106,7 @@ class GetTokenCommand(BasicCommand): ] def get_expiration_time(self): - token_expiration = datetime.utcnow() + timedelta( + token_expiration = datetime.now(UTC) + timedelta( minutes=TOKEN_EXPIRATION_MINS ) return token_expiration.strftime('%Y-%m-%dT%H:%M:%SZ') diff --git a/awscli/customizations/logs/tail.py b/awscli/customizations/logs/tail.py index cb31510..b2f8563 100644 --- a/awscli/customizations/logs/tail.py +++ b/awscli/customizations/logs/tail.py @@ -11,7 +11,8 @@ # ANY KIND, either express or implied. See the License for the specific # language governing permissions and limitations under the License. from collections import defaultdict -from datetime import datetime, timedelta +from datetime import datetime, timedelta, UTC +import functools import json import re import time @@ -261,7 +262,7 @@ class TimestampUtils(object): def __init__(self, now=None): self._now = now if now is None: - self._now = datetime.utcnow + self._now = functools.partial(datetime.now, UTC) def to_epoch_millis(self, timestamp): re_match = self._RELATIVE_TIMESTAMP_REGEX.match(timestamp) diff --git a/awscli/customizations/opsworks.py b/awscli/customizations/opsworks.py index a2a0c1e..217bfca 100644 --- a/awscli/customizations/opsworks.py +++ b/awscli/customizations/opsworks.py @@ -507,7 +507,7 @@ class OpsWorksRegister(BasicCommand): "Resource": arn, } if timeout is not None: - valid_until = datetime.datetime.utcnow() + timeout + valid_until = datetime.datetime.now(datetime.UTC) + timeout statement["Condition"] = { "DateLessThan": { "aws:CurrentTime": diff --git a/tests/functional/botocore/test_credentials.py b/tests/functional/botocore/test_credentials.py index 843be90..1bd9201 100644 --- a/tests/functional/botocore/test_credentials.py +++ b/tests/functional/botocore/test_credentials.py @@ -19,7 +19,7 @@ import time import mock import tempfile import shutil -from datetime import datetime, timedelta +from datetime import datetime, timedelta, UTC import sys import pytest @@ -47,8 +47,8 @@ from botocore.stub import Stubber from botocore.tokens import SSOTokenProvider from botocore.utils import datetime2timestamp -TIME_IN_ONE_HOUR = datetime.utcnow() + timedelta(hours=1) -TIME_IN_SIX_MONTHS = datetime.utcnow() + timedelta(hours=4320) +TIME_IN_ONE_HOUR = datetime.now(UTC) + timedelta(hours=1) +TIME_IN_SIX_MONTHS = datetime.now(UTC) + timedelta(hours=4320) class TestCredentialRefreshRaces(unittest.TestCase): diff --git a/tests/functional/botocore/test_ec2.py b/tests/functional/botocore/test_ec2.py index 795094e..fed43d2 100644 --- a/tests/functional/botocore/test_ec2.py +++ b/tests/functional/botocore/test_ec2.py @@ -86,13 +86,13 @@ class TestCopySnapshotCustomization(BaseSessionTest): '%s\n' '\n' ) - self.now = datetime.datetime(2011, 9, 9, 23, 36) + self.now = datetime.datetime(2011, 9, 9, 23, 36, tzinfo=datetime.UTC) self.datetime_patch = mock.patch.object( botocore.auth.datetime, 'datetime', mock.Mock(wraps=datetime.datetime) ) self.mocked_datetime = self.datetime_patch.start() - self.mocked_datetime.utcnow.return_value = self.now + self.mocked_datetime.now.return_value = self.now def tearDown(self): super(TestCopySnapshotCustomization, self).tearDown() diff --git a/tests/functional/botocore/test_lex.py b/tests/functional/botocore/test_lex.py index 7e7f619..eb623ec 100644 --- a/tests/functional/botocore/test_lex.py +++ b/tests/functional/botocore/test_lex.py @@ -11,7 +11,7 @@ # ANY KIND, either express or implied. See the License for the specific # language governing permissions and limitations under the License. import mock -from datetime import datetime +from datetime import datetime, UTC from tests import BaseSessionTest, ClientHTTPStubber @@ -32,10 +32,10 @@ class TestLex(BaseSessionTest): 'inputStream': b'' } - timestamp = datetime(2017, 3, 22, 0, 0) + timestamp = datetime(2017, 3, 22, 0, 0, tzinfo=UTC) with mock.patch('botocore.auth.datetime') as _datetime: - _datetime.datetime.utcnow.return_value = timestamp + _datetime.datetime.now.return_value = timestamp self.http_stubber.add_response(body=b'{}') with self.http_stubber: self.client.post_content(**params) diff --git a/tests/functional/botocore/test_sts.py b/tests/functional/botocore/test_sts.py index cdc212a..75b367c 100644 --- a/tests/functional/botocore/test_sts.py +++ b/tests/functional/botocore/test_sts.py @@ -10,7 +10,7 @@ # distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF # ANY KIND, either express or implied. See the License for the specific # language governing permissions and limitations under the License. -from datetime import datetime +from datetime import datetime, UTC import re import mock @@ -38,9 +38,9 @@ class TestSTSPresignedUrl(BaseSessionTest): self.stubber.activate() def test_presigned_url_contains_no_content_type(self): - timestamp = datetime(2017, 3, 22, 0, 0) + timestamp = datetime(2017, 3, 22, 0, 0, tzinfo=UTC) with mock.patch('botocore.auth.datetime') as _datetime: - _datetime.datetime.utcnow.return_value = timestamp + _datetime.datetime.now.return_value = timestamp url = self.client.generate_presigned_url('get_caller_identity', {}) # There should be no 'content-type' in x-amz-signedheaders diff --git a/tests/functional/ec2/test_bundle_instance.py b/tests/functional/ec2/test_bundle_instance.py index 5bc3204..7dcc416 100644 --- a/tests/functional/ec2/test_bundle_instance.py +++ b/tests/functional/ec2/test_bundle_instance.py @@ -34,7 +34,7 @@ class TestBundleInstance(BaseAWSCommandParamsTest): def setUp(self): super(TestBundleInstance, self).setUp() - # This mocks out datetime.datetime.utcnow() so that it always + # This mocks out datetime.datetime.now() so that it always # returns the same datetime object. This is because this value # is embedded into the policy file that is generated and we # don't what the policy or its signature to change each time @@ -44,7 +44,7 @@ class TestBundleInstance(BaseAWSCommandParamsTest): mock.Mock(wraps=datetime.datetime) ) mocked_datetime = self.datetime_patcher.start() - mocked_datetime.utcnow.return_value = datetime.datetime(2013, 8, 9) + mocked_datetime.now.return_value = datetime.datetime(2013, 8, 9, tzinfo=datetime.UTC) def tearDown(self): super(TestBundleInstance, self).tearDown() diff --git a/tests/functional/ec2instanceconnect/test_opentunnel.py b/tests/functional/ec2instanceconnect/test_opentunnel.py index 83f824d..ddefc47 100644 --- a/tests/functional/ec2instanceconnect/test_opentunnel.py +++ b/tests/functional/ec2instanceconnect/test_opentunnel.py @@ -310,10 +310,10 @@ def request_params_for_describe_eice(): @pytest.fixture -def datetime_utcnow_patch(): +def datetime_now_patch(): clock = datetime.datetime(2020, 1, 1, 1, 1, 1, tzinfo=tzutc()) with mock.patch('datetime.datetime') as dt: - dt.utcnow.return_value = clock + dt.now.return_value = clock yield dt @@ -393,7 +393,7 @@ class TestOpenTunnel: describe_eice_response, request_params_for_describe_instance, request_params_for_describe_eice, - datetime_utcnow_patch, + datetime_now_patch, ): cli_runner.env["AWS_USE_FIPS_ENDPOINT"] = "false" cmdline = [ diff --git a/tests/functional/eks/test_get_token.py b/tests/functional/eks/test_get_token.py index 89801f9..ea48865 100644 --- a/tests/functional/eks/test_get_token.py +++ b/tests/functional/eks/test_get_token.py @@ -11,7 +11,7 @@ # ANY KIND, either express or implied. See the License for the specific # language governing permissions and limitations under the License. import base64 -from datetime import datetime +from datetime import datetime, UTC import json import os @@ -80,7 +80,7 @@ class TestGetTokenCommand(BaseAWSCommandParamsTest): @mock.patch('awscli.customizations.eks.get_token.datetime') def test_get_token(self, mock_datetime): - mock_datetime.utcnow.return_value = datetime(2019, 10, 23, 23, 0, 0, 0) + mock_datetime.now.return_value = datetime(2019, 10, 23, 23, 0, 0, 0, tzinfo=UTC) cmd = 'eks get-token --cluster-name %s' % self.cluster_name response = self.run_get_token(cmd) self.assertEqual( @@ -98,7 +98,7 @@ class TestGetTokenCommand(BaseAWSCommandParamsTest): @mock.patch('awscli.customizations.eks.get_token.datetime') def test_query_nested_object(self, mock_datetime): - mock_datetime.utcnow.return_value = datetime(2019, 10, 23, 23, 0, 0, 0) + mock_datetime.now.return_value = datetime(2019, 10, 23, 23, 0, 0, 0, tzinfo=UTC) cmd = 'eks get-token --cluster-name %s' % self.cluster_name cmd += ' --query status' response = self.run_get_token(cmd) @@ -120,7 +120,7 @@ class TestGetTokenCommand(BaseAWSCommandParamsTest): @mock.patch('awscli.customizations.eks.get_token.datetime') def test_output_text(self, mock_datetime): - mock_datetime.utcnow.return_value = datetime(2019, 10, 23, 23, 0, 0, 0) + mock_datetime.now.return_value = datetime(2019, 10, 23, 23, 0, 0, 0, tzinfo=UTC) cmd = 'eks get-token --cluster-name %s' % self.cluster_name cmd += ' --output text' stdout, _, _ = self.run_cmd(cmd) @@ -130,7 +130,7 @@ class TestGetTokenCommand(BaseAWSCommandParamsTest): @mock.patch('awscli.customizations.eks.get_token.datetime') def test_output_table(self, mock_datetime): - mock_datetime.utcnow.return_value = datetime(2019, 10, 23, 23, 0, 0, 0) + mock_datetime.now.return_value = datetime(2019, 10, 23, 23, 0, 0, 0, tzinfo=UTC) cmd = 'eks get-token --cluster-name %s' % self.cluster_name cmd += ' --output table' stdout, _, _ = self.run_cmd(cmd) diff --git a/tests/functional/logs/test_tail.py b/tests/functional/logs/test_tail.py index 6049a7f..5707da9 100644 --- a/tests/functional/logs/test_tail.py +++ b/tests/functional/logs/test_tail.py @@ -152,7 +152,7 @@ class TestTailCommand(BaseAWSCommandParamsTest): def test_tail_defaults_to_10m(self): datetime_mock = mock.Mock(wraps=datetime) - datetime_mock.utcnow = mock.Mock( + datetime_mock.now = mock.Mock( return_value=datetime(1970, 1, 1, 0, 10, 1, tzinfo=tz.tzutc())) with mock.patch('awscli.customizations.logs.tail.datetime', new=datetime_mock): @@ -177,7 +177,7 @@ class TestTailCommand(BaseAWSCommandParamsTest): def test_tail_with_relative_since(self): datetime_mock = mock.Mock(wraps=datetime) - datetime_mock.utcnow = mock.Mock( + datetime_mock.now = mock.Mock( return_value=datetime(1970, 1, 1, 0, 0, 2, tzinfo=tz.tzutc())) with mock.patch('awscli.customizations.logs.tail.datetime', new=datetime_mock): diff --git a/tests/functional/rds/test_generate_db_auth_token.py b/tests/functional/rds/test_generate_db_auth_token.py index 795b939..4562b92 100644 --- a/tests/functional/rds/test_generate_db_auth_token.py +++ b/tests/functional/rds/test_generate_db_auth_token.py @@ -53,7 +53,7 @@ class TestGenerateDBAuthToken(BaseAWSCommandParamsTest): clock = datetime.datetime(2016, 11, 7, 17, 39, 33, tzinfo=tzutc()) with mock.patch('datetime.datetime') as dt: - dt.utcnow.return_value = clock + dt.now.return_value = clock stdout, _, _ = self.run_cmd(command, expected_rc=0) expected = ( diff --git a/tests/functional/s3/test_presign_command.py b/tests/functional/s3/test_presign_command.py index 2db338a..8b3120a 100644 --- a/tests/functional/s3/test_presign_command.py +++ b/tests/functional/s3/test_presign_command.py @@ -18,13 +18,13 @@ from awscli.testutils import BaseAWSCommandParamsTest, mock, temporary_file from awscli.testutils import create_clidriver -# Values used to fix time.time() and datetime.datetime.utcnow() +# Values used to fix time.time() and datetime.datetime.now() # so we know the exact values of the signatures generated. FROZEN_TIMESTAMP = 1471305652 DEFAULT_EXPIRES = 3600 FROZEN_TIME = mock.Mock(return_value=FROZEN_TIMESTAMP) FROZEN_DATETIME = mock.Mock( - return_value=datetime.datetime(2016, 8, 18, 14, 33, 3, 0)) + return_value=datetime.datetime(2016, 8, 18, 14, 33, 3, 0, tzinfo=datetime.UTC)) class TestPresignCommand(BaseAWSCommandParamsTest): @@ -78,7 +78,7 @@ class TestPresignCommand(BaseAWSCommandParamsTest): def get_presigned_url_for_cmd(self, cmdline): with mock.patch('time.time', FROZEN_TIME): with mock.patch('datetime.datetime') as d: - d.utcnow = FROZEN_DATETIME + d.now = FROZEN_DATETIME stdout = self.assert_params_for_cmd(cmdline, None)[0].strip() return stdout diff --git a/tests/integration/botocore/test_client_http.py b/tests/integration/botocore/test_client_http.py index d6b0902..4e66fdf 100644 --- a/tests/integration/botocore/test_client_http.py +++ b/tests/integration/botocore/test_client_http.py @@ -8,7 +8,8 @@ from contextlib import contextmanager import botocore.session from botocore.config import Config -from botocore.vendored.six.moves import BaseHTTPServer, socketserver +from http import server as BaseHTTPServer +import socketserver from botocore.exceptions import ( ConnectTimeoutError, ReadTimeoutError, EndpointConnectionError, ConnectionClosedError, ClientError, ProxyConnectionError diff --git a/tests/unit/botocore/auth/test_signers.py b/tests/unit/botocore/auth/test_signers.py index 73d3b12..3b3922d 100644 --- a/tests/unit/botocore/auth/test_signers.py +++ b/tests/unit/botocore/auth/test_signers.py @@ -31,7 +31,7 @@ class BaseTestWithFixedDate(unittest.TestCase): self.fixed_date = datetime.datetime(2014, 3, 10, 17, 2, 55, 0) self.datetime_patch = mock.patch('botocore.auth.datetime.datetime') self.datetime_mock = self.datetime_patch.start() - self.datetime_mock.utcnow.return_value = self.fixed_date + self.datetime_mock.now.return_value = self.fixed_date.replace(tzinfo=datetime.UTC) self.datetime_mock.strptime.return_value = self.fixed_date def tearDown(self): @@ -358,9 +358,9 @@ class TestSigV4(unittest.TestCase): with mock.patch.object( botocore.auth.datetime, 'datetime', mock.Mock(wraps=datetime.datetime)) as mock_datetime: - original_utcnow = datetime.datetime(2014, 1, 1, 0, 0) + original_now = datetime.datetime(2014, 1, 1, 0, 0, tzinfo=datetime.UTC) - mock_datetime.utcnow.return_value = original_utcnow + mock_datetime.now.return_value = original_now # Go through the add_auth process once. This will attach # a timestamp to the request at the beginning of auth. auth.add_auth(request) @@ -368,8 +368,8 @@ class TestSigV4(unittest.TestCase): # Ensure the date is in the Authorization header self.assertIn('20140101', request.headers['Authorization']) # Now suppose the utc time becomes the next day all of a sudden - mock_datetime.utcnow.return_value = datetime.datetime( - 2014, 1, 2, 0, 0) + mock_datetime.now.return_value = datetime.datetime( + 2014, 1, 2, 0, 0, tzinfo=datetime.UTC) # Smaller methods like the canonical request and string_to_sign # should have the timestamp attached to the request in their # body and not what the time is now mocked as. This is to ensure @@ -535,8 +535,8 @@ class TestSigV4Presign(BasePresignTest): mock.Mock(wraps=datetime.datetime) ) mocked_datetime = self.datetime_patcher.start() - mocked_datetime.utcnow.return_value = datetime.datetime( - 2014, 1, 1, 0, 0) + mocked_datetime.now.return_value = datetime.datetime( + 2014, 1, 1, 0, 0, tzinfo=datetime.UTC) def tearDown(self): self.datetime_patcher.stop() @@ -730,8 +730,8 @@ class TestS3SigV4Post(BaseS3PresignPostTest): mock.Mock(wraps=datetime.datetime) ) mocked_datetime = self.datetime_patcher.start() - mocked_datetime.utcnow.return_value = datetime.datetime( - 2014, 1, 1, 0, 0) + mocked_datetime.now.return_value = datetime.datetime( + 2014, 1, 1, 0, 0, tzinfo=datetime.UTC) def tearDown(self): self.datetime_patcher.stop() diff --git a/tests/unit/botocore/test_client.py b/tests/unit/botocore/test_client.py index f28b959..1b3d56b 100644 --- a/tests/unit/botocore/test_client.py +++ b/tests/unit/botocore/test_client.py @@ -960,7 +960,7 @@ class TestAutoGeneratedClient(unittest.TestCase): lines = [ (' Creates an iterator that will paginate through responses ' 'from :py:meth:`MyService.Client.test_operation`.'), - ' **Request Syntax** ', + ' **Request Syntax**', ' ::', ' response_iterator = paginator.paginate(', " Foo='string',", @@ -976,17 +976,17 @@ class TestAutoGeneratedClient(unittest.TestCase): ' :type Bar: string', ' :param Bar: Documents Bar', ' :type PaginationConfig: dict', - ' :param PaginationConfig: ', + ' :param PaginationConfig:', (' A dictionary that provides parameters to control ' 'pagination.'), - ' - **MaxItems** *(integer) --* ', + ' - **MaxItems** *(integer) --*', (' The total number of items to return. If the total ' 'number of items available is more than the value specified ' 'in max-items then a ``NextToken`` will be provided in the ' 'output that you can use to resume pagination.'), - ' - **PageSize** *(integer) --* ', + ' - **PageSize** *(integer) --*', ' The size of each page.', - ' - **StartingToken** *(string) --* ', + ' - **StartingToken** *(string) --*', (' A token to specify where to start paginating. This is ' 'the ``NextToken`` from a previous response.'), ' :returns: None', diff --git a/tests/unit/botocore/test_credentials.py b/tests/unit/botocore/test_credentials.py index cc49596..0a5e4d7 100644 --- a/tests/unit/botocore/test_credentials.py +++ b/tests/unit/botocore/test_credentials.py @@ -11,7 +11,7 @@ # distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF # ANY KIND, either express or implied. See the License for the specific # language governing permissions and limitations under the License. -from datetime import datetime, timedelta +from datetime import datetime, timedelta, UTC import subprocess import mock import os @@ -291,8 +291,8 @@ class TestAssumeRoleCredentialFetcher(BaseEnvVar): self.assertEqual(response, expected_response) def test_retrieves_from_cache(self): - date_in_future = datetime.utcnow() + timedelta(seconds=1000) - utc_timestamp = date_in_future.isoformat() + 'Z' + date_in_future = datetime.now(UTC) + timedelta(seconds=1000) + utc_timestamp = date_in_future.isoformat() cache_key = ( '793d6e2f27667ab2da104824407e486bfec24a47' ) @@ -703,8 +703,8 @@ class TestAssumeRoleWithWebIdentityCredentialFetcher(BaseEnvVar): self.assertEqual(response, expected_response) def test_retrieves_from_cache(self): - date_in_future = datetime.utcnow() + timedelta(seconds=1000) - utc_timestamp = date_in_future.isoformat() + 'Z' + date_in_future = datetime.now(UTC) + timedelta(seconds=1000) + utc_timestamp = date_in_future.isoformat() cache_key = ( '793d6e2f27667ab2da104824407e486bfec24a47' ) @@ -823,8 +823,8 @@ class TestAssumeRoleWithWebIdentityCredentialProvider(unittest.TestCase): mock_loader_cls.assert_called_with('/some/path/token.jwt') def test_assume_role_retrieves_from_cache(self): - date_in_future = datetime.utcnow() + timedelta(seconds=1000) - utc_timestamp = date_in_future.isoformat() + 'Z' + date_in_future = datetime.now(UTC) + timedelta(seconds=1000) + utc_timestamp = date_in_future.isoformat() cache_key = ( 'c29461feeacfbed43017d20612606ff76abc073d' @@ -1961,8 +1961,8 @@ class TestAssumeRoleCredentialProvider(unittest.TestCase): self.assertEqual(expiry_time, '2016-11-06T01:30:00UTC') def test_assume_role_retrieves_from_cache(self): - date_in_future = datetime.utcnow() + timedelta(seconds=1000) - utc_timestamp = date_in_future.isoformat() + 'Z' + date_in_future = datetime.now(UTC) + timedelta(seconds=1000) + utc_timestamp = date_in_future.isoformat() self.fake_config['profiles']['development']['role_arn'] = 'myrole' cache_key = ( @@ -1989,8 +1989,8 @@ class TestAssumeRoleCredentialProvider(unittest.TestCase): self.assertEqual(creds.token, 'baz-cached') def test_chain_prefers_cache(self): - date_in_future = datetime.utcnow() + timedelta(seconds=1000) - utc_timestamp = date_in_future.isoformat() + 'Z' + date_in_future = datetime.now(UTC) + timedelta(seconds=1000) + utc_timestamp = date_in_future.isoformat() # The profile we will be using has a cache entry, but the profile it # is sourcing from does not. This should result in the cached diff --git a/tests/unit/botocore/test_signers.py b/tests/unit/botocore/test_signers.py index e06e0c1..fc56d71 100644 --- a/tests/unit/botocore/test_signers.py +++ b/tests/unit/botocore/test_signers.py @@ -609,9 +609,9 @@ class TestS3PostPresigner(BaseSignerTest): self.datetime_patch = mock.patch('botocore.signers.datetime') self.datetime_mock = self.datetime_patch.start() - self.fixed_date = datetime.datetime(2014, 3, 10, 17, 2, 55, 0) + self.fixed_date = datetime.datetime(2014, 3, 10, 17, 2, 55, 0, tzinfo=datetime.UTC) self.fixed_delta = datetime.timedelta(seconds=3600) - self.datetime_mock.datetime.utcnow.return_value = self.fixed_date + self.datetime_mock.datetime.now.return_value = self.fixed_date self.datetime_mock.timedelta.return_value = self.fixed_delta def tearDown(self): @@ -979,7 +979,7 @@ class TestGenerateDBAuthToken(BaseSignerTest): clock = datetime.datetime(2016, 11, 7, 17, 39, 33, tzinfo=tzutc()) with mock.patch('datetime.datetime') as dt: - dt.utcnow.return_value = clock + dt.now.return_value = clock result = generate_db_auth_token( self.client, hostname, port, username) diff --git a/tests/unit/botocore/test_utils.py b/tests/unit/botocore/test_utils.py index a4d7f13..97df14b 100644 --- a/tests/unit/botocore/test_utils.py +++ b/tests/unit/botocore/test_utils.py @@ -1004,7 +1004,7 @@ class TestSwitchToChunkedEncodingForNonSeekableObjects(unittest.TestCase): def test_switch_to_chunked_encodeing_for_stream_like_object(self): request = AWSRequest( method='POST', headers={}, - data=io.BufferedIOBase(b"some initial binary data"), + data=io.BufferedIOBase(), url='https://foo.amazonaws.com/bucket/key.txt' ) prepared_request = request.prepare() @@ -2794,7 +2794,7 @@ class TestInstanceMetadataFetcher(unittest.TestCase): self, dt=None, offset=None, offset_func=operator.add ): if dt is None: - dt = datetime.datetime.utcnow() + dt = datetime.datetime.now(datetime.UTC) if offset is not None: dt = offset_func(dt, offset) diff --git a/tests/unit/botocore/test_waiters.py b/tests/unit/botocore/test_waiters.py index 27fbe1f..b79e173 100644 --- a/tests/unit/botocore/test_waiters.py +++ b/tests/unit/botocore/test_waiters.py @@ -648,7 +648,7 @@ class TestCreateWaiter(unittest.TestCase): (' Polls :py:meth:`MyService.Client.foo` every 1 ' 'seconds until a successful state is reached. An error ' 'is returned after 1 failed checks.'), - ' **Request Syntax** ', + ' **Request Syntax**', ' ::', ' waiter.wait(', " bar='string'", diff --git a/tests/unit/customizations/test_opsworks.py b/tests/unit/customizations/test_opsworks.py index 1471ba9..3e30717 100644 --- a/tests/unit/customizations/test_opsworks.py +++ b/tests/unit/customizations/test_opsworks.py @@ -34,8 +34,8 @@ class TestOpsWorksBase(unittest.TestCase): mock.Mock(wraps=datetime.datetime) ) mocked_datetime = self.datetime_patcher.start() - mocked_datetime.utcnow.return_value = datetime.datetime( - 2013, 8, 9, 23, 42) + mocked_datetime.now.return_value = datetime.datetime( + 2013, 8, 9, 23, 42, tzinfo=datetime.UTC) def tearDown(self): self.datetime_patcher.stop() diff --git a/tests/utils/botocore/__init__.py b/tests/utils/botocore/__init__.py index 964ec88..2213f96 100644 --- a/tests/utils/botocore/__init__.py +++ b/tests/utils/botocore/__init__.py @@ -555,7 +555,7 @@ class FreezeTime(contextlib.ContextDecorator): def __init__(self, module, date=None): if date is None: - date = datetime.datetime.utcnow() + date = datetime.datetime.now(datetime.UTC) self.date = date self.datetime_patcher = mock.patch.object( module, 'datetime', @@ -564,7 +564,7 @@ class FreezeTime(contextlib.ContextDecorator): def __enter__(self, *args, **kwargs): mock = self.datetime_patcher.start() - mock.utcnow.return_value = self.date + mock.now.return_value = self.date def __exit__(self, *args, **kwargs): self.datetime_patcher.stop()