Ouch, never mind. Performance hit.

This commit is contained in:
Julian Berman 2013-02-17 14:49:38 -05:00
parent 0b8f470371
commit 2091f311f7
4 changed files with 22 additions and 33 deletions

View File

@ -155,18 +155,19 @@ a ``types`` argument on construction that specifies additional types, or which
can be used to specify a different set of Python types to map to a given JSON can be used to specify a different set of Python types to map to a given JSON
type. type.
``jsonschema`` tries to be as general as possible by default. For instance, ``jsonschema`` tries to strike a balance between performance in the common case
JSON defines a ``number`` type, which can be validated with a schema such as and generality. For instance, JSON defines a ``number`` type, which can be
``{"type" : "number"}``. By default, this will validate correctly for instances validated with a schema such as ``{"type" : "number"}``. By default, this will
of Python :class:`number.Number`\s. This includes in particular :class:`int`\s accept instances of Python :class:`number.Number`. This includes in particular
and :class:`float`\s, along with `decimal.Decimal` objects, :class:`complex` :class:`int`\s and :class:`float`\s, along with `decimal.Decimal` objects,
numbers etc. See the numbers_ module documentation for more details. :class:`complex` numbers etc. See the numbers_ module documentation for more
details. For ``integer`` and ``object``, however, rather than checking for
``number.Integral`` and ``collections.Mapping``, ``jsonschema`` simply checks
for ``int`` and ``dict``, since the former can introduce significant slowdown.
For most purposes, if you want to add additional types as being acceptible for If you *do* want the generality, or just want to add a few specific additional
a validator, you should do so by inheriting from the relevant ``abc`` or by types as being acceptible for a validator, :class:`IValidator`\s have a
registering the existing class with the ``abc``. If this isn't an option, or if ``types`` argument that can be used to provide additional or new types.
you otherwise prefer not doing so, :class:`IValidator`\s have a ``types``
argument that can be used to provide additional or new types.
.. code-block:: python .. code-block:: python

View File

@ -30,6 +30,7 @@ if PY3:
from urllib.parse import unquote from urllib.parse import unquote
from urllib.request import urlopen from urllib.request import urlopen
basestring = unicode = str basestring = unicode = str
long = int
iteritems = operator.methodcaller("items") iteritems = operator.methodcaller("items")
else: else:
from itertools import izip as zip from itertools import izip as zip
@ -38,11 +39,6 @@ else:
import urlparse import urlparse
iteritems = operator.methodcaller("iteritems") iteritems = operator.methodcaller("iteritems")
try:
from collections import abc
except ImportError:
import collections as abc
FLOAT_TOLERANCE = 10 ** -15 FLOAT_TOLERANCE = 10 ** -15
validators = {} validators = {}
@ -91,8 +87,8 @@ class Draft3Validator(object):
""" """
DEFAULT_TYPES = { DEFAULT_TYPES = {
"array" : list, "boolean" : bool, "integer" : numbers.Integral, "array" : list, "boolean" : bool, "integer" : (int, long),
"null" : type(None), "number" : numbers.Number, "object" : abc.Mapping, "null" : type(None), "number" : numbers.Number, "object" : dict,
"string" : basestring, "string" : basestring,
} }

View File

@ -6,22 +6,21 @@ A *very* basic performance test.
from __future__ import print_function from __future__ import print_function
import argparse import argparse
import textwrap
import timeit import timeit
from jsonschema import Draft3Validator, validate
parser = argparse.ArgumentParser() parser = argparse.ArgumentParser()
parser.add_argument("-n", "--number", type=int, default=100) parser.add_argument("-n", "--number", type=int, default=100)
arguments = parser.parse_args() arguments = parser.parse_args()
instance = schema = Draft3Validator.META_SCHEMA
results = timeit.timeit( results = timeit.timeit(
number=arguments.number,
# Validate the Draft 3 meta-schema against itself without meta-validating # Validate the Draft 3 meta-schema against itself without meta-validating
stmt="validate(instance, schema)", stmt="validate(instance, schema)",
setup="from __main__ import instance, schema, validate", setup=textwrap.dedent("""
number=arguments.number, from jsonschema import Draft3Validator, validate
instance = schema = Draft3Validator.META_SCHEMA
"""),
) )
print( print(

View File

@ -17,7 +17,7 @@ except ImportError:
import mock import mock
from jsonschema import ( from jsonschema import (
PY3, abc, SchemaError, UnknownType, ValidationError, ErrorTree, PY3, SchemaError, UnknownType, ValidationError, ErrorTree,
Draft3Validator, FormatChecker, RefResolver, validate Draft3Validator, FormatChecker, RefResolver, validate
) )
@ -76,13 +76,6 @@ class TypesMixin(object):
def test_string_a_bytestring_is_a_string(self): def test_string_a_bytestring_is_a_string(self):
self.validator_class({"type" : "string"}).validate(b"foo") self.validator_class({"type" : "string"}).validate(b"foo")
def test_mappings_are_objects(self):
class Mapping(abc.Mapping):
def __getitem__(self): return 12
def __iter__(self): return iter([])
def __len__(self): return 12
self.validator_class({"type" : "object"}).validate(Mapping())
class DecimalMixin(object): class DecimalMixin(object):
def test_it_can_validate_with_decimals(self): def test_it_can_validate_with_decimals(self):