diff options
author | Zuul <zuul@review.opendev.org> | 2020-11-18 19:56:56 +0000 |
---|---|---|
committer | Gerrit Code Review <review@openstack.org> | 2020-11-18 19:56:56 +0000 |
commit | 644041f87fcb112d18e280390ebd038ad30d70e6 (patch) | |
tree | d7be17871638197217c1c4c2165c3f662c5e5631 /cliff | |
parent | 05265bc1daf54fb6a7a5ded34700e912b52d32a8 (diff) | |
parent | bc76d324f514d21ea9d2a5023da094488354acfb (diff) | |
download | cliff-644041f87fcb112d18e280390ebd038ad30d70e6.tar.gz |
Merge "Remove six"
Diffstat (limited to 'cliff')
-rw-r--r-- | cliff/_argparse.py | 12 | ||||
-rw-r--r-- | cliff/app.py | 14 | ||||
-rw-r--r-- | cliff/columns.py | 5 | ||||
-rw-r--r-- | cliff/command.py | 4 | ||||
-rw-r--r-- | cliff/complete.py | 5 | ||||
-rw-r--r-- | cliff/display.py | 4 | ||||
-rw-r--r-- | cliff/formatters/base.py | 11 | ||||
-rw-r--r-- | cliff/formatters/commaseparated.py | 22 | ||||
-rw-r--r-- | cliff/formatters/shell.py | 7 | ||||
-rw-r--r-- | cliff/formatters/table.py | 3 | ||||
-rw-r--r-- | cliff/formatters/value.py | 10 | ||||
-rw-r--r-- | cliff/hooks.py | 5 | ||||
-rw-r--r-- | cliff/lister.py | 4 | ||||
-rw-r--r-- | cliff/show.py | 5 | ||||
-rw-r--r-- | cliff/tests/test_app.py | 162 | ||||
-rw-r--r-- | cliff/tests/test_formatters_csv.py | 13 | ||||
-rw-r--r-- | cliff/tests/test_formatters_json.py | 17 | ||||
-rw-r--r-- | cliff/tests/test_formatters_shell.py | 15 | ||||
-rw-r--r-- | cliff/tests/test_formatters_table.py | 2 | ||||
-rw-r--r-- | cliff/tests/test_formatters_value.py | 10 | ||||
-rw-r--r-- | cliff/tests/test_formatters_yaml.py | 10 | ||||
-rw-r--r-- | cliff/tests/test_help.py | 19 | ||||
-rw-r--r-- | cliff/tests/test_utils.py | 3 | ||||
-rw-r--r-- | cliff/utils.py | 52 |
24 files changed, 94 insertions, 320 deletions
diff --git a/cliff/_argparse.py b/cliff/_argparse.py index 07a5a77..c03d709 100644 --- a/cliff/_argparse.py +++ b/cliff/_argparse.py @@ -13,7 +13,6 @@ """Overrides of standard argparse behavior.""" import argparse -import sys import warnings @@ -44,16 +43,7 @@ class _ArgumentContainerMixIn(object): class ArgumentParser(_ArgumentContainerMixIn, argparse.ArgumentParser): - if sys.version_info < (3, 5): - def __init__(self, *args, **kwargs): - self.allow_abbrev = kwargs.pop("allow_abbrev", True) - super(ArgumentParser, self).__init__(*args, **kwargs) - - def _get_option_tuples(self, option_string): - if self.allow_abbrev: - return super(ArgumentParser, self)._get_option_tuples( - option_string) - return () + pass def _handle_conflict_ignore(container, option_string_actions, diff --git a/cliff/app.py b/cliff/app.py index 88b39d2..603778d 100644 --- a/cliff/app.py +++ b/cliff/app.py @@ -13,12 +13,10 @@ """Application base class. """ -import codecs import locale import logging import logging.handlers import os -import six import sys import cmd2 @@ -118,18 +116,6 @@ class App(object): # has not already already wrapped sys.stdin, sys.stdout and # sys.stderr as this is a common recommendation. - if six.PY2: - encoding = locale.getpreferredencoding() - if encoding: - if not (stdin or isinstance(sys.stdin, codecs.StreamReader)): - stdin = codecs.getreader(encoding)(sys.stdin) - - if not (stdout or isinstance(sys.stdout, codecs.StreamWriter)): - stdout = utils.getwriter(encoding)(sys.stdout) - - if not (stderr or isinstance(sys.stderr, codecs.StreamWriter)): - stderr = utils.getwriter(encoding)(sys.stderr) - self.stdin = stdin or sys.stdin self.stdout = stdout or sys.stdout self.stderr = stderr or sys.stderr diff --git a/cliff/columns.py b/cliff/columns.py index 3b3c2bc..6ecef64 100644 --- a/cliff/columns.py +++ b/cliff/columns.py @@ -15,11 +15,8 @@ import abc -import six - -@six.add_metaclass(abc.ABCMeta) -class FormattableColumn(object): +class FormattableColumn(object, metaclass=abc.ABCMeta): def __init__(self, value): self._value = value diff --git a/cliff/command.py b/cliff/command.py index 663b467..f8d0501 100644 --- a/cliff/command.py +++ b/cliff/command.py @@ -13,7 +13,6 @@ import abc import inspect -import six from stevedore import extension from cliff import _argparse @@ -60,8 +59,7 @@ def _get_distribution_for_module(module): return dist_name -@six.add_metaclass(abc.ABCMeta) -class Command(object): +class Command(object, metaclass=abc.ABCMeta): """Base class for command plugins. When the command is instantiated, it loads extensions from a diff --git a/cliff/complete.py b/cliff/complete.py index 472a14e..06f38be 100644 --- a/cliff/complete.py +++ b/cliff/complete.py @@ -15,7 +15,6 @@ import logging -import six import stevedore from cliff import command @@ -40,7 +39,7 @@ class CompleteDictionary: # For example, {'cmd': 'action'}, and we add the command # 'cmd_other'. We want the result to be # {'cmd': 'action other', 'cmd_other': 'sub_action'} - if isinstance(subdata, six.string_types): + if isinstance(subdata, str): subdata += ' ' + last_cmd dicto[subcmd] = subdata last_cmd = subcmd + '_' + last_cmd @@ -57,7 +56,7 @@ class CompleteDictionary: for cmd in keys: name = path + "_" + cmd if path else cmd value = dictionary[cmd] - if isinstance(value, six.string_types): + if isinstance(value, str): ray.append((name, value)) else: cmdlist = ' '.join(sorted(value.keys())) diff --git a/cliff/display.py b/cliff/display.py index 73d68a8..5ea0713 100644 --- a/cliff/display.py +++ b/cliff/display.py @@ -15,14 +15,12 @@ import abc from itertools import compress -import six import stevedore from . import command -@six.add_metaclass(abc.ABCMeta) -class DisplayCommandBase(command.Command): +class DisplayCommandBase(command.Command, metaclass=abc.ABCMeta): """Command base class for displaying data about a single object. """ diff --git a/cliff/formatters/base.py b/cliff/formatters/base.py index 920cb32..ca65928 100644 --- a/cliff/formatters/base.py +++ b/cliff/formatters/base.py @@ -15,11 +15,8 @@ import abc -import six - -@six.add_metaclass(abc.ABCMeta) -class Formatter(object): +class Formatter(object, metaclass=abc.ABCMeta): @abc.abstractmethod def add_argument_group(self, parser): @@ -29,8 +26,7 @@ class Formatter(object): """ -@six.add_metaclass(abc.ABCMeta) -class ListFormatter(Formatter): +class ListFormatter(Formatter, metaclass=abc.ABCMeta): """Base class for formatters that know how to deal with multiple objects. """ @@ -53,8 +49,7 @@ class ListFormatter(Formatter): """ -@six.add_metaclass(abc.ABCMeta) -class SingleFormatter(Formatter): +class SingleFormatter(Formatter, metaclass=abc.ABCMeta): """Base class for formatters that work with single objects. """ diff --git a/cliff/formatters/commaseparated.py b/cliff/formatters/commaseparated.py index c3511b4..7536817 100644 --- a/cliff/formatters/commaseparated.py +++ b/cliff/formatters/commaseparated.py @@ -13,19 +13,12 @@ """Output formatters using csv format. """ +import csv import os -import sys from .base import ListFormatter from cliff import columns -import six - -if sys.version_info[0] == 3: - import csv -else: - import unicodecsv as csv - class CSVLister(ListFormatter): @@ -53,22 +46,11 @@ class CSVLister(ListFormatter): escapechar='\\', ) - # In Py2 we replace the csv module with unicodecsv because the - # Py2 csv module cannot handle unicode. unicodecsv encodes - # unicode objects based on the value of it's encoding keyword - # with the result unicodecsv emits encoded bytes in a str - # object. The utils.getwriter assures no attempt is made to - # re-encode the encoded bytes in the str object. - - if six.PY2: - writer_kwargs['encoding'] = (getattr(stdout, 'encoding', None) - or 'utf-8') - writer = csv.writer(stdout, **writer_kwargs) writer.writerow(column_names) for row in data: writer.writerow( - [(six.text_type(c.machine_readable()) + [(str(c.machine_readable()) if isinstance(c, columns.FormattableColumn) else c) for c in row] diff --git a/cliff/formatters/shell.py b/cliff/formatters/shell.py index 6e7bae9..d02ebe0 100644 --- a/cliff/formatters/shell.py +++ b/cliff/formatters/shell.py @@ -17,7 +17,6 @@ from . import base from cliff import columns import argparse -import six class ShellFormatter(base.SingleFormatter): @@ -50,12 +49,12 @@ class ShellFormatter(base.SingleFormatter): desired_columns = parsed_args.variables for name, value in zip(variable_names, data): if name in desired_columns or not desired_columns: - value = (six.text_type(value.machine_readable()) + value = (str(value.machine_readable()) if isinstance(value, columns.FormattableColumn) else value) - if isinstance(value, six.string_types): + if isinstance(value, str): value = value.replace('"', '\\"') - if isinstance(name, six.string_types): + if isinstance(name, str): # Colons and dashes may appear as a resource property but # are invalid to use in a shell, replace them with an # underscore. diff --git a/cliff/formatters/table.py b/cliff/formatters/table.py index 22f7300..397777c 100644 --- a/cliff/formatters/table.py +++ b/cliff/formatters/table.py @@ -14,7 +14,6 @@ """ import prettytable -import six import os from cliff import utils @@ -27,7 +26,7 @@ def _format_row(row): for r in row: if isinstance(r, columns.FormattableColumn): r = r.human_readable() - if isinstance(r, six.string_types): + if isinstance(r, str): r = r.replace('\r\n', '\n').replace('\r', ' ') new_row.append(r) return new_row diff --git a/cliff/formatters/value.py b/cliff/formatters/value.py index 24125c0..d4e646a 100644 --- a/cliff/formatters/value.py +++ b/cliff/formatters/value.py @@ -13,8 +13,6 @@ """Output formatters values only """ -import six - from . import base from cliff import columns @@ -28,15 +26,15 @@ class ValueFormatter(base.ListFormatter, base.SingleFormatter): for row in data: stdout.write( ' '.join( - six.text_type(c.machine_readable() - if isinstance(c, columns.FormattableColumn) - else c) + str(c.machine_readable() + if isinstance(c, columns.FormattableColumn) + else c) for c in row) + u'\n') return def emit_one(self, column_names, data, stdout, parsed_args): for value in data: - stdout.write('%s\n' % six.text_type( + stdout.write('%s\n' % str( value.machine_readable() if isinstance(value, columns.FormattableColumn) else value) diff --git a/cliff/hooks.py b/cliff/hooks.py index 5dc9b29..44e0402 100644 --- a/cliff/hooks.py +++ b/cliff/hooks.py @@ -12,11 +12,8 @@ import abc -import six - -@six.add_metaclass(abc.ABCMeta) -class CommandHook(object): +class CommandHook(object, metaclass=abc.ABCMeta): """Base class for command hooks. :param app: Command instance being invoked diff --git a/cliff/lister.py b/cliff/lister.py index e0fab01..cfba233 100644 --- a/cliff/lister.py +++ b/cliff/lister.py @@ -14,13 +14,11 @@ """ import abc import operator -import six from . import display -@six.add_metaclass(abc.ABCMeta) -class Lister(display.DisplayCommandBase): +class Lister(display.DisplayCommandBase, metaclass=abc.ABCMeta): """Command base class for providing a list of data as output. """ diff --git a/cliff/show.py b/cliff/show.py index dc6482a..6273c0e 100644 --- a/cliff/show.py +++ b/cliff/show.py @@ -14,13 +14,10 @@ """ import abc -import six - from . import display -@six.add_metaclass(abc.ABCMeta) -class ShowOne(display.DisplayCommandBase): +class ShowOne(display.DisplayCommandBase, metaclass=abc.ABCMeta): """Command base class for displaying data about a single object. """ diff --git a/cliff/tests/test_app.py b/cliff/tests/test_app.py index d31cd3d..41a28b7 100644 --- a/cliff/tests/test_app.py +++ b/cliff/tests/test_app.py @@ -14,14 +14,7 @@ import argparse import codecs -import locale -try: - from StringIO import StringIO -except ImportError: - from io import StringIO -import sys - -import six +import io from unittest import mock from cliff import app as application @@ -30,6 +23,7 @@ from cliff import commandmanager from cliff.tests import base from cliff.tests import utils as test_utils from cliff import utils +import sys def make_app(**kwargs): @@ -395,7 +389,7 @@ class TestCommandLookup(base.TestBase): self.assertIn("['hell']", str(err)) def test_list_matching_commands(self): - stdout = StringIO() + stdout = io.StringIO() app = application.App('testing', '1', test_utils.TestCommandManager( test_utils.TEST_NAMESPACE), @@ -473,86 +467,27 @@ class TestIO(base.TestBase): cmd_mgr = commandmanager.CommandManager('cliff.tests') io = mock.Mock() - if six.PY2: - stdin_save = sys.stdin - stdout_save = sys.stdout - stderr_save = sys.stderr - encoding = locale.getpreferredencoding() or 'utf-8' - - app = application.App('no io streams', 1, cmd_mgr) - self.assertIsInstance(app.stdin, codecs.StreamReader) - self.assertIsInstance(app.stdout, codecs.StreamWriter) - self.assertIsInstance(app.stderr, codecs.StreamWriter) - - app = application.App('with stdin io stream', 1, cmd_mgr, stdin=io) - self.assertIs(io, app.stdin) - self.assertIsInstance(app.stdout, codecs.StreamWriter) - self.assertIsInstance(app.stderr, codecs.StreamWriter) - - app = application.App('with stdout io stream', 1, cmd_mgr, - stdout=io) - self.assertIsInstance(app.stdin, codecs.StreamReader) - self.assertIs(io, app.stdout) - self.assertIsInstance(app.stderr, codecs.StreamWriter) - - app = application.App('with stderr io stream', 1, cmd_mgr, - stderr=io) - self.assertIsInstance(app.stdin, codecs.StreamReader) - self.assertIsInstance(app.stdout, codecs.StreamWriter) - self.assertIs(io, app.stderr) - - try: - sys.stdin = codecs.getreader(encoding)(sys.stdin) - app = application.App( - 'with wrapped sys.stdin io stream', 1, cmd_mgr) - self.assertIs(sys.stdin, app.stdin) - self.assertIsInstance(app.stdout, codecs.StreamWriter) - self.assertIsInstance(app.stderr, codecs.StreamWriter) - finally: - sys.stdin = stdin_save - - try: - sys.stdout = codecs.getwriter(encoding)(sys.stdout) - app = application.App('with wrapped stdout io stream', 1, - cmd_mgr) - self.assertIsInstance(app.stdin, codecs.StreamReader) - self.assertIs(sys.stdout, app.stdout) - self.assertIsInstance(app.stderr, codecs.StreamWriter) - finally: - sys.stdout = stdout_save - - try: - sys.stderr = codecs.getwriter(encoding)(sys.stderr) - app = application.App('with wrapped stderr io stream', 1, - cmd_mgr) - self.assertIsInstance(app.stdin, codecs.StreamReader) - self.assertIsInstance(app.stdout, codecs.StreamWriter) - self.assertIs(sys.stderr, app.stderr) - finally: - sys.stderr = stderr_save + app = application.App('no io streams', 1, cmd_mgr) + self.assertIs(sys.stdin, app.stdin) + self.assertIs(sys.stdout, app.stdout) + self.assertIs(sys.stderr, app.stderr) - else: - app = application.App('no io streams', 1, cmd_mgr) - self.assertIs(sys.stdin, app.stdin) - self.assertIs(sys.stdout, app.stdout) - self.assertIs(sys.stderr, app.stderr) - - app = application.App('with stdin io stream', 1, cmd_mgr, stdin=io) - self.assertIs(io, app.stdin) - self.assertIs(sys.stdout, app.stdout) - self.assertIs(sys.stderr, app.stderr) - - app = application.App('with stdout io stream', 1, cmd_mgr, - stdout=io) - self.assertIs(sys.stdin, app.stdin) - self.assertIs(io, app.stdout) - self.assertIs(sys.stderr, app.stderr) - - app = application.App('with stderr io stream', 1, cmd_mgr, - stderr=io) - self.assertIs(sys.stdin, app.stdin) - self.assertIs(sys.stdout, app.stdout) - self.assertIs(io, app.stderr) + app = application.App('with stdin io stream', 1, cmd_mgr, stdin=io) + self.assertIs(io, app.stdin) + self.assertIs(sys.stdout, app.stdout) + self.assertIs(sys.stderr, app.stderr) + + app = application.App('with stdout io stream', 1, cmd_mgr, + stdout=io) + self.assertIs(sys.stdin, app.stdin) + self.assertIs(io, app.stdout) + self.assertIs(sys.stderr, app.stderr) + + app = application.App('with stderr io stream', 1, cmd_mgr, + stderr=io) + self.assertIs(sys.stdin, app.stdin) + self.assertIs(sys.stdout, app.stdout) + self.assertIs(io, app.stderr) def test_writer_encoding(self): # The word "test" with the e replaced by @@ -561,45 +496,12 @@ class TestIO(base.TestBase): text = u't\u00E9st' text_utf8 = text.encode('utf-8') - if six.PY2: - # In PY2 StreamWriter can't accept non-ASCII encoded characters - # because it must first promote the encoded byte stream to - # unicode in order to encode it in the desired encoding. - # Because the encoding of the byte stream is not known at this - # point the default-encoding of ASCII is utilized, but you can't - # decode a non-ASCII charcater to ASCII. - io = six.StringIO() - writer = codecs.getwriter('utf-8')(io) - self.assertRaises(UnicodeDecodeError, - writer.write, - text_utf8) - - # In PY2 with our override of codecs.getwriter we do not - # attempt to encode bytes in a str object (only unicode - # objects) therefore the final output string should be the - # utf-8 encoded byte sequence - io = six.StringIO() - writer = utils.getwriter('utf-8')(io) - writer.write(text) - output = io.getvalue() - self.assertEqual(text_utf8, output) - - io = six.StringIO() - writer = utils.getwriter('utf-8')(io) - writer.write(text_utf8) - output = io.getvalue() - self.assertEqual(text_utf8, output) - else: - # In PY3 you can't write encoded bytes to a text writer - # instead text functions require text. - io = six.StringIO() - writer = utils.getwriter('utf-8')(io) - self.assertRaises(TypeError, - writer.write, - text) - - io = six.StringIO() - writer = utils.getwriter('utf-8')(io) - self.assertRaises(TypeError, - writer.write, - text_utf8) + # In PY3 you can't write encoded bytes to a text writer + # instead text functions require text. + out = io.StringIO() + writer = codecs.getwriter('utf-8')(out) + self.assertRaises(TypeError, writer.write, text) + + out = io.StringIO() + writer = codecs.getwriter('utf-8')(out) + self.assertRaises(TypeError, writer.write, text_utf8) diff --git a/cliff/tests/test_formatters_csv.py b/cliff/tests/test_formatters_csv.py index 1767705..608137e 100644 --- a/cliff/tests/test_formatters_csv.py +++ b/cliff/tests/test_formatters_csv.py @@ -14,9 +14,8 @@ # under the License. import argparse +import io import unittest - -import six from unittest import mock from cliff.formatters import commaseparated @@ -32,7 +31,7 @@ class TestCSVFormatter(unittest.TestCase): d2 = ('D', 'E', 'F') data = [d1, d2] expected = 'a,b,c\nA,B,C\nD,E,F\n' - output = six.StringIO() + output = io.StringIO() parsed_args = mock.Mock() parsed_args.quote_mode = 'none' sf.emit_list(c, data, output, parsed_args) @@ -46,7 +45,7 @@ class TestCSVFormatter(unittest.TestCase): d2 = ('D', 'E', 'F') data = [d1, d2] expected = '"a","b","c"\n"A","B","C"\n"D","E","F"\n' - output = six.StringIO() + output = io.StringIO() # Parse arguments as if passed on the command-line parser = argparse.ArgumentParser(description='Testing...') sf.add_argument_group(parser) @@ -61,7 +60,7 @@ class TestCSVFormatter(unittest.TestCase): d1 = ('A', 'B', test_columns.FauxColumn(['the', 'value'])) data = [d1] expected = 'a,b,c\nA,B,[\'the\'\\, \'value\']\n' - output = six.StringIO() + output = io.StringIO() parsed_args = mock.Mock() parsed_args.quote_mode = 'none' sf.emit_list(c, data, output, parsed_args) @@ -76,11 +75,9 @@ class TestCSVFormatter(unittest.TestCase): d2 = (u'D', u'E', happy) data = [d1, d2] expected = u'a,b,c\nA,B,C\nD,E,%s\n' % happy - output = six.StringIO() + output = io.StringIO() parsed_args = mock.Mock() parsed_args.quote_mode = 'none' sf.emit_list(c, data, output, parsed_args) actual = output.getvalue() - if six.PY2: - actual = actual.decode('utf-8') self.assertEqual(expected, actual) diff --git a/cliff/tests/test_formatters_json.py b/cliff/tests/test_formatters_json.py index 95e3218..c57412a 100644 --- a/cliff/tests/test_formatters_json.py +++ b/cliff/tests/test_formatters_json.py @@ -12,15 +12,14 @@ # License for the specific language governing permissions and limitations # under the License. +import io import json +from unittest import mock from cliff.formatters import json_format from cliff.tests import base from cliff.tests import test_columns -import six -from unittest import mock - class TestJSONFormatter(base.TestBase): @@ -38,7 +37,7 @@ class TestJSONFormatter(base.TestBase): sf.add_argument_group(args) args.noindent = True - output = six.StringIO() + output = io.StringIO() sf.emit_one(c, d, output, args) value = output.getvalue() print(len(value.splitlines())) @@ -47,7 +46,7 @@ class TestJSONFormatter(base.TestBase): self.assertEqual(expected, actual) args.noindent = False - output = six.StringIO() + output = io.StringIO() sf.emit_one(c, d, output, args) value = output.getvalue() self.assertEqual(6, len(value.splitlines())) @@ -68,7 +67,7 @@ class TestJSONFormatter(base.TestBase): sf.add_argument_group(args) args.noindent = True - output = six.StringIO() + output = io.StringIO() sf.emit_one(c, d, output, args) value = output.getvalue() print(len(value.splitlines())) @@ -93,7 +92,7 @@ class TestJSONFormatter(base.TestBase): sf.add_argument_group(args) args.noindent = True - output = six.StringIO() + output = io.StringIO() sf.emit_list(c, d, output, args) value = output.getvalue() self.assertEqual(1, len(value.splitlines())) @@ -101,7 +100,7 @@ class TestJSONFormatter(base.TestBase): self.assertEqual(expected, actual) args.noindent = False - output = six.StringIO() + output = io.StringIO() sf.emit_list(c, d, output, args) value = output.getvalue() self.assertEqual(17, len(value.splitlines())) @@ -121,7 +120,7 @@ class TestJSONFormatter(base.TestBase): sf.add_argument_group(args) args.noindent = True - output = six.StringIO() + output = io.StringIO() sf.emit_list(c, d, output, args) value = output.getvalue() self.assertEqual(1, len(value.splitlines())) diff --git a/cliff/tests/test_formatters_shell.py b/cliff/tests/test_formatters_shell.py index 01b4e84..896fe10 100644 --- a/cliff/tests/test_formatters_shell.py +++ b/cliff/tests/test_formatters_shell.py @@ -13,8 +13,7 @@ # under the License. import argparse -import six - +import io from unittest import mock from cliff.formatters import shell @@ -29,7 +28,7 @@ class TestShellFormatter(base.TestBase): c = ('a', 'b', 'c', 'd') d = ('A', 'B', 'C', '"escape me"') expected = 'a="A"\nb="B"\nd="\\"escape me\\""\n' - output = six.StringIO() + output = io.StringIO() args = mock.Mock() args.variables = ['a', 'b', 'd'] args.prefix = '' @@ -42,7 +41,7 @@ class TestShellFormatter(base.TestBase): c = ('a', 'b', 'c', 'd') d = ('A', 'B', 'C', '"escape me"') expected = 'Xd="\\"escape me\\""\n' - output = six.StringIO() + output = io.StringIO() # Parse arguments as if passed on the command-line parser = argparse.ArgumentParser(description='Testing...') sf.add_argument_group(parser) @@ -60,7 +59,7 @@ class TestShellFormatter(base.TestBase): 'b="B"', 'c="[\'the\', \'value\']"\n', ]) - output = six.StringIO() + output = io.StringIO() args = mock.Mock() args.variables = ['a', 'b', 'c'] args.prefix = '' @@ -71,10 +70,10 @@ class TestShellFormatter(base.TestBase): def test_non_string_values(self): sf = shell.ShellFormatter() c = ('a', 'b', 'c', 'd', 'e') - d = (True, False, 100, '"esc"', six.text_type('"esc"')) + d = (True, False, 100, '"esc"', str('"esc"')) expected = ('a="True"\nb="False"\nc="100"\n' 'd="\\"esc\\""\ne="\\"esc\\""\n') - output = six.StringIO() + output = io.StringIO() args = mock.Mock() args.variables = ['a', 'b', 'c', 'd', 'e'] args.prefix = '' @@ -87,7 +86,7 @@ class TestShellFormatter(base.TestBase): c = ('a', 'foo-bar', 'provider:network_type') d = (True, 'baz', 'vxlan') expected = 'a="True"\nfoo_bar="baz"\nprovider_network_type="vxlan"\n' - output = six.StringIO() + output = io.StringIO() args = mock.Mock() args.variables = ['a', 'foo-bar', 'provider:network_type'] args.prefix = '' diff --git a/cliff/tests/test_formatters_table.py b/cliff/tests/test_formatters_table.py index a11ff43..2c0854d 100644 --- a/cliff/tests/test_formatters_table.py +++ b/cliff/tests/test_formatters_table.py @@ -16,7 +16,7 @@ import argparse import os import textwrap -from six import StringIO +from io import StringIO from unittest import mock from cliff.formatters import table diff --git a/cliff/tests/test_formatters_value.py b/cliff/tests/test_formatters_value.py index 6053dd3..a0f2362 100644 --- a/cliff/tests/test_formatters_value.py +++ b/cliff/tests/test_formatters_value.py @@ -12,7 +12,7 @@ # License for the specific language governing permissions and limitations # under the License. -import six +from io import StringIO from cliff.formatters import value from cliff.tests import base @@ -26,7 +26,7 @@ class TestValueFormatter(base.TestBase): c = ('a', 'b', 'c', 'd') d = ('A', 'B', 'C', '"no escape me"') expected = 'A\nB\nC\n"no escape me"\n' - output = six.StringIO() + output = StringIO() sf.emit_one(c, d, output, None) actual = output.getvalue() self.assertEqual(expected, actual) @@ -36,7 +36,7 @@ class TestValueFormatter(base.TestBase): c = ('a', 'b', 'c', 'd') d = ('A', 'B', 'C', test_columns.FauxColumn(['the', 'value'])) expected = "A\nB\nC\n['the', 'value']\n" - output = six.StringIO() + output = StringIO() sf.emit_one(c, d, output, None) actual = output.getvalue() self.assertEqual(expected, actual) @@ -48,7 +48,7 @@ class TestValueFormatter(base.TestBase): d2 = ('D', 'E', 'F') data = [d1, d2] expected = 'A B C\nD E F\n' - output = six.StringIO() + output = StringIO() sf.emit_list(c, data, output, None) actual = output.getvalue() self.assertEqual(expected, actual) @@ -59,7 +59,7 @@ class TestValueFormatter(base.TestBase): d1 = ('A', 'B', test_columns.FauxColumn(['the', 'value'])) data = [d1] expected = "A B ['the', 'value']\n" - output = six.StringIO() + output = StringIO() sf.emit_list(c, data, output, None) actual = output.getvalue() self.assertEqual(expected, actual) diff --git a/cliff/tests/test_formatters_yaml.py b/cliff/tests/test_formatters_yaml.py index a76be85..5d741e2 100644 --- a/cliff/tests/test_formatters_yaml.py +++ b/cliff/tests/test_formatters_yaml.py @@ -12,7 +12,7 @@ # License for the specific language governing permissions and limitations # under the License. -import six +from io import StringIO import yaml from unittest import mock @@ -34,7 +34,7 @@ class TestYAMLFormatter(base.TestBase): 'c': 'C', 'd': '"escape me"' } - output = six.StringIO() + output = StringIO() args = mock.Mock() sf.emit_one(c, d, output, args) actual = yaml.safe_load(output.getvalue()) @@ -54,7 +54,7 @@ class TestYAMLFormatter(base.TestBase): sf.add_argument_group(args) args.noindent = True - output = six.StringIO() + output = StringIO() sf.emit_one(c, d, output, args) value = output.getvalue() print(len(value.splitlines())) @@ -74,7 +74,7 @@ class TestYAMLFormatter(base.TestBase): {'a': 'A2', 'b': 'B2', 'c': 'C2'}, {'a': 'A3', 'b': 'B3', 'c': 'C3'} ] - output = six.StringIO() + output = StringIO() args = mock.Mock() sf.add_argument_group(args) sf.emit_list(c, d, output, args) @@ -94,7 +94,7 @@ class TestYAMLFormatter(base.TestBase): sf.add_argument_group(args) args.noindent = True - output = six.StringIO() + output = StringIO() sf.emit_list(c, d, output, args) actual = yaml.safe_load(output.getvalue()) self.assertEqual(expected, actual) diff --git a/cliff/tests/test_help.py b/cliff/tests/test_help.py index 8b40d58..9034779 100644 --- a/cliff/tests/test_help.py +++ b/cliff/tests/test_help.py @@ -10,10 +10,7 @@ # License for the specific language governing permissions and limitations # under the License. -try: - from StringIO import StringIO -except ImportError: - from io import StringIO +import io import os import sys @@ -32,7 +29,7 @@ class TestHelp(base.TestBase): # FIXME(dhellmann): Are commands tied too closely to the app? Or # do commands know too much about apps by using them to get to the # command manager? - stdout = StringIO() + stdout = io.StringIO() app = application.App('testing', '1', utils.TestCommandManager(utils.TEST_NAMESPACE), stdout=stdout) @@ -50,7 +47,7 @@ class TestHelp(base.TestBase): # FIXME(dhellmann): Are commands tied too closely to the app? Or # do commands know too much about apps by using them to get to the # command manager? - stdout = StringIO() + stdout = io.StringIO() app = application.App('testing', '1', utils.TestCommandManager(utils.TEST_NAMESPACE), stdout=stdout) @@ -70,7 +67,7 @@ class TestHelp(base.TestBase): # FIXME(dhellmann): Are commands tied too closely to the app? Or # do commands know too much about apps by using them to get to the # command manager? - stdout = StringIO() + stdout = io.StringIO() app = application.App('testing', '1', utils.TestCommandManager(utils.TEST_NAMESPACE), stdout=stdout) @@ -88,7 +85,7 @@ class TestHelp(base.TestBase): # FIXME(dhellmann): Are commands tied too closely to the app? Or # do commands know too much about apps by using them to get to the # command manager? - stdout = StringIO() + stdout = io.StringIO() app = application.App('testing', '1', utils.TestCommandManager(utils.TEST_NAMESPACE), stdout=stdout) @@ -115,7 +112,7 @@ class TestHelp(base.TestBase): # FIXME(dhellmann): Are commands tied too closely to the app? Or # do commands know too much about apps by using them to get to the # command manager? - stdout = StringIO() + stdout = io.StringIO() app = application.App('testing', '1', utils.TestCommandManager(utils.TEST_NAMESPACE), stdout=stdout) @@ -132,7 +129,7 @@ class TestHelp(base.TestBase): @mock.patch.object(commandmanager.EntryPointWrapper, 'load', side_effect=Exception('Could not load EntryPoint')) def test_show_help_with_ep_load_fail(self, mock_load): - stdout = StringIO() + stdout = io.StringIO() app = application.App('testing', '1', utils.TestCommandManager(utils.TEST_NAMESPACE), stdout=stdout) @@ -154,7 +151,7 @@ class TestHelp(base.TestBase): @mock.patch.object(commandmanager.EntryPointWrapper, 'load', side_effect=Exception('Could not load EntryPoint')) def test_show_help_print_exc_with_ep_load_fail(self, mock_load): - stdout = StringIO() + stdout = io.StringIO() app = application.App('testing', '1', utils.TestCommandManager(utils.TEST_NAMESPACE), stdout=stdout) diff --git a/cliff/tests/test_utils.py b/cliff/tests/test_utils.py index 6f4e29d..3699a75 100644 --- a/cliff/tests/test_utils.py +++ b/cliff/tests/test_utils.py @@ -14,11 +14,10 @@ import os import sys - from unittest import mock -from cliff import utils from cliff.tests import base +from cliff import utils class TestTerminalWidth(base.TestBase): diff --git a/cliff/utils.py b/cliff/utils.py index 0da9b42..cee1087 100644 --- a/cliff/utils.py +++ b/cliff/utils.py @@ -11,15 +11,12 @@ # See the License for the specific language governing permissions and # limitations under the License. -import codecs import ctypes import inspect import os import struct import sys -import six - # Each edit operation is assigned different cost, such as: # 'w' means swap operation, the cost is 0; # 's' means substitution operation, the cost is 2; @@ -163,52 +160,3 @@ def _get_terminal_width_ioctl(stdout): return columns except IOError: return None - - -if six.PY2: - def getwriter(encoding): - '''Override codecs.getwriter() to prevent codec errors. - - The StreamWriter returned by codecs.getwriter has an unfortunate - property, it will attempt to encode every object presented to it's - write() function. Normally we only want unicode objects to be - encoded to a byte stream. If bytes are presented (e.g. str in - Python2) we make the assumption those bytes represent an already - encoded text stream or they are indeed binary bytes and hence - should not be encoded. - - When the core StreamWriter attempts to encode a str object Python - will first promote the str object to a unicode object. The - promotion of str to unicode requires the str bytes to be - decoded. However the encoding associated with the str object is - not known therefore Python applies the default-encoding which is - ASCII. In the case where the str object contains utf-8 encoded - non-ASCII characters a decoding error is raised. By not attempting - to encode a byte stream we avoid this error. - - It really does not make much sense to try and encode a byte - stream. First of all a byte stream should not be encoded if it's - not text (e.g. binary data). If the byte stream is encoded text - the only way to re-encode it is if we known it's encoding so we - can decode it into a canonical form (e.g. unicode). Thus to - re-encode it we encode from the canonical form (e.g. unicode) to - the new binary encoding. The problem in Python2 is we never know - if the bytes in a str object are text or binary data and if it's - text which encoding it is, hence we should not try to apply - an encoding to a str object. - ''' - class _StreamWriter(codecs.StreamWriter): - def __init__(self, stream, errors='strict'): - codecs.StreamWriter.__init__(self, stream, errors) - - def encode(self, msg, errors='strict'): - if isinstance(msg, six.text_type): - return self.encoder(msg, errors) - return msg, len(msg) - - _StreamWriter.encoder = codecs.getencoder(encoding) - _StreamWriter.encoding = encoding - return _StreamWriter - -else: - getwriter = codecs.getwriter |