diff --git a/jsonschema/_utils.py b/jsonschema/_utils.py index 2262f3305..c4472332b 100644 --- a/jsonschema/_utils.py +++ b/jsonschema/_utils.py @@ -2,10 +2,17 @@ import json import pkgutil import re +import sys from jsonschema.compat import str_types, MutableMapping, urlsplit +if sys.version_info[0] == 3: + STRING_TYPES = str +else: + STRING_TYPES = (str, unicode) + + class URIDict(MutableMapping): """ Dictionary which uses normalized URIs as keys. @@ -97,7 +104,7 @@ def find_additional_properties(instance, schema): patterns = "|".join(schema.get("patternProperties", {})) for property in instance: if property not in properties: - if patterns and re.search(patterns, property): + if isinstance(property, STRING_TYPES) and patterns and re.search(patterns, property): continue yield property diff --git a/jsonschema/_validators.py b/jsonschema/_validators.py index c6e801ccb..5eed8a564 100644 --- a/jsonschema/_validators.py +++ b/jsonschema/_validators.py @@ -1,6 +1,7 @@ import re from jsonschema import _utils +from jsonschema._utils import STRING_TYPES from jsonschema.exceptions import FormatError, ValidationError from jsonschema.compat import iteritems @@ -14,7 +15,7 @@ def patternProperties(validator, patternProperties, instance, schema): for pattern, subschema in iteritems(patternProperties): for k, v in iteritems(instance): - if re.search(pattern, k): + if isinstance(k, STRING_TYPES) and re.search(pattern, k): for error in validator.descend( v, subschema, path=k, schema_path=pattern, ): diff --git a/jsonschema/tests/test_validators.py b/jsonschema/tests/test_validators.py index f8692388e..b877585ca 100644 --- a/jsonschema/tests/test_validators.py +++ b/jsonschema/tests/test_validators.py @@ -777,6 +777,26 @@ def test_if_you_give_it_junk_you_get_a_resolution_error(self): self.assertEqual(str(err.exception), "Oh no! What's this?") +class TestSimpleBug(unittest.TestCase): + def test_non_string_object_key(self): + schema = { + "type": "object", + "patternProperties": { + ".*": { + "type": "string", + }, + }, + "additionalProperties": False, + } + + obj = { + 42: True, + } + + with self.assertRaises(ValidationError): + validate(obj, schema) + + def sorted_errors(errors): def key(error): return (