Update to 2.27.0

Resolves: RHEL-75536
Signed-off-by: Kseniia Nivnia <knivnia@redhat.com>
This commit is contained in:
Kseniia Nivnia 2025-07-24 15:30:41 +01:00
parent 20258e0b59
commit 0889e2db6a
No known key found for this signature in database
9 changed files with 621 additions and 330 deletions

1
.gitignore vendored
View File

@ -39,3 +39,4 @@
/aws-cli-2.17.13.tar.gz /aws-cli-2.17.13.tar.gz
/aws-cli-2.17.18.tar.gz /aws-cli-2.17.18.tar.gz
/aws-cli-2.22.9.tar.gz /aws-cli-2.22.9.tar.gz
/aws-cli-2.27.0.tar.gz

View File

@ -2,7 +2,7 @@ From 4b5762bb17f172d9f9e058df8908651856ff4a69 Mon Sep 17 00:00:00 2001
From: Adam Williamson <awilliam@redhat.com> From: Adam Williamson <awilliam@redhat.com>
Date: Thu, 13 Jun 2024 10:33:42 -0700 Date: Thu, 13 Jun 2024 10:33:42 -0700
Subject: [PATCH] Bump the ceiling for botocore memory leak tests to 15 MiB Subject: [PATCH] Bump the ceiling for botocore memory leak tests to 15 MiB
See https://github.com/boto/botocore/issues/3205 for the See https://github.com/boto/botocore/issues/3205 for the
background on this. In rebuilding awscli2 for Python 3.13 in background on this. In rebuilding awscli2 for Python 3.13 in
Fedora Rawhide, we found that two of these tests fail because Fedora Rawhide, we found that two of these tests fail because
@ -12,12 +12,12 @@ a memory *leak*, so bumping the ceiling seems appropriate. I'm
sending this upstream so I have a reference for the downstream sending this upstream so I have a reference for the downstream
package and to raise awareness of the issue, but the correct fix package and to raise awareness of the issue, but the correct fix
may be something else. may be something else.
Signed-off-by: Adam Williamson <awilliam@redhat.com> Signed-off-by: Adam Williamson <awilliam@redhat.com>
--- ---
tests/functional/botocore/leak/test_resource_leaks.py | 4 ++-- tests/functional/botocore/leak/test_resource_leaks.py | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-) 1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/tests/functional/botocore/leak/test_resource_leaks.py b/tests/functional/botocore/leak/test_resource_leaks.py diff --git a/tests/functional/botocore/leak/test_resource_leaks.py b/tests/functional/botocore/leak/test_resource_leaks.py
index df1c4fe7f..73027725f 100644 index df1c4fe7f..73027725f 100644
--- a/tests/functional/botocore/leak/test_resource_leaks.py --- a/tests/functional/botocore/leak/test_resource_leaks.py
@ -35,4 +35,4 @@ index df1c4fe7f..73027725f 100644
self.cmd('create_client', 's3') self.cmd('create_client', 's3')
-- --
2.45.2 2.45.2

View File

@ -1,40 +0,0 @@
diff --git a/tests/functional/eks/test_kubeconfig.py b/tests/functional/eks/test_kubeconfig.py
index 3d1bcf8..687eef2 100644
--- a/tests/functional/eks/test_kubeconfig.py
+++ b/tests/functional/eks/test_kubeconfig.py
@@ -121,8 +121,9 @@ class TestKubeconfigLoader(unittest.TestCase):
])
loaded_config = self._loader.load_kubeconfig(simple_path)
self.assertEqual(loaded_config.content, content)
- self._validator.validate_config.called_with(Kubeconfig(simple_path,
- content))
+ validated_config = self._validator.validate_config.call_args.args[0]
+ self.assertEqual(validated_config.path, simple_path)
+ self.assertEqual(validated_config.content, content)
def test_load_noexist(self):
no_exist_path = os.path.join(self._temp_directory,
@@ -130,17 +131,18 @@ class TestKubeconfigLoader(unittest.TestCase):
loaded_config = self._loader.load_kubeconfig(no_exist_path)
self.assertEqual(loaded_config.content,
_get_new_kubeconfig_content())
- self._validator.validate_config.called_with(
- Kubeconfig(no_exist_path, _get_new_kubeconfig_content()))
+ validated_config = self._validator.validate_config.call_args.args[0]
+ self.assertEqual(validated_config.path, no_exist_path)
+ self.assertEqual(validated_config.content, _get_new_kubeconfig_content())
def test_load_empty(self):
empty_path = self._clone_config("valid_empty_existing")
loaded_config = self._loader.load_kubeconfig(empty_path)
self.assertEqual(loaded_config.content,
_get_new_kubeconfig_content())
- self._validator.validate_config.called_with(
- Kubeconfig(empty_path,
- _get_new_kubeconfig_content()))
+ validated_config = self._validator.validate_config.call_args.args[0]
+ self.assertEqual(validated_config.path, empty_path)
+ self.assertEqual(validated_config.content, _get_new_kubeconfig_content())
def test_load_directory(self):
current_directory = self._temp_directory

View File

@ -1,18 +1,17 @@
%global pkgname aws-cli %global pkgname aws-cli
Name: awscli2 Name: awscli2
Version: 2.22.9 Version: 2.27.0
Release: %autorelease Release: %autorelease
Summary: Universal Command Line Environment for AWS, version 2 Summary: Universal Command Line Environment for AWS, version 2
# all files are licensed under Apache-2.0, except: # all files are licensed under Apache-2.0, except:
# - awscli/topictags.py is MIT # - awscli/topictags.py is MIT
# - awscli/botocore/vendored/six.py is MIT # - awscli/botocore/vendored/six.py is MIT
License: Apache-2.0 AND MIT License: Apache-2.0 AND MIT
URL: https://github.com/aws/aws-cli/tree/v2 URL: https://github.com/aws/aws-cli/tree/v2
Source0: https://github.com/aws/aws-cli/archive/%{version}/%{pkgname}-%{version}.tar.gz Source0: https://github.com/aws/aws-cli/archive/%{version}/%{pkgname}-%{version}.tar.gz
# adapt to whitespace formatting changes and removal of OrderedDict in ruamel-yaml # adapt to whitespace formatting changes and removal of OrderedDict in ruamel-yaml
Patch0: ruamel-yaml-0.17.32.patch Patch0: ruamel-yaml-0.17.32.patch
# fix Python 3.12 incompatibilities # fix Python 3.12 incompatibilities
@ -21,51 +20,61 @@ Patch1: python312.patch
# https://github.com/aws/aws-cli/pull/8744 # https://github.com/aws/aws-cli/pull/8744
# https://github.com/boto/botocore/issues/3205 # https://github.com/boto/botocore/issues/3205
Patch2: 0001-Bump-the-ceiling-for-botocore-memory-leak-tests-to-1.patch Patch2: 0001-Bump-the-ceiling-for-botocore-memory-leak-tests-to-1.patch
# compatibility fixes for urllib3 v2
Patch3: urllib3-v2.patch
# fix Python 3.14 incompatibilities
Patch4: python314.patch
BuildArch: noarch BuildArch: noarch
BuildRequires: python%{python3_pkgversion}-devel BuildRequires: python%{python3_pkgversion}-devel
BuildRequires: python-unversioned-command BuildRequires: python-unversioned-command
BuildRequires: procps-ng BuildRequires: procps-ng
Recommends: groff Recommends: groff
Recommends: less
Provides: bundled(python3dist(botocore)) = 2.0.0 Provides: bundled(python3dist(botocore)) = 2.0.0
Provides: bundled(python3dist(s3transfer)) = 0.5.1 Provides: bundled(python3dist(s3transfer)) = 0.5.1
Provides: awscli = %{version}-%{release} Provides: awscli = %{version}-%{release}
Obsoletes: awscli < 2 Obsoletes: awscli < 2
# provide an upgrade path from awscli-2 (Amazon Linux) # provide an upgrade path from awscli-2 (Amazon Linux)
Provides: awscli-2 = %{version}-%{release} Provides: awscli-2 = %{version}-%{release}
Obsoletes: awscli-2 < %{version}-%{release} Obsoletes: awscli-2 < %{version}-%{release}
# python-awscrt does not build on s390x # python-awscrt does not build on i686 nor s390x
ExcludeArch: s390x ExcludeArch: %{ix86} s390x
%description %description
This package provides version 2 of the unified command line This package provides version 2 of the unified command line
interface to Amazon Web Services. interface to Amazon Web Services.
%prep %prep
%autosetup -p1 -n %{pkgname}-%{version} %autosetup -p1 -n %{pkgname}-%{version}
# fix permissions # fix permissions
find awscli/examples/ -type f -name '*.rst' -executable -exec chmod -x '{}' + find awscli/examples/ -type f -name '*.rst' -executable -exec chmod -x '{}' +
# remove version caps on dependencies # remove version caps on dependencies
sed -i 's/,<=\?[^"]*"/"/' pyproject.toml sed -i 's/,<=\?[^"]*"/"/' pyproject.toml
# loosen awscrt version requirement
sed -i 's/awscrt==/awscrt>=/' pyproject.toml
# remove zipp dependency
sed -i "/zipp<3.21.0/d" pyproject.toml
# use unittest.mock # use unittest.mock
find -type f -name '*.py' -exec sed \ find -type f -name '*.py' -exec sed \
-e 's/^\( *\)import mock$/\1from unittest import mock/' \ -e 's/^\( *\)import mock$/\1from unittest import mock/' \
-e 's/^\( *\)from mock import mock/\1from unittest import mock/' \ -e 's/^\( *\)from mock import mock/\1from unittest import mock/' \
-e 's/^\( *\)from mock import/\1from unittest.mock import/' \ -e 's/^\( *\)from mock import/\1from unittest.mock import/' \
-i '{}' + -i '{}' +
# Fedora does not run coverage tests. # Fedora does not run coverage tests.
# mock is deprecated in Fedora. We use unittest.mock. # mock is deprecated in Fedora. We use unittest.mock.
# pip-tools is not used directly by the unit tests. # pip-tools is not used directly by the unit tests.
@ -78,44 +87,44 @@ sed \
-e '/pytest-cov/d' \ -e '/pytest-cov/d' \
%{?rhel:-e '/pytest-xdist/d'} \ %{?rhel:-e '/pytest-xdist/d'} \
requirements-test.txt > _requirements-test.txt requirements-test.txt > _requirements-test.txt
%generate_buildrequires %generate_buildrequires
%pyproject_buildrequires _requirements-test.txt %pyproject_buildrequires _requirements-test.txt
%build %build
%pyproject_wheel %pyproject_wheel
%install %install
%pyproject_install %pyproject_install
%pyproject_save_files awscli %pyproject_save_files awscli
# remove unnecessary scripts # remove unnecessary scripts
rm -vf %{buildroot}%{_bindir}/{aws_bash_completer,aws_zsh_completer.sh,aws.cmd} rm -vf %{buildroot}%{_bindir}/{aws_bash_completer,aws_zsh_completer.sh,aws.cmd}
# install shell completion # install shell completion
install -Dpm0644 bin/aws_bash_completer \ install -Dpm0644 bin/aws_bash_completer \
%{buildroot}%{bash_completions_dir}/aws %{buildroot}%{bash_completions_dir}/aws
install -Dpm0644 bin/aws_zsh_completer.sh \ install -Dpm0644 bin/aws_zsh_completer.sh \
%{buildroot}%{zsh_completions_dir}/_awscli %{buildroot}%{zsh_completions_dir}/_awscli
%check %check
# it appears that some tests modify the environment and remove PYTHONPATH # it appears that some tests modify the environment and remove PYTHONPATH
# so it's not passed to botocore cmd-runner, inject it here # so it's not passed to botocore cmd-runner, inject it here
sed -i '/self.driver.start(env=env)/i \ \ \ \ \ \ \ \ env["PYTHONPATH"] = "%{buildroot}%{python3_sitelib}"' \ sed -i '/self.driver.start(env=env)/i \ \ \ \ \ \ \ \ env["PYTHONPATH"] = "%{buildroot}%{python3_sitelib}"' \
tests/utils/botocore/__init__.py tests/utils/botocore/__init__.py
export TESTS_REMOVE_REPO_ROOT_FROM_PATH=1 TZ=UTC export TESTS_REMOVE_REPO_ROOT_FROM_PATH=1 TZ=UTC
export OPENSSL_ENABLE_SHA1_SIGNATURES=yes export OPENSSL_ENABLE_SHA1_SIGNATURES=yes
%pytest --verbose %{!?rhel:--numprocesses=auto --dist=loadfile --maxprocesses=4} \ %pytest --verbose %{!?rhel:--numprocesses=auto --dist=loadfile --maxprocesses=4} \
tests/unit tests/functional \ tests/unit tests/functional \
--ignore tests/functional/autocomplete/test_completion_files.py \ --ignore tests/functional/autocomplete/test_completion_files.py \
--ignore tests/functional/botocore/test_waiter_config.py --ignore tests/functional/botocore/test_waiter_config.py
%files -f %{pyproject_files} %files -f %{pyproject_files}
%license LICENSE.txt %license LICENSE.txt
%doc README.rst %doc README.rst
@ -123,7 +132,7 @@ export OPENSSL_ENABLE_SHA1_SIGNATURES=yes
%{_bindir}/aws_completer %{_bindir}/aws_completer
%{bash_completions_dir}/aws %{bash_completions_dir}/aws
%{zsh_completions_dir}/_awscli %{zsh_completions_dir}/_awscli
%changelog %changelog
%autochangelog %autochangelog

View File

@ -1,8 +1,8 @@
diff --git a/awscli/botocore/auth.py b/awscli/botocore/auth.py diff --git a/awscli/botocore/auth.py b/awscli/botocore/auth.py
index 0c1bc74a..de33e127 100644 index 19fbe36..efb1b02 100644
--- a/awscli/botocore/auth.py --- a/awscli/botocore/auth.py
+++ b/awscli/botocore/auth.py +++ b/awscli/botocore/auth.py
@@ -395,7 +395,7 @@ class SigV4Auth(BaseSigner): @@ -419,7 +419,7 @@ class SigV4Auth(BaseSigner):
def add_auth(self, request): def add_auth(self, request):
if self.credentials is None: if self.credentials is None:
raise NoCredentialsError() raise NoCredentialsError()
@ -11,16 +11,16 @@ index 0c1bc74a..de33e127 100644
request.context['timestamp'] = datetime_now.strftime(SIGV4_TIMESTAMP) request.context['timestamp'] = datetime_now.strftime(SIGV4_TIMESTAMP)
# This could be a retry. Make sure the previous # This could be a retry. Make sure the previous
# authorization header is removed first. # authorization header is removed first.
@@ -439,7 +439,7 @@ class SigV4Auth(BaseSigner): @@ -465,7 +465,7 @@ class SigV4Auth(BaseSigner):
if 'Date' in request.headers: if 'Date' in request.headers:
del request.headers['Date'] del request.headers['Date']
datetime_timestamp = datetime.datetime.strptime( datetime_timestamp = datetime.datetime.strptime(
- request.context['timestamp'], SIGV4_TIMESTAMP) - request.context['timestamp'], SIGV4_TIMESTAMP
+ request.context['timestamp'], SIGV4_TIMESTAMP[:-1] + '%z') + request.context['timestamp'], SIGV4_TIMESTAMP[:-1] + '%z'
)
request.headers['Date'] = formatdate( request.headers['Date'] = formatdate(
int(calendar.timegm(datetime_timestamp.timetuple()))) int(calendar.timegm(datetime_timestamp.timetuple()))
if 'X-Amz-Date' in request.headers: @@ -557,7 +557,7 @@ class S3ExpressPostAuth(S3ExpressAuth):
@@ -527,7 +527,7 @@ class S3ExpressPostAuth(S3ExpressAuth):
REQUIRES_IDENTITY_CACHE = True REQUIRES_IDENTITY_CACHE = True
def add_auth(self, request): def add_auth(self, request):
@ -29,9 +29,9 @@ index 0c1bc74a..de33e127 100644
request.context['timestamp'] = datetime_now.strftime(SIGV4_TIMESTAMP) request.context['timestamp'] = datetime_now.strftime(SIGV4_TIMESTAMP)
fields = {} fields = {}
@@ -780,7 +780,7 @@ class S3SigV4PostAuth(SigV4Auth): @@ -818,7 +818,7 @@ class S3SigV4PostAuth(SigV4Auth):
http://docs.aws.amazon.com/AmazonS3/latest/API/sigv4-UsingHTTPPOST.html
""" """
def add_auth(self, request): def add_auth(self, request):
- datetime_now = datetime.datetime.utcnow() - datetime_now = datetime.datetime.utcnow()
+ datetime_now = datetime.datetime.now(datetime.timezone.utc) + datetime_now = datetime.datetime.now(datetime.timezone.utc)
@ -39,38 +39,40 @@ index 0c1bc74a..de33e127 100644
fields = {} fields = {}
diff --git a/awscli/botocore/crt/auth.py b/awscli/botocore/crt/auth.py diff --git a/awscli/botocore/crt/auth.py b/awscli/botocore/crt/auth.py
index 534a7f8d..5046b35b 100644 index 2b96c7e..86104f3 100644
--- a/awscli/botocore/crt/auth.py --- a/awscli/botocore/crt/auth.py
+++ b/awscli/botocore/crt/auth.py +++ b/awscli/botocore/crt/auth.py
@@ -55,10 +55,7 @@ class CrtSigV4Auth(BaseSigner): @@ -56,11 +56,7 @@ class CrtSigV4Auth(BaseSigner):
if self.credentials is None: if self.credentials is None:
raise NoCredentialsError() raise NoCredentialsError()
- # Use utcnow() because that's what gets mocked by tests, but set - # Use utcnow() because that's what gets mocked by tests, but set
- # timezone because CRT assumes naive datetime is local time. - # timezone because CRT assumes naive datetime is local time.
- datetime_now = datetime.datetime.utcnow().replace( - datetime_now = datetime.datetime.utcnow().replace(
- tzinfo=datetime.timezone.utc) - tzinfo=datetime.timezone.utc
- )
+ datetime_now = datetime.datetime.now(datetime.timezone.utc) + datetime_now = datetime.datetime.now(datetime.timezone.utc)
# Use existing 'X-Amz-Content-SHA256' header if able # Use existing 'X-Amz-Content-SHA256' header if able
existing_sha256 = self._get_existing_sha256(request) existing_sha256 = self._get_existing_sha256(request)
@@ -245,10 +242,7 @@ class CrtSigV4AsymAuth(BaseSigner): @@ -254,11 +250,7 @@ class CrtSigV4AsymAuth(BaseSigner):
if self.credentials is None: if self.credentials is None:
raise NoCredentialsError() raise NoCredentialsError()
- # Use utcnow() because that's what gets mocked by tests, but set - # Use utcnow() because that's what gets mocked by tests, but set
- # timezone because CRT assumes naive datetime is local time. - # timezone because CRT assumes naive datetime is local time.
- datetime_now = datetime.datetime.utcnow().replace( - datetime_now = datetime.datetime.utcnow().replace(
- tzinfo=datetime.timezone.utc) - tzinfo=datetime.timezone.utc
- )
+ datetime_now = datetime.datetime.now(datetime.timezone.utc) + datetime_now = datetime.datetime.now(datetime.timezone.utc)
# Use existing 'X-Amz-Content-SHA256' header if able # Use existing 'X-Amz-Content-SHA256' header if able
existing_sha256 = self._get_existing_sha256(request) existing_sha256 = self._get_existing_sha256(request)
diff --git a/awscli/botocore/signers.py b/awscli/botocore/signers.py diff --git a/awscli/botocore/signers.py b/awscli/botocore/signers.py
index 604f6553..6c55277e 100644 index 02e759b..5e894ae 100644
--- a/awscli/botocore/signers.py --- a/awscli/botocore/signers.py
+++ b/awscli/botocore/signers.py +++ b/awscli/botocore/signers.py
@@ -549,7 +549,7 @@ class S3PostPresigner(object): @@ -713,7 +713,7 @@ class S3PostPresigner:
policy = {} policy = {}
# Create an expiration date for the policy # Create an expiration date for the policy
@ -80,10 +82,10 @@ index 604f6553..6c55277e 100644
policy['expiration'] = expire_date.strftime(botocore.auth.ISO8601) policy['expiration'] = expire_date.strftime(botocore.auth.ISO8601)
diff --git a/awscli/botocore/utils.py b/awscli/botocore/utils.py diff --git a/awscli/botocore/utils.py b/awscli/botocore/utils.py
index 89bcc2aa..8d3688c5 100644 index 78efaba..9d7cd1d 100644
--- a/awscli/botocore/utils.py --- a/awscli/botocore/utils.py
+++ b/awscli/botocore/utils.py +++ b/awscli/botocore/utils.py
@@ -582,13 +582,13 @@ class InstanceMetadataFetcher(IMDSFetcher): @@ -608,7 +608,7 @@ class InstanceMetadataFetcher(IMDSFetcher):
return return
try: try:
expiration = datetime.datetime.strptime( expiration = datetime.datetime.strptime(
@ -92,62 +94,63 @@ index 89bcc2aa..8d3688c5 100644
) )
refresh_interval = self._config.get( refresh_interval = self._config.get(
"ec2_credential_refresh_window", 60 * 10 "ec2_credential_refresh_window", 60 * 10
@@ -616,7 +616,7 @@ class InstanceMetadataFetcher(IMDSFetcher):
refresh_interval_with_jitter = refresh_interval + random.randint(
120, 600
) )
refresh_interval_with_jitter = refresh_interval + random.randint(120, 600)
- current_time = datetime.datetime.utcnow() - current_time = datetime.datetime.utcnow()
+ current_time = datetime.datetime.now(datetime.timezone.utc) + current_time = datetime.datetime.now(datetime.timezone.utc)
refresh_offset = datetime.timedelta(seconds=refresh_interval_with_jitter) refresh_offset = datetime.timedelta(
extension_time = expiration - refresh_offset seconds=refresh_interval_with_jitter
if current_time >= extension_time: )
diff --git a/awscli/compat.py b/awscli/compat.py diff --git a/awscli/compat.py b/awscli/compat.py
index b6ae8981..a41c4c6b 100644 index e1d58bd..cd496d3 100644
--- a/awscli/compat.py --- a/awscli/compat.py
+++ b/awscli/compat.py +++ b/awscli/compat.py
@@ -29,6 +29,8 @@ from functools import partial @@ -24,6 +24,7 @@ import shlex
import signal
import sys
import urllib.parse as urlparse import urllib.parse as urlparse
from urllib.error import URLError
+import queue
+import urllib.request +import urllib.request
from botocore.compat import six import zipfile
from botocore.compat import OrderedDict from configparser import RawConfigParser
from functools import partial
diff --git a/awscli/customizations/cloudformation/deployer.py b/awscli/customizations/cloudformation/deployer.py diff --git a/awscli/customizations/cloudformation/deployer.py b/awscli/customizations/cloudformation/deployer.py
index 3733c55e..8236d33c 100644 index a5c512f..8783ebb 100644
--- a/awscli/customizations/cloudformation/deployer.py --- a/awscli/customizations/cloudformation/deployer.py
+++ b/awscli/customizations/cloudformation/deployer.py +++ b/awscli/customizations/cloudformation/deployer.py
@@ -20,7 +20,7 @@ import collections @@ -15,7 +15,7 @@ import collections
from awscli.customizations.cloudformation import exceptions import logging
from awscli.customizations.cloudformation.artifact_exporter import mktempfile, parse_s3_url import sys
import time
-from datetime import datetime -from datetime import datetime
+from datetime import datetime, timezone +from datetime import datetime, timezone
LOG = logging.getLogger(__name__) import botocore
@@ -85,7 +85,7 @@ class Deployer(object): @@ -98,7 +98,7 @@ class Deployer:
:return: :return:
""" """
- now = datetime.utcnow().isoformat() - now = datetime.utcnow().isoformat()
+ now = datetime.now(timezone.utc).isoformat() + now = datetime.now(timezone.utc).isoformat()
description = "Created by AWS CLI at {0} UTC".format(now) description = f"Created by AWS CLI at {now} UTC"
# Each changeset will get a unique name based on time # Each changeset will get a unique name based on time
diff --git a/awscli/customizations/cloudtrail/validation.py b/awscli/customizations/cloudtrail/validation.py diff --git a/awscli/customizations/cloudtrail/validation.py b/awscli/customizations/cloudtrail/validation.py
index 78e25408..ad135077 100644 index f4229ba..1aa960c 100644
--- a/awscli/customizations/cloudtrail/validation.py --- a/awscli/customizations/cloudtrail/validation.py
+++ b/awscli/customizations/cloudtrail/validation.py +++ b/awscli/customizations/cloudtrail/validation.py
@@ -19,7 +19,7 @@ import re @@ -18,7 +18,7 @@ import logging
import re
import sys import sys
import zlib import zlib
from zlib import error as ZLibError
-from datetime import datetime, timedelta -from datetime import datetime, timedelta
+from datetime import datetime, timedelta, timezone +from datetime import datetime, timedelta, timezone
from dateutil import tz, parser from zlib import error as ZLibError
import cryptography from awscrt.crypto import RSA, RSASignatureAlgorithm
@@ -401,7 +401,7 @@ class DigestTraverser(object): @@ -444,7 +444,7 @@ class DigestTraverser:
:param end_date: Date to stop validating at (inclusive). :param end_date: Date to stop validating at (inclusive).
""" """
if end_date is None: if end_date is None:
@ -156,20 +159,20 @@ index 78e25408..ad135077 100644
end_date = normalize_date(end_date) end_date = normalize_date(end_date)
start_date = normalize_date(start_date) start_date = normalize_date(start_date)
bucket = self.starting_bucket bucket = self.starting_bucket
@@ -703,7 +703,7 @@ class CloudTrailValidateLogs(BasicCommand): @@ -830,7 +830,7 @@ class CloudTrailValidateLogs(BasicCommand):
if args.end_time: if args.end_time:
self.end_time = normalize_date(parse_date(args.end_time)) self.end_time = normalize_date(parse_date(args.end_time))
else: else:
- self.end_time = normalize_date(datetime.utcnow()) - self.end_time = normalize_date(datetime.utcnow())
+ self.end_time = datetime.now(timezone.utc) + self.end_time = normalize_date(datetime.now(timezone.utc))
if self.start_time > self.end_time: if self.start_time > self.end_time:
raise ParamValidationError( raise ParamValidationError(
'Invalid time range specified: start-time must ' 'Invalid time range specified: start-time must '
diff --git a/awscli/customizations/codecommit.py b/awscli/customizations/codecommit.py diff --git a/awscli/customizations/codecommit.py b/awscli/customizations/codecommit.py
index 6b30e834..7859fb89 100644 index b001562..cb9e757 100644
--- a/awscli/customizations/codecommit.py --- a/awscli/customizations/codecommit.py
+++ b/awscli/customizations/codecommit.py +++ b/awscli/customizations/codecommit.py
@@ -150,7 +150,7 @@ class CodeCommitGetCommand(BasicCommand): @@ -159,7 +159,7 @@ class CodeCommitGetCommand(BasicCommand):
request = AWSRequest() request = AWSRequest()
request.url = url_to_sign request.url = url_to_sign
request.method = 'GIT' request.method = 'GIT'
@ -179,29 +182,29 @@ index 6b30e834..7859fb89 100644
split = urlsplit(request.url) split = urlsplit(request.url)
# we don't want to include the port number in the signature # 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 diff --git a/awscli/customizations/codedeploy/push.py b/awscli/customizations/codedeploy/push.py
index 4e0fbcff..9f71f7c2 100644 index bdde82e..3281ce4 100644
--- a/awscli/customizations/codedeploy/push.py --- a/awscli/customizations/codedeploy/push.py
+++ b/awscli/customizations/codedeploy/push.py +++ b/awscli/customizations/codedeploy/push.py
@@ -16,7 +16,7 @@ import sys @@ -16,7 +16,7 @@ import os
import zipfile import sys
import tempfile import tempfile
import contextlib import zipfile
-from datetime import datetime -from datetime import datetime
+from datetime import datetime, timezone +from datetime import datetime, timezone
from botocore.exceptions import ClientError from botocore.exceptions import ClientError
@@ -132,7 +132,7 @@ class Push(BasicCommand): @@ -131,7 +131,7 @@ class Push(BasicCommand):
)
if not parsed_args.description: if not parsed_args.description:
parsed_args.description = ( parsed_args.description = (
'Uploaded by AWS CLI {0} UTC'.format( - f'Uploaded by AWS CLI {datetime.utcnow().isoformat()} UTC'
- datetime.utcnow().isoformat() + f'Uploaded by AWS CLI {datetime.now(timezone.utc).isoformat()} UTC'
+ datetime.now(timezone.utc).isoformat()
)
) )
def _push(self, params):
diff --git a/awscli/customizations/datapipeline/__init__.py b/awscli/customizations/datapipeline/__init__.py diff --git a/awscli/customizations/datapipeline/__init__.py b/awscli/customizations/datapipeline/__init__.py
index c47ca94f..0c12c394 100644 index 5665769..d197339 100644
--- a/awscli/customizations/datapipeline/__init__.py --- a/awscli/customizations/datapipeline/__init__.py
+++ b/awscli/customizations/datapipeline/__init__.py +++ b/awscli/customizations/datapipeline/__init__.py
@@ -12,7 +12,7 @@ @@ -12,7 +12,7 @@
@ -211,10 +214,10 @@ index c47ca94f..0c12c394 100644
-from datetime import datetime, timedelta -from datetime import datetime, timedelta
+from datetime import datetime, timedelta, timezone +from datetime import datetime, timedelta, timezone
from awscli.formatter import get_formatter
from awscli.arguments import CustomArgument from awscli.arguments import CustomArgument
@@ -186,7 +186,7 @@ class QueryArgBuilder(object): from awscli.customizations.commands import BasicCommand
""" @@ -197,7 +197,7 @@ class QueryArgBuilder:
def __init__(self, current_time=None): def __init__(self, current_time=None):
if current_time is None: if current_time is None:
- current_time = datetime.utcnow() - current_time = datetime.utcnow()
@ -223,32 +226,32 @@ index c47ca94f..0c12c394 100644
def build_query(self, parsed_args): def build_query(self, parsed_args):
diff --git a/awscli/customizations/ec2/bundleinstance.py b/awscli/customizations/ec2/bundleinstance.py diff --git a/awscli/customizations/ec2/bundleinstance.py b/awscli/customizations/ec2/bundleinstance.py
index cc6802d6..56c1efa6 100644 index 240540f..8dc2e22 100644
--- a/awscli/customizations/ec2/bundleinstance.py --- a/awscli/customizations/ec2/bundleinstance.py
+++ b/awscli/customizations/ec2/bundleinstance.py +++ b/awscli/customizations/ec2/bundleinstance.py
@@ -118,7 +118,7 @@ def _generate_policy(params): @@ -129,7 +129,7 @@ def _generate_policy(params):
# Called if there is no policy supplied by the user. # Called if there is no policy supplied by the user.
# Creates a policy that provides access for 24 hours. # Creates a policy that provides access for 24 hours.
delta = datetime.timedelta(hours=24) delta = datetime.timedelta(hours=24)
- expires = datetime.datetime.utcnow() + delta - expires = datetime.datetime.utcnow() + delta
+ expires = datetime.datetime.now(datetime.timezone.utc) + delta + expires = datetime.datetime.now(datetime.timezone.utc) + delta
expires_iso = expires.strftime("%Y-%m-%dT%H:%M:%S.%fZ") expires_iso = expires.strftime("%Y-%m-%dT%H:%M:%S.%fZ")
policy = POLICY.format(expires=expires_iso, policy = POLICY.format(
bucket=params['Bucket'], expires=expires_iso, bucket=params['Bucket'], prefix=params['Prefix']
diff --git a/awscli/customizations/eks/get_token.py b/awscli/customizations/eks/get_token.py diff --git a/awscli/customizations/eks/get_token.py b/awscli/customizations/eks/get_token.py
index c85b86dd..9812be4f 100644 index 00fc4d3..ee8c74c 100644
--- a/awscli/customizations/eks/get_token.py --- a/awscli/customizations/eks/get_token.py
+++ b/awscli/customizations/eks/get_token.py +++ b/awscli/customizations/eks/get_token.py
@@ -16,7 +16,7 @@ import json @@ -14,7 +14,7 @@ import base64
import json
import os import os
import sys import sys
-from datetime import datetime, timedelta -from datetime import datetime, timedelta
+from datetime import datetime, timedelta, timezone +from datetime import datetime, timedelta, timezone
from botocore.signers import RequestSigner
from botocore.model import ServiceId
@@ -106,7 +106,7 @@ class GetTokenCommand(BasicCommand): import botocore
from botocore.model import ServiceId
@@ -105,7 +105,7 @@ class GetTokenCommand(BasicCommand):
] ]
def get_expiration_time(self): def get_expiration_time(self):
@ -258,20 +261,24 @@ index c85b86dd..9812be4f 100644
) )
return token_expiration.strftime('%Y-%m-%dT%H:%M:%SZ') return token_expiration.strftime('%Y-%m-%dT%H:%M:%SZ')
diff --git a/awscli/customizations/logs/tail.py b/awscli/customizations/logs/tail.py diff --git a/awscli/customizations/logs/tail.py b/awscli/customizations/logs/tail.py
index cb315100..623e0272 100644 index e22facd..9b464b4 100644
--- a/awscli/customizations/logs/tail.py --- a/awscli/customizations/logs/tail.py
+++ b/awscli/customizations/logs/tail.py +++ b/awscli/customizations/logs/tail.py
@@ -11,7 +11,8 @@ @@ -10,11 +10,12 @@
# distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF
# ANY KIND, either express or implied. See the License for the specific # ANY KIND, either express or implied. See the License for the specific
# language governing permissions and limitations under the License. # language governing permissions and limitations under the License.
from collections import defaultdict
-from datetime import datetime, timedelta
+from datetime import datetime, timedelta, timezone
+import functools +import functools
import json import json
import re import re
import time import time
@@ -261,7 +262,7 @@ class TimestampUtils(object): from collections import defaultdict
-from datetime import datetime, timedelta
+from datetime import datetime, timedelta, timezone
import colorama
from botocore.utils import datetime2timestamp, parse_timestamp
@@ -266,7 +267,7 @@ class TimestampUtils:
def __init__(self, now=None): def __init__(self, now=None):
self._now = now self._now = now
if now is None: if now is None:
@ -281,10 +288,10 @@ index cb315100..623e0272 100644
def to_epoch_millis(self, timestamp): def to_epoch_millis(self, timestamp):
re_match = self._RELATIVE_TIMESTAMP_REGEX.match(timestamp) re_match = self._RELATIVE_TIMESTAMP_REGEX.match(timestamp)
diff --git a/awscli/customizations/opsworks.py b/awscli/customizations/opsworks.py diff --git a/awscli/customizations/opsworks.py b/awscli/customizations/opsworks.py
index e91d4789..9f848c64 100644 index ac23cd5..490f44d 100644
--- a/awscli/customizations/opsworks.py --- a/awscli/customizations/opsworks.py
+++ b/awscli/customizations/opsworks.py +++ b/awscli/customizations/opsworks.py
@@ -507,7 +507,7 @@ class OpsWorksRegister(BasicCommand): @@ -566,7 +566,7 @@ class OpsWorksRegister(BasicCommand):
"Resource": arn, "Resource": arn,
} }
if timeout is not None: if timeout is not None:
@ -292,23 +299,23 @@ index e91d4789..9f848c64 100644
+ valid_until = datetime.datetime.now(datetime.timezone.utc) + timeout + valid_until = datetime.datetime.now(datetime.timezone.utc) + timeout
statement["Condition"] = { statement["Condition"] = {
"DateLessThan": { "DateLessThan": {
"aws:CurrentTime": "aws:CurrentTime": valid_until.strftime(
diff --git a/tests/functional/botocore/test_credentials.py b/tests/functional/botocore/test_credentials.py diff --git a/tests/functional/botocore/test_credentials.py b/tests/functional/botocore/test_credentials.py
index 18bd248d..8af69de4 100644 index 7703df6..1497e11 100644
--- a/tests/functional/botocore/test_credentials.py --- a/tests/functional/botocore/test_credentials.py
+++ b/tests/functional/botocore/test_credentials.py +++ b/tests/functional/botocore/test_credentials.py
@@ -18,7 +18,7 @@ import math @@ -19,7 +19,7 @@ import tempfile
import threading
import time import time
import tempfile import uuid
import shutil
-from datetime import datetime, timedelta -from datetime import datetime, timedelta
+from datetime import datetime, timedelta, timezone +from datetime import datetime, timedelta, timezone
import sys
import pytest import pytest
@@ -46,8 +46,8 @@ from botocore.stub import Stubber from botocore import UNSIGNED
from botocore.tokens import SSOTokenProvider @@ -61,8 +61,8 @@ from tests import (
from botocore.utils import datetime2timestamp unittest,
)
-TIME_IN_ONE_HOUR = datetime.utcnow() + timedelta(hours=1) -TIME_IN_ONE_HOUR = datetime.utcnow() + timedelta(hours=1)
-TIME_IN_SIX_MONTHS = datetime.utcnow() + timedelta(hours=4320) -TIME_IN_SIX_MONTHS = datetime.utcnow() + timedelta(hours=4320)
@ -318,27 +325,28 @@ index 18bd248d..8af69de4 100644
class TestCredentialRefreshRaces(unittest.TestCase): class TestCredentialRefreshRaces(unittest.TestCase):
diff --git a/tests/functional/botocore/test_ec2.py b/tests/functional/botocore/test_ec2.py diff --git a/tests/functional/botocore/test_ec2.py b/tests/functional/botocore/test_ec2.py
index a5aec4aa..475134cc 100644 index 81f4b76..39423aa 100644
--- a/tests/functional/botocore/test_ec2.py --- a/tests/functional/botocore/test_ec2.py
+++ b/tests/functional/botocore/test_ec2.py +++ b/tests/functional/botocore/test_ec2.py
@@ -85,13 +85,13 @@ class TestCopySnapshotCustomization(BaseSessionTest): @@ -92,14 +92,14 @@ class TestCopySnapshotCustomization(BaseSessionTest):
'<snapshotId>%s</snapshotId>\n' '<snapshotId>%s</snapshotId>\n'
'</CopySnapshotResponse>\n' '</CopySnapshotResponse>\n'
) )
- self.now = datetime.datetime(2011, 9, 9, 23, 36) - self.now = datetime.datetime(2011, 9, 9, 23, 36)
+ self.now = datetime.datetime(2011, 9, 9, 23, 36, tzinfo=datetime.timezone.utc) + self.now = datetime.datetime(2011, 9, 9, 23, 36, tzinfo=datetime.timezone.utc)
self.datetime_patch = mock.patch.object( self.datetime_patch = mock.patch.object(
botocore.auth.datetime, 'datetime', botocore.auth.datetime,
mock.Mock(wraps=datetime.datetime) 'datetime',
mock.Mock(wraps=datetime.datetime),
) )
self.mocked_datetime = self.datetime_patch.start() self.mocked_datetime = self.datetime_patch.start()
- self.mocked_datetime.utcnow.return_value = self.now - self.mocked_datetime.utcnow.return_value = self.now
+ self.mocked_datetime.now.return_value = self.now + self.mocked_datetime.now.return_value = self.now
def tearDown(self): def tearDown(self):
super(TestCopySnapshotCustomization, self).tearDown() super().tearDown()
diff --git a/tests/functional/botocore/test_lex.py b/tests/functional/botocore/test_lex.py diff --git a/tests/functional/botocore/test_lex.py b/tests/functional/botocore/test_lex.py
index 659296fd..614691e8 100644 index cded9c0..000f50d 100644
--- a/tests/functional/botocore/test_lex.py --- a/tests/functional/botocore/test_lex.py
+++ b/tests/functional/botocore/test_lex.py +++ b/tests/functional/botocore/test_lex.py
@@ -10,7 +10,7 @@ @@ -10,7 +10,7 @@
@ -348,10 +356,10 @@ index 659296fd..614691e8 100644
-from datetime import datetime -from datetime import datetime
+from datetime import datetime, timezone +from datetime import datetime, timezone
from tests import mock, BaseSessionTest, ClientHTTPStubber from tests import BaseSessionTest, ClientHTTPStubber, mock
@@ -31,10 +31,10 @@ class TestLex(BaseSessionTest): @@ -31,10 +31,10 @@ class TestLex(BaseSessionTest):
'inputStream': b'' 'inputStream': b'',
} }
- timestamp = datetime(2017, 3, 22, 0, 0) - timestamp = datetime(2017, 3, 22, 0, 0)
@ -364,7 +372,7 @@ index 659296fd..614691e8 100644
with self.http_stubber: with self.http_stubber:
self.client.post_content(**params) self.client.post_content(**params)
diff --git a/tests/functional/botocore/test_s3express.py b/tests/functional/botocore/test_s3express.py diff --git a/tests/functional/botocore/test_s3express.py b/tests/functional/botocore/test_s3express.py
index 390721ee..ebb89b0b 100644 index 91ec532..1a516d2 100644
--- a/tests/functional/botocore/test_s3express.py --- a/tests/functional/botocore/test_s3express.py
+++ b/tests/functional/botocore/test_s3express.py +++ b/tests/functional/botocore/test_s3express.py
@@ -108,7 +108,6 @@ class TestS3ExpressAuth: @@ -108,7 +108,6 @@ class TestS3ExpressAuth:
@ -425,19 +433,19 @@ index 390721ee..ebb89b0b 100644
with ClientHTTPStubber(default_s3_client) as stubber: with ClientHTTPStubber(default_s3_client) as stubber:
diff --git a/tests/functional/botocore/test_sts.py b/tests/functional/botocore/test_sts.py diff --git a/tests/functional/botocore/test_sts.py b/tests/functional/botocore/test_sts.py
index beb48030..e6978795 100644 index 6bf343e..407ebab 100644
--- a/tests/functional/botocore/test_sts.py --- a/tests/functional/botocore/test_sts.py
+++ b/tests/functional/botocore/test_sts.py +++ b/tests/functional/botocore/test_sts.py
@@ -10,7 +10,7 @@ @@ -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 # ANY KIND, either express or implied. See the License for the specific
# language governing permissions and limitations under the License. # language governing permissions and limitations under the License.
import re
-from datetime import datetime -from datetime import datetime
+from datetime import datetime, timezone +from datetime import datetime, timezone
import re
from tests import BaseSessionTest from botocore.config import Config
@@ -36,9 +36,9 @@ class TestSTSPresignedUrl(BaseSessionTest): from botocore.stub import Stubber
@@ -32,9 +32,9 @@ class TestSTSPresignedUrl(BaseSessionTest):
self.stubber.activate() self.stubber.activate()
def test_presigned_url_contains_no_content_type(self): def test_presigned_url_contains_no_content_type(self):
@ -449,8 +457,39 @@ index beb48030..e6978795 100644
url = self.client.generate_presigned_url('get_caller_identity', {}) url = self.client.generate_presigned_url('get_caller_identity', {})
# There should be no 'content-type' in x-amz-signedheaders # There should be no 'content-type' in x-amz-signedheaders
diff --git a/tests/functional/dsql/test_generate_db_auth_token.py b/tests/functional/dsql/test_generate_db_auth_token.py
index 2b48453..39871ab 100644
--- a/tests/functional/dsql/test_generate_db_auth_token.py
+++ b/tests/functional/dsql/test_generate_db_auth_token.py
@@ -50,7 +50,7 @@ class TestGenerateDBConnectAuthToken(BaseTestGenerateDBConnectAuthToken):
clock = datetime.datetime(2024, 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 hashes are always the same as session variables come from the BaseAwsCommandParamsTest class
@@ -79,7 +79,7 @@ class TestGenerateDBConnectAuthToken(BaseTestGenerateDBConnectAuthToken):
clock = datetime.datetime(2024, 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=252)
@@ -92,7 +92,7 @@ class TestGenerateDBConnectAdminAuthToken(BaseTestGenerateDBConnectAuthToken):
clock = datetime.datetime(2024, 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 hashes are always the same as session variables come from the BaseAwsCommandParamsTest class
diff --git a/tests/functional/ec2/test_bundle_instance.py b/tests/functional/ec2/test_bundle_instance.py diff --git a/tests/functional/ec2/test_bundle_instance.py b/tests/functional/ec2/test_bundle_instance.py
index 1c485d88..d5037fe0 100644 index 5442929..06747f9 100644
--- a/tests/functional/ec2/test_bundle_instance.py --- a/tests/functional/ec2/test_bundle_instance.py
+++ b/tests/functional/ec2/test_bundle_instance.py +++ b/tests/functional/ec2/test_bundle_instance.py
@@ -31,7 +31,7 @@ class TestBundleInstance(BaseAWSCommandParamsTest): @@ -31,7 +31,7 @@ class TestBundleInstance(BaseAWSCommandParamsTest):
@ -462,8 +501,8 @@ index 1c485d88..d5037fe0 100644
# returns the same datetime object. This is because this value # returns the same datetime object. This is because this value
# is embedded into the policy file that is generated and we # is embedded into the policy file that is generated and we
# don't what the policy or its signature to change each time # don't what the policy or its signature to change each time
@@ -41,7 +41,7 @@ class TestBundleInstance(BaseAWSCommandParamsTest): @@ -42,7 +42,7 @@ class TestBundleInstance(BaseAWSCommandParamsTest):
mock.Mock(wraps=datetime.datetime) mock.Mock(wraps=datetime.datetime),
) )
mocked_datetime = self.datetime_patcher.start() mocked_datetime = self.datetime_patcher.start()
- mocked_datetime.utcnow.return_value = datetime.datetime(2013, 8, 9) - mocked_datetime.utcnow.return_value = datetime.datetime(2013, 8, 9)
@ -472,10 +511,10 @@ index 1c485d88..d5037fe0 100644
def tearDown(self): def tearDown(self):
super(TestBundleInstance, self).tearDown() super(TestBundleInstance, self).tearDown()
diff --git a/tests/functional/ec2instanceconnect/test_opentunnel.py b/tests/functional/ec2instanceconnect/test_opentunnel.py diff --git a/tests/functional/ec2instanceconnect/test_opentunnel.py b/tests/functional/ec2instanceconnect/test_opentunnel.py
index 83f824d2..ddefc47f 100644 index cd85b01..e83bf78 100644
--- a/tests/functional/ec2instanceconnect/test_opentunnel.py --- a/tests/functional/ec2instanceconnect/test_opentunnel.py
+++ b/tests/functional/ec2instanceconnect/test_opentunnel.py +++ b/tests/functional/ec2instanceconnect/test_opentunnel.py
@@ -310,10 +310,10 @@ def request_params_for_describe_eice(): @@ -359,10 +359,10 @@ def request_params_for_describe_eice():
@pytest.fixture @pytest.fixture
@ -488,29 +527,29 @@ index 83f824d2..ddefc47f 100644
yield dt yield dt
@@ -393,7 +393,7 @@ class TestOpenTunnel: @@ -445,7 +445,7 @@ class TestOpenTunnel:
describe_eice_response, describe_eice_response,
request_params_for_describe_instance, request_params_for_describe_instance,
request_params_for_describe_eice, request_params_for_describe_eice,
- datetime_utcnow_patch, - datetime_utcnow_patch,
+ datetime_now_patch, + datetime_now_patch,
): ):
cli_runner.env["AWS_USE_FIPS_ENDPOINT"] = "false" cli_runner.env["AWS_USE_FIPS_ENDPOINT"] = "false"
cmdline = [ cmdline = [
diff --git a/tests/functional/eks/test_get_token.py b/tests/functional/eks/test_get_token.py diff --git a/tests/functional/eks/test_get_token.py b/tests/functional/eks/test_get_token.py
index 89801f9b..cdf51f7b 100644 index 0e78f9a..5600bdf 100644
--- a/tests/functional/eks/test_get_token.py --- a/tests/functional/eks/test_get_token.py
+++ b/tests/functional/eks/test_get_token.py +++ b/tests/functional/eks/test_get_token.py
@@ -11,7 +11,7 @@ @@ -13,7 +13,7 @@
# ANY KIND, either express or implied. See the License for the specific
# language governing permissions and limitations under the License.
import base64 import base64
-from datetime import datetime
+from datetime import datetime, timezone
import json import json
import os import os
-from datetime import datetime
+from datetime import datetime, timezone
@@ -80,7 +80,7 @@ class TestGetTokenCommand(BaseAWSCommandParamsTest): from awscli.compat import urlparse
from awscli.testutils import BaseAWSCommandParamsTest, mock
@@ -78,7 +78,7 @@ class TestGetTokenCommand(BaseAWSCommandParamsTest):
@mock.patch('awscli.customizations.eks.get_token.datetime') @mock.patch('awscli.customizations.eks.get_token.datetime')
def test_get_token(self, mock_datetime): def test_get_token(self, mock_datetime):
@ -519,7 +558,7 @@ index 89801f9b..cdf51f7b 100644
cmd = 'eks get-token --cluster-name %s' % self.cluster_name cmd = 'eks get-token --cluster-name %s' % self.cluster_name
response = self.run_get_token(cmd) response = self.run_get_token(cmd)
self.assertEqual( self.assertEqual(
@@ -98,7 +98,7 @@ class TestGetTokenCommand(BaseAWSCommandParamsTest): @@ -96,7 +96,7 @@ class TestGetTokenCommand(BaseAWSCommandParamsTest):
@mock.patch('awscli.customizations.eks.get_token.datetime') @mock.patch('awscli.customizations.eks.get_token.datetime')
def test_query_nested_object(self, mock_datetime): def test_query_nested_object(self, mock_datetime):
@ -528,7 +567,7 @@ index 89801f9b..cdf51f7b 100644
cmd = 'eks get-token --cluster-name %s' % self.cluster_name cmd = 'eks get-token --cluster-name %s' % self.cluster_name
cmd += ' --query status' cmd += ' --query status'
response = self.run_get_token(cmd) response = self.run_get_token(cmd)
@@ -120,7 +120,7 @@ class TestGetTokenCommand(BaseAWSCommandParamsTest): @@ -119,7 +119,7 @@ class TestGetTokenCommand(BaseAWSCommandParamsTest):
@mock.patch('awscli.customizations.eks.get_token.datetime') @mock.patch('awscli.customizations.eks.get_token.datetime')
def test_output_text(self, mock_datetime): def test_output_text(self, mock_datetime):
@ -537,7 +576,7 @@ index 89801f9b..cdf51f7b 100644
cmd = 'eks get-token --cluster-name %s' % self.cluster_name cmd = 'eks get-token --cluster-name %s' % self.cluster_name
cmd += ' --output text' cmd += ' --output text'
stdout, _, _ = self.run_cmd(cmd) stdout, _, _ = self.run_cmd(cmd)
@@ -130,7 +130,7 @@ class TestGetTokenCommand(BaseAWSCommandParamsTest): @@ -129,7 +129,7 @@ class TestGetTokenCommand(BaseAWSCommandParamsTest):
@mock.patch('awscli.customizations.eks.get_token.datetime') @mock.patch('awscli.customizations.eks.get_token.datetime')
def test_output_table(self, mock_datetime): def test_output_table(self, mock_datetime):
@ -547,32 +586,32 @@ index 89801f9b..cdf51f7b 100644
cmd += ' --output table' cmd += ' --output table'
stdout, _, _ = self.run_cmd(cmd) stdout, _, _ = self.run_cmd(cmd)
diff --git a/tests/functional/logs/test_tail.py b/tests/functional/logs/test_tail.py diff --git a/tests/functional/logs/test_tail.py b/tests/functional/logs/test_tail.py
index 6049a7f8..5707da93 100644 index 0024bd4..8eaf61c 100644
--- a/tests/functional/logs/test_tail.py --- a/tests/functional/logs/test_tail.py
+++ b/tests/functional/logs/test_tail.py +++ b/tests/functional/logs/test_tail.py
@@ -152,7 +152,7 @@ class TestTailCommand(BaseAWSCommandParamsTest): @@ -155,7 +155,7 @@ class TestTailCommand(BaseAWSCommandParamsTest):
def test_tail_defaults_to_10m(self): def test_tail_defaults_to_10m(self):
datetime_mock = mock.Mock(wraps=datetime) datetime_mock = mock.Mock(wraps=datetime)
- datetime_mock.utcnow = mock.Mock( - datetime_mock.utcnow = mock.Mock(
+ datetime_mock.now = mock.Mock( + datetime_mock.now = mock.Mock(
return_value=datetime(1970, 1, 1, 0, 10, 1, tzinfo=tz.tzutc())) return_value=datetime(1970, 1, 1, 0, 10, 1, tzinfo=tz.tzutc())
with mock.patch('awscli.customizations.logs.tail.datetime', )
new=datetime_mock): with mock.patch(
@@ -177,7 +177,7 @@ class TestTailCommand(BaseAWSCommandParamsTest): @@ -182,7 +182,7 @@ class TestTailCommand(BaseAWSCommandParamsTest):
def test_tail_with_relative_since(self): def test_tail_with_relative_since(self):
datetime_mock = mock.Mock(wraps=datetime) datetime_mock = mock.Mock(wraps=datetime)
- datetime_mock.utcnow = mock.Mock( - datetime_mock.utcnow = mock.Mock(
+ datetime_mock.now = mock.Mock( + datetime_mock.now = mock.Mock(
return_value=datetime(1970, 1, 1, 0, 0, 2, tzinfo=tz.tzutc())) return_value=datetime(1970, 1, 1, 0, 0, 2, tzinfo=tz.tzutc())
with mock.patch('awscli.customizations.logs.tail.datetime', )
new=datetime_mock): with mock.patch(
diff --git a/tests/functional/rds/test_generate_db_auth_token.py b/tests/functional/rds/test_generate_db_auth_token.py diff --git a/tests/functional/rds/test_generate_db_auth_token.py b/tests/functional/rds/test_generate_db_auth_token.py
index 79634ed0..1008ba39 100644 index 4cc562a..4ff83e1 100644
--- a/tests/functional/rds/test_generate_db_auth_token.py --- a/tests/functional/rds/test_generate_db_auth_token.py
+++ b/tests/functional/rds/test_generate_db_auth_token.py +++ b/tests/functional/rds/test_generate_db_auth_token.py
@@ -51,7 +51,7 @@ class TestGenerateDBAuthToken(BaseAWSCommandParamsTest): @@ -50,7 +50,7 @@ class TestGenerateDBAuthToken(BaseAWSCommandParamsTest):
clock = datetime.datetime(2016, 11, 7, 17, 39, 33, tzinfo=tzutc()) clock = datetime.datetime(2016, 11, 7, 17, 39, 33, tzinfo=tzutc())
with mock.patch('datetime.datetime') as dt: with mock.patch('datetime.datetime') as dt:
@ -582,12 +621,12 @@ index 79634ed0..1008ba39 100644
expected = ( expected = (
diff --git a/tests/functional/s3/test_presign_command.py b/tests/functional/s3/test_presign_command.py diff --git a/tests/functional/s3/test_presign_command.py b/tests/functional/s3/test_presign_command.py
index 2db338a0..03741d19 100644 index 43ede9a..d315dd3 100644
--- a/tests/functional/s3/test_presign_command.py --- a/tests/functional/s3/test_presign_command.py
+++ b/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 @@ -22,13 +22,13 @@ from awscli.testutils import (
from awscli.testutils import create_clidriver temporary_file,
)
-# Values used to fix time.time() and datetime.datetime.utcnow() -# Values used to fix time.time() and datetime.datetime.utcnow()
+# Values used to fix time.time() and datetime.datetime.now() +# Values used to fix time.time() and datetime.datetime.now()
@ -596,12 +635,12 @@ index 2db338a0..03741d19 100644
DEFAULT_EXPIRES = 3600 DEFAULT_EXPIRES = 3600
FROZEN_TIME = mock.Mock(return_value=FROZEN_TIMESTAMP) FROZEN_TIME = mock.Mock(return_value=FROZEN_TIMESTAMP)
FROZEN_DATETIME = mock.Mock( 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)
+ return_value=datetime.datetime(2016, 8, 18, 14, 33, 3, 0, tzinfo=datetime.timezone.utc)) + return_value=datetime.datetime(2016, 8, 18, 14, 33, 3, 0, tzinfo=datetime.timezone.utc)
)
class TestPresignCommand(BaseAWSCommandParamsTest): @@ -76,7 +76,7 @@ class TestPresignCommand(BaseAWSCommandParamsTest):
@@ -78,7 +78,7 @@ class TestPresignCommand(BaseAWSCommandParamsTest):
def get_presigned_url_for_cmd(self, cmdline): def get_presigned_url_for_cmd(self, cmdline):
with mock.patch('time.time', FROZEN_TIME): with mock.patch('time.time', FROZEN_TIME):
with mock.patch('datetime.datetime') as d: with mock.patch('datetime.datetime') as d:
@ -611,19 +650,19 @@ index 2db338a0..03741d19 100644
return stdout return stdout
diff --git a/tests/integration/customizations/test_codecommit.py b/tests/integration/customizations/test_codecommit.py diff --git a/tests/integration/customizations/test_codecommit.py b/tests/integration/customizations/test_codecommit.py
index 7ffbed65..25c78faf 100644 index 7077c08..d904290 100644
--- a/tests/integration/customizations/test_codecommit.py --- a/tests/integration/customizations/test_codecommit.py
+++ b/tests/integration/customizations/test_codecommit.py +++ b/tests/integration/customizations/test_codecommit.py
@@ -14,7 +14,7 @@ @@ -12,7 +12,7 @@
import awscli # language governing permissions and limitations under the License.
import os
import os
-from datetime import datetime -from datetime import datetime
+from datetime import datetime, timezone +from datetime import datetime, timezone
from awscli.compat import StringIO from botocore.awsrequest import AWSRequest
from botocore.session import Session from botocore.credentials import Credentials
@@ -59,7 +59,7 @@ class TestCodeCommitCredentialHelper(unittest.TestCase): @@ -64,7 +64,7 @@ class TestCodeCommitCredentialHelper(unittest.TestCase):
@mock.patch('sys.stdout', new_callable=StringIOWithFileNo) @mock.patch('sys.stdout', new_callable=StringIOWithFileNo)
@mock.patch.object(awscli.customizations.codecommit.datetime, 'datetime') @mock.patch.object(awscli.customizations.codecommit.datetime, 'datetime')
def test_integration_using_cli_driver(self, dt_mock, stdout_mock): def test_integration_using_cli_driver(self, dt_mock, stdout_mock):
@ -632,7 +671,7 @@ index 7ffbed65..25c78faf 100644
driver = create_clidriver() driver = create_clidriver()
entry_point = AWSCLIEntryPoint(driver) entry_point = AWSCLIEntryPoint(driver)
rc = entry_point.main('codecommit credential-helper get'.split()) rc = entry_point.main('codecommit credential-helper get'.split())
@@ -75,7 +75,7 @@ class TestCodeCommitCredentialHelper(unittest.TestCase): @@ -83,7 +83,7 @@ class TestCodeCommitCredentialHelper(unittest.TestCase):
@mock.patch('sys.stdout', new_callable=StringIOWithFileNo) @mock.patch('sys.stdout', new_callable=StringIOWithFileNo)
@mock.patch.object(awscli.customizations.codecommit.datetime, 'datetime') @mock.patch.object(awscli.customizations.codecommit.datetime, 'datetime')
def test_integration_fips_using_cli_driver(self, dt_mock, stdout_mock): def test_integration_fips_using_cli_driver(self, dt_mock, stdout_mock):
@ -641,7 +680,7 @@ index 7ffbed65..25c78faf 100644
driver = create_clidriver() driver = create_clidriver()
entry_point = AWSCLIEntryPoint(driver) entry_point = AWSCLIEntryPoint(driver)
rc = entry_point.main('codecommit credential-helper get'.split()) rc = entry_point.main('codecommit credential-helper get'.split())
@@ -91,7 +91,7 @@ class TestCodeCommitCredentialHelper(unittest.TestCase): @@ -102,7 +102,7 @@ class TestCodeCommitCredentialHelper(unittest.TestCase):
@mock.patch('sys.stdout', new_callable=StringIOWithFileNo) @mock.patch('sys.stdout', new_callable=StringIOWithFileNo)
@mock.patch.object(awscli.customizations.codecommit.datetime, 'datetime') @mock.patch.object(awscli.customizations.codecommit.datetime, 'datetime')
def test_integration_vpc_using_cli_driver(self, dt_mock, stdout_mock): def test_integration_vpc_using_cli_driver(self, dt_mock, stdout_mock):
@ -651,10 +690,10 @@ index 7ffbed65..25c78faf 100644
entry_point = AWSCLIEntryPoint(driver) entry_point = AWSCLIEntryPoint(driver)
rc = entry_point.main('codecommit credential-helper get'.split()) rc = entry_point.main('codecommit credential-helper get'.split())
diff --git a/tests/unit/botocore/auth/test_signers.py b/tests/unit/botocore/auth/test_signers.py diff --git a/tests/unit/botocore/auth/test_signers.py b/tests/unit/botocore/auth/test_signers.py
index 19d559ac..e7db8d8b 100644 index 7effaf3..ff62c77 100644
--- a/tests/unit/botocore/auth/test_signers.py --- a/tests/unit/botocore/auth/test_signers.py
+++ b/tests/unit/botocore/auth/test_signers.py +++ b/tests/unit/botocore/auth/test_signers.py
@@ -27,10 +27,10 @@ from botocore.awsrequest import AWSRequest @@ -28,10 +28,10 @@ from tests import mock, unittest
class BaseTestWithFixedDate(unittest.TestCase): class BaseTestWithFixedDate(unittest.TestCase):
def setUp(self): def setUp(self):
@ -667,10 +706,10 @@ index 19d559ac..e7db8d8b 100644
self.datetime_mock.strptime.return_value = self.fixed_date self.datetime_mock.strptime.return_value = self.fixed_date
def tearDown(self): def tearDown(self):
@@ -357,9 +357,9 @@ class TestSigV4(unittest.TestCase): @@ -379,9 +379,9 @@ class TestSigV4(unittest.TestCase):
with mock.patch.object( 'datetime',
botocore.auth.datetime, 'datetime', mock.Mock(wraps=datetime.datetime),
mock.Mock(wraps=datetime.datetime)) as mock_datetime: ) as mock_datetime:
- original_utcnow = datetime.datetime(2014, 1, 1, 0, 0) - original_utcnow = datetime.datetime(2014, 1, 1, 0, 0)
+ original_now = datetime.datetime(2014, 1, 1, 0, 0, tzinfo=datetime.timezone.utc) + original_now = datetime.datetime(2014, 1, 1, 0, 0, tzinfo=datetime.timezone.utc)
@ -679,53 +718,54 @@ index 19d559ac..e7db8d8b 100644
# Go through the add_auth process once. This will attach # Go through the add_auth process once. This will attach
# a timestamp to the request at the beginning of auth. # a timestamp to the request at the beginning of auth.
auth.add_auth(request) auth.add_auth(request)
@@ -367,8 +367,8 @@ class TestSigV4(unittest.TestCase): @@ -389,9 +389,8 @@ class TestSigV4(unittest.TestCase):
# Ensure the date is in the Authorization header # Ensure the date is in the Authorization header
self.assertIn('20140101', request.headers['Authorization']) self.assertIn('20140101', request.headers['Authorization'])
# Now suppose the utc time becomes the next day all of a sudden # Now suppose the utc time becomes the next day all of a sudden
- mock_datetime.utcnow.return_value = datetime.datetime( - mock_datetime.utcnow.return_value = datetime.datetime(
- 2014, 1, 2, 0, 0) - 2014, 1, 2, 0, 0
- )
+ mock_datetime.now.return_value = datetime.datetime( + mock_datetime.now.return_value = datetime.datetime(
+ 2014, 1, 2, 0, 0, tzinfo=datetime.timezone.utc) + 2014, 1, 2, 0, 0, tzinfo=datetime.timezone.utc)
# Smaller methods like the canonical request and string_to_sign # Smaller methods like the canonical request and string_to_sign
# should have the timestamp attached to the request in their # should have the timestamp attached to the request in their
# body and not what the time is now mocked as. This is to ensure # body and not what the time is now mocked as. This is to ensure
@@ -534,8 +534,8 @@ class TestSigV4Presign(BasePresignTest): @@ -563,8 +562,8 @@ class TestSigV4Presign(BasePresignTest):
mock.Mock(wraps=datetime.datetime) mock.Mock(wraps=datetime.datetime),
) )
mocked_datetime = self.datetime_patcher.start() mocked_datetime = self.datetime_patcher.start()
- mocked_datetime.utcnow.return_value = datetime.datetime( - mocked_datetime.utcnow.return_value = datetime.datetime(
- 2014, 1, 1, 0, 0) - 2014, 1, 1, 0, 0
+ mocked_datetime.now.return_value = datetime.datetime( + mocked_datetime.now.return_value = datetime.datetime(
+ 2014, 1, 1, 0, 0, tzinfo=datetime.timezone.utc) + 2014, 1, 1, 0, 0, tzinfo=datetime.timezone.utc
)
def tearDown(self): def tearDown(self):
self.datetime_patcher.stop() @@ -780,8 +779,8 @@ class TestS3SigV4Post(BaseS3PresignPostTest):
@@ -729,8 +729,8 @@ class TestS3SigV4Post(BaseS3PresignPostTest): mock.Mock(wraps=datetime.datetime),
mock.Mock(wraps=datetime.datetime)
) )
mocked_datetime = self.datetime_patcher.start() mocked_datetime = self.datetime_patcher.start()
- mocked_datetime.utcnow.return_value = datetime.datetime( - mocked_datetime.utcnow.return_value = datetime.datetime(
- 2014, 1, 1, 0, 0) - 2014, 1, 1, 0, 0
+ mocked_datetime.now.return_value = datetime.datetime( + mocked_datetime.now.return_value = datetime.datetime(
+ 2014, 1, 1, 0, 0, tzinfo=datetime.timezone.utc) + 2014, 1, 1, 0, 0, tzinfo=datetime.timezone.utc
)
def tearDown(self): def tearDown(self):
self.datetime_patcher.stop()
diff --git a/tests/unit/botocore/test_credentials.py b/tests/unit/botocore/test_credentials.py diff --git a/tests/unit/botocore/test_credentials.py b/tests/unit/botocore/test_credentials.py
index b9931216..7fdcf4ba 100644 index feb35d0..70f2b47 100644
--- a/tests/unit/botocore/test_credentials.py --- a/tests/unit/botocore/test_credentials.py
+++ b/tests/unit/botocore/test_credentials.py +++ b/tests/unit/botocore/test_credentials.py
@@ -11,7 +11,7 @@ @@ -16,7 +16,7 @@ import os
# distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF import shutil
# ANY KIND, either express or implied. See the License for the specific import subprocess
# language governing permissions and limitations under the License. import tempfile
-from datetime import datetime, timedelta -from datetime import datetime, timedelta
+from datetime import datetime, timedelta, timezone +from datetime import datetime, timedelta, timezone
import subprocess
import os import botocore.exceptions
import tempfile import botocore.session
@@ -110,7 +110,7 @@ class TestRefreshableCredentials(TestCredentials): @@ -125,7 +125,7 @@ class TestRefreshableCredentials(TestCredentials):
def test_refresh_needed(self): def test_refresh_needed(self):
# The expiry time was set for 30 minutes ago, so if we # The expiry time was set for 30 minutes ago, so if we
@ -734,7 +774,7 @@ index b9931216..7fdcf4ba 100644
# a refresh. # a refresh.
self.mock_time.return_value = datetime.now(tzlocal()) self.mock_time.return_value = datetime.now(tzlocal())
self.assertTrue(self.creds.refresh_needed()) self.assertTrue(self.creds.refresh_needed())
@@ -290,8 +290,8 @@ class TestAssumeRoleCredentialFetcher(BaseEnvVar): @@ -313,8 +313,8 @@ class TestAssumeRoleCredentialFetcher(BaseEnvVar):
self.assertEqual(response, expected_response) self.assertEqual(response, expected_response)
def test_retrieves_from_cache(self): def test_retrieves_from_cache(self):
@ -742,10 +782,10 @@ index b9931216..7fdcf4ba 100644
- utc_timestamp = date_in_future.isoformat() + 'Z' - utc_timestamp = date_in_future.isoformat() + 'Z'
+ date_in_future = datetime.now(timezone.utc) + timedelta(seconds=1000) + date_in_future = datetime.now(timezone.utc) + timedelta(seconds=1000)
+ utc_timestamp = date_in_future.isoformat() + utc_timestamp = date_in_future.isoformat()
cache_key = ( cache_key = '793d6e2f27667ab2da104824407e486bfec24a47'
'793d6e2f27667ab2da104824407e486bfec24a47' cache = {
) cache_key: {
@@ -702,8 +702,8 @@ class TestAssumeRoleWithWebIdentityCredentialFetcher(BaseEnvVar): @@ -793,8 +793,8 @@ class TestAssumeRoleWithWebIdentityCredentialFetcher(BaseEnvVar):
self.assertEqual(response, expected_response) self.assertEqual(response, expected_response)
def test_retrieves_from_cache(self): def test_retrieves_from_cache(self):
@ -753,10 +793,10 @@ index b9931216..7fdcf4ba 100644
- utc_timestamp = date_in_future.isoformat() + 'Z' - utc_timestamp = date_in_future.isoformat() + 'Z'
+ date_in_future = datetime.now(timezone.utc) + timedelta(seconds=1000) + date_in_future = datetime.now(timezone.utc) + timedelta(seconds=1000)
+ utc_timestamp = date_in_future.isoformat() + utc_timestamp = date_in_future.isoformat()
cache_key = ( cache_key = '793d6e2f27667ab2da104824407e486bfec24a47'
'793d6e2f27667ab2da104824407e486bfec24a47' cache = {
) cache_key: {
@@ -822,8 +822,8 @@ class TestAssumeRoleWithWebIdentityCredentialProvider(unittest.TestCase): @@ -958,8 +958,8 @@ class TestAssumeRoleWithWebIdentityCredentialProvider(unittest.TestCase):
mock_loader_cls.assert_called_with('/some/path/token.jwt') mock_loader_cls.assert_called_with('/some/path/token.jwt')
def test_assume_role_retrieves_from_cache(self): def test_assume_role_retrieves_from_cache(self):
@ -765,9 +805,9 @@ index b9931216..7fdcf4ba 100644
+ date_in_future = datetime.now(timezone.utc) + timedelta(seconds=1000) + date_in_future = datetime.now(timezone.utc) + timedelta(seconds=1000)
+ utc_timestamp = date_in_future.isoformat() + utc_timestamp = date_in_future.isoformat()
cache_key = ( cache_key = 'c29461feeacfbed43017d20612606ff76abc073d'
'c29461feeacfbed43017d20612606ff76abc073d' cache = {
@@ -1960,8 +1960,8 @@ class TestAssumeRoleCredentialProvider(unittest.TestCase): @@ -2199,8 +2199,8 @@ class TestAssumeRoleCredentialProvider(unittest.TestCase):
self.assertEqual(expiry_time, '2016-11-06T01:30:00UTC') self.assertEqual(expiry_time, '2016-11-06T01:30:00UTC')
def test_assume_role_retrieves_from_cache(self): def test_assume_role_retrieves_from_cache(self):
@ -777,8 +817,8 @@ index b9931216..7fdcf4ba 100644
+ utc_timestamp = date_in_future.isoformat() + utc_timestamp = date_in_future.isoformat()
self.fake_config['profiles']['development']['role_arn'] = 'myrole' self.fake_config['profiles']['development']['role_arn'] = 'myrole'
cache_key = ( cache_key = '793d6e2f27667ab2da104824407e486bfec24a47'
@@ -1988,8 +1988,8 @@ class TestAssumeRoleCredentialProvider(unittest.TestCase): @@ -2228,8 +2228,8 @@ class TestAssumeRoleCredentialProvider(unittest.TestCase):
self.assertEqual(creds.token, 'baz-cached') self.assertEqual(creds.token, 'baz-cached')
def test_chain_prefers_cache(self): def test_chain_prefers_cache(self):
@ -790,10 +830,10 @@ index b9931216..7fdcf4ba 100644
# The profile we will be using has a cache entry, but the profile it # 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 # 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 diff --git a/tests/unit/botocore/test_signers.py b/tests/unit/botocore/test_signers.py
index a38d1b59..b0840d54 100644 index b97bf58..ed54e9a 100644
--- a/tests/unit/botocore/test_signers.py --- a/tests/unit/botocore/test_signers.py
+++ b/tests/unit/botocore/test_signers.py +++ b/tests/unit/botocore/test_signers.py
@@ -607,9 +607,9 @@ class TestS3PostPresigner(BaseSignerTest): @@ -686,9 +686,9 @@ class TestS3PostPresigner(BaseSignerTest):
self.datetime_patch = mock.patch('botocore.signers.datetime') self.datetime_patch = mock.patch('botocore.signers.datetime')
self.datetime_mock = self.datetime_patch.start() self.datetime_mock = self.datetime_patch.start()
@ -805,70 +845,70 @@ index a38d1b59..b0840d54 100644
self.datetime_mock.timedelta.return_value = self.fixed_delta self.datetime_mock.timedelta.return_value = self.fixed_delta
def tearDown(self): def tearDown(self):
@@ -1004,7 +1004,7 @@ class TestGenerateDBAuthToken(BaseSignerTest): @@ -1141,7 +1141,7 @@ class TestGenerateDBAuthToken(BaseSignerTest):
clock = datetime.datetime(2016, 11, 7, 17, 39, 33, tzinfo=tzutc()) clock = datetime.datetime(2016, 11, 7, 17, 39, 33, tzinfo=tzutc())
with mock.patch('datetime.datetime') as dt: with mock.patch('datetime.datetime') as dt:
- dt.utcnow.return_value = clock - dt.utcnow.return_value = clock
+ dt.now.return_value = clock + dt.now.return_value = clock
result = generate_db_auth_token( result = generate_db_auth_token(
self.client, hostname, port, username) self.client, hostname, port, username
)
diff --git a/tests/unit/botocore/test_utils.py b/tests/unit/botocore/test_utils.py diff --git a/tests/unit/botocore/test_utils.py b/tests/unit/botocore/test_utils.py
index b4699c6c..2d128bf1 100644 index 7538f02..f9579a3 100644
--- a/tests/unit/botocore/test_utils.py --- a/tests/unit/botocore/test_utils.py
+++ b/tests/unit/botocore/test_utils.py +++ b/tests/unit/botocore/test_utils.py
@@ -98,7 +98,7 @@ from botocore.stub import Stubber @@ -102,7 +102,7 @@ from dateutil.tz import tzoffset, tzutc
from botocore.config import Config
from botocore.endpoint_provider import RuleSetEndpoint from tests import FreezeTime, RawResponse, create_session, mock, unittest
-DATE = datetime.datetime(2021, 12, 10, 00, 00, 00) -DATE = datetime.datetime(2021, 12, 10, 00, 00, 00)
+DATE = datetime.datetime(2021, 12, 10, 00, 00, 00, tzinfo=datetime.timezone.utc) +DATE = datetime.datetime(2021, 12, 10, 00, 00, 00, tzinfo=datetime.timezone.utc)
DT_FORMAT = "%Y-%m-%dT%H:%M:%SZ" DT_FORMAT = "%Y-%m-%dT%H:%M:%SZ"
@@ -2913,7 +2913,7 @@ class TestInstanceMetadataFetcher(unittest.TestCase): @@ -3116,7 +3116,7 @@ class TestInstanceMetadataFetcher(unittest.TestCase):
self, dt=None, offset=None, offset_func=operator.add
): def _get_datetime(self, dt=None, offset=None, offset_func=operator.add):
if dt is None: if dt is None:
- dt = datetime.datetime.utcnow() - dt = datetime.datetime.utcnow()
+ dt = datetime.datetime.now(datetime.timezone.utc) + dt = datetime.datetime.now(datetime.timezone.utc)
if offset is not None: if offset is not None:
dt = offset_func(dt, offset) dt = offset_func(dt, offset)
diff --git a/tests/unit/customizations/eks/test_get_token.py b/tests/unit/customizations/eks/test_get_token.py diff --git a/tests/unit/customizations/eks/test_get_token.py b/tests/unit/customizations/eks/test_get_token.py
index 9575aa0d..2664e1fe 100644 index 7f830b3..0f019c3 100644
--- a/tests/unit/customizations/eks/test_get_token.py --- a/tests/unit/customizations/eks/test_get_token.py
+++ b/tests/unit/customizations/eks/test_get_token.py +++ b/tests/unit/customizations/eks/test_get_token.py
@@ -46,6 +46,6 @@ class TestGetTokenCommand(BaseTokenTest): @@ -48,7 +48,7 @@ class TestGetTokenCommand(BaseTokenTest):
cmd = GetTokenCommand(self._session) cmd = GetTokenCommand(self._session)
timestamp = cmd.get_expiration_time() timestamp = cmd.get_expiration_time()
try: try:
- datetime.strptime(timestamp, '%Y-%m-%dT%H:%M:%SZ') - datetime.strptime(timestamp, '%Y-%m-%dT%H:%M:%SZ')
+ datetime.strptime(timestamp, '%Y-%m-%dT%H:%M:%S%z') + datetime.strptime(timestamp, '%Y-%m-%dT%H:%M:%S%z')
except ValueError: except ValueError:
raise ValueError("Incorrect data format, should be %Y-%m-%dT%H:%M:%SZ") raise ValueError(
"Incorrect data format, should be %Y-%m-%dT%H:%M:%SZ"
diff --git a/tests/unit/customizations/test_opsworks.py b/tests/unit/customizations/test_opsworks.py diff --git a/tests/unit/customizations/test_opsworks.py b/tests/unit/customizations/test_opsworks.py
index d5a6eba3..bad37a90 100644 index 0712d63..951ad31 100644
--- a/tests/unit/customizations/test_opsworks.py --- a/tests/unit/customizations/test_opsworks.py
+++ b/tests/unit/customizations/test_opsworks.py +++ b/tests/unit/customizations/test_opsworks.py
@@ -33,8 +33,8 @@ class TestOpsWorksBase(unittest.TestCase): @@ -32,8 +32,8 @@ class TestOpsWorksBase(unittest.TestCase):
mock.Mock(wraps=datetime.datetime) opsworks.datetime, "datetime", mock.Mock(wraps=datetime.datetime)
) )
mocked_datetime = self.datetime_patcher.start() mocked_datetime = self.datetime_patcher.start()
- mocked_datetime.utcnow.return_value = datetime.datetime( - mocked_datetime.utcnow.return_value = datetime.datetime(
- 2013, 8, 9, 23, 42) - 2013, 8, 9, 23, 42
+ mocked_datetime.now.return_value = datetime.datetime( + mocked_datetime.now.return_value = datetime.datetime(
+ 2013, 8, 9, 23, 42, tzinfo=datetime.timezone.utc) + 2013, 8, 9, 23, 42, tzinfo=datetime.timezone.utc
)
def tearDown(self): def tearDown(self):
self.datetime_patcher.stop()
diff --git a/tests/utils/botocore/__init__.py b/tests/utils/botocore/__init__.py diff --git a/tests/utils/botocore/__init__.py b/tests/utils/botocore/__init__.py
index 106736f3..c76288b5 100644 index bbe6a59..dddaf26 100644
--- a/tests/utils/botocore/__init__.py --- a/tests/utils/botocore/__init__.py
+++ b/tests/utils/botocore/__init__.py +++ b/tests/utils/botocore/__init__.py
@@ -559,12 +559,12 @@ class FreezeTime(contextlib.ContextDecorator): @@ -579,12 +579,12 @@ class FreezeTime(contextlib.ContextDecorator):
:param module: reference to imported module to patch (e.g. botocore.auth.datetime) :param module: reference to imported module to patch (e.g. botocore.auth.datetime)
:type date: datetime.datetime :type date: datetime.datetime
@ -882,8 +922,8 @@ index 106736f3..c76288b5 100644
+ date = datetime.datetime.now(datetime.timezone.utc) + date = datetime.datetime.now(datetime.timezone.utc)
self.date = date self.date = date
self.datetime_patcher = mock.patch.object( self.datetime_patcher = mock.patch.object(
module, 'datetime', module, 'datetime', mock.Mock(wraps=datetime.datetime)
@@ -573,7 +573,7 @@ class FreezeTime(contextlib.ContextDecorator): @@ -592,7 +592,7 @@ class FreezeTime(contextlib.ContextDecorator):
def __enter__(self, *args, **kwargs): def __enter__(self, *args, **kwargs):
mock = self.datetime_patcher.start() mock = self.datetime_patcher.start()

139
python314.patch Normal file
View File

@ -0,0 +1,139 @@
diff --git a/awscli/arguments.py b/awscli/arguments.py
index 77639cf..3ab060b 100644
--- a/awscli/arguments.py
+++ b/awscli/arguments.py
@@ -451,7 +451,7 @@ class CLIArgument(BaseCLIArgument):
cli_name = self.cli_name
parser.add_argument(
cli_name,
- help=self.documentation,
+ help=self.documentation.replace("%", "%%"),
type=self.cli_type,
required=self.required,
)
@@ -602,7 +602,7 @@ class BooleanArgument(CLIArgument):
def add_to_parser(self, parser):
parser.add_argument(
self.cli_name,
- help=self.documentation,
+ help=self.documentation.replace("%", "%%"),
action=self._action,
default=self._default,
dest=self._destination,
diff --git a/awscli/customizations/logs/startlivetail.py b/awscli/customizations/logs/startlivetail.py
index cc5849b..bc71a3d 100644
--- a/awscli/customizations/logs/startlivetail.py
+++ b/awscli/customizations/logs/startlivetail.py
@@ -833,7 +833,7 @@ class InteractiveUI(BaseLiveTailUI):
await self._application.run_async()
def run(self):
- asyncio.get_event_loop().run_until_complete(self._run_ui())
+ asyncio.run(self._run_ui())
class PrintOnlyPrinter(BaseLiveTailPrinter):
diff --git a/awscli/customizations/wizard/app.py b/awscli/customizations/wizard/app.py
index c813b97..028fcaa 100644
--- a/awscli/customizations/wizard/app.py
+++ b/awscli/customizations/wizard/app.py
@@ -10,9 +10,9 @@
# 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.
+import asyncio
import json
import os
-from asyncio import new_event_loop, set_event_loop
from collections.abc import MutableMapping
from prompt_toolkit.application import Application
@@ -77,14 +77,12 @@ class WizardApp(Application):
)
def run(self, pre_run=None, **kwargs):
- loop = new_event_loop()
- try:
- set_event_loop(loop)
+ def create_event_loop():
+ loop = asyncio.new_event_loop()
loop.set_exception_handler(self._handle_exception)
- f = self.run_async(pre_run=pre_run, set_exception_handler=False)
- return loop.run_until_complete(f)
- finally:
- loop.close()
+ return loop
+ f = self.run_async(pre_run=pre_run, set_exception_handler=False)
+ return asyncio.run(f, loop_factory=create_event_loop)
def _handle_exception(self, loop, context):
self.exit(exception=UnexpectedWizardException(context['exception']))
diff --git a/tests/__init__.py b/tests/__init__.py
index db70912..0ab2e4a 100644
--- a/tests/__init__.py
+++ b/tests/__init__.py
@@ -471,16 +471,9 @@ class PromptToolkitAppRunner:
# This is the function that will be passed to our thread to
# actually run the application
try:
- # When we run the app in a separate thread, there is no
- # default event loop. This ensures we create one as it is
- # likely the application will try to grab the default loop
- loop = asyncio.new_event_loop()
- asyncio.set_event_loop(loop)
app_run_context.return_value = target(*target_args)
except BaseException as e:
app_run_context.raised_exception = e
- finally:
- loop.close()
def _wait_until_app_is_done_updating(self):
self._wait_until_app_is_done_rendering()
diff --git a/tests/functional/test_utils.py b/tests/functional/test_utils.py
--- a/tests/functional/test_utils.py
+++ b/tests/functional/test_utils.py
@@ -18,7 +18,7 @@ class TestWriteException(unittest.TestCa
def test_write_exception(self):
error_message = "Some error message."
ex = Exception(error_message)
- with codecs.open(self.outfile, 'w+', encoding='utf-8') as outfile:
+ with open(self.outfile, 'w+', encoding='utf-8') as outfile:
write_exception(ex, outfile)
outfile.seek(0)
diff --git a/tests/unit/botocore/test_utils.py b/tests/unit/botocore/test_utils.py
--- a/tests/unit/botocore/test_utils.py
+++ b/tests/unit/botocore/test_utils.py
@@ -3646,20 +3646,28 @@ def test_lru_cache_weakref():
cls2 = ClassWithCachedMethod()
assert cls1.cached_fn.cache_info().currsize == 0
- assert getrefcount(cls1) == 2
- assert getrefcount(cls2) == 2
+ refcount1 = getrefcount(cls1)
+ refcount2 = getrefcount(cls2)
+ assert refcount1 in (1, 2)
+ assert refcount2 in (1, 2)
# "The count returned is generally one higher than you might expect, because
# it includes the (temporary) reference as an argument to getrefcount()."
# https://docs.python.org/3.8/library/sys.html#getrefcount
+ # However, as of 3.14: "The interpreter internally avoids some reference
+ # count modifications when loading objects onto the operands stack by
+ # borrowing references when possible. This can lead to smaller reference
+ # count values compared to previous Python versions."
+ # https://docs.python.org/3.14/whatsnew/3.14.html#whatsnew314-refcount
+
cls1.cached_fn(1, 1)
cls2.cached_fn(1, 1)
# The cache now has two entries, but the reference count remains the same as
# before.
assert cls1.cached_fn.cache_info().currsize == 2
- assert getrefcount(cls1) == 2
- assert getrefcount(cls2) == 2
+ assert getrefcount(cls1) == refcount1
+ assert getrefcount(cls2) == refcount2
# Deleting one of the objects does not interfere with the cache entries
# related to the other object.

View File

@ -1,8 +1,8 @@
diff --git a/awscli/customizations/cloudformation/yamlhelper.py b/awscli/customizations/cloudformation/yamlhelper.py diff --git a/awscli/customizations/cloudformation/yamlhelper.py b/awscli/customizations/cloudformation/yamlhelper.py
index abdc749..9cf9496 100644 index 8e3b291..a926d53 100644
--- a/awscli/customizations/cloudformation/yamlhelper.py --- a/awscli/customizations/cloudformation/yamlhelper.py
+++ b/awscli/customizations/cloudformation/yamlhelper.py +++ b/awscli/customizations/cloudformation/yamlhelper.py
@@ -92,8 +92,14 @@ def yaml_dump(dict_to_dump): @@ -91,8 +91,14 @@ def yaml_dump(dict_to_dump):
yaml.Representer = FlattenAliasRepresenter yaml.Representer = FlattenAliasRepresenter
_add_yaml_1_1_boolean_resolvers(yaml.Resolver) _add_yaml_1_1_boolean_resolvers(yaml.Resolver)
yaml.Representer.add_representer(OrderedDict, _dict_representer) yaml.Representer.add_representer(OrderedDict, _dict_representer)
@ -19,32 +19,32 @@ index abdc749..9cf9496 100644
def _dict_constructor(loader, node): def _dict_constructor(loader, node):
diff --git a/awscli/customizations/eks/kubeconfig.py b/awscli/customizations/eks/kubeconfig.py diff --git a/awscli/customizations/eks/kubeconfig.py b/awscli/customizations/eks/kubeconfig.py
index 5130f7f..64526a7 100644 index 2d302d8..d00c4a8 100644
--- a/awscli/customizations/eks/kubeconfig.py --- a/awscli/customizations/eks/kubeconfig.py
+++ b/awscli/customizations/eks/kubeconfig.py +++ b/awscli/customizations/eks/kubeconfig.py
@@ -44,7 +44,7 @@ def _get_new_kubeconfig_content(): @@ -45,7 +45,7 @@ def _get_new_kubeconfig_content():
("contexts", []), ("contexts", []),
("current-context", ""), ("current-context", ""),
("kind", "Config"), ("kind", "Config"),
- ("preferences", OrderedDict()), - ("preferences", OrderedDict()),
+ ("preferences", {}), + ("preferences", {}),
("users", []) ("users", []),
]) ]
)
@@ -121,7 +121,7 @@ class KubeconfigValidator(object): @@ -135,7 +135,7 @@ class KubeconfigValidator(object):
if (key in config.content and for key, value in self._validation_content.items():
type(config.content[key]) == list): if key in config.content and type(config.content[key]) == list:
for element in config.content[key]: for element in config.content[key]:
- if not isinstance(element, OrderedDict): - if not isinstance(element, OrderedDict):
+ if not isinstance(element, dict): + if not isinstance(element, dict):
raise KubeconfigCorruptedError( raise KubeconfigCorruptedError(
f"Entry in {key} not a {dict}. ") f"Entry in {key} not a {dict}. "
)
diff --git a/awscli/customizations/eks/ordered_yaml.py b/awscli/customizations/eks/ordered_yaml.py diff --git a/awscli/customizations/eks/ordered_yaml.py b/awscli/customizations/eks/ordered_yaml.py
index 23834e0..5c0f92a 100644 index f9b1a11..0cce12e 100644
--- a/awscli/customizations/eks/ordered_yaml.py --- a/awscli/customizations/eks/ordered_yaml.py
+++ b/awscli/customizations/eks/ordered_yaml.py +++ b/awscli/customizations/eks/ordered_yaml.py
@@ -46,10 +46,18 @@ def ordered_yaml_dump(to_dump, stream=None): @@ -50,10 +50,18 @@ def ordered_yaml_dump(to_dump, stream=None):
:type stream: file :type stream: file
""" """
yaml = ruamel.yaml.YAML(typ="safe", pure=True) yaml = ruamel.yaml.YAML(typ="safe", pure=True)
@ -66,17 +66,35 @@ index 23834e0..5c0f92a 100644
+ +
+ return result + return result
diff --git a/tests/unit/customizations/cloudformation/test_yamlhelper.py b/tests/unit/customizations/cloudformation/test_yamlhelper.py diff --git a/tests/unit/customizations/cloudformation/test_yamlhelper.py b/tests/unit/customizations/cloudformation/test_yamlhelper.py
index 466ae2e..1adad4e 100644 index e7ac758..b9632e9 100644
--- a/tests/unit/customizations/cloudformation/test_yamlhelper.py --- a/tests/unit/customizations/cloudformation/test_yamlhelper.py
+++ b/tests/unit/customizations/cloudformation/test_yamlhelper.py +++ b/tests/unit/customizations/cloudformation/test_yamlhelper.py
@@ -139,10 +139,10 @@ class TestYaml(BaseYAMLTest): @@ -130,28 +130,10 @@ class TestYaml(BaseYAMLTest):
' Name: name1\n' ' Name: name1\n'
) )
output_dict = yaml_parse(input_template) output_dict = yaml_parse(input_template)
- expected_dict = OrderedDict([ - expected_dict = OrderedDict(
- ('B_Resource', OrderedDict([('Key2', {'Name': 'name2'}), ('Key1', {'Name': 'name1'})])), - [
- ('A_Resource', OrderedDict([('Key2', {'Name': 'name2'}), ('Key1', {'Name': 'name1'})])) - (
- ]) - 'B_Resource',
- OrderedDict(
- [
- ('Key2', {'Name': 'name2'}),
- ('Key1', {'Name': 'name1'}),
- ]
- ),
- ),
- (
- 'A_Resource',
- OrderedDict(
- [
- ('Key2', {'Name': 'name2'}),
- ('Key1', {'Name': 'name1'}),
- ]
- ),
- ),
- ]
- )
+ expected_dict = { + expected_dict = {
+ 'B_Resource': {'Key2': {'Name': 'name2'}, 'Key1': {'Name': 'name1'}}, + 'B_Resource': {'Key2': {'Name': 'name2'}, 'Key1': {'Name': 'name1'}},
+ 'A_Resource': {'Key2': {'Name': 'name2'}, 'Key1': {'Name': 'name1'}} + 'A_Resource': {'Key2': {'Name': 'name2'}, 'Key1': {'Name': 'name1'}}
@ -84,7 +102,7 @@ index 466ae2e..1adad4e 100644
self.assertEqual(expected_dict, output_dict) self.assertEqual(expected_dict, output_dict)
output_template = yaml_dump(output_dict) output_template = yaml_dump(output_dict)
@@ -156,7 +156,7 @@ class TestYaml(BaseYAMLTest): @@ -165,7 +147,7 @@ class TestYaml(BaseYAMLTest):
<<: *base <<: *base
""" """
output = yaml_parse(test_yaml) output = yaml_parse(test_yaml)

View File

@ -1 +1 @@
SHA512 (aws-cli-2.22.9.tar.gz) = 36869662105f0aa10f294f96777c9be52c4603d3ce69f57713a225f38a975cebf0d4102d520a9378a9c88d5104eff7003b64c72628059f286b4f592dcdfeca20 SHA512 (aws-cli-2.27.0.tar.gz) = 6651d978bfadb936ccf760603602988a70e794749d0772e7f2b2443db2381c72965d1691eedb7d082d5cd1179dc73688841ac8f0589367e2486f2b1295c59b71

124
urllib3-v2.patch Normal file
View File

@ -0,0 +1,124 @@
diff --git a/awscli/botocore/awsrequest.py b/awscli/botocore/awsrequest.py
index 4ce0449..2b14009 100644
--- a/awscli/botocore/awsrequest.py
+++ b/awscli/botocore/awsrequest.py
@@ -14,6 +14,7 @@
import functools
import io
import logging
+from collections.abc import Mapping
import socket
import sys
@@ -24,6 +25,7 @@ from botocore.compat import (
HTTPResponse,
MutableMapping,
urlencode,
+ urlparse,
urlsplit,
urlunsplit,
)
@@ -66,32 +68,34 @@ class AWSConnection:
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self._original_response_cls = self.response_class
- # We'd ideally hook into httplib's states, but they're all
- # __mangled_vars so we use our own state var. This variable is set
- # when we receive an early response from the server. If this value is
- # set to True, any calls to send() are noops. This value is reset to
- # false every time _send_request is called. This is to workaround the
- # fact that py2.6 (and only py2.6) has a separate send() call for the
- # body in _send_request, as opposed to endheaders(), which is where the
- # body is sent in all versions > 2.6.
+ # This variable is set when we receive an early response from the
+ # server. If this value is set to True, any calls to send() are noops.
+ # This value is reset to false every time _send_request is called.
+ # This is to workaround changes in urllib3 2.0 which uses separate
+ # send() calls in request() instead of delegating to endheaders(),
+ # which is where the body is sent in CPython's HTTPConnection.
self._response_received = False
self._expect_header_set = False
+ self._send_called = False
def close(self):
super().close()
# Reset all of our instance state we were tracking.
self._response_received = False
self._expect_header_set = False
+ self._send_called = False
self.response_class = self._original_response_cls
- def _send_request(self, method, url, body, headers, *args, **kwargs):
+ def request(self, method, url, body=None, headers=None, *args, **kwargs):
+ if headers is None:
+ headers = {}
self._response_received = False
if headers.get('Expect', b'') == b'100-continue':
self._expect_header_set = True
else:
self._expect_header_set = False
self.response_class = self._original_response_cls
- rval = super()._send_request(
+ rval = super().request(
method, url, body, headers, *args, **kwargs
)
self._expect_header_set = False
@@ -210,10 +214,13 @@ class AWSConnection:
def send(self, str):
if self._response_received:
- logger.debug(
- "send() called, but reseponse already received. "
- "Not sending data."
- )
+ if not self._send_called:
+ # urllib3 2.0 chunks and calls send potentially
+ # thousands of times inside `request` unlike the
+ # standard library. Only log this once for sanity.
+ logger.debug("send() called, but reseponse already received. "
+ "Not sending data.")
+ self._send_called = True
return
return super().send(str)
@@ -370,8 +377,14 @@ class AWSRequestPreparer:
def _prepare_url(self, original):
url = original.url
if original.params:
- params = urlencode(list(original.params.items()), doseq=True)
- url = f'{url}?{params}'
+ url_parts = urlparse(url)
+ delim = '&' if url_parts.query else '?'
+ if isinstance(original.params, Mapping):
+ params_to_encode = list(original.params.items())
+ else:
+ params_to_encode = original.params
+ params = urlencode(params_to_encode, doseq=True)
+ url = delim.join((url, params))
return url
def _prepare_headers(self, original, prepared_body=None):
diff --git a/awscli/botocore/httpsession.py b/awscli/botocore/httpsession.py
index 516bb3f..25f982d 100644
--- a/awscli/botocore/httpsession.py
+++ b/awscli/botocore/httpsession.py
@@ -328,7 +328,6 @@ class URLLib3Session:
def _get_pool_manager_kwargs(self, **extra_kwargs):
pool_manager_kwargs = {
- 'strict': True,
'timeout': self._timeout,
'maxsize': self._max_pool_connections,
'ssl_context': self._get_ssl_context(),
diff --git a/tests/unit/botocore/test_http_session.py b/tests/unit/botocore/test_http_session.py
index 90ed7d4..0a10c15 100644
--- a/tests/unit/botocore/test_http_session.py
+++ b/tests/unit/botocore/test_http_session.py
@@ -148,7 +148,6 @@ class TestURLLib3Session(unittest.TestCase):
def _assert_manager_call(self, manager, *assert_args, **assert_kwargs):
call_kwargs = {
- 'strict': True,
'maxsize': mock.ANY,
'timeout': mock.ANY,
'ssl_context': mock.ANY,