Merge "Handle complex objects in yaml formatter better"
This commit is contained in:
commit
3ee0725a09
cliff
@ -17,6 +17,17 @@ from . import base
|
||||
from cliff import columns
|
||||
|
||||
|
||||
def _yaml_friendly(value):
|
||||
if isinstance(value, columns.FormattableColumn):
|
||||
return value.machine_readable()
|
||||
elif hasattr(value, "toDict"):
|
||||
return value.toDict()
|
||||
elif hasattr(value, "to_dict"):
|
||||
return value.to_dict()
|
||||
else:
|
||||
return value
|
||||
|
||||
|
||||
class YAMLFormatter(base.ListFormatter, base.SingleFormatter):
|
||||
|
||||
def add_argument_group(self, parser):
|
||||
@ -29,10 +40,7 @@ class YAMLFormatter(base.ListFormatter, base.SingleFormatter):
|
||||
items = []
|
||||
for item in data:
|
||||
items.append(
|
||||
{n: (i.machine_readable()
|
||||
if isinstance(i, columns.FormattableColumn)
|
||||
else i)
|
||||
for n, i in zip(column_names, item)}
|
||||
{n: _yaml_friendly(i) for n, i in zip(column_names, item)}
|
||||
)
|
||||
yaml.safe_dump(items, stream=stdout, default_flow_style=False)
|
||||
|
||||
@ -41,9 +49,5 @@ class YAMLFormatter(base.ListFormatter, base.SingleFormatter):
|
||||
import yaml
|
||||
|
||||
for key, value in zip(column_names, data):
|
||||
dict_data = {
|
||||
key: (value.machine_readable()
|
||||
if isinstance(value, columns.FormattableColumn)
|
||||
else value)
|
||||
}
|
||||
dict_data = {key: _yaml_friendly(value)}
|
||||
yaml.safe_dump(dict_data, stream=stdout, default_flow_style=False)
|
||||
|
@ -22,6 +22,23 @@ from cliff.tests import base
|
||||
from cliff.tests import test_columns
|
||||
|
||||
|
||||
class _toDict:
|
||||
|
||||
def __init__(self, **kwargs):
|
||||
self._data = kwargs
|
||||
|
||||
def toDict(self):
|
||||
return self._data
|
||||
|
||||
|
||||
class _to_Dict:
|
||||
def __init__(self, **kwargs):
|
||||
self._data = kwargs
|
||||
|
||||
def to_dict(self):
|
||||
return self._data
|
||||
|
||||
|
||||
class TestYAMLFormatter(base.TestBase):
|
||||
|
||||
def test_format_one(self):
|
||||
@ -98,3 +115,39 @@ class TestYAMLFormatter(base.TestBase):
|
||||
sf.emit_list(c, d, output, args)
|
||||
actual = yaml.safe_load(output.getvalue())
|
||||
self.assertEqual(expected, actual)
|
||||
|
||||
def test_one_custom_object(self):
|
||||
sf = yaml_format.YAMLFormatter()
|
||||
c = ('a', 'b', 'toDict', 'to_dict')
|
||||
d = ('A', 'B', _toDict(spam="ham"), _to_Dict(ham="eggs"))
|
||||
expected = {
|
||||
'a': 'A',
|
||||
'b': 'B',
|
||||
'toDict': {"spam": "ham"},
|
||||
'to_dict': {"ham": "eggs"}
|
||||
}
|
||||
output = StringIO()
|
||||
args = mock.Mock()
|
||||
sf.emit_one(c, d, output, args)
|
||||
actual = yaml.safe_load(output.getvalue())
|
||||
self.assertEqual(expected, actual)
|
||||
|
||||
def test_list_custom_object(self):
|
||||
sf = yaml_format.YAMLFormatter()
|
||||
c = ('a', 'toDict', 'to_dict')
|
||||
d = (
|
||||
('A1', _toDict(B=1), _to_Dict(C=1)),
|
||||
('A2', _toDict(B=2), _to_Dict(C=2)),
|
||||
('A3', _toDict(B=3), _to_Dict(C=3))
|
||||
)
|
||||
expected = [
|
||||
{'a': 'A1', 'toDict': {'B': 1}, 'to_dict': {'C': 1}},
|
||||
{'a': 'A2', 'toDict': {'B': 2}, 'to_dict': {'C': 2}},
|
||||
{'a': 'A3', 'toDict': {'B': 3}, 'to_dict': {'C': 3}}
|
||||
]
|
||||
output = StringIO()
|
||||
args = mock.Mock()
|
||||
sf.add_argument_group(args)
|
||||
sf.emit_list(c, d, output, args)
|
||||
actual = yaml.safe_load(output.getvalue())
|
||||
self.assertEqual(expected, actual)
|
||||
|
Loading…
x
Reference in New Issue
Block a user