Skip to content

Commit

Permalink
Added JSONDecodeError for rapidjson >= 0.7.1 with fallback to ValueEr…
Browse files Browse the repository at this point in the history
…ror. (#199)

* Added JSONDecodeError for rapidjson >= 0.7.1 with fallback to ValueError.

* Fix Python 2 and add comments.

* Update rapidjson on CircleCI.

* Add test for parsing invalid JSON.

* Use redirect_stderr from signac-flow.
  • Loading branch information
bdice authored and csadorf committed Jul 3, 2019
1 parent 01fc155 commit 48ab755
Show file tree
Hide file tree
Showing 4 changed files with 48 additions and 4 deletions.
2 changes: 1 addition & 1 deletion .circleci/config.yml
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@ jobs:
command: |
. venv/bin/activate
coverage run -m unittest discover tests/ -v
pip install python-rapidjson==0.7 && coverage run -m unittest discover tests/ -v
pip install python-rapidjson==0.7.1 && coverage run -m unittest discover tests/ -v
coverage report -i
codecov
Expand Down
2 changes: 1 addition & 1 deletion signac/contrib/filterparse.py
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ def _is_regex(q):
def _parse_json(q):
try:
return json.loads(q)
except json.decoder.JSONDecodeError:
except json.JSONDecodeError:
_print_err("Failed to parse query argument. "
"Ensure that '{}' is valid JSON!".format(q))
raise
Expand Down
13 changes: 12 additions & 1 deletion signac/core/json.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,12 @@
try:
import rapidjson as json
from rapidjson import Encoder
try:
# Defined for rapidjson >= 0.7.1
from rapidjson import JSONDecodeError
except ImportError:
# rapidjson < 0.7.1 raises a ValueError
JSONDecodeError = ValueError

class JSONEncoder(Encoder):
encode = Encoder.__call__
Expand All @@ -24,6 +30,11 @@ class JSONEncoder(Encoder):
except ImportError:
import json
from json import JSONEncoder
try:
from json.decoder import JSONDecodeError
except ImportError:
# JSONDecodeError doesn't exist for Python 2
JSONDecodeError = ValueError

logger.debug(msg.format('json'))

Expand Down Expand Up @@ -63,4 +74,4 @@ def dumps(o, sort_keys=False, indent=None):
return CustomJSONEncoder(sort_keys=sort_keys, indent=indent).encode(o)


__all__ = ['loads', 'dumps']
__all__ = ['loads', 'dumps', 'JSONDecodeError']
35 changes: 34 additions & 1 deletion tests/test_find_command_line_interface.py
Original file line number Diff line number Diff line change
@@ -1,12 +1,17 @@
# Copyright (c) 2017 The Regents of the University of Michigan
# Copyright (c) 2019 The Regents of the University of Michigan
# All rights reserved.
# This software is licensed under the BSD 3-Clause License.
import io
import os
import sys
import json
import unittest
from itertools import chain
from contextlib import contextmanager

from signac.common import six
from signac.contrib.filterparse import parse_filter_arg
from signac.core.json import JSONDecodeError

FILTERS = [
{'a': 0},
Expand Down Expand Up @@ -65,6 +70,29 @@
]


class StringIO(io.StringIO):
"PY27 compatibility layer."

def write(self, s):
if six.PY2:
super(StringIO, self).write(unicode(s)) # noqa
else:
super(StringIO, self).write(s)


@contextmanager
def redirect_stderr(new_target=None):
"Temporarily redirect all output to stderr to new_target."
if new_target is None:
new_target = StringIO()
old_target = sys.stderr
try:
sys.stderr = new_target
yield
finally:
sys.stderr = old_target


class FindCommandLineInterfaceTest(unittest.TestCase):

@staticmethod
Expand Down Expand Up @@ -92,6 +120,11 @@ def test_interpret_mixed_key_value(self):
for expr in chain(ARITHMETIC_EXPRESSIONS, ARRAY_EXPRESSIONS):
self.assertEqual(self._parse(['a', json.dumps(expr)]), {'a': expr})

def test_invalid_json(self):
with redirect_stderr():
with self.assertRaises(JSONDecodeError):
parse_filter_arg(['{"x": True}'])


if __name__ == '__main__':
unittest.main()

0 comments on commit 48ab755

Please sign in to comment.