-
-
Notifications
You must be signed in to change notification settings - Fork 593
Validationerror context #86
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
54f16a7
741c275
cf20b09
77ffe31
300f389
7234ec3
951ee65
d493bdb
ff74103
45e20de
af86042
1a74234
832f51c
d3c6f27
ceede42
0e49379
4fe2a8b
cf7056d
16ec13c
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -15,15 +15,102 @@ raised or returned, depending on which method or function is used. | |
|
||
A human readable message explaining the error. | ||
|
||
.. attribute:: validator | ||
.. attribute:: validator_keyword | ||
|
||
The failed validator. | ||
|
||
.. attribute:: validator_value | ||
|
||
The value for the failed validator in the schema. | ||
|
||
.. attribute:: schema | ||
|
||
The full (sub)schema that this error came from. | ||
|
||
.. attribute:: schema_path | ||
|
||
A deque containing the path to the failed validator within the schema. | ||
|
||
.. attribute:: path | ||
|
||
A deque containing the path to the offending element (or an empty deque | ||
if the error happened globally). | ||
|
||
.. attribute:: instance | ||
|
||
The instance that was being validated. | ||
|
||
.. attribute:: context | ||
|
||
If the error was caused by errors in subschemas, the list of errors | ||
from the subschemas will be available on this property. The | ||
``schema_path`` and ``path`` of these errors will be relative to the | ||
parent error. | ||
|
||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think it'd be helpful if we also added one more (very short) prose section to this file showing an example using all these new attributes. Say something that used There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Okay, I added a bit on this, not sure if it's what you had in mind, documentation is not my strong suit. :P There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. We don't actually need an attribute for the instance do we? The caller knows what they passed in, no? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think we should keep it, the instance you pass in may be a deeply nested structure, the instance on the error is the one that was passed into the validator that failed. You could trace it out using the There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Ah OK we should make that clear.
|
||
These attributes can be clarified with a short example: | ||
|
||
.. code-block:: python | ||
|
||
>>> from jsonschema import Draft4Validator | ||
>>> schema = { | ||
... "items": { | ||
... "anyOf": [ | ||
... {"type": "string", "maxLength": 2}, | ||
... {"type": "integer", "minimum": 5} | ||
... ] | ||
... } | ||
... } | ||
>>> instance = [{}, 3, "foo"] | ||
>>> v = Draft4Validator(schema) | ||
>>> errors = sorted(v.iter_errors(instance), key=lambda e: e.path) | ||
|
||
The error messages in this situation are not very helpful on their own: | ||
|
||
.. code-block:: python | ||
|
||
>>> for e in errors: | ||
... print(e.message) | ||
The instance is not valid under any of the given schemas | ||
The instance is not valid under any of the given schemas | ||
The instance is not valid under any of the given schemas | ||
|
||
If we look at the :attr:`ValidationError.path` attribute, we can find out which | ||
elements in the instance we are validating are causing each of the errors. In | ||
this example, :attr:`ValidationError.path` will have only one element, which | ||
will be the index in our list. | ||
|
||
.. code-block:: python | ||
|
||
>>> for e in errors: | ||
... print(list(e.path)) | ||
[0] | ||
[1] | ||
[2] | ||
|
||
Since our schema contained nested subschemas, it can be helpful to look at | ||
the specific part of the instance and subschema that caused each of the errors. | ||
This can be seen with the :attr:`ValidationError.instance` and | ||
:attr:`ValidationError.schema` attributes. | ||
|
||
With validators like ``anyOf``, the :attr:`ValidationError.context`` attribute | ||
can be used to see the sub-errors which caused the failure. Since these errors | ||
actually came from two separate subschemas, so it can be helpful to look at the | ||
:attr:`ValidationError.schema_path` attribute as well to see where exactly in | ||
the schema each of these errors come from. In the case of sub-errors from the | ||
:attr:`ValidationError.context` attribute, this path will be relative to the | ||
:attr:`ValidationError.schema_path` of the parent error. | ||
|
||
.. code-block:: python | ||
|
||
>>> for e in errors: | ||
... for sube in sorted(e.context, key=lambda e: e.schema_path): | ||
... print(list(sube.schema_path), sube) | ||
[0, 'type'] {} is not of type 'string' | ||
[1, 'type'] {} is not of type 'integer' | ||
[0, 'type'] 3 is not of type 'string' | ||
[1, 'minimum'] 3.0 is less than the minimum of 5 | ||
[0, 'maxLength'] 'foo' is too long | ||
[1, 'type'] 'foo' is not of type 'integer' | ||
|
||
In case an invalid schema itself is encountered, a :exc:`SchemaError` is | ||
raised. | ||
|
@@ -62,7 +149,7 @@ For clarity's sake, the given instance has three errors under this schema: | |
|
||
>>> v = Draft3Validator(schema) | ||
>>> for error in sorted(v.iter_errors(["spam", 2]), key=str): | ||
... print error | ||
... print(error) | ||
'spam' is not of type 'number' | ||
'spam' is not one of [1, 2, 3] | ||
['spam', 2] is too short | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Despite the fact that I also like validator_keyword better, I think to avoid the API churn we should leave it as is. It's going to be a pain -- we couldn't remove validator until at least v2.0 and it's just going to annoy for a tiny purity benefit.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You da boss. 😄 That's fine by me.