Graduation Prep: Use six.text_type instead of str
Previously, `str()` was used to convert things into strings. This will not work for unicode messages in Python 2, so everything was converted to using `six.text_type` instead.
This commit is contained in:
parent
4faad94ced
commit
6bfdb33cc9
@ -18,7 +18,10 @@ This module includes various utilities
|
|||||||
used in generating reports.
|
used in generating reports.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
class StringWithAttrs(str):
|
import six
|
||||||
|
|
||||||
|
|
||||||
|
class StringWithAttrs(six.text_type):
|
||||||
"""A String that can have arbitrary attributes"""
|
"""A String that can have arbitrary attributes"""
|
||||||
|
|
||||||
pass
|
pass
|
||||||
|
@ -67,7 +67,7 @@ class ReportModel(col.MutableMapping):
|
|||||||
self_cpy = copy.deepcopy(self)
|
self_cpy = copy.deepcopy(self)
|
||||||
for key in self_cpy:
|
for key in self_cpy:
|
||||||
if getattr(self_cpy[key], 'attached_view', None) is not None:
|
if getattr(self_cpy[key], 'attached_view', None) is not None:
|
||||||
self_cpy[key] = str(self_cpy[key])
|
self_cpy[key] = six.text_type(self_cpy[key])
|
||||||
|
|
||||||
if self.attached_view is not None:
|
if self.attached_view is not None:
|
||||||
return self.attached_view(self_cpy)
|
return self.attached_view(self_cpy)
|
||||||
|
@ -19,6 +19,8 @@ All reports take the form of a report class containing various report
|
|||||||
sections.
|
sections.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
import six
|
||||||
|
|
||||||
from oslo_reports.views.text import header as header_views
|
from oslo_reports.views.text import header as header_views
|
||||||
|
|
||||||
|
|
||||||
@ -72,15 +74,15 @@ class BasicReport(object):
|
|||||||
:returns: the serialized report
|
:returns: the serialized report
|
||||||
"""
|
"""
|
||||||
|
|
||||||
return "\n".join(str(sect) for sect in self.sections)
|
return "\n".join(six.text_type(sect) for sect in self.sections)
|
||||||
|
|
||||||
|
|
||||||
class ReportSection(object):
|
class ReportSection(object):
|
||||||
"""A Report Section
|
"""A Report Section
|
||||||
|
|
||||||
A report section contains a generator and a top-level view. When something
|
A report section contains a generator and a top-level view. When something
|
||||||
attempts to serialize the section by calling str() on it, the section runs
|
attempts to serialize the section by calling str() or unicode() on it, the
|
||||||
the generator and calls the view on the resulting model.
|
section runs the generator and calls the view on the resulting model.
|
||||||
|
|
||||||
.. seealso::
|
.. seealso::
|
||||||
|
|
||||||
|
@ -16,6 +16,7 @@ import collections as col
|
|||||||
import re
|
import re
|
||||||
|
|
||||||
from oslotest import base
|
from oslotest import base
|
||||||
|
import six
|
||||||
|
|
||||||
from oslo_reports.models import base as base_model
|
from oslo_reports.models import base as base_model
|
||||||
from oslo_reports import report
|
from oslo_reports import report
|
||||||
@ -25,7 +26,7 @@ class BasicView(object):
|
|||||||
def __call__(self, model):
|
def __call__(self, model):
|
||||||
res = ""
|
res = ""
|
||||||
for k in sorted(model.keys()):
|
for k in sorted(model.keys()):
|
||||||
res += str(k) + ": " + str(model[k]) + ";"
|
res += six.text_type(k) + ": " + six.text_type(model[k]) + ";"
|
||||||
return res
|
return res
|
||||||
|
|
||||||
|
|
||||||
@ -66,7 +67,7 @@ class TestBaseModel(base.BaseTestCase):
|
|||||||
def test_submodel_attached_view(self):
|
def test_submodel_attached_view(self):
|
||||||
class TmpView(object):
|
class TmpView(object):
|
||||||
def __call__(self, model):
|
def __call__(self, model):
|
||||||
return '{len: ' + str(len(model.c)) + '}'
|
return '{len: ' + six.text_type(len(model.c)) + '}'
|
||||||
|
|
||||||
def generate_model_with_submodel():
|
def generate_model_with_submodel():
|
||||||
base_m = basic_generator()
|
base_m = basic_generator()
|
||||||
@ -84,10 +85,10 @@ class TestBaseModel(base.BaseTestCase):
|
|||||||
# ugly code for python 2.6 compat, since python 2.6
|
# ugly code for python 2.6 compat, since python 2.6
|
||||||
# does not have assertRaisesRegexp
|
# does not have assertRaisesRegexp
|
||||||
try:
|
try:
|
||||||
str(model)
|
six.text_type(model)
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
err_str = 'Cannot stringify model: no attached view'
|
err_str = 'Cannot stringify model: no attached view'
|
||||||
self.assertEqual(str(e), err_str)
|
self.assertEqual(six.text_type(e), err_str)
|
||||||
else:
|
else:
|
||||||
self.assertTrue(False)
|
self.assertTrue(False)
|
||||||
|
|
||||||
@ -95,7 +96,7 @@ class TestBaseModel(base.BaseTestCase):
|
|||||||
model = base_model.ReportModel(data={'a': 1, 'b': 2},
|
model = base_model.ReportModel(data={'a': 1, 'b': 2},
|
||||||
attached_view=BasicView())
|
attached_view=BasicView())
|
||||||
|
|
||||||
self.assertEqual(str(model), 'a: 1;b: 2;')
|
self.assertEqual(six.text_type(model), 'a: 1;b: 2;')
|
||||||
|
|
||||||
def test_model_repr(self):
|
def test_model_repr(self):
|
||||||
model1 = base_model.ReportModel(data={'a': 1, 'b': 2},
|
model1 = base_model.ReportModel(data={'a': 1, 'b': 2},
|
||||||
@ -122,7 +123,7 @@ class TestBaseModel(base.BaseTestCase):
|
|||||||
model.attached_view = BasicView()
|
model.attached_view = BasicView()
|
||||||
|
|
||||||
# if we don't handle lists properly, we'll get a TypeError here
|
# if we don't handle lists properly, we'll get a TypeError here
|
||||||
self.assertEqual('0: a;1: b;', str(model))
|
self.assertEqual('0: a;1: b;', six.text_type(model))
|
||||||
|
|
||||||
def test_immutable_mappings_produce_mutable_models(self):
|
def test_immutable_mappings_produce_mutable_models(self):
|
||||||
class SomeImmutableMapping(col.Mapping):
|
class SomeImmutableMapping(col.Mapping):
|
||||||
@ -142,9 +143,9 @@ class TestBaseModel(base.BaseTestCase):
|
|||||||
model = base_model.ReportModel(data=mp)
|
model = base_model.ReportModel(data=mp)
|
||||||
model.attached_view = BasicView()
|
model.attached_view = BasicView()
|
||||||
|
|
||||||
self.assertEqual('a: 2;b: 4;c: 8;', str(model))
|
self.assertEqual('a: 2;b: 4;c: 8;', six.text_type(model))
|
||||||
|
|
||||||
model['d'] = 16
|
model['d'] = 16
|
||||||
|
|
||||||
self.assertEqual('a: 2;b: 4;c: 8;d: 16;', str(model))
|
self.assertEqual('a: 2;b: 4;c: 8;d: 16;', six.text_type(model))
|
||||||
self.assertEqual({'a': 2, 'b': 4, 'c': 8}, mp.data)
|
self.assertEqual({'a': 2, 'b': 4, 'c': 8}, mp.data)
|
||||||
|
@ -19,6 +19,7 @@ import greenlet
|
|||||||
import mock
|
import mock
|
||||||
from oslo_config import cfg
|
from oslo_config import cfg
|
||||||
from oslotest import base
|
from oslotest import base
|
||||||
|
import six
|
||||||
|
|
||||||
from oslo_reports.generators import conf as os_cgen
|
from oslo_reports.generators import conf as os_cgen
|
||||||
from oslo_reports.generators import threading as os_tgen
|
from oslo_reports.generators import threading as os_tgen
|
||||||
@ -42,7 +43,7 @@ class TestOpenstackGenerators(base.BaseTestCase):
|
|||||||
self.assertTrue(was_ok)
|
self.assertTrue(was_ok)
|
||||||
|
|
||||||
model.set_current_view_type('text')
|
model.set_current_view_type('text')
|
||||||
self.assertIsNotNone(str(model))
|
self.assertIsNotNone(six.text_type(model))
|
||||||
|
|
||||||
def test_thread_generator_tb(self):
|
def test_thread_generator_tb(self):
|
||||||
class FakeModel(object):
|
class FakeModel(object):
|
||||||
@ -72,7 +73,7 @@ class TestOpenstackGenerators(base.BaseTestCase):
|
|||||||
self.assertTrue(was_ok)
|
self.assertTrue(was_ok)
|
||||||
|
|
||||||
model.set_current_view_type('text')
|
model.set_current_view_type('text')
|
||||||
self.assertIsNotNone(str(model))
|
self.assertIsNotNone(six.text_type(model))
|
||||||
|
|
||||||
def test_config_model(self):
|
def test_config_model(self):
|
||||||
conf = cfg.ConfigOpts()
|
conf = cfg.ConfigOpts()
|
||||||
@ -102,7 +103,7 @@ class TestOpenstackGenerators(base.BaseTestCase):
|
|||||||
'default: \n'
|
'default: \n'
|
||||||
' crackers = triscuit\n'
|
' crackers = triscuit\n'
|
||||||
' secrets = ***')
|
' secrets = ***')
|
||||||
self.assertEqual(target_str, str(model))
|
self.assertEqual(target_str, six.text_type(model))
|
||||||
|
|
||||||
def test_package_report_generator(self):
|
def test_package_report_generator(self):
|
||||||
class VersionObj(object):
|
class VersionObj(object):
|
||||||
@ -121,4 +122,4 @@ class TestOpenstackGenerators(base.BaseTestCase):
|
|||||||
target_str = ('product = Sharp Cheddar\n'
|
target_str = ('product = Sharp Cheddar\n'
|
||||||
'vendor = Cheese Shoppe\n'
|
'vendor = Cheese Shoppe\n'
|
||||||
'version = 1.0.0')
|
'version = 1.0.0')
|
||||||
self.assertEqual(target_str, str(model))
|
self.assertEqual(target_str, six.text_type(model))
|
||||||
|
@ -16,6 +16,7 @@ import copy
|
|||||||
|
|
||||||
import mock
|
import mock
|
||||||
from oslotest import base
|
from oslotest import base
|
||||||
|
import six
|
||||||
|
|
||||||
from oslo_reports.models import base as base_model
|
from oslo_reports.models import base as base_model
|
||||||
from oslo_reports.models import with_default_views as mwdv
|
from oslo_reports.models import with_default_views as mwdv
|
||||||
@ -34,15 +35,15 @@ class TestModelReportType(base.BaseTestCase):
|
|||||||
model = mwdv_generator()
|
model = mwdv_generator()
|
||||||
|
|
||||||
model.set_current_view_type('text')
|
model.set_current_view_type('text')
|
||||||
self.assertEqual('int = 1\nstring = value', str(model))
|
self.assertEqual('int = 1\nstring = value', six.text_type(model))
|
||||||
|
|
||||||
model.set_current_view_type('json')
|
model.set_current_view_type('json')
|
||||||
self.assertEqual('{"int": 1, "string": "value"}', str(model))
|
self.assertEqual('{"int": 1, "string": "value"}', six.text_type(model))
|
||||||
|
|
||||||
model.set_current_view_type('xml')
|
model.set_current_view_type('xml')
|
||||||
|
|
||||||
self.assertEqual('<model><int>1</int><string>value</string></model>',
|
self.assertEqual('<model><int>1</int><string>value</string></model>',
|
||||||
str(model))
|
six.text_type(model))
|
||||||
|
|
||||||
def test_recursive_type_propagation_with_nested_models(self):
|
def test_recursive_type_propagation_with_nested_models(self):
|
||||||
model = mwdv_generator()
|
model = mwdv_generator()
|
||||||
@ -84,7 +85,7 @@ class TestModelReportType(base.BaseTestCase):
|
|||||||
|
|
||||||
def test_report_of_type(self):
|
def test_report_of_type(self):
|
||||||
rep = report.ReportOfType('json')
|
rep = report.ReportOfType('json')
|
||||||
rep.add_section(lambda x: str(x), mwdv_generator)
|
rep.add_section(lambda x: six.text_type(x), mwdv_generator)
|
||||||
|
|
||||||
self.assertEqual('{"int": 1, "string": "value"}', rep.run())
|
self.assertEqual('{"int": 1, "string": "value"}', rep.run())
|
||||||
|
|
||||||
@ -133,7 +134,7 @@ class TestGenericXMLView(base.BaseTestCase):
|
|||||||
'<dt><a>1</a><b>2</b></dt>'
|
'<dt><a>1</a><b>2</b></dt>'
|
||||||
'<int>1</int>'
|
'<int>1</int>'
|
||||||
'<string>value</string></model>')
|
'<string>value</string></model>')
|
||||||
self.assertEqual(target_str, str(self.model))
|
self.assertEqual(target_str, six.text_type(self.model))
|
||||||
|
|
||||||
def test_list_serialization(self):
|
def test_list_serialization(self):
|
||||||
self.model['lt'] = ['a', 'b']
|
self.model['lt'] = ['a', 'b']
|
||||||
@ -142,7 +143,7 @@ class TestGenericXMLView(base.BaseTestCase):
|
|||||||
'<int>1</int>'
|
'<int>1</int>'
|
||||||
'<lt><item>a</item><item>b</item></lt>'
|
'<lt><item>a</item><item>b</item></lt>'
|
||||||
'<string>value</string></model>')
|
'<string>value</string></model>')
|
||||||
self.assertEqual(target_str, str(self.model))
|
self.assertEqual(target_str, six.text_type(self.model))
|
||||||
|
|
||||||
def test_list_in_dict_serialization(self):
|
def test_list_in_dict_serialization(self):
|
||||||
self.model['dt'] = {'a': 1, 'b': [2, 3]}
|
self.model['dt'] = {'a': 1, 'b': [2, 3]}
|
||||||
@ -152,7 +153,7 @@ class TestGenericXMLView(base.BaseTestCase):
|
|||||||
'<b><item>2</item><item>3</item></b></dt>'
|
'<b><item>2</item><item>3</item></b></dt>'
|
||||||
'<int>1</int>'
|
'<int>1</int>'
|
||||||
'<string>value</string></model>')
|
'<string>value</string></model>')
|
||||||
self.assertEqual(target_str, str(self.model))
|
self.assertEqual(target_str, six.text_type(self.model))
|
||||||
|
|
||||||
def test_dict_in_list_serialization(self):
|
def test_dict_in_list_serialization(self):
|
||||||
self.model['lt'] = [1, {'b': 2, 'c': 3}]
|
self.model['lt'] = [1, {'b': 2, 'c': 3}]
|
||||||
@ -162,7 +163,7 @@ class TestGenericXMLView(base.BaseTestCase):
|
|||||||
'<lt><item>1</item>'
|
'<lt><item>1</item>'
|
||||||
'<item><b>2</b><c>3</c></item></lt>'
|
'<item><b>2</b><c>3</c></item></lt>'
|
||||||
'<string>value</string></model>')
|
'<string>value</string></model>')
|
||||||
self.assertEqual(target_str, str(self.model))
|
self.assertEqual(target_str, six.text_type(self.model))
|
||||||
|
|
||||||
def test_submodel_serialization(self):
|
def test_submodel_serialization(self):
|
||||||
sm = mwdv_generator()
|
sm = mwdv_generator()
|
||||||
@ -177,7 +178,7 @@ class TestGenericXMLView(base.BaseTestCase):
|
|||||||
'<model><int>1</int><string>value</string></model>'
|
'<model><int>1</int><string>value</string></model>'
|
||||||
'</submodel>'
|
'</submodel>'
|
||||||
'</model>')
|
'</model>')
|
||||||
self.assertEqual(target_str, str(self.model))
|
self.assertEqual(target_str, six.text_type(self.model))
|
||||||
|
|
||||||
def test_wrapper_name(self):
|
def test_wrapper_name(self):
|
||||||
self.model.attached_view.wrapper_name = 'cheese'
|
self.model.attached_view.wrapper_name = 'cheese'
|
||||||
@ -186,7 +187,7 @@ class TestGenericXMLView(base.BaseTestCase):
|
|||||||
'<int>1</int>'
|
'<int>1</int>'
|
||||||
'<string>value</string>'
|
'<string>value</string>'
|
||||||
'</cheese>')
|
'</cheese>')
|
||||||
self.assertEqual(target_str, str(self.model))
|
self.assertEqual(target_str, six.text_type(self.model))
|
||||||
|
|
||||||
|
|
||||||
class TestGenericJSONViews(base.BaseTestCase):
|
class TestGenericJSONViews(base.BaseTestCase):
|
||||||
@ -201,7 +202,8 @@ class TestGenericJSONViews(base.BaseTestCase):
|
|||||||
self.model = base_model.ReportModel(data={'string': 'value', 'int': 1},
|
self.model = base_model.ReportModel(data={'string': 'value', 'int': 1},
|
||||||
attached_view=attached_view)
|
attached_view=attached_view)
|
||||||
|
|
||||||
self.assertEqual('{"int": 1, "string": "value"}', str(self.model))
|
self.assertEqual('{"int": 1, "string": "value"}',
|
||||||
|
six.text_type(self.model))
|
||||||
|
|
||||||
def test_dict_serialization(self):
|
def test_dict_serialization(self):
|
||||||
self.model['dt'] = {'a': 1, 'b': 2}
|
self.model['dt'] = {'a': 1, 'b': 2}
|
||||||
@ -211,7 +213,7 @@ class TestGenericJSONViews(base.BaseTestCase):
|
|||||||
'"int": 1, '
|
'"int": 1, '
|
||||||
'"string": "value"'
|
'"string": "value"'
|
||||||
'}')
|
'}')
|
||||||
self.assertEqual(target_str, str(self.model))
|
self.assertEqual(target_str, six.text_type(self.model))
|
||||||
|
|
||||||
def test_list_serialization(self):
|
def test_list_serialization(self):
|
||||||
self.model['lt'] = ['a', 'b']
|
self.model['lt'] = ['a', 'b']
|
||||||
@ -221,7 +223,7 @@ class TestGenericJSONViews(base.BaseTestCase):
|
|||||||
'"lt": ["a", "b"], '
|
'"lt": ["a", "b"], '
|
||||||
'"string": "value"'
|
'"string": "value"'
|
||||||
'}')
|
'}')
|
||||||
self.assertEqual(target_str, str(self.model))
|
self.assertEqual(target_str, six.text_type(self.model))
|
||||||
|
|
||||||
def test_list_in_dict_serialization(self):
|
def test_list_in_dict_serialization(self):
|
||||||
self.model['dt'] = {'a': 1, 'b': [2, 3]}
|
self.model['dt'] = {'a': 1, 'b': [2, 3]}
|
||||||
@ -231,7 +233,7 @@ class TestGenericJSONViews(base.BaseTestCase):
|
|||||||
'"int": 1, '
|
'"int": 1, '
|
||||||
'"string": "value"'
|
'"string": "value"'
|
||||||
'}')
|
'}')
|
||||||
self.assertEqual(target_str, str(self.model))
|
self.assertEqual(target_str, six.text_type(self.model))
|
||||||
|
|
||||||
def test_dict_in_list_serialization(self):
|
def test_dict_in_list_serialization(self):
|
||||||
self.model['lt'] = [1, {'b': 2, 'c': 3}]
|
self.model['lt'] = [1, {'b': 2, 'c': 3}]
|
||||||
@ -241,7 +243,7 @@ class TestGenericJSONViews(base.BaseTestCase):
|
|||||||
'"lt": [1, {"b": 2, "c": 3}], '
|
'"lt": [1, {"b": 2, "c": 3}], '
|
||||||
'"string": "value"'
|
'"string": "value"'
|
||||||
'}')
|
'}')
|
||||||
self.assertEqual(target_str, str(self.model))
|
self.assertEqual(target_str, six.text_type(self.model))
|
||||||
|
|
||||||
def test_submodel_serialization(self):
|
def test_submodel_serialization(self):
|
||||||
sm = mwdv_generator()
|
sm = mwdv_generator()
|
||||||
@ -254,7 +256,7 @@ class TestGenericJSONViews(base.BaseTestCase):
|
|||||||
'"string": "value", '
|
'"string": "value", '
|
||||||
'"submodel": {"int": 1, "string": "value"}'
|
'"submodel": {"int": 1, "string": "value"}'
|
||||||
'}')
|
'}')
|
||||||
self.assertEqual(target_str, str(self.model))
|
self.assertEqual(target_str, six.text_type(self.model))
|
||||||
|
|
||||||
|
|
||||||
class TestGenericTextViews(base.BaseTestCase):
|
class TestGenericTextViews(base.BaseTestCase):
|
||||||
@ -278,14 +280,15 @@ class TestGenericTextViews(base.BaseTestCase):
|
|||||||
'string = value\n'
|
'string = value\n'
|
||||||
'int = 2\n'
|
'int = 2\n'
|
||||||
'string = value')
|
'string = value')
|
||||||
self.assertEqual(target_str, str(self.model))
|
self.assertEqual(target_str, six.text_type(self.model))
|
||||||
|
|
||||||
def test_basic_kv_view(self):
|
def test_basic_kv_view(self):
|
||||||
attached_view = text_generic.BasicKeyValueView()
|
attached_view = text_generic.BasicKeyValueView()
|
||||||
self.model = base_model.ReportModel(data={'string': 'value', 'int': 1},
|
self.model = base_model.ReportModel(data={'string': 'value', 'int': 1},
|
||||||
attached_view=attached_view)
|
attached_view=attached_view)
|
||||||
|
|
||||||
self.assertEqual('int = 1\nstring = value\n', str(self.model))
|
self.assertEqual('int = 1\nstring = value\n',
|
||||||
|
six.text_type(self.model))
|
||||||
|
|
||||||
def test_table_view(self):
|
def test_table_view(self):
|
||||||
column_names = ['Column A', 'Column B']
|
column_names = ['Column A', 'Column B']
|
||||||
@ -302,7 +305,7 @@ class TestGenericTextViews(base.BaseTestCase):
|
|||||||
' 1 | 2 \n' # noqa
|
' 1 | 2 \n' # noqa
|
||||||
' 3 | 4 \n') # noqa
|
' 3 | 4 \n') # noqa
|
||||||
|
|
||||||
self.assertEqual(target_str, str(self.model))
|
self.assertEqual(target_str, six.text_type(self.model))
|
||||||
|
|
||||||
def test_dict_serialization(self):
|
def test_dict_serialization(self):
|
||||||
self.model['dt'] = {'a': 1, 'b': 2}
|
self.model['dt'] = {'a': 1, 'b': 2}
|
||||||
@ -312,7 +315,7 @@ class TestGenericTextViews(base.BaseTestCase):
|
|||||||
' b = 2\n'
|
' b = 2\n'
|
||||||
'int = 1\n'
|
'int = 1\n'
|
||||||
'string = value')
|
'string = value')
|
||||||
self.assertEqual(target_str, str(self.model))
|
self.assertEqual(target_str, six.text_type(self.model))
|
||||||
|
|
||||||
def test_list_serialization(self):
|
def test_list_serialization(self):
|
||||||
self.model['lt'] = ['a', 'b']
|
self.model['lt'] = ['a', 'b']
|
||||||
@ -322,7 +325,7 @@ class TestGenericTextViews(base.BaseTestCase):
|
|||||||
' a\n'
|
' a\n'
|
||||||
' b\n'
|
' b\n'
|
||||||
'string = value')
|
'string = value')
|
||||||
self.assertEqual(target_str, str(self.model))
|
self.assertEqual(target_str, six.text_type(self.model))
|
||||||
|
|
||||||
def test_list_in_dict_serialization(self):
|
def test_list_in_dict_serialization(self):
|
||||||
self.model['dt'] = {'a': 1, 'b': [2, 3]}
|
self.model['dt'] = {'a': 1, 'b': [2, 3]}
|
||||||
@ -335,7 +338,7 @@ class TestGenericTextViews(base.BaseTestCase):
|
|||||||
'int = 1\n'
|
'int = 1\n'
|
||||||
'string = value')
|
'string = value')
|
||||||
|
|
||||||
self.assertEqual(target_str, str(self.model))
|
self.assertEqual(target_str, six.text_type(self.model))
|
||||||
|
|
||||||
def test_dict_in_list_serialization(self):
|
def test_dict_in_list_serialization(self):
|
||||||
self.model['lt'] = [1, {'b': 2, 'c': 3}]
|
self.model['lt'] = [1, {'b': 2, 'c': 3}]
|
||||||
@ -347,7 +350,7 @@ class TestGenericTextViews(base.BaseTestCase):
|
|||||||
' b = 2\n'
|
' b = 2\n'
|
||||||
' c = 3\n'
|
' c = 3\n'
|
||||||
'string = value')
|
'string = value')
|
||||||
self.assertEqual(target_str, str(self.model))
|
self.assertEqual(target_str, six.text_type(self.model))
|
||||||
|
|
||||||
def test_submodel_serialization(self):
|
def test_submodel_serialization(self):
|
||||||
sm = mwdv_generator()
|
sm = mwdv_generator()
|
||||||
@ -360,7 +363,7 @@ class TestGenericTextViews(base.BaseTestCase):
|
|||||||
'submodel = \n'
|
'submodel = \n'
|
||||||
' int = 1\n'
|
' int = 1\n'
|
||||||
' string = value')
|
' string = value')
|
||||||
self.assertEqual(target_str, str(self.model))
|
self.assertEqual(target_str, six.text_type(self.model))
|
||||||
|
|
||||||
def test_custom_indent_string(self):
|
def test_custom_indent_string(self):
|
||||||
view = text_generic.KeyValueView(indent_str='~~')
|
view = text_generic.KeyValueView(indent_str='~~')
|
||||||
@ -373,7 +376,7 @@ class TestGenericTextViews(base.BaseTestCase):
|
|||||||
'~~a\n'
|
'~~a\n'
|
||||||
'~~b\n'
|
'~~b\n'
|
||||||
'string = value')
|
'string = value')
|
||||||
self.assertEqual(target_str, str(self.model))
|
self.assertEqual(target_str, six.text_type(self.model))
|
||||||
|
|
||||||
|
|
||||||
def get_open_mocks(rv):
|
def get_open_mocks(rv):
|
||||||
@ -397,13 +400,15 @@ class TestJinjaView(base.BaseTestCase):
|
|||||||
def test_load_from_file(self):
|
def test_load_from_file(self):
|
||||||
self.model.attached_view = jv.JinjaView(path='a/b/c/d.jinja.txt')
|
self.model.attached_view = jv.JinjaView(path='a/b/c/d.jinja.txt')
|
||||||
|
|
||||||
self.assertEqual('int is 1, string is value', str(self.model))
|
self.assertEqual('int is 1, string is value',
|
||||||
|
six.text_type(self.model))
|
||||||
self.MM_FILE.assert_called_with_once('a/b/c/d.jinja.txt')
|
self.MM_FILE.assert_called_with_once('a/b/c/d.jinja.txt')
|
||||||
|
|
||||||
def test_direct_pass(self):
|
def test_direct_pass(self):
|
||||||
self.model.attached_view = jv.JinjaView(text=self.TEMPL_STR)
|
self.model.attached_view = jv.JinjaView(text=self.TEMPL_STR)
|
||||||
|
|
||||||
self.assertEqual('int is 1, string is value', str(self.model))
|
self.assertEqual('int is 1, string is value',
|
||||||
|
six.text_type(self.model))
|
||||||
|
|
||||||
def test_load_from_class(self):
|
def test_load_from_class(self):
|
||||||
class TmpJinjaView(jv.JinjaView):
|
class TmpJinjaView(jv.JinjaView):
|
||||||
@ -411,7 +416,8 @@ class TestJinjaView(base.BaseTestCase):
|
|||||||
|
|
||||||
self.model.attached_view = TmpJinjaView()
|
self.model.attached_view = TmpJinjaView()
|
||||||
|
|
||||||
self.assertEqual('int is 1, string is value', str(self.model))
|
self.assertEqual('int is 1, string is value',
|
||||||
|
six.text_type(self.model))
|
||||||
|
|
||||||
def test_is_deepcopiable(self):
|
def test_is_deepcopiable(self):
|
||||||
view_orig = jv.JinjaView(text=self.TEMPL_STR)
|
view_orig = jv.JinjaView(text=self.TEMPL_STR)
|
||||||
|
@ -35,7 +35,7 @@ class MultiView(object):
|
|||||||
"""
|
"""
|
||||||
|
|
||||||
def __call__(self, model):
|
def __call__(self, model):
|
||||||
res = [str(model[key]) for key in model]
|
res = [six.text_type(model[key]) for key in model]
|
||||||
return "\n".join(res)
|
return "\n".join(res)
|
||||||
|
|
||||||
|
|
||||||
@ -132,7 +132,7 @@ class KeyValueView(object):
|
|||||||
for val in sorted(root, key=str):
|
for val in sorted(root, key=str):
|
||||||
res.extend(serialize(val, None, indent + 1))
|
res.extend(serialize(val, None, indent + 1))
|
||||||
else:
|
else:
|
||||||
str_root = str(root)
|
str_root = six.text_type(root)
|
||||||
if '\n' in str_root:
|
if '\n' in str_root:
|
||||||
# we are in a submodel
|
# we are in a submodel
|
||||||
if rootkey is not None:
|
if rootkey is not None:
|
||||||
@ -175,7 +175,7 @@ class TableView(object):
|
|||||||
self.column_width = (72 - len(column_names) + 1) // len(column_names)
|
self.column_width = (72 - len(column_names) + 1) // len(column_names)
|
||||||
|
|
||||||
column_headers = "|".join(
|
column_headers = "|".join(
|
||||||
"{ch[" + str(n) + "]: ^" + str(self.column_width) + "}"
|
"{{ch[{n}]: ^{width}}}".format(n=n, width=self.column_width)
|
||||||
for n in range(len(column_names))
|
for n in range(len(column_names))
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -188,14 +188,15 @@ class TableView(object):
|
|||||||
self.header_fmt_str = column_headers + "\n" + vert_divider + "\n"
|
self.header_fmt_str = column_headers + "\n" + vert_divider + "\n"
|
||||||
|
|
||||||
self.row_fmt_str = "|".join(
|
self.row_fmt_str = "|".join(
|
||||||
"{cv[" + str(n) + "]: ^" + str(self.column_width) + "}"
|
"{{cv[{n}]: ^{width}}}".format(n=n, width=self.column_width)
|
||||||
for n in range(len(column_values))
|
for n in range(len(column_values))
|
||||||
)
|
)
|
||||||
|
|
||||||
def __call__(self, model):
|
def __call__(self, model):
|
||||||
res = self.header_fmt_str.format(ch=self.column_names)
|
res = self.header_fmt_str.format(ch=self.column_names)
|
||||||
for raw_row in model[self.table_prop_name]:
|
for raw_row in model[self.table_prop_name]:
|
||||||
row = [str(raw_row[prop_name]) for prop_name in self.column_values]
|
row = [six.text_type(raw_row[prop_name])
|
||||||
|
for prop_name in self.column_values]
|
||||||
# double format is in case we have roundoff error
|
# double format is in case we have roundoff error
|
||||||
res += '{0: <72}\n'.format(self.row_fmt_str.format(cv=row))
|
res += '{0: <72}\n'.format(self.row_fmt_str.format(cv=row))
|
||||||
|
|
||||||
|
@ -17,6 +17,8 @@
|
|||||||
This package defines several text views with headers
|
This package defines several text views with headers
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
import six
|
||||||
|
|
||||||
|
|
||||||
class HeaderView(object):
|
class HeaderView(object):
|
||||||
"""A Text View With a Header
|
"""A Text View With a Header
|
||||||
@ -31,7 +33,7 @@ class HeaderView(object):
|
|||||||
self.header = header
|
self.header = header
|
||||||
|
|
||||||
def __call__(self, model):
|
def __call__(self, model):
|
||||||
return str(self.header) + "\n" + str(model)
|
return six.text_type(self.header) + "\n" + six.text_type(model)
|
||||||
|
|
||||||
|
|
||||||
class TitledView(HeaderView):
|
class TitledView(HeaderView):
|
||||||
|
@ -75,7 +75,7 @@ class KeyValueView(object):
|
|||||||
elif ET.iselement(rootmodel):
|
elif ET.iselement(rootmodel):
|
||||||
res.append(rootmodel)
|
res.append(rootmodel)
|
||||||
else:
|
else:
|
||||||
res.text = str(rootmodel)
|
res.text = six.text_type(rootmodel)
|
||||||
|
|
||||||
return res
|
return res
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user