diff --git a/.travis.yml b/.travis.yml index 88b2cfd..4941809 100644 --- a/.travis.yml +++ b/.travis.yml @@ -6,4 +6,6 @@ python: - "3.4" - "3.5" - "nightly" + - "pypy" + - "pypy3" script: python setup.py test diff --git a/doc/installation.rst b/doc/installation.rst index e6f786d..3ee2003 100644 --- a/doc/installation.rst +++ b/doc/installation.rst @@ -6,7 +6,6 @@ Prerequisites This package has the following prerequisites: -* simplejson * versiontools To run the test suite you will also need: diff --git a/json_schema_validator/shortcuts.py b/json_schema_validator/shortcuts.py index a56e30c..ce9afe6 100644 --- a/json_schema_validator/shortcuts.py +++ b/json_schema_validator/shortcuts.py @@ -20,16 +20,22 @@ One liners that make the code shorter """ -import simplejson +try: + import simplejson as json +except ImportError: + import json from json_schema_validator.schema import Schema from json_schema_validator.validator import Validator +_default_deserializer = json.loads -def validate(schema_text, data_text): + +def validate(schema_text, data_text, deserializer=_default_deserializer): """ Validate specified JSON text (data_text) with specified schema (schema - text). Both are converted to JSON objects with :func:`simplesjon.loads`. + text). Both are converted to JSON objects with :func:`simplejson.loads` + if present or :func:`json.loads`. :param schema_text: Text of the JSON schema to check against @@ -39,11 +45,16 @@ def validate(schema_text, data_text): Text of the JSON object to check :type data_text: :class:`str` + :param deserializer: + Function to convert the schema and data to JSON objects + :type deserializer: + :class:`callable` :returns: Same as :meth:`json_schema_validator.validator.Validator.validate` :raises: Whatever may be raised by simplejson (in particular :class:`simplejson.decoder.JSONDecoderError`, a subclass of :class:`ValueError`) + or json :raises: Whatever may be raised by :meth:`json_schema_validator.validator.Validator.validate`. In particular @@ -52,6 +63,6 @@ def validate(schema_text, data_text): """ - schema = Schema(simplejson.loads(schema_text)) - data = simplejson.loads(data_text) + schema = Schema(deserializer(schema_text)) + data = deserializer(data_text) return Validator.validate(schema, data) diff --git a/json_schema_validator/tests/test_schema.py b/json_schema_validator/tests/test_schema.py index 14293fb..5c3a3b4 100644 --- a/json_schema_validator/tests/test_schema.py +++ b/json_schema_validator/tests/test_schema.py @@ -20,18 +20,24 @@ Unit tests for JSON schema """ +import json import sys -import simplejson - from testscenarios import TestWithScenarios from testtools import TestCase from json_schema_validator.errors import SchemaError from json_schema_validator.schema import Schema +PY2 = sys.version_info[0] == 2 PY35 = sys.version_info[0:2] >= (3, 5) +if PY2: + import yaml + deserializer = yaml.safe_load +else: + deserializer = json.loads + class SchemaTests(TestWithScenarios, TestCase): @@ -775,7 +781,12 @@ class SchemaTests(TestWithScenarios, TestCase): ] def test_schema_attribute(self): - schema = Schema(simplejson.loads(self.schema)) + if deserializer != json.loads: + # Always check the serialised JSON using the native JSON loader + # so that any error messages are consistent and appropriate. + json.loads(self.schema) + + schema = Schema(deserializer(self.schema)) if hasattr(self, 'expected'): for attr, expected_value in self.expected.items(): self.assertEqual( diff --git a/json_schema_validator/tests/test_validator.py b/json_schema_validator/tests/test_validator.py index 3f8df59..aab3ead 100644 --- a/json_schema_validator/tests/test_validator.py +++ b/json_schema_validator/tests/test_validator.py @@ -20,6 +20,8 @@ Unit tests for JSON schema """ +import functools +import json import sys from testscenarios import TestWithScenarios @@ -30,6 +32,16 @@ from json_schema_validator.validator import Validator PY2 = sys.version_info[0] == 2 +if PY2: + import yaml + + def deserializer(json_string): + # Always check the serialised JSON using the native JSON loader + # so that any error messages are consistent and appropriate. + json.loads(json_string) + return yaml.safe_load(json_string) + + validate = functools.partial(validate, deserializer=deserializer) class ValidatorFailureTests(TestWithScenarios, TestCase): @@ -111,7 +123,6 @@ class ValidatorFailureTests(TestWithScenarios, TestCase): 'schema': '{"type": "boolean"}', 'data': '""', 'raises': ValidationError( - ('u' if PY2 else '') + "'' does not match type 'boolean'", "Object has incorrect type (expected boolean)"), 'object_expr': 'object', @@ -175,7 +186,6 @@ class ValidatorFailureTests(TestWithScenarios, TestCase): 'schema': '{"type": "null"}', 'data': '""', 'raises': ValidationError( - ('u' if PY2 else '') + "'' does not match type 'null'", "Object has incorrect type (expected null)"), 'object_expr': 'object', diff --git a/setup.py b/setup.py index abac3b7..52cbbfa 100755 --- a/setup.py +++ b/setup.py @@ -19,8 +19,17 @@ # You should have received a copy of the GNU Lesser General Public License # along with json-schema-validator. If not, see . +import sys + from setuptools import setup, find_packages +test_dependencies = [ + 'testscenarios >= 0.1', + 'testtools >= 0.9.2' +] + +if sys.version_info[0] == 2: + test_dependencies.append('PyYaml') setup( name='json-schema-validator', @@ -40,12 +49,10 @@ "Programming Language :: Python :: 2.6", "Programming Language :: Python :: 2.7", "Programming Language :: Python :: 3", + "Programming Language :: Python :: Implementation :: CPython", + "Programming Language :: Python :: Implementation :: PyPy", ], - install_requires=[ - 'simplejson >= 2.0.9'], setup_requires=[ 'versiontools >= 1.3.1'], - tests_require=[ - 'testscenarios >= 0.1', - 'testtools >= 0.9.2'], + tests_require=test_dependencies, zip_safe=True) diff --git a/tox.ini b/tox.ini index de33c2b..d12f43a 100644 --- a/tox.ini +++ b/tox.ini @@ -7,7 +7,7 @@ commands= sphinx-build -b doctest doc html sphinx-build doc html deps= - simplejson + PyYAML sphinx testscenarios testtools