Skip to content

Commit

Permalink
Merge pull request oracc#80 from rillian/json
Browse files Browse the repository at this point in the history
json serialization
  • Loading branch information
ageorgou authored Jun 7, 2019
2 parents 39c612f + 17aa9c3 commit c32960b
Show file tree
Hide file tree
Showing 2 changed files with 56 additions and 0 deletions.
28 changes: 28 additions & 0 deletions pyoracc/atf/common/atffile.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,8 @@
import codecs
import sys
import logging
import json
from numbers import Number

from pyoracc.atf.cdli.atflex import AtfCDLILexer
from pyoracc.atf.cdli.atfyacc import AtfCDLIParser
Expand Down Expand Up @@ -72,6 +74,32 @@ def __str__(self):
def serialize(self):
return AtfFile.template.render_unicode(**vars(self))

def to_json(self, skip_empty=True, **kwargs):
'''Return a JSON representation of the parsed file.
The optional skip_empty argument determines whether keys
with empty values are included in the output. Set it to
False to see all possible object members.
Otherwise it accepts the same optional arguments as
json.dumps().'''
def _make_serializable(obj):
'''Construct a dict representation of an object.
This is necessary to handle our custom objects
which json.JSONEncoder doesn't know how to
serialize.'''

return {k: v
for k, v in vars(obj).items()
if not str(k).startswith('_') and not (
skip_empty and not v and not isinstance(v, Number)
)}

kwargs.setdefault('indent', 2)
kwargs.setdefault('default', _make_serializable)
return json.dumps(self.text, **kwargs)


def check_atf(infile, atftype, verbose=False):
content = codecs.open(infile,
Expand Down
28 changes: 28 additions & 0 deletions pyoracc/test/atf/test_atffile.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
from pyoracc.atf.common.atffile import AtfFile
from ..fixtures import anzu, belsunu, sample_file
import pytest
import json


def test_create():
Expand Down Expand Up @@ -108,3 +109,30 @@ def test_text_designation(name, code, description):
afile = AtfFile(sample_file(name))
assert afile.text.code == code
assert afile.text.description == description


# ATF filenames which fail the serialization tests.
_xfail_texts = [
# Multilingual objects store the unmarked language
# under the `None` key in their `lines` dictionary,
# which is incompatible with `sort_keys=True`.
'bb_2_6',
]


@pytest.mark.parametrize('name', [
name if name not in _xfail_texts
else pytest.param(name, marks=[pytest.mark.xfail()])
for name in [text[0] for text in texts]])
def test_json_serialization(name):
"""
Parses ATF and verifies the to_json() method output.
"""
afile = AtfFile(sample_file(name))
js = afile.to_json()
result = json.loads(js)
assert result
noskipjs = afile.to_json(skip_empty=False, sort_keys=True)
result = json.loads(noskipjs)
assert result
assert len(noskipjs) >= len(js)

0 comments on commit c32960b

Please sign in to comment.