Merge "Remove six"

This commit is contained in:
Zuul 2020-11-18 19:56:56 +00:00 committed by Gerrit Code Review
commit 644041f87f
26 changed files with 91 additions and 319 deletions

View File

@ -13,7 +13,6 @@
"""Overrides of standard argparse behavior.""" """Overrides of standard argparse behavior."""
import argparse import argparse
import sys
import warnings import warnings
@ -44,16 +43,7 @@ class _ArgumentContainerMixIn(object):
class ArgumentParser(_ArgumentContainerMixIn, argparse.ArgumentParser): class ArgumentParser(_ArgumentContainerMixIn, argparse.ArgumentParser):
if sys.version_info < (3, 5): pass
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 ()
def _handle_conflict_ignore(container, option_string_actions, def _handle_conflict_ignore(container, option_string_actions,

View File

@ -13,12 +13,10 @@
"""Application base class. """Application base class.
""" """
import codecs
import locale import locale
import logging import logging
import logging.handlers import logging.handlers
import os import os
import six
import sys import sys
import cmd2 import cmd2
@ -118,18 +116,6 @@ class App(object):
# has not already already wrapped sys.stdin, sys.stdout and # has not already already wrapped sys.stdin, sys.stdout and
# sys.stderr as this is a common recommendation. # 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.stdin = stdin or sys.stdin
self.stdout = stdout or sys.stdout self.stdout = stdout or sys.stdout
self.stderr = stderr or sys.stderr self.stderr = stderr or sys.stderr

View File

@ -15,11 +15,8 @@
import abc import abc
import six
class FormattableColumn(object, metaclass=abc.ABCMeta):
@six.add_metaclass(abc.ABCMeta)
class FormattableColumn(object):
def __init__(self, value): def __init__(self, value):
self._value = value self._value = value

View File

@ -13,7 +13,6 @@
import abc import abc
import inspect import inspect
import six
from stevedore import extension from stevedore import extension
from cliff import _argparse from cliff import _argparse
@ -60,8 +59,7 @@ def _get_distribution_for_module(module):
return dist_name return dist_name
@six.add_metaclass(abc.ABCMeta) class Command(object, metaclass=abc.ABCMeta):
class Command(object):
"""Base class for command plugins. """Base class for command plugins.
When the command is instantiated, it loads extensions from a When the command is instantiated, it loads extensions from a

View File

@ -15,7 +15,6 @@
import logging import logging
import six
import stevedore import stevedore
from cliff import command from cliff import command
@ -40,7 +39,7 @@ class CompleteDictionary:
# For example, {'cmd': 'action'}, and we add the command # For example, {'cmd': 'action'}, and we add the command
# 'cmd_other'. We want the result to be # 'cmd_other'. We want the result to be
# {'cmd': 'action other', 'cmd_other': 'sub_action'} # {'cmd': 'action other', 'cmd_other': 'sub_action'}
if isinstance(subdata, six.string_types): if isinstance(subdata, str):
subdata += ' ' + last_cmd subdata += ' ' + last_cmd
dicto[subcmd] = subdata dicto[subcmd] = subdata
last_cmd = subcmd + '_' + last_cmd last_cmd = subcmd + '_' + last_cmd
@ -57,7 +56,7 @@ class CompleteDictionary:
for cmd in keys: for cmd in keys:
name = path + "_" + cmd if path else cmd name = path + "_" + cmd if path else cmd
value = dictionary[cmd] value = dictionary[cmd]
if isinstance(value, six.string_types): if isinstance(value, str):
ray.append((name, value)) ray.append((name, value))
else: else:
cmdlist = ' '.join(sorted(value.keys())) cmdlist = ' '.join(sorted(value.keys()))

View File

@ -15,14 +15,12 @@
import abc import abc
from itertools import compress from itertools import compress
import six
import stevedore import stevedore
from . import command from . import command
@six.add_metaclass(abc.ABCMeta) class DisplayCommandBase(command.Command, metaclass=abc.ABCMeta):
class DisplayCommandBase(command.Command):
"""Command base class for displaying data about a single object. """Command base class for displaying data about a single object.
""" """

View File

@ -15,11 +15,8 @@
import abc import abc
import six
class Formatter(object, metaclass=abc.ABCMeta):
@six.add_metaclass(abc.ABCMeta)
class Formatter(object):
@abc.abstractmethod @abc.abstractmethod
def add_argument_group(self, parser): def add_argument_group(self, parser):
@ -29,8 +26,7 @@ class Formatter(object):
""" """
@six.add_metaclass(abc.ABCMeta) class ListFormatter(Formatter, metaclass=abc.ABCMeta):
class ListFormatter(Formatter):
"""Base class for formatters that know how to deal with multiple objects. """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, metaclass=abc.ABCMeta):
class SingleFormatter(Formatter):
"""Base class for formatters that work with single objects. """Base class for formatters that work with single objects.
""" """

View File

@ -13,19 +13,12 @@
"""Output formatters using csv format. """Output formatters using csv format.
""" """
import csv
import os import os
import sys
from .base import ListFormatter from .base import ListFormatter
from cliff import columns from cliff import columns
import six
if sys.version_info[0] == 3:
import csv
else:
import unicodecsv as csv
class CSVLister(ListFormatter): class CSVLister(ListFormatter):
@ -53,22 +46,11 @@ class CSVLister(ListFormatter):
escapechar='\\', 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 = csv.writer(stdout, **writer_kwargs)
writer.writerow(column_names) writer.writerow(column_names)
for row in data: for row in data:
writer.writerow( writer.writerow(
[(six.text_type(c.machine_readable()) [(str(c.machine_readable())
if isinstance(c, columns.FormattableColumn) if isinstance(c, columns.FormattableColumn)
else c) else c)
for c in row] for c in row]

View File

@ -17,7 +17,6 @@ from . import base
from cliff import columns from cliff import columns
import argparse import argparse
import six
class ShellFormatter(base.SingleFormatter): class ShellFormatter(base.SingleFormatter):
@ -50,12 +49,12 @@ class ShellFormatter(base.SingleFormatter):
desired_columns = parsed_args.variables desired_columns = parsed_args.variables
for name, value in zip(variable_names, data): for name, value in zip(variable_names, data):
if name in desired_columns or not desired_columns: 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) if isinstance(value, columns.FormattableColumn)
else value) else value)
if isinstance(value, six.string_types): if isinstance(value, str):
value = value.replace('"', '\\"') value = value.replace('"', '\\"')
if isinstance(name, six.string_types): if isinstance(name, str):
# Colons and dashes may appear as a resource property but # Colons and dashes may appear as a resource property but
# are invalid to use in a shell, replace them with an # are invalid to use in a shell, replace them with an
# underscore. # underscore.

View File

@ -14,7 +14,6 @@
""" """
import prettytable import prettytable
import six
import os import os
from cliff import utils from cliff import utils
@ -27,7 +26,7 @@ def _format_row(row):
for r in row: for r in row:
if isinstance(r, columns.FormattableColumn): if isinstance(r, columns.FormattableColumn):
r = r.human_readable() r = r.human_readable()
if isinstance(r, six.string_types): if isinstance(r, str):
r = r.replace('\r\n', '\n').replace('\r', ' ') r = r.replace('\r\n', '\n').replace('\r', ' ')
new_row.append(r) new_row.append(r)
return new_row return new_row

View File

@ -13,8 +13,6 @@
"""Output formatters values only """Output formatters values only
""" """
import six
from . import base from . import base
from cliff import columns from cliff import columns
@ -28,15 +26,15 @@ class ValueFormatter(base.ListFormatter, base.SingleFormatter):
for row in data: for row in data:
stdout.write( stdout.write(
' '.join( ' '.join(
six.text_type(c.machine_readable() str(c.machine_readable()
if isinstance(c, columns.FormattableColumn) if isinstance(c, columns.FormattableColumn)
else c) else c)
for c in row) + u'\n') for c in row) + u'\n')
return return
def emit_one(self, column_names, data, stdout, parsed_args): def emit_one(self, column_names, data, stdout, parsed_args):
for value in data: for value in data:
stdout.write('%s\n' % six.text_type( stdout.write('%s\n' % str(
value.machine_readable() value.machine_readable()
if isinstance(value, columns.FormattableColumn) if isinstance(value, columns.FormattableColumn)
else value) else value)

View File

@ -12,11 +12,8 @@
import abc import abc
import six
class CommandHook(object, metaclass=abc.ABCMeta):
@six.add_metaclass(abc.ABCMeta)
class CommandHook(object):
"""Base class for command hooks. """Base class for command hooks.
:param app: Command instance being invoked :param app: Command instance being invoked

View File

@ -14,13 +14,11 @@
""" """
import abc import abc
import operator import operator
import six
from . import display from . import display
@six.add_metaclass(abc.ABCMeta) class Lister(display.DisplayCommandBase, metaclass=abc.ABCMeta):
class Lister(display.DisplayCommandBase):
"""Command base class for providing a list of data as output. """Command base class for providing a list of data as output.
""" """

View File

@ -14,13 +14,10 @@
""" """
import abc import abc
import six
from . import display from . import display
@six.add_metaclass(abc.ABCMeta) class ShowOne(display.DisplayCommandBase, metaclass=abc.ABCMeta):
class ShowOne(display.DisplayCommandBase):
"""Command base class for displaying data about a single object. """Command base class for displaying data about a single object.
""" """

View File

@ -14,14 +14,7 @@
import argparse import argparse
import codecs import codecs
import locale import io
try:
from StringIO import StringIO
except ImportError:
from io import StringIO
import sys
import six
from unittest import mock from unittest import mock
from cliff import app as application from cliff import app as application
@ -30,6 +23,7 @@ from cliff import commandmanager
from cliff.tests import base from cliff.tests import base
from cliff.tests import utils as test_utils from cliff.tests import utils as test_utils
from cliff import utils from cliff import utils
import sys
def make_app(**kwargs): def make_app(**kwargs):
@ -395,7 +389,7 @@ class TestCommandLookup(base.TestBase):
self.assertIn("['hell']", str(err)) self.assertIn("['hell']", str(err))
def test_list_matching_commands(self): def test_list_matching_commands(self):
stdout = StringIO() stdout = io.StringIO()
app = application.App('testing', '1', app = application.App('testing', '1',
test_utils.TestCommandManager( test_utils.TestCommandManager(
test_utils.TEST_NAMESPACE), test_utils.TEST_NAMESPACE),
@ -473,86 +467,27 @@ class TestIO(base.TestBase):
cmd_mgr = commandmanager.CommandManager('cliff.tests') cmd_mgr = commandmanager.CommandManager('cliff.tests')
io = mock.Mock() io = mock.Mock()
if six.PY2: app = application.App('no io streams', 1, cmd_mgr)
stdin_save = sys.stdin self.assertIs(sys.stdin, app.stdin)
stdout_save = sys.stdout self.assertIs(sys.stdout, app.stdout)
stderr_save = sys.stderr self.assertIs(sys.stderr, app.stderr)
encoding = locale.getpreferredencoding() or 'utf-8'
app = application.App('no io streams', 1, cmd_mgr) app = application.App('with stdin io stream', 1, cmd_mgr, stdin=io)
self.assertIsInstance(app.stdin, codecs.StreamReader) self.assertIs(io, app.stdin)
self.assertIsInstance(app.stdout, codecs.StreamWriter) self.assertIs(sys.stdout, app.stdout)
self.assertIsInstance(app.stderr, codecs.StreamWriter) self.assertIs(sys.stderr, app.stderr)
app = application.App('with stdin io stream', 1, cmd_mgr, stdin=io) app = application.App('with stdout io stream', 1, cmd_mgr,
self.assertIs(io, app.stdin) stdout=io)
self.assertIsInstance(app.stdout, codecs.StreamWriter) self.assertIs(sys.stdin, app.stdin)
self.assertIsInstance(app.stderr, codecs.StreamWriter) self.assertIs(io, app.stdout)
self.assertIs(sys.stderr, app.stderr)
app = application.App('with stdout io stream', 1, cmd_mgr, app = application.App('with stderr io stream', 1, cmd_mgr,
stdout=io) stderr=io)
self.assertIsInstance(app.stdin, codecs.StreamReader) self.assertIs(sys.stdin, app.stdin)
self.assertIs(io, app.stdout) self.assertIs(sys.stdout, app.stdout)
self.assertIsInstance(app.stderr, codecs.StreamWriter) self.assertIs(io, app.stderr)
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
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)
def test_writer_encoding(self): def test_writer_encoding(self):
# The word "test" with the e replaced by # The word "test" with the e replaced by
@ -561,45 +496,12 @@ class TestIO(base.TestBase):
text = u't\u00E9st' text = u't\u00E9st'
text_utf8 = text.encode('utf-8') text_utf8 = text.encode('utf-8')
if six.PY2: # In PY3 you can't write encoded bytes to a text writer
# In PY2 StreamWriter can't accept non-ASCII encoded characters # instead text functions require text.
# because it must first promote the encoded byte stream to out = io.StringIO()
# unicode in order to encode it in the desired encoding. writer = codecs.getwriter('utf-8')(out)
# Because the encoding of the byte stream is not known at this self.assertRaises(TypeError, writer.write, text)
# 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 out = io.StringIO()
# attempt to encode bytes in a str object (only unicode writer = codecs.getwriter('utf-8')(out)
# objects) therefore the final output string should be the self.assertRaises(TypeError, writer.write, text_utf8)
# 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)

View File

@ -14,9 +14,8 @@
# under the License. # under the License.
import argparse import argparse
import io
import unittest import unittest
import six
from unittest import mock from unittest import mock
from cliff.formatters import commaseparated from cliff.formatters import commaseparated
@ -32,7 +31,7 @@ class TestCSVFormatter(unittest.TestCase):
d2 = ('D', 'E', 'F') d2 = ('D', 'E', 'F')
data = [d1, d2] data = [d1, d2]
expected = 'a,b,c\nA,B,C\nD,E,F\n' expected = 'a,b,c\nA,B,C\nD,E,F\n'
output = six.StringIO() output = io.StringIO()
parsed_args = mock.Mock() parsed_args = mock.Mock()
parsed_args.quote_mode = 'none' parsed_args.quote_mode = 'none'
sf.emit_list(c, data, output, parsed_args) sf.emit_list(c, data, output, parsed_args)
@ -46,7 +45,7 @@ class TestCSVFormatter(unittest.TestCase):
d2 = ('D', 'E', 'F') d2 = ('D', 'E', 'F')
data = [d1, d2] data = [d1, d2]
expected = '"a","b","c"\n"A","B","C"\n"D","E","F"\n' 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 # Parse arguments as if passed on the command-line
parser = argparse.ArgumentParser(description='Testing...') parser = argparse.ArgumentParser(description='Testing...')
sf.add_argument_group(parser) sf.add_argument_group(parser)
@ -61,7 +60,7 @@ class TestCSVFormatter(unittest.TestCase):
d1 = ('A', 'B', test_columns.FauxColumn(['the', 'value'])) d1 = ('A', 'B', test_columns.FauxColumn(['the', 'value']))
data = [d1] data = [d1]
expected = 'a,b,c\nA,B,[\'the\'\\, \'value\']\n' expected = 'a,b,c\nA,B,[\'the\'\\, \'value\']\n'
output = six.StringIO() output = io.StringIO()
parsed_args = mock.Mock() parsed_args = mock.Mock()
parsed_args.quote_mode = 'none' parsed_args.quote_mode = 'none'
sf.emit_list(c, data, output, parsed_args) sf.emit_list(c, data, output, parsed_args)
@ -76,11 +75,9 @@ class TestCSVFormatter(unittest.TestCase):
d2 = (u'D', u'E', happy) d2 = (u'D', u'E', happy)
data = [d1, d2] data = [d1, d2]
expected = u'a,b,c\nA,B,C\nD,E,%s\n' % happy 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 = mock.Mock()
parsed_args.quote_mode = 'none' parsed_args.quote_mode = 'none'
sf.emit_list(c, data, output, parsed_args) sf.emit_list(c, data, output, parsed_args)
actual = output.getvalue() actual = output.getvalue()
if six.PY2:
actual = actual.decode('utf-8')
self.assertEqual(expected, actual) self.assertEqual(expected, actual)

View File

@ -12,15 +12,14 @@
# License for the specific language governing permissions and limitations # License for the specific language governing permissions and limitations
# under the License. # under the License.
import io
import json import json
from unittest import mock
from cliff.formatters import json_format from cliff.formatters import json_format
from cliff.tests import base from cliff.tests import base
from cliff.tests import test_columns from cliff.tests import test_columns
import six
from unittest import mock
class TestJSONFormatter(base.TestBase): class TestJSONFormatter(base.TestBase):
@ -38,7 +37,7 @@ class TestJSONFormatter(base.TestBase):
sf.add_argument_group(args) sf.add_argument_group(args)
args.noindent = True args.noindent = True
output = six.StringIO() output = io.StringIO()
sf.emit_one(c, d, output, args) sf.emit_one(c, d, output, args)
value = output.getvalue() value = output.getvalue()
print(len(value.splitlines())) print(len(value.splitlines()))
@ -47,7 +46,7 @@ class TestJSONFormatter(base.TestBase):
self.assertEqual(expected, actual) self.assertEqual(expected, actual)
args.noindent = False args.noindent = False
output = six.StringIO() output = io.StringIO()
sf.emit_one(c, d, output, args) sf.emit_one(c, d, output, args)
value = output.getvalue() value = output.getvalue()
self.assertEqual(6, len(value.splitlines())) self.assertEqual(6, len(value.splitlines()))
@ -68,7 +67,7 @@ class TestJSONFormatter(base.TestBase):
sf.add_argument_group(args) sf.add_argument_group(args)
args.noindent = True args.noindent = True
output = six.StringIO() output = io.StringIO()
sf.emit_one(c, d, output, args) sf.emit_one(c, d, output, args)
value = output.getvalue() value = output.getvalue()
print(len(value.splitlines())) print(len(value.splitlines()))
@ -93,7 +92,7 @@ class TestJSONFormatter(base.TestBase):
sf.add_argument_group(args) sf.add_argument_group(args)
args.noindent = True args.noindent = True
output = six.StringIO() output = io.StringIO()
sf.emit_list(c, d, output, args) sf.emit_list(c, d, output, args)
value = output.getvalue() value = output.getvalue()
self.assertEqual(1, len(value.splitlines())) self.assertEqual(1, len(value.splitlines()))
@ -101,7 +100,7 @@ class TestJSONFormatter(base.TestBase):
self.assertEqual(expected, actual) self.assertEqual(expected, actual)
args.noindent = False args.noindent = False
output = six.StringIO() output = io.StringIO()
sf.emit_list(c, d, output, args) sf.emit_list(c, d, output, args)
value = output.getvalue() value = output.getvalue()
self.assertEqual(17, len(value.splitlines())) self.assertEqual(17, len(value.splitlines()))
@ -121,7 +120,7 @@ class TestJSONFormatter(base.TestBase):
sf.add_argument_group(args) sf.add_argument_group(args)
args.noindent = True args.noindent = True
output = six.StringIO() output = io.StringIO()
sf.emit_list(c, d, output, args) sf.emit_list(c, d, output, args)
value = output.getvalue() value = output.getvalue()
self.assertEqual(1, len(value.splitlines())) self.assertEqual(1, len(value.splitlines()))

View File

@ -13,8 +13,7 @@
# under the License. # under the License.
import argparse import argparse
import six import io
from unittest import mock from unittest import mock
from cliff.formatters import shell from cliff.formatters import shell
@ -29,7 +28,7 @@ class TestShellFormatter(base.TestBase):
c = ('a', 'b', 'c', 'd') c = ('a', 'b', 'c', 'd')
d = ('A', 'B', 'C', '"escape me"') d = ('A', 'B', 'C', '"escape me"')
expected = 'a="A"\nb="B"\nd="\\"escape me\\""\n' expected = 'a="A"\nb="B"\nd="\\"escape me\\""\n'
output = six.StringIO() output = io.StringIO()
args = mock.Mock() args = mock.Mock()
args.variables = ['a', 'b', 'd'] args.variables = ['a', 'b', 'd']
args.prefix = '' args.prefix = ''
@ -42,7 +41,7 @@ class TestShellFormatter(base.TestBase):
c = ('a', 'b', 'c', 'd') c = ('a', 'b', 'c', 'd')
d = ('A', 'B', 'C', '"escape me"') d = ('A', 'B', 'C', '"escape me"')
expected = 'Xd="\\"escape me\\""\n' expected = 'Xd="\\"escape me\\""\n'
output = six.StringIO() output = io.StringIO()
# Parse arguments as if passed on the command-line # Parse arguments as if passed on the command-line
parser = argparse.ArgumentParser(description='Testing...') parser = argparse.ArgumentParser(description='Testing...')
sf.add_argument_group(parser) sf.add_argument_group(parser)
@ -60,7 +59,7 @@ class TestShellFormatter(base.TestBase):
'b="B"', 'b="B"',
'c="[\'the\', \'value\']"\n', 'c="[\'the\', \'value\']"\n',
]) ])
output = six.StringIO() output = io.StringIO()
args = mock.Mock() args = mock.Mock()
args.variables = ['a', 'b', 'c'] args.variables = ['a', 'b', 'c']
args.prefix = '' args.prefix = ''
@ -71,10 +70,10 @@ class TestShellFormatter(base.TestBase):
def test_non_string_values(self): def test_non_string_values(self):
sf = shell.ShellFormatter() sf = shell.ShellFormatter()
c = ('a', 'b', 'c', 'd', 'e') 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' expected = ('a="True"\nb="False"\nc="100"\n'
'd="\\"esc\\""\ne="\\"esc\\""\n') 'd="\\"esc\\""\ne="\\"esc\\""\n')
output = six.StringIO() output = io.StringIO()
args = mock.Mock() args = mock.Mock()
args.variables = ['a', 'b', 'c', 'd', 'e'] args.variables = ['a', 'b', 'c', 'd', 'e']
args.prefix = '' args.prefix = ''
@ -87,7 +86,7 @@ class TestShellFormatter(base.TestBase):
c = ('a', 'foo-bar', 'provider:network_type') c = ('a', 'foo-bar', 'provider:network_type')
d = (True, 'baz', 'vxlan') d = (True, 'baz', 'vxlan')
expected = 'a="True"\nfoo_bar="baz"\nprovider_network_type="vxlan"\n' expected = 'a="True"\nfoo_bar="baz"\nprovider_network_type="vxlan"\n'
output = six.StringIO() output = io.StringIO()
args = mock.Mock() args = mock.Mock()
args.variables = ['a', 'foo-bar', 'provider:network_type'] args.variables = ['a', 'foo-bar', 'provider:network_type']
args.prefix = '' args.prefix = ''

View File

@ -16,7 +16,7 @@ import argparse
import os import os
import textwrap import textwrap
from six import StringIO from io import StringIO
from unittest import mock from unittest import mock
from cliff.formatters import table from cliff.formatters import table

View File

@ -12,7 +12,7 @@
# License for the specific language governing permissions and limitations # License for the specific language governing permissions and limitations
# under the License. # under the License.
import six from io import StringIO
from cliff.formatters import value from cliff.formatters import value
from cliff.tests import base from cliff.tests import base
@ -26,7 +26,7 @@ class TestValueFormatter(base.TestBase):
c = ('a', 'b', 'c', 'd') c = ('a', 'b', 'c', 'd')
d = ('A', 'B', 'C', '"no escape me"') d = ('A', 'B', 'C', '"no escape me"')
expected = 'A\nB\nC\n"no escape me"\n' expected = 'A\nB\nC\n"no escape me"\n'
output = six.StringIO() output = StringIO()
sf.emit_one(c, d, output, None) sf.emit_one(c, d, output, None)
actual = output.getvalue() actual = output.getvalue()
self.assertEqual(expected, actual) self.assertEqual(expected, actual)
@ -36,7 +36,7 @@ class TestValueFormatter(base.TestBase):
c = ('a', 'b', 'c', 'd') c = ('a', 'b', 'c', 'd')
d = ('A', 'B', 'C', test_columns.FauxColumn(['the', 'value'])) d = ('A', 'B', 'C', test_columns.FauxColumn(['the', 'value']))
expected = "A\nB\nC\n['the', 'value']\n" expected = "A\nB\nC\n['the', 'value']\n"
output = six.StringIO() output = StringIO()
sf.emit_one(c, d, output, None) sf.emit_one(c, d, output, None)
actual = output.getvalue() actual = output.getvalue()
self.assertEqual(expected, actual) self.assertEqual(expected, actual)
@ -48,7 +48,7 @@ class TestValueFormatter(base.TestBase):
d2 = ('D', 'E', 'F') d2 = ('D', 'E', 'F')
data = [d1, d2] data = [d1, d2]
expected = 'A B C\nD E F\n' expected = 'A B C\nD E F\n'
output = six.StringIO() output = StringIO()
sf.emit_list(c, data, output, None) sf.emit_list(c, data, output, None)
actual = output.getvalue() actual = output.getvalue()
self.assertEqual(expected, actual) self.assertEqual(expected, actual)
@ -59,7 +59,7 @@ class TestValueFormatter(base.TestBase):
d1 = ('A', 'B', test_columns.FauxColumn(['the', 'value'])) d1 = ('A', 'B', test_columns.FauxColumn(['the', 'value']))
data = [d1] data = [d1]
expected = "A B ['the', 'value']\n" expected = "A B ['the', 'value']\n"
output = six.StringIO() output = StringIO()
sf.emit_list(c, data, output, None) sf.emit_list(c, data, output, None)
actual = output.getvalue() actual = output.getvalue()
self.assertEqual(expected, actual) self.assertEqual(expected, actual)

View File

@ -12,7 +12,7 @@
# License for the specific language governing permissions and limitations # License for the specific language governing permissions and limitations
# under the License. # under the License.
import six from io import StringIO
import yaml import yaml
from unittest import mock from unittest import mock
@ -34,7 +34,7 @@ class TestYAMLFormatter(base.TestBase):
'c': 'C', 'c': 'C',
'd': '"escape me"' 'd': '"escape me"'
} }
output = six.StringIO() output = StringIO()
args = mock.Mock() args = mock.Mock()
sf.emit_one(c, d, output, args) sf.emit_one(c, d, output, args)
actual = yaml.safe_load(output.getvalue()) actual = yaml.safe_load(output.getvalue())
@ -54,7 +54,7 @@ class TestYAMLFormatter(base.TestBase):
sf.add_argument_group(args) sf.add_argument_group(args)
args.noindent = True args.noindent = True
output = six.StringIO() output = StringIO()
sf.emit_one(c, d, output, args) sf.emit_one(c, d, output, args)
value = output.getvalue() value = output.getvalue()
print(len(value.splitlines())) print(len(value.splitlines()))
@ -74,7 +74,7 @@ class TestYAMLFormatter(base.TestBase):
{'a': 'A2', 'b': 'B2', 'c': 'C2'}, {'a': 'A2', 'b': 'B2', 'c': 'C2'},
{'a': 'A3', 'b': 'B3', 'c': 'C3'} {'a': 'A3', 'b': 'B3', 'c': 'C3'}
] ]
output = six.StringIO() output = StringIO()
args = mock.Mock() args = mock.Mock()
sf.add_argument_group(args) sf.add_argument_group(args)
sf.emit_list(c, d, output, args) sf.emit_list(c, d, output, args)
@ -94,7 +94,7 @@ class TestYAMLFormatter(base.TestBase):
sf.add_argument_group(args) sf.add_argument_group(args)
args.noindent = True args.noindent = True
output = six.StringIO() output = StringIO()
sf.emit_list(c, d, output, args) sf.emit_list(c, d, output, args)
actual = yaml.safe_load(output.getvalue()) actual = yaml.safe_load(output.getvalue())
self.assertEqual(expected, actual) self.assertEqual(expected, actual)

View File

@ -10,10 +10,7 @@
# License for the specific language governing permissions and limitations # License for the specific language governing permissions and limitations
# under the License. # under the License.
try: import io
from StringIO import StringIO
except ImportError:
from io import StringIO
import os import os
import sys import sys
@ -32,7 +29,7 @@ class TestHelp(base.TestBase):
# FIXME(dhellmann): Are commands tied too closely to the app? Or # 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 # do commands know too much about apps by using them to get to the
# command manager? # command manager?
stdout = StringIO() stdout = io.StringIO()
app = application.App('testing', '1', app = application.App('testing', '1',
utils.TestCommandManager(utils.TEST_NAMESPACE), utils.TestCommandManager(utils.TEST_NAMESPACE),
stdout=stdout) stdout=stdout)
@ -50,7 +47,7 @@ class TestHelp(base.TestBase):
# FIXME(dhellmann): Are commands tied too closely to the app? Or # 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 # do commands know too much about apps by using them to get to the
# command manager? # command manager?
stdout = StringIO() stdout = io.StringIO()
app = application.App('testing', '1', app = application.App('testing', '1',
utils.TestCommandManager(utils.TEST_NAMESPACE), utils.TestCommandManager(utils.TEST_NAMESPACE),
stdout=stdout) stdout=stdout)
@ -70,7 +67,7 @@ class TestHelp(base.TestBase):
# FIXME(dhellmann): Are commands tied too closely to the app? Or # 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 # do commands know too much about apps by using them to get to the
# command manager? # command manager?
stdout = StringIO() stdout = io.StringIO()
app = application.App('testing', '1', app = application.App('testing', '1',
utils.TestCommandManager(utils.TEST_NAMESPACE), utils.TestCommandManager(utils.TEST_NAMESPACE),
stdout=stdout) stdout=stdout)
@ -88,7 +85,7 @@ class TestHelp(base.TestBase):
# FIXME(dhellmann): Are commands tied too closely to the app? Or # 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 # do commands know too much about apps by using them to get to the
# command manager? # command manager?
stdout = StringIO() stdout = io.StringIO()
app = application.App('testing', '1', app = application.App('testing', '1',
utils.TestCommandManager(utils.TEST_NAMESPACE), utils.TestCommandManager(utils.TEST_NAMESPACE),
stdout=stdout) stdout=stdout)
@ -115,7 +112,7 @@ class TestHelp(base.TestBase):
# FIXME(dhellmann): Are commands tied too closely to the app? Or # 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 # do commands know too much about apps by using them to get to the
# command manager? # command manager?
stdout = StringIO() stdout = io.StringIO()
app = application.App('testing', '1', app = application.App('testing', '1',
utils.TestCommandManager(utils.TEST_NAMESPACE), utils.TestCommandManager(utils.TEST_NAMESPACE),
stdout=stdout) stdout=stdout)
@ -132,7 +129,7 @@ class TestHelp(base.TestBase):
@mock.patch.object(commandmanager.EntryPointWrapper, 'load', @mock.patch.object(commandmanager.EntryPointWrapper, 'load',
side_effect=Exception('Could not load EntryPoint')) side_effect=Exception('Could not load EntryPoint'))
def test_show_help_with_ep_load_fail(self, mock_load): def test_show_help_with_ep_load_fail(self, mock_load):
stdout = StringIO() stdout = io.StringIO()
app = application.App('testing', '1', app = application.App('testing', '1',
utils.TestCommandManager(utils.TEST_NAMESPACE), utils.TestCommandManager(utils.TEST_NAMESPACE),
stdout=stdout) stdout=stdout)
@ -154,7 +151,7 @@ class TestHelp(base.TestBase):
@mock.patch.object(commandmanager.EntryPointWrapper, 'load', @mock.patch.object(commandmanager.EntryPointWrapper, 'load',
side_effect=Exception('Could not load EntryPoint')) side_effect=Exception('Could not load EntryPoint'))
def test_show_help_print_exc_with_ep_load_fail(self, mock_load): def test_show_help_print_exc_with_ep_load_fail(self, mock_load):
stdout = StringIO() stdout = io.StringIO()
app = application.App('testing', '1', app = application.App('testing', '1',
utils.TestCommandManager(utils.TEST_NAMESPACE), utils.TestCommandManager(utils.TEST_NAMESPACE),
stdout=stdout) stdout=stdout)

View File

@ -14,11 +14,10 @@
import os import os
import sys import sys
from unittest import mock from unittest import mock
from cliff import utils
from cliff.tests import base from cliff.tests import base
from cliff import utils
class TestTerminalWidth(base.TestBase): class TestTerminalWidth(base.TestBase):

View File

@ -11,15 +11,12 @@
# See the License for the specific language governing permissions and # See the License for the specific language governing permissions and
# limitations under the License. # limitations under the License.
import codecs
import ctypes import ctypes
import inspect import inspect
import os import os
import struct import struct
import sys import sys
import six
# Each edit operation is assigned different cost, such as: # Each edit operation is assigned different cost, such as:
# 'w' means swap operation, the cost is 0; # 'w' means swap operation, the cost is 0;
# 's' means substitution operation, the cost is 2; # 's' means substitution operation, the cost is 2;
@ -163,52 +160,3 @@ def _get_terminal_width_ioctl(stdout):
return columns return columns
except IOError: except IOError:
return None 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

View File

@ -21,7 +21,6 @@ python-subunit==1.0.0
pytz==2013.6 pytz==2013.6
PyYAML==3.12 PyYAML==3.12
requests==2.14.2 requests==2.14.2
six==1.10.0
smmap==0.9.0 smmap==0.9.0
snowballstemmer==1.2.1 snowballstemmer==1.2.1
Sphinx==2.0.0 Sphinx==2.0.0

View File

@ -5,6 +5,5 @@ pbr!=2.1.0,>=2.0.0 # Apache-2.0
cmd2>=0.8.0,!=0.8.3 # MIT cmd2>=0.8.0,!=0.8.3 # MIT
PrettyTable<0.8,>=0.7.2 # BSD PrettyTable<0.8,>=0.7.2 # BSD
pyparsing>=2.1.0 # MIT pyparsing>=2.1.0 # MIT
six>=1.10.0 # MIT
stevedore>=2.0.1 # Apache-2.0 stevedore>=2.0.1 # Apache-2.0
PyYAML>=3.12 # MIT PyYAML>=3.12 # MIT