diff options
author | Julian Berman <Julian@GrayVines.com> | 2013-10-30 17:02:44 -0400 |
---|---|---|
committer | Julian Berman <Julian@GrayVines.com> | 2013-10-30 17:02:44 -0400 |
commit | c763ab974c36891e2b8bcb6a6c1ebb1dd84009b6 (patch) | |
tree | 114d7152eb2b89ac460fce35c93f4db822622b14 | |
parent | 699528300b90a5d3de79a69838d604ef6fdd9fea (diff) | |
download | jsonschema-c763ab974c36891e2b8bcb6a6c1ebb1dd84009b6.tar.gz |
Apply built-in formats only to strings, otherwise ignore.
-rw-r--r-- | jsonschema/_format.py | 45 | ||||
-rw-r--r-- | jsonschema/tests/test_exceptions.py | 4 | ||||
-rw-r--r-- | jsonschema/tests/test_validators.py | 22 | ||||
-rw-r--r-- | jsonschema/validators.py | 2 |
4 files changed, 61 insertions, 12 deletions
diff --git a/jsonschema/_format.py b/jsonschema/_format.py index 6460ded..2a9b5c1 100644 --- a/jsonschema/_format.py +++ b/jsonschema/_format.py @@ -2,6 +2,7 @@ import datetime import re import socket +from jsonschema.compat import str_types from jsonschema.exceptions import FormatError @@ -117,17 +118,23 @@ def _checks_drafts(both=None, draft3=None, draft4=None, raises=()): @_checks_drafts("email") def is_email(instance): + if not isinstance(instance, str_types): + return True return "@" in instance -_checks_drafts(draft3="ip-address", draft4="ipv4", raises=socket.error)( - socket.inet_aton -) +@_checks_drafts(draft3="ip-address", draft4="ipv4", raises=socket.error) +def is_ipv4(instance): + if not isinstance(instance, str_types): + return True + return socket.inet_aton(instance) if hasattr(socket, "inet_pton"): @_checks_drafts("ipv6", raises=socket.error) def is_ipv6(instance): + if not isinstance(instance, str_types): + return True return socket.inet_pton(socket.AF_INET6, instance) @@ -135,6 +142,8 @@ _host_name_re = re.compile(r"^[A-Za-z0-9][A-Za-z0-9\.\-]{1,255}$") @_checks_drafts(draft3="host-name", draft4="hostname") def is_host_name(instance): + if not isinstance(instance, str_types): + return True if not _host_name_re.match(instance): return False components = instance.split(".") @@ -151,6 +160,8 @@ except ImportError: else: @_checks_drafts("uri", raises=ValueError) def is_uri(instance): + if not isinstance(instance, str_types): + return True return rfc3987.parse(instance, rule="URI") @@ -162,22 +173,37 @@ except ImportError: except ImportError: pass else: - _err = (ValueError, isodate.ISO8601Error) - _checks_drafts("date-time", raises=_err)(isodate.parse_datetime) + @_checks_drafts("date-time", raises=(ValueError, isodate.ISO8601Error)) + def is_date(instance): + if not isinstance(instance, str_types): + return True + return isodate.parse_datetime(instance) else: - _checks_drafts("date-time")(strict_rfc3339.validate_rfc3339) + @_checks_drafts("date-time") + def is_date(instance): + if not isinstance(instance, str_types): + return True + return strict_rfc3339.validate_rfc3339(instance) -_checks_drafts("regex", raises=re.error)(re.compile) +@_checks_drafts("regex", raises=re.error) +def is_regex(instance): + if not isinstance(instance, str_types): + return True + return re.compile(instance) @_checks_drafts(draft3="date", raises=ValueError) def is_date(instance): + if not isinstance(instance, str_types): + return True return datetime.datetime.strptime(instance, "%Y-%m-%d") @_checks_drafts(draft3="time", raises=ValueError) def is_time(instance): + if not isinstance(instance, str_types): + return True return datetime.datetime.strptime(instance, "%H:%M:%S") @@ -192,7 +218,10 @@ else: @_checks_drafts(draft3="color", raises=(ValueError, TypeError)) def is_css21_color(instance): - if instance.lower() in webcolors.css21_names_to_hex: + if ( + not isinstance(instance, str_types) or + instance.lower() in webcolors.css21_names_to_hex + ): return True return is_css_color_code(instance) diff --git a/jsonschema/tests/test_exceptions.py b/jsonschema/tests/test_exceptions.py index 0466596..ab4d1c6 100644 --- a/jsonschema/tests/test_exceptions.py +++ b/jsonschema/tests/test_exceptions.py @@ -1,7 +1,5 @@ -import mock - from jsonschema import Draft4Validator, exceptions -from jsonschema.tests.compat import unittest +from jsonschema.tests.compat import mock, unittest class TestBestMatch(unittest.TestCase): diff --git a/jsonschema/tests/test_validators.py b/jsonschema/tests/test_validators.py index bfc5871..ba78c42 100644 --- a/jsonschema/tests/test_validators.py +++ b/jsonschema/tests/test_validators.py @@ -602,6 +602,28 @@ class TestDraft4Validator(ValidatorTestMixin, unittest.TestCase): validator_class = Draft4Validator +class TestBuiltinFormats(unittest.TestCase): + """ + The built-in (specification-defined) formats do not raise type errors. + + If an instance or value is not a string, it should be ignored. + + """ + + +for format in FormatChecker.checkers: + def test(self, format=format): + v = Draft4Validator({"format": format}, format_checker=FormatChecker()) + v.validate(123) + + name = "test_{0}_ignores_non_strings".format(format) + if not PY3: + name = name.encode("utf-8") + test.__name__ = name + setattr(TestBuiltinFormats, name, test) + del test # Ugh py.test. Stop discovering top level tests. + + class TestValidatorFor(unittest.TestCase): def test_draft_3(self): schema = {"$schema" : "http://json-schema.org/draft-03/schema"} diff --git a/jsonschema/validators.py b/jsonschema/validators.py index fab8201..2ee202c 100644 --- a/jsonschema/validators.py +++ b/jsonschema/validators.py @@ -14,7 +14,7 @@ from jsonschema.compat import ( PY3, Sequence, urljoin, urlsplit, urldefrag, unquote, urlopen, str_types, int_types, iteritems, ) -from jsonschema.exceptions import ErrorTree # For backwards compatibility +from jsonschema.exceptions import ErrorTree # Backwards compatibility # noqa from jsonschema.exceptions import RefResolutionError, SchemaError, UnknownType |