From 375c8e8e100d86d34a181ee2cc60f0004bbfe133 Mon Sep 17 00:00:00 2001 From: Nate Prewitt Date: Sun, 19 Nov 2023 14:37:54 -0700 Subject: [PATCH 1/3] Remove six from awscli codebase --- awscli/argparser.py | 5 +- awscli/argprocess.py | 9 +- awscli/bcdoc/docstringparser.py | 14 +- awscli/clidriver.py | 1 - awscli/compat.py | 128 ++++++------------ awscli/customizations/awslambda.py | 5 +- .../cloudformation/artifact_exporter.py | 5 +- .../cloudformation/yamlhelper.py | 4 +- awscli/customizations/codedeploy/push.py | 5 +- awscli/customizations/configure/__init__.py | 4 +- awscli/customizations/configure/get.py | 3 +- awscli/customizations/dynamodb.py | 2 - awscli/customizations/ec2/bundleinstance.py | 6 +- awscli/customizations/ec2/decryptpassword.py | 3 +- awscli/customizations/history/show.py | 3 +- awscli/customizations/opsworks.py | 4 +- awscli/customizations/s3/filegenerator.py | 3 +- awscli/customizations/s3/subcommands.py | 3 +- awscli/customizations/s3/transferconfig.py | 5 +- awscli/paramfile.py | 5 +- awscli/table.py | 5 +- awscli/testutils.py | 27 +--- awscli/text.py | 9 +- awscli/utils.py | 14 +- 24 files changed, 93 insertions(+), 179 deletions(-) diff --git a/awscli/argparser.py b/awscli/argparser.py index 126b27f8e1e9..2bb41f8ec01c 100644 --- a/awscli/argparser.py +++ b/awscli/argparser.py @@ -12,7 +12,6 @@ # language governing permissions and limitations under the License. import argparse import sys -from awscli.compat import six from difflib import get_close_matches @@ -106,12 +105,12 @@ def parse_known_args(self, args, namespace=None): # default to utf-8. terminal_encoding = 'utf-8' for arg, value in vars(parsed).items(): - if isinstance(value, six.binary_type): + if isinstance(value, bytes): setattr(parsed, arg, value.decode(terminal_encoding)) elif isinstance(value, list): encoded = [] for v in value: - if isinstance(v, six.binary_type): + if isinstance(v, bytes): encoded.append(v.decode(terminal_encoding)) else: encoded.append(v) diff --git a/awscli/argprocess.py b/awscli/argprocess.py index 5cd418ce2606..c65fd83a067d 100644 --- a/awscli/argprocess.py +++ b/awscli/argprocess.py @@ -13,7 +13,6 @@ """Module for processing CLI args.""" import os import logging -from awscli.compat import six from botocore.compat import OrderedDict, json @@ -166,7 +165,7 @@ def _unpack_cli_arg(argument_model, value, cli_name): return _unpack_complex_cli_arg( argument_model, value, cli_name) else: - return six.text_type(value) + return str(value) def _unpack_json_cli_arg(argument_model, value, cli_name): @@ -185,7 +184,7 @@ def _unpack_complex_cli_arg(argument_model, value, cli_name): return _unpack_json_cli_arg(argument_model, value, cli_name) raise ParamError(cli_name, "Invalid JSON:\n%s" % value) elif type_name == 'list': - if isinstance(value, six.string_types): + if isinstance(value, str): if value.lstrip()[0] == '[': return _unpack_json_cli_arg(argument_model, value, cli_name) elif isinstance(value, list) and len(value) == 1: @@ -226,7 +225,7 @@ def unpack_scalar_cli_arg(argument_model, value, cli_name=''): raise ParamError(cli_name, msg) return open(file_path, 'rb') elif argument_model.type_name == 'boolean': - if isinstance(value, six.string_types) and value.lower() == 'false': + if isinstance(value, str) and value.lower() == 'false': return False return bool(value) else: @@ -401,7 +400,7 @@ def _should_parse_as_shorthand(self, cli_argument, value): check_val = value[0] else: check_val = value - if isinstance(check_val, six.string_types) and check_val.strip().startswith( + if isinstance(check_val, str) and check_val.strip().startswith( ('[', '{')): LOG.debug("Param %s looks like JSON, not considered for " "param shorthand.", cli_argument.py_name) diff --git a/awscli/bcdoc/docstringparser.py b/awscli/bcdoc/docstringparser.py index 868bd5d8914b..cfff547db59d 100644 --- a/awscli/bcdoc/docstringparser.py +++ b/awscli/bcdoc/docstringparser.py @@ -10,10 +10,10 @@ # 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 botocore.compat import six +from html.parser import HTMLParser -class DocStringParser(six.moves.html_parser.HTMLParser): +class DocStringParser(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 +23,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) + HTMLParser.__init__(self) def reset(self): - six.moves.html_parser.HTMLParser.reset(self) + 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) + HTMLParser.feed(self, data) self.tree.write() self.tree = HTMLTree(self.doc) def close(self): - six.moves.html_parser.HTMLParser.close(self) + HTMLParser.close(self) # Write if there is anything remaining. self.tree.write() self.tree = HTMLTree(self.doc) @@ -176,7 +176,7 @@ class DataNode(Node): """ def __init__(self, data, parent=None): super(DataNode, self).__init__(parent) - if not isinstance(data, six.string_types): + if not isinstance(data, str): raise ValueError("Expecting string type, %s given." % type(data)) self.data = data diff --git a/awscli/clidriver.py b/awscli/clidriver.py index d7db5656c720..1c1e2fa91f9a 100644 --- a/awscli/clidriver.py +++ b/awscli/clidriver.py @@ -29,7 +29,6 @@ from awscli.formatter import get_formatter from awscli.plugin import load_plugins from awscli.commands import CLICommand -from awscli.compat import six from awscli.argparser import MainArgParser from awscli.argparser import ServiceArgParser from awscli.argparser import ArgTableArgParser diff --git a/awscli/compat.py b/awscli/compat.py index 6ad8ae69ea0f..348ab042b243 100644 --- a/awscli/compat.py +++ b/awscli/compat.py @@ -19,25 +19,29 @@ import zipfile import signal import contextlib +import queue +import io +import collections.abc as collections_abc +import locale +import urllib.parse as urlparse +from urllib.error import URLError +from urllib.request import urlopen from configparser import RawConfigParser from functools import partial -from botocore.compat import six -#import botocore.compat +from urllib.error import URLError +from botocore.compat import six from botocore.compat import OrderedDict -# If you ever want to import from the vendored six. Add it here and then -# import from awscli.compat. Also try to keep it in alphabetical order. -# This may get large. -advance_iterator = six.advance_iterator -PY3 = six.PY3 -queue = six.moves.queue -shlex_quote = six.moves.shlex_quote -StringIO = six.StringIO -BytesIO = six.BytesIO -urlopen = six.moves.urllib.request.urlopen -binary_type = six.binary_type +# Backwards compatible definitions from six +PY3 = sys.version_info[0] == 3 +advance_iterator = next +shlex_quote = shlex.quote +StringIO = io.StringIO +BytesIO = io.BytesIO +binary_type = bytes +raw_input = input # Most, but not all, python installations will have zlib. This is required to @@ -104,89 +108,33 @@ def ensure_text_type(s): raise ValueError("Expected str, unicode or bytes, received %s." % type(s)) -if six.PY3: - import collections.abc as collections_abc - import locale - import urllib.parse as urlparse - - from urllib.error import URLError - - raw_input = input - - def get_binary_stdin(): - if sys.stdin is None: - raise StdinMissingError() - return sys.stdin.buffer - - def get_binary_stdout(): - return sys.stdout.buffer - - def _get_text_writer(stream, errors): - return stream - - def bytes_print(statement, stdout=None): - """ - This function is used to write raw bytes to stdout. - """ - if stdout is None: - stdout = sys.stdout - - if getattr(stdout, 'buffer', None): - stdout.buffer.write(statement) - else: - # If it is not possible to write to the standard out buffer. - # The next best option is to decode and write to standard out. - stdout.write(statement.decode('utf-8')) - -else: - import codecs - import collections as collections_abc - import locale - import io - import urlparse - - from urllib2 import URLError +def get_binary_stdin(): + if sys.stdin is None: + raise StdinMissingError() + return sys.stdin.buffer - raw_input = raw_input - def get_binary_stdin(): - if sys.stdin is None: - raise StdinMissingError() - return sys.stdin +def get_binary_stdout(): + return sys.stdout.buffer - def get_binary_stdout(): - return sys.stdout - def _get_text_writer(stream, errors): - # In python3, all the sys.stdout/sys.stderr streams are in text - # mode. This means they expect unicode, and will encode the - # unicode automatically before actually writing to stdout/stderr. - # In python2, that's not the case. In order to provide a consistent - # interface, we can create a wrapper around sys.stdout that will take - # unicode, and automatically encode it to the preferred encoding. - # That way consumers can just call get_text_writer(stream) and write - # unicode to the returned stream. Note that get_text_writer - # just returns the stream in the PY3 section above because python3 - # handles this. - - # We're going to use the preferred encoding, but in cases that there is - # no preferred encoding we're going to fall back to assuming ASCII is - # what we should use. This will currently break the use of - # PYTHONIOENCODING, which would require checking stream.encoding first, - # however, the existing behavior is to only use - # locale.getpreferredencoding() and so in the hope of not breaking what - # is currently working, we will continue to only use that. - encoding = locale.getpreferredencoding() - if encoding is None: - encoding = "ascii" +def _get_text_writer(stream, errors): + return stream - return codecs.getwriter(encoding)(stream, errors) - def bytes_print(statement, stdout=None): - if stdout is None: - stdout = sys.stdout +def bytes_print(statement, stdout=None): + """ + This function is used to write raw bytes to stdout. + """ + if stdout is None: + stdout = sys.stdout - stdout.write(statement) + if getattr(stdout, 'buffer', None): + stdout.buffer.write(statement) + else: + # If it is not possible to write to the standard out buffer. + # The next best option is to decode and write to standard out. + stdout.write(statement.decode('utf-8')) def compat_open(filename, mode='r', encoding=None, access_permissions=None): @@ -252,7 +200,7 @@ def compat_shell_quote(s, platform=None): if platform == "win32": return _windows_shell_quote(s) else: - return shlex_quote(s) + return shlex.quote(s) def _windows_shell_quote(s): diff --git a/awscli/customizations/awslambda.py b/awscli/customizations/awslambda.py index c55437c8680e..d373881a383f 100644 --- a/awscli/customizations/awslambda.py +++ b/awscli/customizations/awslambda.py @@ -14,9 +14,8 @@ import copy from contextlib import closing -from botocore.vendored import six - from awscli.arguments import CustomArgument, CLIArgument +from awscli.compat import BytesIO ERROR_MSG = ( @@ -90,7 +89,7 @@ def _should_contain_zip_content(value): # still try to load the contents as a zip file # to be absolutely sure. value = value.encode('utf-8') - fileobj = six.BytesIO(value) + fileobj = BytesIO(value) try: with closing(zipfile.ZipFile(fileobj)) as f: f.infolist() diff --git a/awscli/customizations/cloudformation/artifact_exporter.py b/awscli/customizations/cloudformation/artifact_exporter.py index 64eb5a06e1a4..7fba8dddbba3 100644 --- a/awscli/customizations/cloudformation/artifact_exporter.py +++ b/awscli/customizations/cloudformation/artifact_exporter.py @@ -18,7 +18,6 @@ import contextlib import uuid import shutil -from awscli.compat import six from botocore.utils import set_value_from_jmespath from awscli.compat import urlparse @@ -33,7 +32,7 @@ def is_path_value_valid(path): - return isinstance(path, six.string_types) + return isinstance(path, str) def make_abs_path(directory, path): @@ -70,7 +69,7 @@ def parse_s3_url(url, object_key_property="Key", version_property=None): - if isinstance(url, six.string_types) \ + if isinstance(url, str) \ and url.startswith("s3://"): # Python < 2.7.10 don't parse query parameters from URI with custom diff --git a/awscli/customizations/cloudformation/yamlhelper.py b/awscli/customizations/cloudformation/yamlhelper.py index d251a41c428d..61603603e669 100644 --- a/awscli/customizations/cloudformation/yamlhelper.py +++ b/awscli/customizations/cloudformation/yamlhelper.py @@ -16,8 +16,6 @@ import yaml from yaml.resolver import ScalarNode, SequenceNode -from awscli.compat import six - def intrinsics_multi_constructor(loader, tag_prefix, node): """ @@ -35,7 +33,7 @@ def intrinsics_multi_constructor(loader, tag_prefix, node): cfntag = prefix + tag - if tag == "GetAtt" and isinstance(node.value, six.string_types): + if tag == "GetAtt" and isinstance(node.value, str): # ShortHand notation for !GetAtt accepts Resource.Attribute format # while the standard notation is to use an array # [Resource, Attribute]. Convert shorthand to standard format diff --git a/awscli/customizations/codedeploy/push.py b/awscli/customizations/codedeploy/push.py index 046c3b37636d..f483a3980427 100644 --- a/awscli/customizations/codedeploy/push.py +++ b/awscli/customizations/codedeploy/push.py @@ -20,10 +20,9 @@ from botocore.exceptions import ClientError -from awscli.compat import six from awscli.customizations.codedeploy.utils import validate_s3_location from awscli.customizations.commands import BasicCommand -from awscli.compat import ZIP_COMPRESSION_MODE +from awscli.compat import BytesIO, ZIP_COMPRESSION_MODE ONE_MB = 1 << 20 @@ -246,7 +245,7 @@ def _multipart_upload_to_s3(self, params, bundle, size_remaining): Key=params.key, UploadId=upload_id, PartNumber=part_num, - Body=six.BytesIO(data) + Body=BytesIO(data) ) multipart_list.append({ 'PartNumber': part_num, diff --git a/awscli/customizations/configure/__init__.py b/awscli/customizations/configure/__init__.py index ea49773888da..46aeed5f53db 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 awscli.compat import shlex NOT_SET = '' PREDEFINED_SECTION_NAMES = ('preview', 'plugins') @@ -45,5 +45,5 @@ def mask_value(current_value): def profile_to_section(profile_name): """Converts a profile name to a section header to be used in the config.""" if any(c in _WHITESPACE for c in profile_name): - profile_name = shlex_quote(profile_name) + profile_name = shlex.quote(profile_name) return 'profile %s' % profile_name diff --git a/awscli/customizations/configure/get.py b/awscli/customizations/configure/get.py index a8c55f743473..1d48e06fa46d 100644 --- a/awscli/customizations/configure/get.py +++ b/awscli/customizations/configure/get.py @@ -14,7 +14,6 @@ import logging from awscli.customizations.commands import BasicCommand -from awscli.compat import six from . import PREDEFINED_SECTION_NAMES @@ -56,7 +55,7 @@ def _run_main(self, args, parsed_globals): LOG.debug(u'Config value retrieved: %s' % value) - if isinstance(value, six.string_types): + if isinstance(value, str): self._stream.write(value) self._stream.write('\n') return 0 diff --git a/awscli/customizations/dynamodb.py b/awscli/customizations/dynamodb.py index 90aaab1d39df..83bd5685f579 100644 --- a/awscli/customizations/dynamodb.py +++ b/awscli/customizations/dynamodb.py @@ -14,8 +14,6 @@ import binascii import logging -from awscli.compat import six - logger = logging.getLogger(__name__) diff --git a/awscli/customizations/ec2/bundleinstance.py b/awscli/customizations/ec2/bundleinstance.py index 37c3461258c8..46c9ae16e673 100644 --- a/awscli/customizations/ec2/bundleinstance.py +++ b/awscli/customizations/ec2/bundleinstance.py @@ -17,8 +17,6 @@ import base64 import datetime -from awscli.compat import six - from awscli.arguments import CustomArgument logger = logging.getLogger('ec2bundleinstance') @@ -132,9 +130,9 @@ def _generate_signature(params): policy = params.get('UploadPolicy') sak = params.get('_SAK') if policy and sak: - policy = base64.b64encode(six.b(policy)).decode('utf-8') + policy = base64.b64encode(policy.encode('latin-1')).decode('utf-8') new_hmac = hmac.new(sak.encode('utf-8'), digestmod=sha1) - new_hmac.update(six.b(policy)) + new_hmac.update(policy.encode('latin-1')) ps = base64.encodebytes(new_hmac.digest()).strip().decode('utf-8') params['UploadPolicySignature'] = ps del params['_SAK'] diff --git a/awscli/customizations/ec2/decryptpassword.py b/awscli/customizations/ec2/decryptpassword.py index 9d110636463d..a62a3493ce6d 100644 --- a/awscli/customizations/ec2/decryptpassword.py +++ b/awscli/customizations/ec2/decryptpassword.py @@ -14,7 +14,6 @@ import os import base64 import rsa -from awscli.compat import six from botocore import model @@ -109,7 +108,7 @@ def _decrypt_password_data(self, parsed, **kwargs): try: with open(self._key_path) as pk_file: pk_contents = pk_file.read() - private_key = rsa.PrivateKey.load_pkcs1(six.b(pk_contents)) + private_key = rsa.PrivateKey.load_pkcs1(pk_contents.encode("latin-1")) value = base64.b64decode(value) value = rsa.decrypt(value, private_key) logger.debug(parsed) diff --git a/awscli/customizations/history/show.py b/awscli/customizations/history/show.py index da8bb84fec1b..771e1678e0f8 100644 --- a/awscli/customizations/history/show.py +++ b/awscli/customizations/history/show.py @@ -19,7 +19,6 @@ import colorama from awscli.table import COLORAMA_KWARGS -from awscli.compat import six from awscli.customizations.history.commands import HistorySubcommand from awscli.customizations.history.filters import RegexFilter @@ -213,7 +212,7 @@ def _display_value(self, value_definition, event_record): self._write_output(formatted_value) def _write_output(self, content): - if isinstance(content, six.text_type): + if isinstance(content, str): content = content.encode('utf-8') self._output.write(content) diff --git a/awscli/customizations/opsworks.py b/awscli/customizations/opsworks.py index 604109cdf6c7..94d10cd876fc 100644 --- a/awscli/customizations/opsworks.py +++ b/awscli/customizations/opsworks.py @@ -24,7 +24,7 @@ from botocore.exceptions import ClientError -from awscli.compat import shlex_quote, urlopen, ensure_text_type +from awscli.compat import urlopen, ensure_text_type from awscli.customizations.commands import BasicCommand from awscli.customizations.utils import create_client_from_parsed_globals @@ -475,7 +475,7 @@ def ssh(self, args, remote_script): call.append(self._use_address) remote_call = ["/bin/sh", "-c", remote_script] - call.append(" ".join(shlex_quote(word) for word in remote_call)) + call.append(" ".join(shlex.quote(word) for word in remote_call)) subprocess.check_call(call) def _pre_config_document(self, args): diff --git a/awscli/customizations/s3/filegenerator.py b/awscli/customizations/s3/filegenerator.py index ad0ab4f27c62..e98d78c78edb 100644 --- a/awscli/customizations/s3/filegenerator.py +++ b/awscli/customizations/s3/filegenerator.py @@ -21,7 +21,6 @@ from awscli.customizations.s3.utils import find_bucket_key, get_file_stat from awscli.customizations.s3.utils import BucketLister, create_warning, \ find_dest_path_comp_key, EPOCH_TIME -from awscli.compat import six from awscli.compat import queue _open = open @@ -250,7 +249,7 @@ def should_ignore_file_with_decoding_warnings(self, dirname, filename): happens we warn using a FileDecodingError that provides more information into what's going on. """ - if not isinstance(filename, six.text_type): + if not isinstance(filename, str): decoding_error = FileDecodingError(dirname, filename) warning = create_warning(repr(filename), decoding_error.error_message) diff --git a/awscli/customizations/s3/subcommands.py b/awscli/customizations/s3/subcommands.py index 996d103309a0..f0f8bf4f33c8 100644 --- a/awscli/customizations/s3/subcommands.py +++ b/awscli/customizations/s3/subcommands.py @@ -19,7 +19,6 @@ from dateutil.parser import parse from dateutil.tz import tzlocal -from awscli.compat import six from awscli.compat import queue from awscli.customizations.commands import BasicCommand from awscli.customizations.s3.comparator import Comparator @@ -739,7 +738,7 @@ def _convert_path_args(self, parsed_args): parsed_args.paths = [parsed_args.paths] for i in range(len(parsed_args.paths)): path = parsed_args.paths[i] - if isinstance(path, six.binary_type): + if isinstance(path, bytes): dec_path = path.decode(sys.getfilesystemencoding()) enc_path = dec_path.encode('utf-8') new_path = enc_path.decode('utf-8') diff --git a/awscli/customizations/s3/transferconfig.py b/awscli/customizations/s3/transferconfig.py index d65d21d5bca5..b533aee4eced 100644 --- a/awscli/customizations/s3/transferconfig.py +++ b/awscli/customizations/s3/transferconfig.py @@ -13,7 +13,6 @@ from s3transfer.manager import TransferConfig from awscli.customizations.s3.utils import human_readable_to_bytes -from awscli.compat import six # If the user does not specify any overrides, # these are the default values we use for the s3 transfer # commands. @@ -64,13 +63,13 @@ def build_config(self, **kwargs): def _convert_human_readable_sizes(self, runtime_config): for attr in self.HUMAN_READABLE_SIZES: value = runtime_config.get(attr) - if value is not None and not isinstance(value, six.integer_types): + if value is not None and not isinstance(value, int): runtime_config[attr] = human_readable_to_bytes(value) def _convert_human_readable_rates(self, runtime_config): for attr in self.HUMAN_READABLE_RATES: value = runtime_config.get(attr) - if value is not None and not isinstance(value, six.integer_types): + if value is not None and not isinstance(value, int): if not value.endswith('B/s'): raise InvalidConfigError( 'Invalid rate: %s. The value must be expressed ' diff --git a/awscli/paramfile.py b/awscli/paramfile.py index 4e71b4311983..36f3ac6593f6 100644 --- a/awscli/paramfile.py +++ b/awscli/paramfile.py @@ -17,7 +17,6 @@ from botocore.awsrequest import AWSRequest from botocore.httpsession import URLLib3Session from botocore.exceptions import ProfileNotFound -from awscli.compat import six from awscli.compat import compat_open from awscli.argprocess import ParamError @@ -197,7 +196,7 @@ def _check_for_uri_param(self, param, value): try: return get_paramfile(value, self._prefixes) except ResourceLoadingError as e: - raise ParamError(param.cli_name, six.text_type(e)) + raise ParamError(param.cli_name, str(e)) def get_paramfile(path, cases): @@ -224,7 +223,7 @@ def get_paramfile(path, cases): """ data = None - if isinstance(path, six.string_types): + if isinstance(path, str): for prefix, function_spec in cases.items(): if path.startswith(prefix): function, kwargs = function_spec diff --git a/awscli/table.py b/awscli/table.py index df96392fc9fe..8ebfc454d0ed 100644 --- a/awscli/table.py +++ b/awscli/table.py @@ -17,7 +17,6 @@ import colorama from awscli.utils import is_a_tty -from awscli.compat import six # `autoreset` allows us to not have to sent reset sequences for every @@ -35,7 +34,7 @@ def get_text_length(text): # * A(Ambiguous) # * F(Fullwidth) # * W(Wide) - text = six.text_type(text) + text = str(text) return sum(2 if unicodedata.east_asian_width(char) in 'WFA' else 1 for char in text) @@ -412,7 +411,7 @@ def add_row(self, row): self._update_max_widths(row) def _format_row(self, row): - return [six.text_type(r) for r in row] + return [str(r) for r in row] def _update_max_widths(self, row): if not self._max_widths: diff --git a/awscli/testutils.py b/awscli/testutils.py index 807db01915dd..950290a0567d 100644 --- a/awscli/testutils.py +++ b/awscli/testutils.py @@ -38,7 +38,6 @@ from awscli.compat import StringIO -from awscli.compat import six from botocore.session import Session from botocore.exceptions import ClientError from botocore.exceptions import WaiterError @@ -48,20 +47,13 @@ import awscli.clidriver from awscli.plugin import load_plugins from awscli.clidriver import CLIDriver +from awscli.compat import BytesIO, StringIO from awscli import EnvironmentVariables import unittest -# In python 3, order matters when calling assertEqual to -# compare lists and dictionaries with lists. Therefore, -# assertItemsEqual needs to be used but it is renamed to -# assertCountEqual in python 3. -if six.PY2: - unittest.TestCase.assertCountEqual = unittest.TestCase.assertItemsEqual - - _LOADER = botocore.loaders.Loader() INTEG_LOG = logging.getLogger('awscli.tests.integration') AWS_CMD = None @@ -289,8 +281,8 @@ def __init__(self, stdout, stderr): @contextlib.contextmanager def capture_output(): - stderr = six.StringIO() - stdout = six.StringIO() + stderr = StringIO() + stdout = StringIO() with mock.patch('sys.stderr', stderr): with mock.patch('sys.stdout', stdout): yield CapturedOutput(stdout, stderr) @@ -298,12 +290,9 @@ def capture_output(): @contextlib.contextmanager def capture_input(input_bytes=b''): - input_data = six.BytesIO(input_bytes) - if six.PY3: - mock_object = mock.Mock() - mock_object.buffer = input_data - else: - mock_object = input_data + input_data = BytesIO(input_bytes) + mock_object = mock.Mock() + mock_object.buffer = input_data with mock.patch('sys.stdin', mock_object): yield input_data @@ -623,8 +612,6 @@ def aws(command, collect_memory=False, env_vars=None, aws_command = 'python %s' % get_aws_cmd() full_command = '%s %s' % (aws_command, command) stdout_encoding = get_stdout_encoding() - if isinstance(full_command, six.text_type) and not six.PY3: - full_command = full_command.encode(stdout_encoding) INTEG_LOG.debug("Running command: %s", full_command) env = os.environ.copy() if 'AWS_DEFAULT_REGION' not in env: @@ -742,7 +729,7 @@ def create_client_for_bucket(self, bucket_name): def assert_key_contents_equal(self, bucket, key, expected_contents): self.wait_until_key_exists(bucket, key) - if isinstance(expected_contents, six.BytesIO): + if isinstance(expected_contents, BytesIO): expected_contents = expected_contents.getvalue().decode('utf-8') actual_contents = self.get_key_contents(bucket, key) # The contents can be huge so we try to give helpful error messages diff --git a/awscli/text.py b/awscli/text.py index 9bc505042fee..a5bd0090829e 100644 --- a/awscli/text.py +++ b/awscli/text.py @@ -10,7 +10,6 @@ # 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 awscli.compat import six def format_text(data, stream): @@ -25,7 +24,7 @@ def _format_text(item, stream, identifier=None, scalar_keys=None): else: # If it's not a list or a dict, we just write the scalar # value out directly. - stream.write(six.text_type(item)) + stream.write(str(item)) stream.write('\n') @@ -66,7 +65,7 @@ def _format_scalar_list(elements, identifier, stream): item)) else: # For a bare list, just print the contents. - stream.write('\t'.join([six.text_type(item) for item in elements])) + stream.write('\t'.join([str(item) for item in elements])) stream.write('\n') @@ -107,10 +106,10 @@ def _partition_dict(item_dict, scalar_keys): if isinstance(value, (dict, list)): non_scalar.append((key, value)) else: - scalar.append(six.text_type(value)) + scalar.append(str(value)) else: for key in scalar_keys: - scalar.append(six.text_type(item_dict.get(key, ''))) + scalar.append(str(item_dict.get(key, ''))) remaining_keys = sorted(set(item_dict.keys()) - set(scalar_keys)) for remaining_key in remaining_keys: non_scalar.append((remaining_key, item_dict[remaining_key])) diff --git a/awscli/utils.py b/awscli/utils.py index 7ed20575a24f..39579ad98ba6 100644 --- a/awscli/utils.py +++ b/awscli/utils.py @@ -18,9 +18,9 @@ import sys import subprocess -from awscli.compat import six -from awscli.compat import get_binary_stdout -from awscli.compat import get_popen_kwargs_for_pager_cmd +from awscli.compat import ( + BytesIO, StringIO, get_binary_stdout, get_popen_kwargs_for_pager_cmd +) def split_on_commas(value): @@ -29,7 +29,7 @@ def split_on_commas(value): return value.split(',') elif not any(char in value for char in ['"', "'", '[', ']']): # Simple escaping, let the csv module handle it. - return list(csv.reader(six.StringIO(value), escapechar='\\'))[0] + return list(csv.reader(StringIO(value), escapechar='\\'))[0] else: # If there's quotes for the values, we have to handle this # ourselves. @@ -38,7 +38,7 @@ def split_on_commas(value): def _split_with_quotes(value): try: - parts = list(csv.reader(six.StringIO(value), escapechar='\\'))[0] + parts = list(csv.reader(StringIO(value), escapechar='\\'))[0] except csv.Error: raise ValueError("Bad csv value: %s" % value) iter_parts = iter(parts) @@ -88,7 +88,7 @@ def _eat_items(value, iter_parts, part, end_char, replace_char=''): chunks = [current.replace(replace_char, '')] while True: try: - current = six.advance_iterator(iter_parts) + current = next(iter_parts) except StopIteration: raise ValueError(value) chunks.append(current.replace(replace_char, '')) @@ -236,7 +236,7 @@ def _get_process_pager_kwargs(self, pager_cmd): def write_exception(ex, outfile): outfile.write("\n") - outfile.write(six.text_type(ex)) + outfile.write(str(ex)) outfile.write("\n") From d8eec1b7e3cdfc55142eb3e6f9f4dc16f36a1745 Mon Sep 17 00:00:00 2001 From: Nate Prewitt Date: Wed, 19 Jun 2024 11:49:18 -0700 Subject: [PATCH 2/3] Remove six from tests --- .../functional/cloudtrail/test_validation.py | 18 ++++++------- tests/functional/docs/test_help_output.py | 4 +-- tests/functional/ec2/test_bundle_instance.py | 8 +++--- tests/functional/ec2/test_create_tags.py | 15 ----------- .../test_create_application.py | 19 -------------- .../gamelift/test_get_game_session_log.py | 4 +-- .../rds/test_generate_db_auth_token.py | 3 +-- tests/functional/s3/__init__.py | 4 +-- tests/functional/s3/test_cp_command.py | 14 +++++------ tests/functional/s3/test_mv_command.py | 4 +-- tests/functional/s3/test_sync_command.py | 6 ++--- tests/functional/s3api/test_get_object.py | 5 ++-- .../s3api/test_put_bucket_tagging.py | 1 - tests/functional/s3api/test_put_object.py | 1 - tests/functional/ses/test_send_email.py | 3 --- tests/functional/test_preview.py | 5 ++-- tests/functional/test_streaming_output.py | 4 +-- .../customizations/s3/test_plugin.py | 18 ++++++------- .../customizations/test_codecommit.py | 2 +- .../customizations/cloudformation/__init__.py | 6 ++--- .../cloudformation/test_deploy.py | 1 - .../cloudtrail/test_subscribe.py | 4 +-- .../cloudtrail/test_validation.py | 16 ++++++------ .../customizations/codedeploy/test_push.py | 3 +-- .../configservice/test_getstatus.py | 23 ++++++++--------- .../configure/test_configure.py | 4 +-- .../unit/customizations/configure/test_get.py | 6 ++--- .../customizations/configure/test_list.py | 12 ++++----- .../datapipeline/test_listrunsformatter.py | 4 +-- .../customizations/gamelift/test_getlog.py | 4 +-- .../gamelift/test_uploadbuild.py | 8 +++--- tests/unit/customizations/s3/__init__.py | 6 ++--- .../customizations/s3/test_filegenerator.py | 15 ++++++----- .../customizations/s3/test_transferconfig.py | 5 ++-- tests/unit/customizations/test_codecommit.py | 2 +- .../test_generatecliskeleton.py | 11 ++++---- tests/unit/customizations/test_globalargs.py | 3 +-- tests/unit/output/test_json_output.py | 7 +++--- tests/unit/output/test_table_formatter.py | 4 +-- tests/unit/output/test_text_output.py | 23 +---------------- tests/unit/test_clidriver.py | 25 ++++++++----------- tests/unit/test_compat.py | 10 +++----- tests/unit/test_help.py | 6 ++--- tests/unit/test_paramfile.py | 5 ++-- tests/unit/test_text.py | 4 +-- 45 files changed, 136 insertions(+), 219 deletions(-) diff --git a/tests/functional/cloudtrail/test_validation.py b/tests/functional/cloudtrail/test_validation.py index 906d6eb0a664..275cdbca384d 100644 --- a/tests/functional/cloudtrail/test_validation.py +++ b/tests/functional/cloudtrail/test_validation.py @@ -12,7 +12,6 @@ # language governing permissions and limitations under the License. import gzip -from awscli.compat import six from botocore.exceptions import ClientError from tests.unit.customizations.cloudtrail.test_validation import \ create_scenario, TEST_TRAIL_ARN, START_DATE, END_DATE, VALID_TEST_KEY, \ @@ -20,6 +19,7 @@ from awscli.testutils import mock, BaseAWSCommandParamsTest from awscli.customizations.cloudtrail.validation import DigestTraverser, \ DATE_FORMAT, format_display_date, S3ClientProvider +from awscli.compat import BytesIO from botocore.handlers import parse_get_bucket_location RETRIEVER_FUNCTION = 'awscli.customizations.cloudtrail.validation.create_digest_traverser' @@ -28,7 +28,7 @@ def _gz_compress(data): - out = six.BytesIO() + out = BytesIO() f = gzip.GzipFile(fileobj=out, mode="wb") f.write(data.encode()) f.close() @@ -96,7 +96,7 @@ def tearDown(self): def test_verbose_output_shows_happy_case(self): self.parsed_responses = [ {'LocationConstraint': 'us-east-1'}, - {'Body': six.BytesIO(_gz_compress(self._logs[0]['_raw_value']))} + {'Body': BytesIO(_gz_compress(self._logs[0]['_raw_value']))} ] key_provider, digest_provider, validator = create_scenario( ['gap', 'link'], [[], [self._logs[0]]]) @@ -226,7 +226,7 @@ def test_fails_and_warns_when_log_hash_is_invalid(self): ['gap'], [[self._logs[0]]]) self.parsed_responses = [ {'LocationConstraint': ''}, - {'Body': six.BytesIO(_gz_compress('does not match'))} + {'Body': BytesIO(_gz_compress('does not match'))} ] _setup_mock_traverser(self._mock_traverser, key_provider, digest_provider, validator) @@ -242,9 +242,9 @@ def test_validates_valid_log_files(self): [[self._logs[2]], [], [self._logs[0], self._logs[1]]]) self.parsed_responses = [ {'LocationConstraint': ''}, - {'Body': six.BytesIO(_gz_compress(self._logs[0]['_raw_value']))}, - {'Body': six.BytesIO(_gz_compress(self._logs[1]['_raw_value']))}, - {'Body': six.BytesIO(_gz_compress(self._logs[2]['_raw_value']))}, + {'Body': BytesIO(_gz_compress(self._logs[0]['_raw_value']))}, + {'Body': BytesIO(_gz_compress(self._logs[1]['_raw_value']))}, + {'Body': BytesIO(_gz_compress(self._logs[2]['_raw_value']))}, ] _setup_mock_traverser(self._mock_traverser, key_provider, digest_provider, validator) @@ -301,7 +301,7 @@ def test_fails_when_digest_metadata_is_missing(self): self.parsed_responses = [ {'LocationConstraint': ''}, {'Contents': [{'Key': key}]}, - {'Body': six.BytesIO(_gz_compress(self._logs[0]['_raw_value'])), + {'Body': BytesIO(_gz_compress(self._logs[0]['_raw_value'])), 'Metadata': {}}, ] s3_client_provider = S3ClientProvider(self.driver.session, 'us-east-1') @@ -323,7 +323,7 @@ def test_fails_when_digest_metadata_is_missing(self): def test_follows_trails_when_bucket_changes(self): self.parsed_responses = [ {'LocationConstraint': 'us-east-1'}, - {'Body': six.BytesIO(_gz_compress(self._logs[0]['_raw_value']))}, + {'Body': BytesIO(_gz_compress(self._logs[0]['_raw_value']))}, {'LocationConstraint': 'us-west-2'}, {'LocationConstraint': 'eu-west-1'} ] diff --git a/tests/functional/docs/test_help_output.py b/tests/functional/docs/test_help_output.py index b9025c302e81..26cc751201f7 100644 --- a/tests/functional/docs/test_help_output.py +++ b/tests/functional/docs/test_help_output.py @@ -25,8 +25,8 @@ from awscli.testutils import FileCreator from awscli.testutils import mock from awscli.testutils import aws +from awscli.compat import StringIO -from awscli.compat import six from awscli.alias import AliasLoader @@ -204,7 +204,7 @@ def assert_command_does_not_exist(self, service, command): # command verify that we get a SystemExit exception # and that we get something in stderr that says that # we made an invalid choice (because the operation is removed). - stderr = six.StringIO() + stderr = StringIO() with mock.patch('sys.stderr', stderr): with self.assertRaises(SystemExit): self.driver.main([service, command, 'help']) diff --git a/tests/functional/ec2/test_bundle_instance.py b/tests/functional/ec2/test_bundle_instance.py index ad99990977a1..432640cacc25 100644 --- a/tests/functional/ec2/test_bundle_instance.py +++ b/tests/functional/ec2/test_bundle_instance.py @@ -14,11 +14,9 @@ import base64 import datetime -from six.moves import cStringIO - import awscli.customizations.ec2.bundleinstance -from awscli.compat import six from awscli.testutils import mock, BaseAWSCommandParamsTest +from awscli.compat import StringIO class TestBundleInstance(BaseAWSCommandParamsTest): @@ -69,7 +67,7 @@ def test_no_policy_provided(self): def test_policy_provided(self): policy = '{"notarealpolicy":true}' - base64policy = base64.encodebytes(six.b(policy)).strip().decode('utf-8') + base64policy = base64.encodebytes(policy.encode('latin-1')).strip().decode('utf-8') policy_signature = 'a5SmoLOxoM0MHpOdC25nE7KIafg=' args = ' --instance-id i-12345678 --owner-akid AKIAIOSFODNN7EXAMPLE' args += ' --owner-sak wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY' @@ -88,7 +86,7 @@ def test_policy_provided(self): self.assert_params_for_cmd(args_list, result) def test_both(self): - captured = cStringIO() + captured = StringIO() json = """{"S3":{"Bucket":"foobar","Prefix":"fiebaz"}}""" args = ' --instance-id i-12345678 --owner-aki blah --owner-sak blah --storage %s' % json args_list = (self.prefix + args).split() diff --git a/tests/functional/ec2/test_create_tags.py b/tests/functional/ec2/test_create_tags.py index ba254f770a21..3ac64916b6e8 100644 --- a/tests/functional/ec2/test_create_tags.py +++ b/tests/functional/ec2/test_create_tags.py @@ -13,7 +13,6 @@ # language governing permissions and limitations under the License. import sys -from awscli.compat import six from awscli.testutils import unittest from awscli.testutils import BaseAWSCommandParamsTest @@ -29,17 +28,3 @@ def test_create_tag_normal(self): 'Resources': ['i-12345678'], 'Tags': [{'Key': 'Name', 'Value': 'bar'}]} self.assert_params_for_cmd(cmdline, result) - - @unittest.skipIf( - six.PY3, 'Unicode cmd line test only is relevant to python2.') - def test_create_tag_unicode(self): - cmdline = self.prefix - cmdline += u' --resources i-12345678 --tags Key=Name,Value=\u6211' - encoding = getattr(sys.stdin, 'encoding', 'utf-8') - if encoding is None: - encoding = 'utf-8' - cmdline = cmdline.encode(encoding) - result = { - 'Resources': ['i-12345678'], - 'Tags': [{'Key': 'Name', 'Value': u'\u6211'}]} - self.assert_params_for_cmd(cmdline, result) diff --git a/tests/functional/elasticbeanstalk/test_create_application.py b/tests/functional/elasticbeanstalk/test_create_application.py index b5e9a779164d..df9b7cd05a8b 100644 --- a/tests/functional/elasticbeanstalk/test_create_application.py +++ b/tests/functional/elasticbeanstalk/test_create_application.py @@ -13,7 +13,6 @@ # language governing permissions and limitations under the License. from awscli.testutils import BaseAWSCommandParamsTest, unittest import sys -from awscli.compat import six class TestUpdateConfigurationTemplate(BaseAWSCommandParamsTest): @@ -25,21 +24,3 @@ def test_ascii(self): cmdline += ' --application-name FooBar' result = {'ApplicationName': 'FooBar',} self.assert_params_for_cmd(cmdline, result) - - @unittest.skipIf( - six.PY3, 'Unicode cmd line test only is relevant to python2.') - def test_py2_bytestring_unicode(self): - # In Python2, sys.argv is a list of bytestrings that are encoded - # in whatever encoding the terminal uses. We have an extra step - # where we need to decode the bytestring into unicode. In - # python3, sys.argv is a list of unicode objects so this test - # doesn't make sense for python3. - cmdline = self.prefix - app_name = u'\u2713' - cmdline += u' --application-name %s' % app_name - encoding = getattr(sys.stdin, 'encoding') - if encoding is None: - encoding = 'utf-8' - cmdline = cmdline.encode(encoding) - result = {'ApplicationName': u'\u2713',} - self.assert_params_for_cmd(cmdline, result) diff --git a/tests/functional/gamelift/test_get_game_session_log.py b/tests/functional/gamelift/test_get_game_session_log.py index b03c17faa000..0f6982c07d3a 100644 --- a/tests/functional/gamelift/test_get_game_session_log.py +++ b/tests/functional/gamelift/test_get_game_session_log.py @@ -13,7 +13,7 @@ import os from awscli.testutils import BaseAWSCommandParamsTest, FileCreator, mock -from awscli.compat import six +from awscli.compat import BytesIO class TestGetGameSessionLog(BaseAWSCommandParamsTest): @@ -28,7 +28,7 @@ def setUp(self): 'awscli.customizations.gamelift.getlog.urlopen') self.contents = b'My Contents' self.urlopen_mock = self.urlopen_patch.start() - self.urlopen_mock.return_value = six.BytesIO(self.contents) + self.urlopen_mock.return_value = BytesIO(self.contents) def tearDown(self): super(TestGetGameSessionLog, self).tearDown() diff --git a/tests/functional/rds/test_generate_db_auth_token.py b/tests/functional/rds/test_generate_db_auth_token.py index 5d50f291405f..79634ed083c7 100644 --- a/tests/functional/rds/test_generate_db_auth_token.py +++ b/tests/functional/rds/test_generate_db_auth_token.py @@ -15,7 +15,6 @@ from dateutil.tz import tzutc from botocore.compat import urlparse, parse_qs -from awscli.compat import six from awscli.testutils import mock, BaseAWSCommandParamsTest @@ -24,7 +23,7 @@ class TestGenerateDBAuthToken(BaseAWSCommandParamsTest): prefix = 'rds generate-db-auth-token' def _urlparse(self, url): - if isinstance(url, six.binary_type): + if isinstance(url, bytes): # Not really necessary, but it helps to reduce noise on Python 2.x url = url.decode('utf8') return urlparse(url) diff --git a/tests/functional/s3/__init__.py b/tests/functional/s3/__init__.py index 42b943126726..8fe4c6a65006 100644 --- a/tests/functional/s3/__init__.py +++ b/tests/functional/s3/__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. from awscli.testutils import mock, BaseAWSCommandParamsTest, FileCreator -from awscli.compat import six +from awscli.compat import BytesIO class BaseS3TransferCommandTest(BaseAWSCommandParamsTest): def setUp(self): @@ -57,7 +57,7 @@ def list_objects_response(self, keys): def get_object_response(self): return { 'ETag': '"foo-1"', - 'Body': six.BytesIO(b'foo') + 'Body': BytesIO(b'foo') } def copy_object_response(self): diff --git a/tests/functional/s3/test_cp_command.py b/tests/functional/s3/test_cp_command.py index 4300a32a4a2e..441689da3774 100644 --- a/tests/functional/s3/test_cp_command.py +++ b/tests/functional/s3/test_cp_command.py @@ -16,12 +16,12 @@ from awscli.testutils import BaseAWSCommandParamsTest from awscli.testutils import capture_input from awscli.testutils import mock -from awscli.compat import six +from awscli.compat import BytesIO from tests.functional.s3 import BaseS3TransferCommandTest from tests import requires_crt -class BufferedBytesIO(six.BytesIO): +class BufferedBytesIO(BytesIO): @property def buffer(self): return self @@ -178,7 +178,7 @@ def test_upload_deep_archive(self): def test_operations_used_in_download_file(self): self.parsed_responses = [ {"ContentLength": "100", "LastModified": "00:00:00Z"}, - {'ETag': '"foo-1"', 'Body': six.BytesIO(b'foo')}, + {'ETag': '"foo-1"', 'Body': BytesIO(b'foo')}, ] cmdline = '%s s3://bucket/key.txt %s' % (self.prefix, self.files.rootdir) @@ -306,7 +306,7 @@ def test_cp_fails_with_utime_errors_but_continues(self): cmdline = '%s s3://bucket/key.txt %s' % (self.prefix, full_path) self.parsed_responses = [ {"ContentLength": "100", "LastModified": "00:00:00Z"}, - {'ETag': '"foo-1"', 'Body': six.BytesIO(b'foo')} + {'ETag': '"foo-1"', 'Body': BytesIO(b'foo')} ] with mock.patch('os.utime') as mock_utime: mock_utime.side_effect = OSError(1, '') @@ -324,7 +324,7 @@ def test_recursive_glacier_download_with_force_glacier(self): ], 'CommonPrefixes': [] }, - {'ETag': '"foo-1"', 'Body': six.BytesIO(b'foo')}, + {'ETag': '"foo-1"', 'Body': BytesIO(b'foo')}, ] cmdline = '%s s3://bucket/foo %s --recursive --force-glacier-transfer'\ % (self.prefix, self.files.rootdir) @@ -512,7 +512,7 @@ def test_cp_with_sse_c_copy_source_fileb(self): "ContentLength": 4, "ETag": '"d3b07384d113edec49eaa6238ad5ff00"', "LastModified": "Tue, 12 Jul 2016 21:26:07 GMT", - "Body": six.BytesIO(b'foo\n') + "Body": BytesIO(b'foo\n') }, {} ] @@ -790,7 +790,7 @@ def test_streaming_download(self): "ContentLength": 4, "ETag": '"d3b07384d113edec49eaa6238ad5ff00"', "LastModified": "Tue, 12 Jul 2016 21:26:07 GMT", - "Body": six.BytesIO(b'foo\n') + "Body": BytesIO(b'foo\n') } ] diff --git a/tests/functional/s3/test_mv_command.py b/tests/functional/s3/test_mv_command.py index 49af07994395..da8637dff8b3 100644 --- a/tests/functional/s3/test_mv_command.py +++ b/tests/functional/s3/test_mv_command.py @@ -11,8 +11,8 @@ # 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 awscli.compat import six from awscli.customizations.s3.utils import S3PathResolver +from awscli.compat import BytesIO from tests.functional.s3 import BaseS3TransferCommandTest from tests import requires_crt @@ -83,7 +83,7 @@ def test_download_move_with_request_payer(self): # Response for HeadObject {"ContentLength": 100, "LastModified": "00:00:00Z"}, # Response for GetObject - {'ETag': '"foo-1"', 'Body': six.BytesIO(b'foo')}, + {'ETag': '"foo-1"', 'Body': BytesIO(b'foo')}, # Response for DeleteObject {} ] diff --git a/tests/functional/s3/test_sync_command.py b/tests/functional/s3/test_sync_command.py index 86b7351e8055..2e94f30986d2 100644 --- a/tests/functional/s3/test_sync_command.py +++ b/tests/functional/s3/test_sync_command.py @@ -12,8 +12,8 @@ # language governing permissions and limitations under the License. import os -from awscli.compat import six from awscli.testutils import mock, cd +from awscli.compat import BytesIO from tests.functional.s3 import BaseS3TransferCommandTest @@ -65,7 +65,7 @@ def test_sync_to_non_existant_directory(self): {"Key": key, "Size": 3, "LastModified": "2014-01-09T20:45:49.000Z"}]}, {'ETag': '"c8afdb36c52cf4727836669019e69222-"', - 'Body': six.BytesIO(b'foo')} + 'Body': BytesIO(b'foo')} ] self.run_cmd(cmdline, expected_rc=0) # Make sure the file now exists. @@ -83,7 +83,7 @@ def test_glacier_sync_with_force_glacier(self): ], 'CommonPrefixes': [] }, - {'ETag': '"foo-1"', 'Body': six.BytesIO(b'foo')}, + {'ETag': '"foo-1"', 'Body': BytesIO(b'foo')}, ] cmdline = '%s s3://bucket/foo %s --force-glacier-transfer' % ( self.prefix, self.files.rootdir) diff --git a/tests/functional/s3api/test_get_object.py b/tests/functional/s3api/test_get_object.py index c23f72cd2218..ec32015254d9 100644 --- a/tests/functional/s3api/test_get_object.py +++ b/tests/functional/s3api/test_get_object.py @@ -12,11 +12,10 @@ # ANY KIND, either express or implied. See the License for the specific # language governing permissions and limitations under the License. from awscli.testutils import BaseAWSCommandParamsTest +from awscli.compat import StringIO import os import re -from awscli.compat import six - import awscli.clidriver @@ -26,7 +25,7 @@ class TestGetObject(BaseAWSCommandParamsTest): def setUp(self): super(TestGetObject, self).setUp() - self.parsed_response = {'Body': six.StringIO()} + self.parsed_response = {'Body': StringIO()} def remove_file_if_exists(self, filename): if os.path.isfile(filename): diff --git a/tests/functional/s3api/test_put_bucket_tagging.py b/tests/functional/s3api/test_put_bucket_tagging.py index 7bde081c93af..92ce5b874290 100644 --- a/tests/functional/s3api/test_put_bucket_tagging.py +++ b/tests/functional/s3api/test_put_bucket_tagging.py @@ -15,7 +15,6 @@ import copy from awscli.testutils import BaseAWSCommandParamsTest -from awscli.compat import six # file is gone in python3, so instead IOBase must be used. diff --git a/tests/functional/s3api/test_put_object.py b/tests/functional/s3api/test_put_object.py index c60a0627a20a..2bc37f9cc1e6 100644 --- a/tests/functional/s3api/test_put_object.py +++ b/tests/functional/s3api/test_put_object.py @@ -16,7 +16,6 @@ import copy from awscli.testutils import BaseAWSCommandParamsTest, FileCreator -from awscli.compat import six import awscli.clidriver diff --git a/tests/functional/ses/test_send_email.py b/tests/functional/ses/test_send_email.py index 9c449291fa4d..90d18960d0a5 100644 --- a/tests/functional/ses/test_send_email.py +++ b/tests/functional/ses/test_send_email.py @@ -13,9 +13,6 @@ # language governing permissions and limitations under the License. from awscli.testutils import BaseAWSCommandParamsTest -from awscli.compat import six -from six.moves import cStringIO - class TestSendEmail(BaseAWSCommandParamsTest): diff --git a/tests/functional/test_preview.py b/tests/functional/test_preview.py index eca12322587b..6630cce426b2 100644 --- a/tests/functional/test_preview.py +++ b/tests/functional/test_preview.py @@ -10,9 +10,8 @@ # 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 awscli.compat import six - from awscli.customizations import preview +from awscli.compat import StringIO from awscli.testutils import mock, BaseAWSCommandParamsTest @@ -20,7 +19,7 @@ class TestPreviewMode(BaseAWSCommandParamsTest): def setUp(self): super(TestPreviewMode, self).setUp() - self.stderr = six.StringIO() + self.stderr = StringIO() self.stderr_patch = mock.patch('sys.stderr', self.stderr) self.stderr_patch.start() self.full_config = {'profiles': {}} diff --git a/tests/functional/test_streaming_output.py b/tests/functional/test_streaming_output.py index 1a6ce849484a..75e6db05142c 100644 --- a/tests/functional/test_streaming_output.py +++ b/tests/functional/test_streaming_output.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 awscli.compat import six +from awscli.compat import BytesIO from awscli.testutils import BaseAWSCommandParamsTest from awscli.testutils import FileCreator @@ -33,7 +33,7 @@ def test_get_media_streaming_output(self): ) self.parsed_response = { 'ContentType': 'video/webm', - 'Payload': six.BytesIO(b'testbody') + 'Payload': BytesIO(b'testbody') } outpath = self.files.full_path('outfile') params = { diff --git a/tests/integration/customizations/s3/test_plugin.py b/tests/integration/customizations/s3/test_plugin.py index 0f05c232053f..6968b1702600 100644 --- a/tests/integration/customizations/s3/test_plugin.py +++ b/tests/integration/customizations/s3/test_plugin.py @@ -30,7 +30,7 @@ import pytest -from awscli.compat import six, urlopen +from awscli.compat import BytesIO, urlopen import botocore.session from awscli.testutils import unittest, get_stdout_encoding @@ -188,7 +188,7 @@ def test_mv_s3_to_s3(self): def test_mv_s3_to_s3_multipart(self): from_bucket = _SHARED_BUCKET to_bucket = self.create_bucket() - file_contents = six.BytesIO(b'abcd' * (1024 * 1024 * 10)) + file_contents = BytesIO(b'abcd' * (1024 * 1024 * 10)) self.put_object(from_bucket, 'foo.txt', file_contents) p = aws('s3 mv s3://%s/foo.txt s3://%s/foo.txt' % (from_bucket, @@ -202,7 +202,7 @@ def test_mv_s3_to_s3_multipart_recursive(self): from_bucket = _SHARED_BUCKET to_bucket = self.create_bucket() - large_file_contents = six.BytesIO(b'abcd' * (1024 * 1024 * 10)) + large_file_contents = BytesIO(b'abcd' * (1024 * 1024 * 10)) small_file_contents = 'small file contents' self.put_object(from_bucket, 'largefile', large_file_contents) self.put_object(from_bucket, 'smallfile', small_file_contents) @@ -250,7 +250,7 @@ def test_mv_s3_to_s3_with_sig4(self): def test_mv_with_large_file(self): bucket_name = _SHARED_BUCKET # 40MB will force a multipart upload. - file_contents = six.BytesIO(b'abcd' * (1024 * 1024 * 10)) + file_contents = BytesIO(b'abcd' * (1024 * 1024 * 10)) foo_txt = self.files.create_file( 'foo.txt', file_contents.getvalue().decode('utf-8')) p = aws('s3 mv %s s3://%s/foo.txt' % (foo_txt, bucket_name)) @@ -287,7 +287,7 @@ def test_cant_move_large_file_onto_itself(self): # but a mv command doesn't make sense because a mv is just a # cp + an rm of the src file. We should be consistent and # not allow large files to be mv'd onto themselves. - file_contents = six.BytesIO(b'a' * (1024 * 1024 * 10)) + file_contents = BytesIO(b'a' * (1024 * 1024 * 10)) bucket_name = _SHARED_BUCKET self.put_object(bucket_name, key_name='key.txt', contents=file_contents) @@ -382,7 +382,7 @@ def test_cp_without_trailing_slash(self): def test_cp_s3_s3_multipart(self): from_bucket = _SHARED_BUCKET to_bucket = self.create_bucket() - file_contents = six.BytesIO(b'abcd' * (1024 * 1024 * 10)) + file_contents = BytesIO(b'abcd' * (1024 * 1024 * 10)) self.put_object(from_bucket, 'foo.txt', file_contents) p = aws('s3 cp s3://%s/foo.txt s3://%s/foo.txt' % @@ -407,7 +407,7 @@ def test_guess_mime_type(self): def test_download_large_file(self): # This will force a multipart download. bucket_name = _SHARED_BUCKET - foo_contents = six.BytesIO(b'abcd' * (1024 * 1024 * 10)) + foo_contents = BytesIO(b'abcd' * (1024 * 1024 * 10)) self.put_object(bucket_name, key_name='foo.txt', contents=foo_contents) local_foo_txt = self.files.full_path('foo.txt') @@ -420,7 +420,7 @@ def test_download_large_file(self): @skip_if_windows('SIGINT not supported on Windows.') def test_download_ctrl_c_does_not_hang(self): bucket_name = _SHARED_BUCKET - foo_contents = six.BytesIO(b'abcd' * (1024 * 1024 * 40)) + foo_contents = BytesIO(b'abcd' * (1024 * 1024 * 40)) self.put_object(bucket_name, key_name='foo.txt', contents=foo_contents) local_foo_txt = self.files.full_path('foo.txt') @@ -993,7 +993,7 @@ def test_no_write_access_large_file(self): # which effectively disables the expect 100 continue logic. # This will result in a test error because we won't follow # the temporary redirect for the newly created bucket. - contents = six.BytesIO(b'a' * 10 * 1024 * 1024) + contents = BytesIO(b'a' * 10 * 1024 * 1024) self.put_object(bucket_name, 'foo.txt', contents=contents) os.chmod(self.files.rootdir, 0o444) diff --git a/tests/integration/customizations/test_codecommit.py b/tests/integration/customizations/test_codecommit.py index 16592960e7f1..781c8b650946 100644 --- a/tests/integration/customizations/test_codecommit.py +++ b/tests/integration/customizations/test_codecommit.py @@ -16,7 +16,7 @@ from datetime import datetime -from six import StringIO +from awscli.compat import StringIO from botocore.session import Session from botocore.credentials import Credentials from awscli.customizations.codecommit import CodeCommitGetCommand diff --git a/tests/unit/customizations/cloudformation/__init__.py b/tests/unit/customizations/cloudformation/__init__.py index 26daca4df412..5746f5416ecf 100644 --- a/tests/unit/customizations/cloudformation/__init__.py +++ b/tests/unit/customizations/cloudformation/__init__.py @@ -11,7 +11,5 @@ # ANY KIND, either express or implied. See the License for the specific # language governing permissions and limitations under the License. -import six, unittest - -if six.PY3: - unittest.TestCase.assertItemsEqual = unittest.TestCase.assertCountEqual +import unittest +unittest.TestCase.assertItemsEqual = unittest.TestCase.assertCountEqual diff --git a/tests/unit/customizations/cloudformation/test_deploy.py b/tests/unit/customizations/cloudformation/test_deploy.py index 6e67a20117ba..8aac8ae3be4f 100644 --- a/tests/unit/customizations/cloudformation/test_deploy.py +++ b/tests/unit/customizations/cloudformation/test_deploy.py @@ -11,7 +11,6 @@ # ANY KIND, either express or implied. See the License for the specific # language governing permissions and limitations under the License. import tempfile -import six import collections from awscli.testutils import mock, unittest diff --git a/tests/unit/customizations/cloudtrail/test_subscribe.py b/tests/unit/customizations/cloudtrail/test_subscribe.py index f9483a180e38..4c372f4a16e6 100644 --- a/tests/unit/customizations/cloudtrail/test_subscribe.py +++ b/tests/unit/customizations/cloudtrail/test_subscribe.py @@ -16,8 +16,8 @@ from botocore.session import Session from tests.unit.test_clidriver import FakeSession -from awscli.compat import six from awscli.customizations.cloudtrail.subscribe import CloudTrailError, CloudTrailSubscribe +from awscli.compat import BytesIO from awscli.testutils import BaseAWSCommandParamsTest from awscli.testutils import mock, unittest, temporary_file @@ -70,7 +70,7 @@ def setUp(self): self.subscribe.s3 = mock.Mock() self.subscribe.s3.meta.region_name = 'us-east-1' - policy_template = six.BytesIO(six.b(u'{"Statement": []}')) + policy_template = BytesIO(u'{"Statement": []}'.encode('latin-1')) self.subscribe.s3.get_object = mock.Mock( return_value={'Body': policy_template}) self.subscribe.s3.head_bucket.return_value = {} diff --git a/tests/unit/customizations/cloudtrail/test_validation.py b/tests/unit/customizations/cloudtrail/test_validation.py index 66262492cf93..5b0fec1f6382 100644 --- a/tests/unit/customizations/cloudtrail/test_validation.py +++ b/tests/unit/customizations/cloudtrail/test_validation.py @@ -21,7 +21,6 @@ import rsa from argparse import Namespace -from awscli.compat import six from awscli.testutils import BaseAWSCommandParamsTest from awscli.customizations.cloudtrail.validation import DigestError, \ extract_digest_key_date, normalize_date, format_date, DigestProvider, \ @@ -29,6 +28,7 @@ Sha256RSADigestValidator, DATE_FORMAT, CloudTrailValidateLogs, \ parse_date, assert_cloudtrail_arn_is_valid, DigestSignatureError, \ InvalidDigestFormat, S3ClientProvider +from awscli.compat import BytesIO from botocore.exceptions import ClientError from awscli.testutils import mock, unittest from awscli.schema import ParameterRequiredError @@ -532,14 +532,14 @@ def test_calls_list_objects_correctly_org_trails(self): ) def test_ensures_digest_has_proper_metadata(self): - out = six.BytesIO() + out = BytesIO() f = gzip.GzipFile(fileobj=out, mode="wb") f.write('{"foo":"bar"}'.encode()) f.close() gzipped_data = out.getvalue() s3_client = mock.Mock() s3_client.get_object.return_value = { - 'Body': six.BytesIO(gzipped_data), + 'Body': BytesIO(gzipped_data), 'Metadata': {}} provider = self._get_mock_provider(s3_client) with self.assertRaises(DigestSignatureError): @@ -548,7 +548,7 @@ def test_ensures_digest_has_proper_metadata(self): def test_ensures_digest_can_be_gzip_inflated(self): s3_client = mock.Mock() s3_client.get_object.return_value = { - 'Body': six.BytesIO('foo'.encode()), + 'Body': BytesIO('foo'.encode()), 'Metadata': {}} provider = self._get_mock_provider(s3_client) with self.assertRaises(InvalidDigestFormat): @@ -556,14 +556,14 @@ def test_ensures_digest_can_be_gzip_inflated(self): def test_ensures_digests_can_be_json_parsed(self): json_str = '{{{' - out = six.BytesIO() + out = BytesIO() f = gzip.GzipFile(fileobj=out, mode="wb") f.write(json_str.encode()) f.close() gzipped_data = out.getvalue() s3_client = mock.Mock() s3_client.get_object.return_value = { - 'Body': six.BytesIO(gzipped_data), + 'Body': BytesIO(gzipped_data), 'Metadata': {'signature': 'abc', 'signature-algorithm': 'SHA256'}} provider = self._get_mock_provider(s3_client) with self.assertRaises(InvalidDigestFormat): @@ -571,14 +571,14 @@ def test_ensures_digests_can_be_json_parsed(self): def test_fetches_digests(self): json_str = '{"foo":"bar"}' - out = six.BytesIO() + out = BytesIO() f = gzip.GzipFile(fileobj=out, mode="wb") f.write(json_str.encode()) f.close() gzipped_data = out.getvalue() s3_client = mock.Mock() s3_client.get_object.return_value = { - 'Body': six.BytesIO(gzipped_data), + 'Body': BytesIO(gzipped_data), 'Metadata': {'signature': 'abc', 'signature-algorithm': 'SHA256'}} provider = self._get_mock_provider(s3_client) result = provider.fetch_digest('bucket', 'key') diff --git a/tests/unit/customizations/codedeploy/test_push.py b/tests/unit/customizations/codedeploy/test_push.py index ae6110a43bfe..c1c5bd833950 100644 --- a/tests/unit/customizations/codedeploy/test_push.py +++ b/tests/unit/customizations/codedeploy/test_push.py @@ -14,12 +14,11 @@ import awscli from argparse import Namespace -from six import StringIO from botocore.exceptions import ClientError from awscli.customizations.codedeploy.push import Push from awscli.testutils import mock, unittest -from awscli.compat import ZIP_COMPRESSION_MODE +from awscli.compat import StringIO, ZIP_COMPRESSION_MODE class TestPush(unittest.TestCase): diff --git a/tests/unit/customizations/configservice/test_getstatus.py b/tests/unit/customizations/configservice/test_getstatus.py index aab2c0a1f9da..a10f2ee2d4f7 100644 --- a/tests/unit/customizations/configservice/test_getstatus.py +++ b/tests/unit/customizations/configservice/test_getstatus.py @@ -10,8 +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 awscli.compat import six - +from awscli.compat import StringIO from awscli.testutils import mock, unittest from awscli.customizations.configservice.getstatus import GetStatusCommand @@ -78,7 +77,7 @@ def test_configuration_recorder_success(self): 'Delivery Channels:\n\n' ) - with mock.patch('sys.stdout', six.StringIO()) as mock_stdout: + with mock.patch('sys.stdout', StringIO()) as mock_stdout: self.cmd._run_main(self.parsed_args, self.parsed_globals) self.assertEqual(expected_output, mock_stdout.getvalue()) @@ -98,7 +97,7 @@ def test_configuration_recorder_fail(self): 'Delivery Channels:\n\n' ) - with mock.patch('sys.stdout', six.StringIO()) as mock_stdout: + with mock.patch('sys.stdout', StringIO()) as mock_stdout: self.cmd._run_main(self.parsed_args, self.parsed_globals) self.assertEqual(expected_output, mock_stdout.getvalue()) @@ -113,7 +112,7 @@ def test_configuration_recorder_off(self): 'Delivery Channels:\n\n' ) - with mock.patch('sys.stdout', six.StringIO()) as mock_stdout: + with mock.patch('sys.stdout', StringIO()) as mock_stdout: self.cmd._run_main(self.parsed_args, self.parsed_globals) self.assertEqual(expected_output, mock_stdout.getvalue()) @@ -144,7 +143,7 @@ def test_multiple_configuration_recorders(self): 'recorder: OFF\n\n' 'Delivery Channels:\n\n' ) - with mock.patch('sys.stdout', six.StringIO()) as mock_stdout: + with mock.patch('sys.stdout', StringIO()) as mock_stdout: self.cmd._run_main(self.parsed_args, self.parsed_globals) self.assertEqual(expected_output, mock_stdout.getvalue()) @@ -170,7 +169,7 @@ def test_delivery_channel_success_single_delivery_info(self): 'last stream delivery status: SUCCESS\n\n' ) - with mock.patch('sys.stdout', six.StringIO()) as mock_stdout: + with mock.patch('sys.stdout', StringIO()) as mock_stdout: self.cmd._run_main(self.parsed_args, self.parsed_globals) self.assertEqual(expected_output, mock_stdout.getvalue()) @@ -198,7 +197,7 @@ def test_delivery_channel_success_multiple_delivery_info(self): 'last snapshot delivery status: SUCCESS\n\n' ) - with mock.patch('sys.stdout', six.StringIO()) as mock_stdout: + with mock.patch('sys.stdout', StringIO()) as mock_stdout: self.cmd._run_main(self.parsed_args, self.parsed_globals) self.assertEqual(expected_output, mock_stdout.getvalue()) @@ -227,7 +226,7 @@ def test_delivery_channel_fail_single_delivery_info(self): 'message: This is the error\n\n' ) - with mock.patch('sys.stdout', six.StringIO()) as mock_stdout: + with mock.patch('sys.stdout', StringIO()) as mock_stdout: self.cmd._run_main(self.parsed_args, self.parsed_globals) self.assertEqual(expected_output, mock_stdout.getvalue()) @@ -259,7 +258,7 @@ def test_delivery_channel_mixed_multiple_delivery_info(self): 'last snapshot delivery status: SUCCESS\n\n' ) - with mock.patch('sys.stdout', six.StringIO()) as mock_stdout: + with mock.patch('sys.stdout', StringIO()) as mock_stdout: self.cmd._run_main(self.parsed_args, self.parsed_globals) self.assertEqual(expected_output, mock_stdout.getvalue()) @@ -298,7 +297,7 @@ def test_multiple_delivery_channels(self): 'last snapshot delivery status: SUCCESS\n\n' ) - with mock.patch('sys.stdout', six.StringIO()) as mock_stdout: + with mock.patch('sys.stdout', StringIO()) as mock_stdout: self.cmd._run_main(self.parsed_args, self.parsed_globals) self.assertEqual(expected_output, mock_stdout.getvalue()) @@ -361,6 +360,6 @@ def test_full_get_status(self): 'last snapshot delivery status: SUCCESS\n\n' ) - with mock.patch('sys.stdout', six.StringIO()) as mock_stdout: + with mock.patch('sys.stdout', StringIO()) as mock_stdout: self.cmd._run_main(self.parsed_args, self.parsed_globals) self.assertEqual(expected_output, mock_stdout.getvalue()) diff --git a/tests/unit/customizations/configure/test_configure.py b/tests/unit/customizations/configure/test_configure.py index 5756a15e6156..33e6021edd45 100644 --- a/tests/unit/customizations/configure/test_configure.py +++ b/tests/unit/customizations/configure/test_configure.py @@ -15,7 +15,7 @@ from awscli.customizations.configure import configure, ConfigValue, NOT_SET from awscli.customizations.configure import profile_to_section from awscli.testutils import mock, unittest -from awscli.compat import six +from awscli.compat import StringIO from . import FakeSession @@ -135,7 +135,7 @@ class TestInteractivePrompter(unittest.TestCase): def setUp(self): self.input_patch = mock.patch('awscli.compat.raw_input') self.mock_raw_input = self.input_patch.start() - self.stdout = six.StringIO() + self.stdout = StringIO() self.stdout_patch = mock.patch('sys.stdout', self.stdout) self.stdout_patch.start() diff --git a/tests/unit/customizations/configure/test_get.py b/tests/unit/customizations/configure/test_get.py index cf34fbb4a968..71c239e6ba73 100644 --- a/tests/unit/customizations/configure/test_get.py +++ b/tests/unit/customizations/configure/test_get.py @@ -11,9 +11,9 @@ # ANY KIND, either express or implied. See the License for the specific # language governing permissions and limitations under the License. from awscli.testutils import unittest +from awscli.compat import StringIO from awscli.customizations.configure.get import ConfigureGetCommand -from awscli.compat import six from . import FakeSession @@ -21,8 +21,8 @@ class TestConfigureGetCommand(unittest.TestCase): def create_command(self, session): - stdout = six.StringIO() - stderr = six.StringIO() + stdout = StringIO() + stderr = StringIO() command = ConfigureGetCommand(session, stdout, stderr) return stdout, stderr, command diff --git a/tests/unit/customizations/configure/test_list.py b/tests/unit/customizations/configure/test_list.py index e00cf9e8e309..d702b2dba6e2 100644 --- a/tests/unit/customizations/configure/test_list.py +++ b/tests/unit/customizations/configure/test_list.py @@ -13,8 +13,8 @@ from argparse import Namespace from awscli.testutils import mock, unittest -from awscli.compat import six from awscli.customizations.configure.list import ConfigureListCommand +from awscli.compat import StringIO from . import FakeSession @@ -27,7 +27,7 @@ def test_configure_list_command_nothing_set(self): all_variables={'config_file': '/config/location'}) session.full_config = { 'profiles': {'default': {'region': 'AWS_DEFAULT_REGION'}}} - stream = six.StringIO() + stream = StringIO() self.configure_list = ConfigureListCommand(session, stream) self.configure_list(args=[], parsed_globals=None) rendered = stream.getvalue() @@ -46,7 +46,7 @@ def test_configure_from_env(self): session.session_var_map = {'profile': (None, "PROFILE_ENV_VAR")} session.full_config = { 'profiles': {'default': {'region': 'AWS_DEFAULT_REGION'}}} - stream = six.StringIO() + stream = StringIO() self.configure_list = ConfigureListCommand(session, stream) self.configure_list(args=[], parsed_globals=None) rendered = stream.getvalue() @@ -63,7 +63,7 @@ def test_configure_from_config_file(self): session.session_var_map = {'region': ('region', "AWS_DEFAULT_REGION")} session.full_config = { 'profiles': {'default': {'region': 'AWS_DEFAULT_REGION'}}} - stream = six.StringIO() + stream = StringIO() self.configure_list = ConfigureListCommand(session, stream) self.configure_list(args=[], parsed_globals=None) rendered = stream.getvalue() @@ -94,7 +94,7 @@ def test_configure_from_multiple_sources(self): 'profile': ('profile', 'AWS_DEFAULT_PROFILE')} session.full_config = { 'profiles': {'default': {'region': 'AWS_DEFAULT_REGION'}}} - stream = six.StringIO() + stream = StringIO() self.configure_list = ConfigureListCommand(session, stream) self.configure_list(args=[], parsed_globals=None) rendered = stream.getvalue() @@ -123,7 +123,7 @@ def test_configure_from_args(self): session.session_var_map = {'profile': (None, ['AWS_PROFILE'])} session.full_config = { 'profiles': {'foo': {'region': 'AWS_REGION'}}} - stream = six.StringIO() + stream = StringIO() self.configure_list = ConfigureListCommand(session, stream) self.configure_list(args=[], parsed_globals=parsed_globals) rendered = stream.getvalue() diff --git a/tests/unit/customizations/datapipeline/test_listrunsformatter.py b/tests/unit/customizations/datapipeline/test_listrunsformatter.py index c0a09e053689..aa8211490a18 100644 --- a/tests/unit/customizations/datapipeline/test_listrunsformatter.py +++ b/tests/unit/customizations/datapipeline/test_listrunsformatter.py @@ -14,15 +14,15 @@ import difflib from awscli.testutils import mock, unittest -from awscli.compat import six from awscli.customizations.datapipeline.listrunsformatter \ import ListRunsFormatter +from awscli.compat import StringIO class TestListRunsFormatter(unittest.TestCase): def setUp(self): self.formatter = ListRunsFormatter(mock.Mock(query=None)) - self.stream = six.StringIO() + self.stream = StringIO() def assert_data_renders_to(self, data, table): self.formatter('list-runs', data, stream=self.stream) diff --git a/tests/unit/customizations/gamelift/test_getlog.py b/tests/unit/customizations/gamelift/test_getlog.py index e46b79f492e5..fd2f0c8f0dfc 100644 --- a/tests/unit/customizations/gamelift/test_getlog.py +++ b/tests/unit/customizations/gamelift/test_getlog.py @@ -15,9 +15,9 @@ from botocore.session import get_session -from awscli.compat import six from awscli.testutils import unittest, mock, FileCreator from awscli.customizations.gamelift.getlog import GetGameSessionLogCommand +from awscli.compat import BytesIO class TestGetGameSessionLogCommand(unittest.TestCase): @@ -37,7 +37,7 @@ def setUp(self): self.urlopen_patch = mock.patch( 'awscli.customizations.gamelift.getlog.urlopen') self.urlopen_mock = self.urlopen_patch.start() - self.urlopen_mock.return_value = six.BytesIO(self.contents) + self.urlopen_mock.return_value = BytesIO(self.contents) def tearDown(self): self.create_client_patch.stop() diff --git a/tests/unit/customizations/gamelift/test_uploadbuild.py b/tests/unit/customizations/gamelift/test_uploadbuild.py index 48c6f2cdc7c6..98c9ccf400f8 100644 --- a/tests/unit/customizations/gamelift/test_uploadbuild.py +++ b/tests/unit/customizations/gamelift/test_uploadbuild.py @@ -18,11 +18,11 @@ from botocore.session import get_session from botocore.exceptions import ClientError -from awscli.compat import six from awscli.testutils import unittest, mock, FileCreator from awscli.customizations.gamelift.uploadbuild import UploadBuildCommand from awscli.customizations.gamelift.uploadbuild import zip_directory from awscli.customizations.gamelift.uploadbuild import validate_directory +from awscli.compat import StringIO class TestGetGameSessionLogCommand(unittest.TestCase): @@ -142,7 +142,7 @@ def test_upload_build_when_operating_system_is_provided(self): OperatingSystem=operating_system) def test_error_message_when_directory_is_empty(self): - with mock.patch('sys.stderr', six.StringIO()) as mock_stderr: + with mock.patch('sys.stderr', StringIO()) as mock_stderr: self.cmd(self.args, self.global_args) self.assertEqual( mock_stderr.getvalue(), @@ -158,7 +158,7 @@ def test_error_message_when_directory_is_not_provided(self): '--build-root', '' ] - with mock.patch('sys.stderr', six.StringIO()) as mock_stderr: + with mock.patch('sys.stderr', StringIO()) as mock_stderr: self.cmd(self.args, self.global_args) self.assertEqual( mock_stderr.getvalue(), @@ -175,7 +175,7 @@ def test_error_message_when_directory_does_not_exist(self): '--build-root', dir_not_exist ] - with mock.patch('sys.stderr', six.StringIO()) as mock_stderr: + with mock.patch('sys.stderr', StringIO()) as mock_stderr: self.cmd(self.args, self.global_args) self.assertEqual( mock_stderr.getvalue(), diff --git a/tests/unit/customizations/s3/__init__.py b/tests/unit/customizations/s3/__init__.py index 9aa736cba1ee..36703b6421c7 100644 --- a/tests/unit/customizations/s3/__init__.py +++ b/tests/unit/customizations/s3/__init__.py @@ -12,8 +12,6 @@ # language governing permissions and limitations under the License. import os -from awscli.compat import six - class FakeTransferFuture(object): def __init__(self, result=None, exception=None, meta=None): @@ -56,8 +54,8 @@ def make_loc_files(file_creator, size=None): filename2 = file_creator.create_file( os.path.join('some_directory', 'another_directory', 'text2.txt'), body) - filename1 = six.text_type(filename1) - filename2 = six.text_type(filename2) + filename1 = str(filename1) + filename2 = str(filename2) return [filename1, filename2, os.path.dirname(filename2), os.path.dirname(filename1)] diff --git a/tests/unit/customizations/s3/test_filegenerator.py b/tests/unit/customizations/s3/test_filegenerator.py index c69c1f5dc12d..039e52cde662 100644 --- a/tests/unit/customizations/s3/test_filegenerator.py +++ b/tests/unit/customizations/s3/test_filegenerator.py @@ -20,7 +20,6 @@ import socket from botocore.exceptions import ClientError -from awscli.compat import six from awscli.customizations.s3.filegenerator import FileGenerator, \ FileDecodingError, FileStat, is_special_file, is_readable @@ -311,7 +310,7 @@ def tearDown(self): self.files.remove_all() def test_no_follow_symlink(self): - abs_root = six.text_type(os.path.abspath(self.root) + os.sep) + abs_root = str(os.path.abspath(self.root) + os.sep) input_local_dir = {'src': {'path': abs_root, 'type': 'local'}, 'dest': {'path': self.bucket, @@ -325,14 +324,14 @@ def test_no_follow_symlink(self): self.assertEqual(len(result_list), len(self.filenames)) # Just check to make sure the right local files are generated. for i in range(len(result_list)): - filename = six.text_type(os.path.abspath(self.filenames[i])) + filename = str(os.path.abspath(self.filenames[i])) self.assertEqual(result_list[i], filename) def test_warn_bad_symlink(self): """ This tests to make sure it fails when following bad symlinks. """ - abs_root = six.text_type(os.path.abspath(self.root) + os.sep) + abs_root = str(os.path.abspath(self.root) + os.sep) input_local_dir = {'src': {'path': abs_root, 'type': 'local'}, 'dest': {'path': self.bucket, @@ -349,14 +348,14 @@ def test_warn_bad_symlink(self): self.assertEqual(len(result_list), len(all_filenames)) # Just check to make sure the right local files are generated. for i in range(len(result_list)): - filename = six.text_type(os.path.abspath(all_filenames[i])) + filename = str(os.path.abspath(all_filenames[i])) self.assertEqual(result_list[i], filename) self.assertFalse(file_gen.result_queue.empty()) def test_follow_symlink(self): # First remove the bad symlink. os.remove(os.path.join(self.root, 'symlink_2')) - abs_root = six.text_type(os.path.abspath(self.root) + os.sep) + abs_root = str(os.path.abspath(self.root) + os.sep) input_local_dir = {'src': {'path': abs_root, 'type': 'local'}, 'dest': {'path': self.bucket, @@ -371,7 +370,7 @@ def test_follow_symlink(self): self.assertEqual(len(result_list), len(all_filenames)) # Just check to make sure the right local files are generated. for i in range(len(result_list)): - filename = six.text_type(os.path.abspath(all_filenames[i])) + filename = str(os.path.abspath(all_filenames[i])) self.assertEqual(result_list[i], filename) @@ -379,7 +378,7 @@ class TestListFilesLocally(unittest.TestCase): maxDiff = None def setUp(self): - self.directory = six.text_type(tempfile.mkdtemp()) + self.directory = str(tempfile.mkdtemp()) def tearDown(self): shutil.rmtree(self.directory) diff --git a/tests/unit/customizations/s3/test_transferconfig.py b/tests/unit/customizations/s3/test_transferconfig.py index cad4bdc8bb36..6470beb85964 100644 --- a/tests/unit/customizations/s3/test_transferconfig.py +++ b/tests/unit/customizations/s3/test_transferconfig.py @@ -10,10 +10,11 @@ # 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 sys + from awscli.testutils import unittest from awscli.customizations.s3 import transferconfig -from awscli.compat import six class TestTransferConfig(unittest.TestCase): @@ -65,7 +66,7 @@ def test_long_value(self): # MAXSIZE is the max size of an int on python 2 and the maximum size # of Py_ssize_t on python 3, but notably not the maximum size of an # int since they are effectively unbounded. - long_value = six.MAXSIZE + 1 + long_value = sys.maxsize + 1 runtime_config = self.build_config_with( multipart_threshold=long_value) self.assertEqual(runtime_config['multipart_threshold'], long_value) diff --git a/tests/unit/customizations/test_codecommit.py b/tests/unit/customizations/test_codecommit.py index 1c783f62a2cc..6d527186a786 100644 --- a/tests/unit/customizations/test_codecommit.py +++ b/tests/unit/customizations/test_codecommit.py @@ -14,12 +14,12 @@ import awscli from argparse import Namespace -from six import StringIO from botocore.session import Session from botocore.credentials import Credentials from awscli.customizations.codecommit import CodeCommitGetCommand from awscli.customizations.codecommit import CodeCommitCommand from awscli.testutils import mock, unittest, StringIOWithFileNo +from awscli.compat import StringIO from botocore.auth import SigV4Auth from botocore.awsrequest import AWSRequest diff --git a/tests/unit/customizations/test_generatecliskeleton.py b/tests/unit/customizations/test_generatecliskeleton.py index e2133fa94e98..dca8084117d8 100644 --- a/tests/unit/customizations/test_generatecliskeleton.py +++ b/tests/unit/customizations/test_generatecliskeleton.py @@ -10,13 +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 # language governing permissions and limitations under the License. -from awscli.compat import six - from botocore.model import DenormalizedStructureBuilder from awscli.testutils import mock, unittest from awscli.customizations.generatecliskeleton import \ GenerateCliSkeletonArgument +from awscli.compat import StringIO class TestGenerateCliSkeleton(unittest.TestCase): @@ -80,7 +79,7 @@ def test_override_required_args_when_output_present_but_not_value(self): def test_generate_json_skeleton(self): parsed_args = mock.Mock() parsed_args.generate_cli_skeleton = 'input' - with mock.patch('sys.stdout', six.StringIO()) as mock_stdout: + with mock.patch('sys.stdout', StringIO()) as mock_stdout: rc = self.argument.generate_json_skeleton( service_operation=self.service_operation, call_parameters=None, parsed_args=parsed_args, parsed_globals=None @@ -93,7 +92,7 @@ def test_generate_json_skeleton(self): def test_no_generate_json_skeleton(self): parsed_args = mock.Mock() parsed_args.generate_cli_skeleton = None - with mock.patch('sys.stdout', six.StringIO()) as mock_stdout: + with mock.patch('sys.stdout', StringIO()) as mock_stdout: rc = self.argument.generate_json_skeleton( service_operation=self.service_operation, call_parameters=None, parsed_args=parsed_args, parsed_globals=None @@ -110,7 +109,7 @@ def test_generate_json_skeleton_no_input_shape(self): # Set the input shape to ``None``. self.argument = GenerateCliSkeletonArgument( self.session, mock.Mock(input_shape=None)) - with mock.patch('sys.stdout', six.StringIO()) as mock_stdout: + with mock.patch('sys.stdout', StringIO()) as mock_stdout: rc = self.argument.generate_json_skeleton( service_operation=self.service_operation, call_parameters=None, parsed_args=parsed_args, parsed_globals=None @@ -137,7 +136,7 @@ def test_generate_json_skeleton_with_timestamp(self): operation_model = mock.Mock(input_shape=shape) argument = GenerateCliSkeletonArgument( self.session, operation_model) - with mock.patch('sys.stdout', six.StringIO()) as mock_stdout: + with mock.patch('sys.stdout', StringIO()) as mock_stdout: rc = argument.generate_json_skeleton( call_parameters=None, parsed_args=parsed_args, parsed_globals=None diff --git a/tests/unit/customizations/test_globalargs.py b/tests/unit/customizations/test_globalargs.py index d35ffcbb0070..96586b705118 100644 --- a/tests/unit/customizations/test_globalargs.py +++ b/tests/unit/customizations/test_globalargs.py @@ -15,7 +15,6 @@ import os from awscli.testutils import mock, unittest -from awscli.compat import six from awscli.customizations import globalargs @@ -57,7 +56,7 @@ def test_parse_query(self): parsed_args = FakeParsedArgs(query='foo.bar') globalargs.resolve_types(parsed_args) # Assert that it looks like a jmespath parsed expression. - self.assertFalse(isinstance(parsed_args.query, six.string_types)) + self.assertFalse(isinstance(parsed_args.query, str)) self.assertTrue(hasattr(parsed_args.query, 'search')) def test_parse_query_error_message(self): diff --git a/tests/unit/output/test_json_output.py b/tests/unit/output/test_json_output.py index a11758f64c0c..826380ec3453 100644 --- a/tests/unit/output/test_json_output.py +++ b/tests/unit/output/test_json_output.py @@ -13,12 +13,11 @@ # language governing permissions and limitations under the License. from botocore.compat import json import platform -from awscli.compat import six from awscli.formatter import JSONFormatter from awscli.testutils import BaseAWSCommandParamsTest, unittest from awscli.testutils import mock, skip_if_windows -from awscli.compat import get_stdout_text_writer +from awscli.compat import StringIO, get_stdout_text_writer class TestGetPasswordData(BaseAWSCommandParamsTest): @@ -105,7 +104,7 @@ def test_unknown_output_type_from_env_var(self): def test_json_prints_unicode_chars(self): self.parsed_response['Users'][1]['UserId'] = u'\u2713' output = self.run_cmd('iam list-users', expected_rc=0)[0] - with mock.patch('sys.stdout', six.StringIO()) as f: + with mock.patch('sys.stdout', StringIO()) as f: out = get_stdout_text_writer() out.write(u'\u2713') expected = f.getvalue() @@ -120,7 +119,7 @@ def test_fully_buffered_handles_io_error(self): args = mock.Mock(query=None) operation = mock.Mock(can_paginate=False) response = '{"Foo": "Bar"}' - fake_closed_stream = mock.Mock(spec=six.StringIO) + fake_closed_stream = mock.Mock(spec=StringIO) fake_closed_stream.flush.side_effect = IOError formatter = JSONFormatter(args) formatter('command_name', response, stream=fake_closed_stream) diff --git a/tests/unit/output/test_table_formatter.py b/tests/unit/output/test_table_formatter.py index 4f77bce4ef8c..37c1d193c45e 100644 --- a/tests/unit/output/test_table_formatter.py +++ b/tests/unit/output/test_table_formatter.py @@ -11,10 +11,10 @@ # ANY KIND, either express or implied. See the License for the specific # language governing permissions and limitations under the License. import unittest -from awscli.compat import six from awscli.formatter import TableFormatter from awscli.table import MultiTable, Styler +from awscli.compat import StringIO SIMPLE_LIST = { "QueueUrls": [ @@ -378,7 +378,7 @@ def setUp(self): auto_reformat=False) self.formatter = TableFormatter(Object(color='off')) self.formatter.table = self.table - self.stream = six.StringIO() + self.stream = StringIO() def assert_data_renders_to(self, data, table): self.formatter('OperationName', data, stream=self.stream) diff --git a/tests/unit/output/test_text_output.py b/tests/unit/output/test_text_output.py index 9b6e490db442..a4a552504d68 100644 --- a/tests/unit/output/test_text_output.py +++ b/tests/unit/output/test_text_output.py @@ -13,15 +13,13 @@ # language governing permissions and limitations under the License. from awscli.testutils import BaseAWSCommandParamsTest from awscli.testutils import mock, unittest +from awscli.compat import StringIO import json import os import sys import re import locale -from awscli.compat import six -from six.moves import cStringIO - from awscli.formatter import Formatter @@ -153,22 +151,3 @@ def assert_in(self, key, fields, count=None): key, actual_count, count ) ) - - -class CustomFormatter(Formatter): - def __call__(self, operation, response, stream=None): - self.stream = self._get_default_stream() - - -class TestDefaultStream(BaseAWSCommandParamsTest): - @unittest.skipIf(six.PY3, "Text writer only vaild on py3.") - def test_default_stream_with_table_output(self): - formatter = CustomFormatter(None) - stream = cStringIO() - with mock.patch('sys.stdout', stream): - formatter(None, None) - formatter.stream.write(u'\u00e9') - # Ensure the unicode data is written as UTF-8 by default. - self.assertEqual( - formatter.stream.getvalue(), - u'\u00e9'.encode(locale.getpreferredencoding())) diff --git a/tests/unit/test_clidriver.py b/tests/unit/test_clidriver.py index 4adc6640f719..b720b0347986 100644 --- a/tests/unit/test_clidriver.py +++ b/tests/unit/test_clidriver.py @@ -17,8 +17,8 @@ import logging import io import sys +import importlib -from awscli.compat import six from botocore.awsrequest import AWSResponse from botocore.exceptions import NoCredentialsError from botocore.compat import OrderedDict @@ -35,6 +35,7 @@ from awscli.customizations.commands import BasicCommand from awscli import formatter from awscli.argparser import HELP_BLURB +from awscli.compat import StringIO from botocore.hooks import HierarchicalEmitter @@ -314,14 +315,8 @@ def test_ctrl_c_is_handled(self): self.assertEqual(rc, 130) def test_error_unicode(self): - # We need a different type for Py3 and Py2 because on Py3 six.StringIO - # doesn't let us set the encoding and returns a string. - if six.PY3: - stderr_b = io.BytesIO() - stderr = io.TextIOWrapper(stderr_b, encoding="UTF-8") - else: - stderr = stderr_b = six.StringIO() - stderr.encoding = "UTF-8" + stderr_b = io.BytesIO() + stderr = io.TextIOWrapper(stderr_b, encoding="UTF-8") driver = CLIDriver(session=self.session) fake_client = mock.Mock() fake_client.list_objects.side_effect = Exception(u"☃") @@ -341,8 +336,8 @@ def setUp(self): self.session = FakeSession() self.emitter = mock.Mock() self.emitter.emit.return_value = [] - self.stdout = six.StringIO() - self.stderr = six.StringIO() + self.stdout = StringIO() + self.stderr = StringIO() self.stdout_patch = mock.patch('sys.stdout', self.stdout) #self.stdout_patch.start() self.stderr_patch = mock.patch('sys.stderr', self.stderr) @@ -419,7 +414,7 @@ def test_unknown_command_suggests_help(self): class TestSearchPath(unittest.TestCase): def tearDown(self): - six.moves.reload_module(awscli) + importlib.reload(awscli) @mock.patch('os.pathsep', ';') @mock.patch('os.environ', {'AWS_DATA_PATH': 'c:\\foo;c:\\bar'}) @@ -427,7 +422,7 @@ def test_windows_style_search_path(self): driver = CLIDriver() # Because the os.environ patching happens at import time, # we have to force a reimport of the module to test our changes. - six.moves.reload_module(awscli) + importlib.reload(awscli) # Our two overrides should be the last two elements in the search path. search_paths = driver.session.get_component( 'data_loader').search_paths @@ -440,7 +435,7 @@ class TestAWSCommand(BaseAWSCommandParamsTest): # but with the http part mocked out. def setUp(self): super(TestAWSCommand, self).setUp() - self.stderr = six.StringIO() + self.stderr = StringIO() self.stderr_patch = mock.patch('sys.stderr', self.stderr) self.stderr_patch.start() @@ -807,7 +802,7 @@ class TestHTTPParamFileDoesNotExist(BaseAWSCommandParamsTest): def setUp(self): super(TestHTTPParamFileDoesNotExist, self).setUp() - self.stderr = six.StringIO() + self.stderr = StringIO() self.stderr_patch = mock.patch('sys.stderr', self.stderr) self.stderr_patch.start() diff --git a/tests/unit/test_compat.py b/tests/unit/test_compat.py index 58ca8ecfd537..ec557614d922 100644 --- a/tests/unit/test_compat.py +++ b/tests/unit/test_compat.py @@ -15,8 +15,6 @@ import pytest -from botocore.compat import six - from awscli.compat import ensure_text_type from awscli.compat import compat_shell_quote from awscli.compat import compat_open @@ -29,25 +27,25 @@ class TestEnsureText(unittest.TestCase): def test_string(self): value = 'foo' response = ensure_text_type(value) - self.assertIsInstance(response, six.text_type) + self.assertIsInstance(response, str) self.assertEqual(response, 'foo') def test_binary(self): value = b'bar' response = ensure_text_type(value) - self.assertIsInstance(response, six.text_type) + self.assertIsInstance(response, str) self.assertEqual(response, 'bar') def test_unicode(self): value = u'baz' response = ensure_text_type(value) - self.assertIsInstance(response, six.text_type) + self.assertIsInstance(response, str) self.assertEqual(response, 'baz') def test_non_ascii(self): value = b'\xe2\x9c\x93' response = ensure_text_type(value) - self.assertIsInstance(response, six.text_type) + self.assertIsInstance(response, str) self.assertEqual(response, u'\u2713') def test_non_string_or_bytes_raises_error(self): diff --git a/tests/unit/test_help.py b/tests/unit/test_help.py index 8727309cfccb..360b8692ebf4 100644 --- a/tests/unit/test_help.py +++ b/tests/unit/test_help.py @@ -17,11 +17,11 @@ import sys import os -from awscli.compat import six from awscli.help import PosixHelpRenderer, ExecutableNotFoundError from awscli.help import WindowsHelpRenderer, ProviderHelpCommand, HelpCommand from awscli.help import TopicListerCommand, TopicHelpCommand from awscli.argparser import HELP_BLURB +from awscli.compat import StringIO class HelpSpyMixin(object): @@ -106,7 +106,7 @@ def test_no_groff_or_mandoc_exists(self): @skip_if_windows('Requires POSIX system.') def test_renderer_falls_back_to_mandoc(self): - stdout = six.StringIO() + stdout = StringIO() renderer = FakePosixHelpRenderer(output_stream=stdout) renderer.exists_on_path['groff'] = False @@ -119,7 +119,7 @@ def test_renderer_falls_back_to_mandoc(self): def test_no_pager_exists(self): fake_pager = 'foobar' os.environ['MANPAGER'] = fake_pager - stdout = six.StringIO() + stdout = StringIO() renderer = FakePosixHelpRenderer(output_stream=stdout) renderer.exists_on_path[fake_pager] = False diff --git a/tests/unit/test_paramfile.py b/tests/unit/test_paramfile.py index df06b6e2d4ba..2745ca755e84 100644 --- a/tests/unit/test_paramfile.py +++ b/tests/unit/test_paramfile.py @@ -10,7 +10,6 @@ # 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 awscli.compat import six from awscli.testutils import mock, unittest, FileCreator from awscli.testutils import skip_if_windows @@ -37,7 +36,7 @@ def test_text_file(self): prefixed_filename = 'file://' + filename data = self.get_paramfile(prefixed_filename) self.assertEqual(data, contents) - self.assertIsInstance(data, six.string_types) + self.assertIsInstance(data, str) def test_binary_file(self): contents = 'This is a test' @@ -45,7 +44,7 @@ def test_binary_file(self): prefixed_filename = 'fileb://' + filename data = self.get_paramfile(prefixed_filename) self.assertEqual(data, b'This is a test') - self.assertIsInstance(data, six.binary_type) + self.assertIsInstance(data, bytes) @skip_if_windows('Binary content error only occurs ' 'on non-Windows platforms.') diff --git a/tests/unit/test_text.py b/tests/unit/test_text.py index 3ee6eb8011da..c08e2e23033d 100644 --- a/tests/unit/test_text.py +++ b/tests/unit/test_text.py @@ -21,8 +21,8 @@ # import sys -from awscli.compat import six from awscli.testutils import mock, unittest +from awscli.compat import StringIO from awscli import text @@ -30,7 +30,7 @@ class TestSection(unittest.TestCase): def format_text(self, data, stream=None): if stream is None: - stream = six.StringIO() + stream = StringIO() text.format_text(data, stream=stream) return stream.getvalue() From 341a42dccae8cbcdeb1f6f7fc996ca937e913eeb Mon Sep 17 00:00:00 2001 From: Nate Prewitt Date: Thu, 20 Jun 2024 14:25:45 -0600 Subject: [PATCH 3/3] Remove extra six usage in compat.py --- awscli/compat.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/awscli/compat.py b/awscli/compat.py index 348ab042b243..90907d967a09 100644 --- a/awscli/compat.py +++ b/awscli/compat.py @@ -101,9 +101,9 @@ def __exit__(self, type, value, traceback): def ensure_text_type(s): - if isinstance(s, six.text_type): + if isinstance(s, str): return s - if isinstance(s, six.binary_type): + if isinstance(s, bytes): return s.decode('utf-8') raise ValueError("Expected str, unicode or bytes, received %s." % type(s))