Don't mix unicode and bytes when loading schemas.

Get rid of stupid from __future__ import unicode_literals in places, which was
causing these to be unicode.
This commit is contained in:
Julian Berman
2013-12-01 19:52:36 -05:00
parent 3de5b177c7
commit bbbc8f8c22
3 changed files with 107 additions and 113 deletions

View File

@@ -53,13 +53,12 @@ def load_schema(name):
Load a schema from ./schemas/``name``.json and return it.
"""
schemadir = os.path.join(
os.path.dirname(os.path.abspath(__file__)),
'schemas'
schema_dir = os.path.join(
os.path.dirname(os.path.abspath(__file__)), "schemas",
)
schemapath = os.path.join(schemadir, '%s.json' % (name,))
with open(schemapath) as f:
return json.load(f)
with open(os.path.join(schema_dir, name + ".json")) as schema_file:
return json.load(schema_file)
def indent(string, times=1):

View File

@@ -1,4 +1,3 @@
from __future__ import unicode_literals
import contextlib
import json
import pprint
@@ -15,10 +14,10 @@ from jsonschema.validators import (
class TestCreateAndExtend(unittest.TestCase):
def setUp(self):
self.meta_schema = {"properties" : {"smelly" : {}}}
self.meta_schema = {u"properties" : {u"smelly" : {}}}
self.smelly = mock.MagicMock()
self.validators = {"smelly" : self.smelly}
self.types = {"dict" : dict}
self.validators = {u"smelly" : self.smelly}
self.types = {u"dict" : dict}
self.Validator = create(
meta_schema=self.meta_schema,
validators=self.validators,
@@ -26,7 +25,7 @@ class TestCreateAndExtend(unittest.TestCase):
)
self.validator_value = 12
self.schema = {"smelly" : self.validator_value}
self.schema = {u"smelly" : self.validator_value}
self.validator = self.Validator(self.schema)
def test_attrs(self):
@@ -54,24 +53,24 @@ class TestCreateAndExtend(unittest.TestCase):
def test_if_a_version_is_provided_it_is_registered(self):
with mock.patch("jsonschema.validators.validates") as validates:
validates.side_effect = lambda version : lambda cls : cls
Validator = create(meta_schema={"id" : "id"}, version="my version")
Validator = create(meta_schema={u"id" : ""}, version="my version")
validates.assert_called_once_with("my version")
self.assertEqual(Validator.__name__, "MyVersionValidator")
def test_if_a_version_is_not_provided_it_is_not_registered(self):
with mock.patch("jsonschema.validators.validates") as validates:
create(meta_schema={"id" : "id"})
create(meta_schema={u"id" : "id"})
self.assertFalse(validates.called)
def test_extend(self):
validators = dict(self.Validator.VALIDATORS)
new = mock.Mock()
Extended = extend(self.Validator, validators={"a new one" : new})
Extended = extend(self.Validator, validators={u"a new one" : new})
validators.update([("a new one", new)])
validators.update([(u"a new one", new)])
self.assertEqual(Extended.VALIDATORS, validators)
self.assertNotIn("a new one", self.Validator.VALIDATORS)
self.assertNotIn(u"a new one", self.Validator.VALIDATORS)
self.assertEqual(Extended.META_SCHEMA, self.Validator.META_SCHEMA)
self.assertEqual(Extended.DEFAULT_TYPES, self.Validator.DEFAULT_TYPES)
@@ -84,9 +83,9 @@ class TestIterErrors(unittest.TestCase):
def test_iter_errors(self):
instance = [1, 2]
schema = {
"disallow" : "array",
"enum" : [["a", "b", "c"], ["d", "e", "f"]],
"minItems" : 3
u"disallow" : u"array",
u"enum" : [["a", "b", "c"], ["d", "e", "f"]],
u"minItems" : 3
}
got = (e.message for e in self.validator.iter_errors(instance, schema))
@@ -100,10 +99,10 @@ class TestIterErrors(unittest.TestCase):
def test_iter_errors_multiple_failures_one_validator(self):
instance = {"foo" : 2, "bar" : [1], "baz" : 15, "quux" : "spam"}
schema = {
"properties" : {
"foo" : {"type" : "string"},
"bar" : {"minItems" : 2},
"baz" : {"maximum" : 10, "enum" : [2, 4, 6, 8]},
u"properties" : {
"foo" : {u"type" : "string"},
"bar" : {u"minItems" : 2},
"baz" : {u"maximum" : 10, u"enum" : [2, 4, 6, 8]},
}
}
@@ -119,55 +118,55 @@ class TestValidationErrorMessages(unittest.TestCase):
return e.exception.message
def test_single_type_failure(self):
message = self.message_for(instance=1, schema={"type" : "string"})
self.assertEqual(message, "1 is not of type %r" % "string")
message = self.message_for(instance=1, schema={u"type" : u"string"})
self.assertEqual(message, "1 is not of type %r" % u"string")
def test_single_type_list_failure(self):
message = self.message_for(instance=1, schema={"type" : ["string"]})
self.assertEqual(message, "1 is not of type %r" % "string")
message = self.message_for(instance=1, schema={u"type" : [u"string"]})
self.assertEqual(message, "1 is not of type %r" % u"string")
def test_multiple_type_failure(self):
types = ("string", "object")
message = self.message_for(instance=1, schema={"type" : list(types)})
types = u"string", u"object"
message = self.message_for(instance=1, schema={u"type" : list(types)})
self.assertEqual(message, "1 is not of type %r, %r" % types)
def test_object_without_title_type_failure(self):
type = {"type" : [{"minimum" : 3}]}
message = self.message_for(instance=1, schema={"type" : [type]})
type = {u"type" : [{u"minimum" : 3}]}
message = self.message_for(instance=1, schema={u"type" : [type]})
self.assertEqual(message, "1 is not of type %r" % (type,))
def test_object_with_name_type_failure(self):
name = "Foo"
schema = {"type" : [{"name" : name, "minimum" : 3}]}
schema = {u"type" : [{u"name" : name, u"minimum" : 3}]}
message = self.message_for(instance=1, schema=schema)
self.assertEqual(message, "1 is not of type %r" % (name,))
def test_dependencies_failure_has_single_element_not_list(self):
depend, on = "bar", "foo"
schema = {"dependencies" : {depend : on}}
schema = {u"dependencies" : {depend : on}}
message = self.message_for({"bar" : 2}, schema)
self.assertEqual(message, "%r is a dependency of %r" % (on, depend))
def test_additionalItems_single_failure(self):
message = self.message_for(
[2], {"items" : [], "additionalItems" : False},
[2], {u"items" : [], u"additionalItems" : False},
)
self.assertIn("(2 was unexpected)", message)
def test_additionalItems_multiple_failures(self):
message = self.message_for(
[1, 2, 3], {"items" : [], "additionalItems" : False}
[1, 2, 3], {u"items" : [], u"additionalItems" : False}
)
self.assertIn("(1, 2, 3 were unexpected)", message)
def test_additionalProperties_single_failure(self):
additional = "foo"
schema = {"additionalProperties" : False}
schema = {u"additionalProperties" : False}
message = self.message_for({additional : 2}, schema)
self.assertIn("(%r was unexpected)" % (additional,), message)
def test_additionalProperties_multiple_failures(self):
schema = {"additionalProperties" : False}
schema = {u"additionalProperties" : False}
message = self.message_for(dict.fromkeys(["foo", "bar"]), schema)
self.assertIn(repr("foo"), message)
@@ -177,9 +176,9 @@ class TestValidationErrorMessages(unittest.TestCase):
def test_invalid_format_default_message(self):
checker = FormatChecker(formats=())
check_fn = mock.Mock(return_value=False)
checker.checks("thing")(check_fn)
checker.checks(u"thing")(check_fn)
schema = {"format" : "thing"}
schema = {u"format" : u"thing"}
message = self.message_for("bla", schema, format_checker=checker)
self.assertIn(repr("bla"), message)
@@ -194,10 +193,10 @@ class TestErrorReprStr(unittest.TestCase):
def setUp(self):
self.error = ValidationError(
message=self.message,
validator="type",
validator_value="string",
validator=u"type",
validator_value=u"string",
instance=5,
schema={"type" : "string"},
schema={u"type" : u"string"},
)
def assertShows(self, message):
@@ -258,8 +257,8 @@ class TestErrorReprStr(unittest.TestCase):
)
def test_multiple_item_paths(self):
self.error.path = [0, "a"]
self.error.schema_path = ["items", 0, 1]
self.error.path = [0, u"a"]
self.error.schema_path = [u"items", 0, 1]
self.assertShows(
"""
Failed validating u'type' in schema[u'items'][0]:

View File

@@ -1,4 +1,4 @@
from __future__ import division, unicode_literals
from __future__ import division
import contextlib
import json
@@ -38,8 +38,8 @@ def validates(version):
def _validates(cls):
validators[version] = cls
if "id" in cls.META_SCHEMA:
meta_schemas[cls.META_SCHEMA["id"]] = cls
if u"id" in cls.META_SCHEMA:
meta_schemas[cls.META_SCHEMA[u"id"]] = cls
return cls
return _validates
@@ -47,9 +47,9 @@ def validates(version):
def create(meta_schema, validators=(), version=None, default_types=None): # noqa
if default_types is None:
default_types = {
"array" : list, "boolean" : bool, "integer" : int_types,
"null" : type(None), "number" : numbers.Number, "object" : dict,
"string" : str_types,
u"array" : list, u"boolean" : bool, u"integer" : int_types,
u"null" : type(None), u"number" : numbers.Number, u"object" : dict,
u"string" : str_types,
}
class Validator(object):
@@ -79,10 +79,10 @@ def create(meta_schema, validators=(), version=None, default_types=None): # noq
if _schema is None:
_schema = self.schema
with self.resolver.in_scope(_schema.get("id", "")):
ref = _schema.get("$ref")
with self.resolver.in_scope(_schema.get(u"id", u"")):
ref = _schema.get(u"$ref")
if ref is not None:
validators = [("$ref", ref)]
validators = [(u"$ref", ref)]
else:
validators = iteritems(_schema)
@@ -100,7 +100,7 @@ def create(meta_schema, validators=(), version=None, default_types=None): # noq
instance=instance,
schema=_schema,
)
if k != "$ref":
if k != u"$ref":
error.schema_path.appendleft(k)
yield error
@@ -137,11 +137,7 @@ def create(meta_schema, validators=(), version=None, default_types=None): # noq
if version is not None:
Validator = validates(version)(Validator)
name = "{0}Validator".format(version.title().replace(" ", ""))
if not PY3 and isinstance(name, unicode):
name = name.encode("utf-8")
Validator.__name__ = name
Validator.__name__ = version.title().replace(" ", "") + "Validator"
return Validator
@@ -160,28 +156,28 @@ def extend(validator, validators, version=None):
Draft3Validator = create(
meta_schema=_utils.load_schema("draft3"),
validators={
"$ref" : _validators.ref,
"additionalItems" : _validators.additionalItems,
"additionalProperties" : _validators.additionalProperties,
"dependencies" : _validators.dependencies,
"disallow" : _validators.disallow_draft3,
"divisibleBy" : _validators.multipleOf,
"enum" : _validators.enum,
"extends" : _validators.extends_draft3,
"format" : _validators.format,
"items" : _validators.items,
"maxItems" : _validators.maxItems,
"maxLength" : _validators.maxLength,
"maximum" : _validators.maximum,
"minItems" : _validators.minItems,
"minLength" : _validators.minLength,
"minimum" : _validators.minimum,
"multipleOf" : _validators.multipleOf,
"pattern" : _validators.pattern,
"patternProperties" : _validators.patternProperties,
"properties" : _validators.properties_draft3,
"type" : _validators.type_draft3,
"uniqueItems" : _validators.uniqueItems,
u"$ref" : _validators.ref,
u"additionalItems" : _validators.additionalItems,
u"additionalProperties" : _validators.additionalProperties,
u"dependencies" : _validators.dependencies,
u"disallow" : _validators.disallow_draft3,
u"divisibleBy" : _validators.multipleOf,
u"enum" : _validators.enum,
u"extends" : _validators.extends_draft3,
u"format" : _validators.format,
u"items" : _validators.items,
u"maxItems" : _validators.maxItems,
u"maxLength" : _validators.maxLength,
u"maximum" : _validators.maximum,
u"minItems" : _validators.minItems,
u"minLength" : _validators.minLength,
u"minimum" : _validators.minimum,
u"multipleOf" : _validators.multipleOf,
u"pattern" : _validators.pattern,
u"patternProperties" : _validators.patternProperties,
u"properties" : _validators.properties_draft3,
u"type" : _validators.type_draft3,
u"uniqueItems" : _validators.uniqueItems,
},
version="draft3",
)
@@ -189,32 +185,32 @@ Draft3Validator = create(
Draft4Validator = create(
meta_schema=_utils.load_schema("draft4"),
validators={
"$ref" : _validators.ref,
"additionalItems" : _validators.additionalItems,
"additionalProperties" : _validators.additionalProperties,
"allOf" : _validators.allOf_draft4,
"anyOf" : _validators.anyOf_draft4,
"dependencies" : _validators.dependencies,
"enum" : _validators.enum,
"format" : _validators.format,
"items" : _validators.items,
"maxItems" : _validators.maxItems,
"maxLength" : _validators.maxLength,
"maxProperties" : _validators.maxProperties_draft4,
"maximum" : _validators.maximum,
"minItems" : _validators.minItems,
"minLength" : _validators.minLength,
"minProperties" : _validators.minProperties_draft4,
"minimum" : _validators.minimum,
"multipleOf" : _validators.multipleOf,
"not" : _validators.not_draft4,
"oneOf" : _validators.oneOf_draft4,
"pattern" : _validators.pattern,
"patternProperties" : _validators.patternProperties,
"properties" : _validators.properties_draft4,
"required" : _validators.required_draft4,
"type" : _validators.type_draft4,
"uniqueItems" : _validators.uniqueItems,
u"$ref" : _validators.ref,
u"additionalItems" : _validators.additionalItems,
u"additionalProperties" : _validators.additionalProperties,
u"allOf" : _validators.allOf_draft4,
u"anyOf" : _validators.anyOf_draft4,
u"dependencies" : _validators.dependencies,
u"enum" : _validators.enum,
u"format" : _validators.format,
u"items" : _validators.items,
u"maxItems" : _validators.maxItems,
u"maxLength" : _validators.maxLength,
u"maxProperties" : _validators.maxProperties_draft4,
u"maximum" : _validators.maximum,
u"minItems" : _validators.minItems,
u"minLength" : _validators.minLength,
u"minProperties" : _validators.minProperties_draft4,
u"minimum" : _validators.minimum,
u"multipleOf" : _validators.multipleOf,
u"not" : _validators.not_draft4,
u"oneOf" : _validators.oneOf_draft4,
u"pattern" : _validators.pattern,
u"patternProperties" : _validators.patternProperties,
u"properties" : _validators.properties_draft4,
u"required" : _validators.required_draft4,
u"type" : _validators.type_draft4,
u"uniqueItems" : _validators.uniqueItems,
},
version="draft4",
)
@@ -261,7 +257,7 @@ class RefResolver(object):
"""
return cls(schema.get("id", ""), schema, *args, **kwargs)
return cls(schema.get(u"id", u""), schema, *args, **kwargs)
@contextlib.contextmanager
def in_scope(self, scope):
@@ -311,11 +307,11 @@ class RefResolver(object):
"""
fragment = fragment.lstrip("/")
parts = unquote(fragment).split("/") if fragment else []
fragment = fragment.lstrip(u"/")
parts = unquote(fragment).split(u"/") if fragment else []
for part in parts:
part = part.replace("~1", "/").replace("~0", "~")
part = part.replace(u"~1", u"/").replace(u"~0", u"~")
if isinstance(document, Sequence):
# Array indexes should be turned into integers
@@ -360,7 +356,7 @@ class RefResolver(object):
if scheme in self.handlers:
result = self.handlers[scheme](uri)
elif (
scheme in ["http", "https"] and
scheme in [u"http", u"https"] and
requests and
getattr(requests.Response, "json", None) is not None
):
@@ -382,7 +378,7 @@ class RefResolver(object):
def validator_for(schema, default=_unset):
if default is _unset:
default = Draft4Validator
return meta_schemas.get(schema.get("$schema", ""), default)
return meta_schemas.get(schema.get(u"$schema", u""), default)
def validate(instance, schema, cls=None, *args, **kwargs):