Skip to content

Commit

Permalink
Make use of simplejson optional
Browse files Browse the repository at this point in the history
simplejson doesnt provide any benefits on Python 3, and
isnt consistent on Python 2 between CPython and PyPy.
Use the standard library json if simplejson is not installed.

Use PyYaml for tests on Python 2 as it puts strings into str
on Python 2 whereas json uses type unicode, causing many test
failures due to u'..' prefix in error messages.

Add PyPy to build and support matrix.
  • Loading branch information
jayvdb committed Feb 5, 2016
1 parent 4bf5425 commit b4c14e2
Show file tree
Hide file tree
Showing 7 changed files with 57 additions and 17 deletions.
2 changes: 2 additions & 0 deletions .travis.yml
Expand Up @@ -6,4 +6,6 @@ python:
- "3.4"
- "3.5"
- "nightly"
- "pypy"
- "pypy3"
script: python setup.py test
1 change: 0 additions & 1 deletion doc/installation.rst
Expand Up @@ -6,7 +6,6 @@ Prerequisites

This package has the following prerequisites:

* simplejson
* versiontools

To run the test suite you will also need:
Expand Down
21 changes: 16 additions & 5 deletions json_schema_validator/shortcuts.py
Expand Up @@ -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
Expand All @@ -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
Expand All @@ -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)
17 changes: 14 additions & 3 deletions json_schema_validator/tests/test_schema.py
Expand Up @@ -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):

Expand Down Expand Up @@ -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(
Expand Down
14 changes: 12 additions & 2 deletions json_schema_validator/tests/test_validator.py
Expand Up @@ -20,6 +20,8 @@
Unit tests for JSON schema
"""

import functools
import json
import sys

from testscenarios import TestWithScenarios
Expand All @@ -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):
Expand Down Expand Up @@ -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',
Expand Down Expand Up @@ -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',
Expand Down
17 changes: 12 additions & 5 deletions setup.py
Expand Up @@ -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 <http://www.gnu.org/licenses/>.

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',
Expand All @@ -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)
2 changes: 1 addition & 1 deletion tox.ini
Expand Up @@ -7,7 +7,7 @@ commands=
sphinx-build -b doctest doc html
sphinx-build doc html
deps=
simplejson
PyYAML
sphinx
testscenarios
testtools
Expand Down

0 comments on commit b4c14e2

Please sign in to comment.