summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJulian Berman <Julian@GrayVines.com>2013-10-30 17:02:44 -0400
committerJulian Berman <Julian@GrayVines.com>2013-10-30 17:02:44 -0400
commitc763ab974c36891e2b8bcb6a6c1ebb1dd84009b6 (patch)
tree114d7152eb2b89ac460fce35c93f4db822622b14
parent699528300b90a5d3de79a69838d604ef6fdd9fea (diff)
downloadjsonschema-c763ab974c36891e2b8bcb6a6c1ebb1dd84009b6.tar.gz
Apply built-in formats only to strings, otherwise ignore.
-rw-r--r--jsonschema/_format.py45
-rw-r--r--jsonschema/tests/test_exceptions.py4
-rw-r--r--jsonschema/tests/test_validators.py22
-rw-r--r--jsonschema/validators.py2
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