Merge "Remove six"
This commit is contained in:
commit
644041f87f
@ -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,
|
||||||
|
14
cliff/app.py
14
cliff/app.py
@ -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
|
||||||
|
@ -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
|
||||||
|
@ -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
|
||||||
|
@ -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()))
|
||||||
|
@ -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.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
@ -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.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
@ -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]
|
||||||
|
@ -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.
|
||||||
|
@ -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
|
||||||
|
@ -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,7 +26,7 @@ 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')
|
||||||
@ -36,7 +34,7 @@ class ValueFormatter(base.ListFormatter, base.SingleFormatter):
|
|||||||
|
|
||||||
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)
|
||||||
|
@ -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
|
||||||
|
@ -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.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
@ -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.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
@ -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,65 +467,6 @@ 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:
|
|
||||||
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
|
|
||||||
|
|
||||||
else:
|
|
||||||
app = application.App('no io streams', 1, cmd_mgr)
|
app = application.App('no io streams', 1, cmd_mgr)
|
||||||
self.assertIs(sys.stdin, app.stdin)
|
self.assertIs(sys.stdin, app.stdin)
|
||||||
self.assertIs(sys.stdout, app.stdout)
|
self.assertIs(sys.stdout, app.stdout)
|
||||||
@ -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 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
|
# In PY3 you can't write encoded bytes to a text writer
|
||||||
# instead text functions require text.
|
# instead text functions require text.
|
||||||
io = six.StringIO()
|
out = io.StringIO()
|
||||||
writer = utils.getwriter('utf-8')(io)
|
writer = codecs.getwriter('utf-8')(out)
|
||||||
self.assertRaises(TypeError,
|
self.assertRaises(TypeError, writer.write, text)
|
||||||
writer.write,
|
|
||||||
text)
|
|
||||||
|
|
||||||
io = six.StringIO()
|
out = io.StringIO()
|
||||||
writer = utils.getwriter('utf-8')(io)
|
writer = codecs.getwriter('utf-8')(out)
|
||||||
self.assertRaises(TypeError,
|
self.assertRaises(TypeError, writer.write, text_utf8)
|
||||||
writer.write,
|
|
||||||
text_utf8)
|
|
||||||
|
@ -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)
|
||||||
|
@ -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()))
|
||||||
|
@ -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 = ''
|
||||||
|
@ -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
|
||||||
|
@ -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)
|
||||||
|
@ -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)
|
||||||
|
@ -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)
|
||||||
|
@ -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):
|
||||||
|
@ -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
|
|
||||||
|
@ -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
|
||||||
|
@ -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
|
||||||
|
Loading…
Reference in New Issue
Block a user