summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJulian Berman <Julian@GrayVines.com>2019-08-04 18:57:26 -0400
committerJulian Berman <Julian@GrayVines.com>2019-08-04 18:57:26 -0400
commitcab27b8f1515536e7fb030ea4d3a2ce2713d0498 (patch)
treef3da45d47915e70a9ab79f76a62cc3dfe11d2687
parent918dad5989736e2d40cffe85556bc87935dbfb35 (diff)
downloadjsonschema-protocol.tar.gz
-rw-r--r--README.rst2
-rw-r--r--docs/errors.rst2
-rw-r--r--docs/faq.rst13
-rw-r--r--docs/spelling-wordlist.txt1
-rw-r--r--docs/validate.rst158
-rw-r--r--jsonschema/_protocol.py135
-rw-r--r--jsonschema/_types.py5
-rw-r--r--jsonschema/tests/test_validators.py8
-rw-r--r--jsonschema/validators.py21
-rw-r--r--test-requirements.txt1
10 files changed, 187 insertions, 159 deletions
diff --git a/README.rst b/README.rst
index e87b1bd..2b26d6e 100644
--- a/README.rst
+++ b/README.rst
@@ -71,7 +71,7 @@ Features
and
`Draft 3 <https://python-jsonschema.readthedocs.io/en/latest/validate/#jsonschema.Draft3Validator>`_
-* `Lazy validation <https://python-jsonschema.readthedocs.io/en/latest/validate/#jsonschema.IValidator.iter_errors>`_
+* `Lazy validation <https://python-jsonschema.readthedocs.io/en/latest/validate/#jsonschema.validators.ValidatorProtocol.iter_errors>`_
that can iteratively report *all* validation errors.
* `Programmatic querying <https://python-jsonschema.readthedocs.io/en/latest/errors/#module-jsonschema>`_
diff --git a/docs/errors.rst b/docs/errors.rst
index 1851ff5..e892777 100644
--- a/docs/errors.rst
+++ b/docs/errors.rst
@@ -272,7 +272,7 @@ error objects.
As you can see, `jsonschema.exceptions.ErrorTree` takes an
iterable of `ValidationError`\s when constructing a tree so
you can directly pass it the return value of a validator object's
-`jsonschema.IValidator.iter_errors` method.
+`jsonschema.validators.ValidatorProtocol.iter_errors` method.
`ErrorTree`\s support a number of useful operations. The first one we
might want to perform is to check whether a given element in our instance
diff --git a/docs/faq.rst b/docs/faq.rst
index 889b306..33fa293 100644
--- a/docs/faq.rst
+++ b/docs/faq.rst
@@ -16,12 +16,13 @@ It's perfectly valid (and perhaps even useful) to have a default that is not
valid under the schema it lives in! So an instance modified by the default
would pass validation the first time, but fail the second!
-Still, filling in defaults is a thing that is useful. `jsonschema` allows
-you to `define your own validator classes and callables <creating>`, so you can
-easily create an `jsonschema.IValidator` that does do default setting. Here's
-some code to get you started. (In this code, we add the default properties to
-each object *before* the properties are validated, so the default values
-themselves will need to be valid under the schema.)
+Still, filling in defaults is a thing that is useful.
+`jsonschema` allows you to `define your own validator classes
+and callables <creating>`, so you can easily create an
+`jsonschema.validators.ValidatorProtocol` that does do default setting.
+Here's some code to get you started. (In this code, we add the default
+properties to each object *before* the properties are validated, so the
+default values themselves will need to be valid under the schema.)
.. code-block:: python
diff --git a/docs/spelling-wordlist.txt b/docs/spelling-wordlist.txt
index e43b09c..8dfaff9 100644
--- a/docs/spelling-wordlist.txt
+++ b/docs/spelling-wordlist.txt
@@ -1,5 +1,4 @@
# this appears to be misinterpreting Napoleon types as prose, sigh...
-IValidator
TypeChecker
UnknownType
ValidationError
diff --git a/docs/validate.rst b/docs/validate.rst
index 5a4448d..726bb0e 100644
--- a/docs/validate.rst
+++ b/docs/validate.rst
@@ -26,130 +26,7 @@ The Validator Interface
`jsonschema` defines an (informal) interface that all validator
classes should adhere to.
-.. class:: IValidator(schema, types=(), resolver=None, format_checker=None)
-
- :argument dict schema: the schema that the validator object
- will validate with. It is assumed to be valid, and providing
- an invalid schema can lead to undefined behavior. See
- `IValidator.check_schema` to validate a schema first.
- :argument resolver: an instance of `RefResolver` that will be
- used to resolve :validator:`$ref` properties (JSON references). If
- unprovided, one will be created.
- :argument format_checker: an instance of `FormatChecker`
- whose `FormatChecker.conforms` method will be called to
- check and see if instances conform to each :validator:`format`
- property present in the schema. If unprovided, no validation
- will be done for :validator:`format`. Certain formats require
- additional packages to be installed (ipv5, uri, color, date-time).
- The required packages can be found at the bottom of this page.
- :argument types:
- .. deprecated:: 3.0.0
-
- Use `TypeChecker.redefine` and
- `jsonschema.validators.extend` instead of this argument.
-
- See `validating-types` for details.
-
- If used, this overrides or extends the list of known types when
- validating the :validator:`type` property.
-
- What is provided should map strings (type names) to class objects
- that will be checked via `isinstance`.
-
-
- .. attribute:: META_SCHEMA
-
- An object representing the validator's meta schema (the schema that
- describes valid schemas in the given version).
-
- .. attribute:: VALIDATORS
-
- A mapping of validator names (`str`\s) to functions
- that validate the validator property with that name. For more
- information see `creating-validators`.
-
- .. attribute:: TYPE_CHECKER
-
- A `TypeChecker` that will be used when validating :validator:`type`
- properties in JSON schemas.
-
- .. attribute:: schema
-
- The schema that was passed in when initializing the object.
-
- .. attribute:: DEFAULT_TYPES
-
- .. deprecated:: 3.0.0
-
- Use of this attribute is deprecated in favor of the new `type
- checkers <TypeChecker>`.
-
- See `validating-types` for details.
-
- For backwards compatibility on existing validator classes, a mapping of
- JSON types to Python class objects which define the Python types for
- each JSON type.
-
- Any existing code using this attribute should likely transition to
- using `TypeChecker.is_type`.
-
-
- .. classmethod:: check_schema(schema)
-
- Validate the given schema against the validator's `META_SCHEMA`.
-
- :raises: `jsonschema.exceptions.SchemaError` if the schema
- is invalid
-
- .. method:: is_type(instance, type)
-
- Check if the instance is of the given (JSON Schema) type.
-
- :type type: str
- :rtype: bool
- :raises: `jsonschema.exceptions.UnknownType` if ``type``
- is not a known type.
-
- .. method:: is_valid(instance)
-
- Check if the instance is valid under the current `schema`.
-
- :rtype: bool
-
- >>> schema = {"maxItems" : 2}
- >>> Draft3Validator(schema).is_valid([2, 3, 4])
- False
-
- .. method:: iter_errors(instance)
-
- Lazily yield each of the validation errors in the given instance.
-
- :rtype: an `collections.Iterable` of
- `jsonschema.exceptions.ValidationError`\s
-
- >>> schema = {
- ... "type" : "array",
- ... "items" : {"enum" : [1, 2, 3]},
- ... "maxItems" : 2,
- ... }
- >>> v = Draft3Validator(schema)
- >>> for error in sorted(v.iter_errors([2, 3, 4]), key=str):
- ... print(error.message)
- 4 is not one of [1, 2, 3]
- [2, 3, 4] is too long
-
- .. method:: validate(instance)
-
- Check if the instance is valid under the current `schema`.
-
- :raises: `jsonschema.exceptions.ValidationError` if the
- instance is invalid
-
- >>> schema = {"maxItems" : 2}
- >>> Draft3Validator(schema).validate([2, 3, 4])
- Traceback (most recent call last):
- ...
- ValidationError: [2, 3, 4] is too long
+.. autoclass:: jsonschema.validators.ValidatorProtocol
All of the `versioned validators <versioned-validators>` that are included with
@@ -160,12 +37,13 @@ more information see `creating-validators`.
Type Checking
-------------
-To handle JSON Schema's :validator:`type` property, a `IValidator` uses
-an associated `TypeChecker`. The type checker provides an immutable
-mapping between names of types and functions that can test if an instance is
-of that type. The defaults are suitable for most users - each of the
-`versioned validators <versioned-validators>` that are included with
-`jsonschema` have a `TypeChecker` that can correctly handle their respective
+To handle JSON Schema's :validator:`type` property, a
+`jsonschema.validators.ValidatorProtocol` uses an associated
+`TypeChecker`. The type checker provides an immutable mapping between
+names of types and functions that can test if an instance is of that
+type. The defaults are suitable for most users - each of the `versioned
+validators <versioned-validators>` that are included with `jsonschema`
+have a `TypeChecker` that can correctly handle their respective
versions.
.. seealso:: `validating-types`
@@ -201,10 +79,11 @@ particular `int`\s and `float`\s, along with
more general instance checks can introduce significant slowdown, especially
given how common validating these types are.
-If you *do* want the generality, or just want to add a few specific additional
-types as being acceptable for a validator object, then you should update an
-existing `TypeChecker` or create a new one. You may then create a new
-`IValidator` via `jsonschema.validators.extend`.
+If you *do* want the generality, or just want to add a few specific
+additional types as being acceptable for a validator object, then
+you should update an existing `TypeChecker` or create a new one. You
+may then create a new `jsonschema.validators.ValidatorProtocol` via
+`jsonschema.validators.extend`.
.. code-block:: python
@@ -230,10 +109,11 @@ existing `TypeChecker` or create a new one. You may then create a new
Versioned Validators
--------------------
-`jsonschema` ships with validator classes for various versions of
-the JSON Schema specification. For details on the methods and attributes
-that each validator class provides see the `IValidator` interface,
-which each included validator class implements.
+`jsonschema` ships with validator classes for various versions
+of the JSON Schema specification. For details on the methods
+and attributes that each validator class provides see the
+`jsonschema.validators.ValidatorProtocol` protocol, which each included
+validator class implements.
.. autoclass:: Draft7Validator
@@ -271,7 +151,7 @@ JSON Schema defines the :validator:`format` property which can be used to check
if primitive types (``string``\s, ``number``\s, ``boolean``\s) conform to
well-defined formats. By default, no validation is enforced, but optionally,
validation can be enabled by hooking in a format-checking object into an
-`IValidator`.
+`jsonschema.validators.ValidatorProtocol`.
.. doctest::
diff --git a/jsonschema/_protocol.py b/jsonschema/_protocol.py
new file mode 100644
index 0000000..86106a8
--- /dev/null
+++ b/jsonschema/_protocol.py
@@ -0,0 +1,135 @@
+try:
+ from typing import Protocol
+except ImportError:
+ Protocol = object
+
+
+class ValidatorProtocol(Protocol):
+ def iter_errors(self):
+ pass
+
+# (schema, types=(), resolver=None, format_checker=None)
+ #
+ # :argument dict schema: the schema that the validator object
+ # will validate with. It is assumed to be valid, and providing
+ # an invalid schema can lead to undefined behavior. See
+ # `jsonschema.validators.ValidatorProtocol.check_schema` to
+ # validate a schema first.
+ # :argument resolver: an instance of `RefResolver` that will be
+ # used to resolve :validator:`$ref` properties (JSON references). If
+ # unprovided, one will be created.
+ # :argument format_checker: an instance of `FormatChecker`
+ # whose `FormatChecker.conforms` method will be called to
+ # check and see if instances conform to each :validator:`format`
+ # property present in the schema. If unprovided, no validation
+ # will be done for :validator:`format`. Certain formats require
+ # additional packages to be installed (ipv5, uri, color, date-time).
+ # The required packages can be found at the bottom of this page.
+ # :argument types:
+ # .. deprecated:: 3.0.0
+ #
+ # Use `TypeChecker.redefine` and
+ # `jsonschema.validators.extend` instead of this argument.
+ #
+ # See `validating-types` for details.
+ #
+ # If used, this overrides or extends the list of known types when
+ # validating the :validator:`type` property.
+ #
+ # What is provided should map strings (type names) to class objects
+ # that will be checked via `isinstance`.
+ #
+ #
+ # .. attribute:: META_SCHEMA
+ #
+ # An object representing the validator's meta schema (the schema that
+ # describes valid schemas in the given version).
+ #
+ # .. attribute:: VALIDATORS
+ #
+ # A mapping of validator names (`str`\s) to functions
+ # that validate the validator property with that name. For more
+ # information see `creating-validators`.
+ #
+ # .. attribute:: TYPE_CHECKER
+ #
+ # A `TypeChecker` that will be used when validating :validator:`type`
+ # properties in JSON schemas.
+ #
+ # .. attribute:: schema
+ #
+ # The schema that was passed in when initializing the object.
+ #
+ # .. attribute:: DEFAULT_TYPES
+ #
+ # .. deprecated:: 3.0.0
+ #
+ # Use of this attribute is deprecated in favor of the new `type
+ # checkers <TypeChecker>`.
+ #
+ # See `validating-types` for details.
+ #
+ # For backwards compatibility on existing validator classes, a mapping of
+ # JSON types to Python class objects which define the Python types for
+ # each JSON type.
+ #
+ # Any existing code using this attribute should likely transition to
+ # using `TypeChecker.is_type`.
+ #
+ #
+ # .. classmethod:: check_schema(schema)
+ #
+ # Validate the given schema against the validator's `META_SCHEMA`.
+ #
+ # :raises: `jsonschema.exceptions.SchemaError` if the schema
+ # is invalid
+ #
+ # .. method:: is_type(instance, type)
+ #
+ # Check if the instance is of the given (JSON Schema) type.
+ #
+ # :type type: str
+ # :rtype: bool
+ # :raises: `jsonschema.exceptions.UnknownType` if ``type``
+ # is not a known type.
+ #
+ # .. method:: is_valid(instance)
+ #
+ # Check if the instance is valid under the current `schema`.
+ #
+ # :rtype: bool
+ #
+ # >>> schema = {"maxItems" : 2}
+ # >>> Draft3Validator(schema).is_valid([2, 3, 4])
+ # False
+ #
+ # .. method:: iter_errors(instance)
+ #
+ # Lazily yield each of the validation errors in the given instance.
+ #
+ # :rtype: an `collections.Iterable` of
+ # `jsonschema.exceptions.ValidationError`\s
+ #
+ # >>> schema = {
+ # ... "type" : "array",
+ # ... "items" : {"enum" : [1, 2, 3]},
+ # ... "maxItems" : 2,
+ # ... }
+ # >>> v = Draft3Validator(schema)
+ # >>> for error in sorted(v.iter_errors([2, 3, 4]), key=str):
+ # ... print(error.message)
+ # 4 is not one of [1, 2, 3]
+ # [2, 3, 4] is too long
+ #
+ # .. method:: validate(instance)
+ #
+ # Check if the instance is valid under the current `schema`.
+ #
+ # :raises: `jsonschema.exceptions.ValidationError` if the
+ # instance is invalid
+ #
+ # >>> schema = {"maxItems" : 2}
+ # >>> Draft3Validator(schema).validate([2, 3, 4])
+ # Traceback (most recent call last):
+ # ...
+ # ValidationError: [2, 3, 4] is too long
diff --git a/jsonschema/_types.py b/jsonschema/_types.py
index a71a4e3..b79d1df 100644
--- a/jsonschema/_types.py
+++ b/jsonschema/_types.py
@@ -50,8 +50,9 @@ class TypeChecker(object):
"""
A ``type`` property checker.
- A `TypeChecker` performs type checking for an `IValidator`. Type
- checks to perform are updated using `TypeChecker.redefine` or
+ A `TypeChecker` performs type checking for an
+ `jsonschema.validators.ValidatorProtocol`. Type checks
+ to perform are updated using `TypeChecker.redefine` or
`TypeChecker.redefine_many` and removed via `TypeChecker.remove`.
Each of these return a new `TypeChecker` object.
diff --git a/jsonschema/tests/test_validators.py b/jsonschema/tests/test_validators.py
index e4572c5..e5a6677 100644
--- a/jsonschema/tests/test_validators.py
+++ b/jsonschema/tests/test_validators.py
@@ -7,6 +7,7 @@ import json
import os
import sys
import tempfile
+import typing
import unittest
from twisted.trial.unittest import SynchronousTestCase
@@ -176,6 +177,13 @@ class TestCreateAndExtend(SynchronousTestCase):
Derived = validators.extend(Original)
self.assertEqual(Derived.ID_OF(Derived.META_SCHEMA), correct_id)
+ def test_create_produces_something_ValidatorProtocol_compliant(self):
+ Validator = validators.create(meta_schema={}, validators=())
+ self.assertIsInstance(
+ Validator({}),
+ typing.runtime_checkable(validators.ValidatorProtocol),
+ )
+
class TestLegacyTypeChecking(SynchronousTestCase):
def test_create_default_types(self):
diff --git a/jsonschema/validators.py b/jsonschema/validators.py
index e1ea871..a06c936 100644
--- a/jsonschema/validators.py
+++ b/jsonschema/validators.py
@@ -14,6 +14,7 @@ from jsonschema import (
_validators,
exceptions,
)
+from jsonschema._protocol import ValidatorProtocol
from jsonschema.compat import (
Sequence,
int_types,
@@ -214,7 +215,7 @@ def create(
Returns:
- a new `jsonschema.IValidator` class
+ a new `ValidatorProtocol` class
"""
if default_types is not None:
@@ -372,7 +373,7 @@ def extend(validator, validators=(), version=None, type_checker=None):
Arguments:
- validator (jsonschema.IValidator):
+ validator (ValidatorProtocol):
an existing validator class
@@ -402,11 +403,12 @@ def extend(validator, validators=(), version=None, type_checker=None):
a type checker, used when applying the :validator:`type` validator.
If unprovided, the type checker of the extended
- `jsonschema.IValidator` will be carried along.`
+ `ValidatorProtocol` will be carried along.`
Returns:
- a new `jsonschema.IValidator` class extending the one provided
+ a new `jsonschema.validators.ValidatorProtocol`-implementing
+ class extending the one provided
.. note:: Meta Schemas
@@ -848,10 +850,11 @@ def validate(instance, schema, cls=None, *args, **kwargs):
valid, since not doing so can lead to less obvious error messages and fail
in less obvious or consistent ways.
- If you know you have a valid schema already, especially if you
- intend to validate multiple instances with the same schema, you
- likely would prefer using the `IValidator.validate` method directly
- on a specific validator (e.g. ``Draft7Validator.validate``).
+ If you know you have a valid schema already, especially
+ if you intend to validate multiple instances with
+ the same schema, you likely would prefer using the
+ `ValidatorProtocol.validate` method directly on a specific validator
+ (e.g. ``Draft7Validator.validate``).
Arguments:
@@ -864,7 +867,7 @@ def validate(instance, schema, cls=None, *args, **kwargs):
The schema to validate with
- cls (IValidator):
+ cls (jsonschema.validators.ValidatorProtocol):
The class that will be used to validate the instance.
diff --git a/test-requirements.txt b/test-requirements.txt
index 082785c..9ecacd2 100644
--- a/test-requirements.txt
+++ b/test-requirements.txt
@@ -1 +1,2 @@
+typing; python_version == '2.7'
Twisted