Merge pull request #255 from stuarteberg/fix-docs-faq-default-property

docs: faq: Updates to extend_with_default() example
This commit is contained in:
Julian Berman 2015-11-01 10:06:41 -05:00
commit 3eb5de857f

View File

@ -19,7 +19,9 @@ would pass validation the first time, but fail the second!
Still, filling in defaults is a thing that is useful. :mod:`jsonschema` Still, filling in defaults is a thing that is useful. :mod:`jsonschema`
allows you to :doc:`define your own validator classes and callables allows you to :doc:`define your own validator classes and callables
<creating>`, so you can easily create a :class:`IValidator` that does do <creating>`, so you can easily create a :class:`IValidator` that does do
default setting. Here's some code to get you started: 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 .. code-block:: python
@ -30,15 +32,15 @@ default setting. Here's some code to get you started:
validate_properties = validator_class.VALIDATORS["properties"] validate_properties = validator_class.VALIDATORS["properties"]
def set_defaults(validator, properties, instance, schema): def set_defaults(validator, properties, instance, schema):
for property, subschema in properties.iteritems():
if "default" in subschema:
instance.setdefault(property, subschema["default"])
for error in validate_properties( for error in validate_properties(
validator, properties, instance, schema, validator, properties, instance, schema,
): ):
yield error yield error
for property, subschema in properties.iteritems():
if "default" in subschema:
instance.setdefault(property, subschema["default"])
return validators.extend( return validators.extend(
validator_class, {"properties" : set_defaults}, validator_class, {"properties" : set_defaults},
) )
@ -60,12 +62,52 @@ See the above-linked document for more info on how this works, but basically,
it just extends the :validator:`properties` validator on a it just extends the :validator:`properties` validator on a
:class:`Draft4Validator` to then go ahead and update all the defaults. :class:`Draft4Validator` to then go ahead and update all the defaults.
.. note::
If you're interested in a more interesting solution to a larger class of these If you're interested in a more interesting solution to a larger class of these
types of transformations, keep an eye on `Seep types of transformations, keep an eye on `Seep
<https://github.com/Julian/Seep>`_, which is an experimental data <https://github.com/Julian/Seep>`_, which is an experimental data
transformation and extraction library written on top of :mod:`jsonschema`. transformation and extraction library written on top of :mod:`jsonschema`.
.. hint::
The above code can provide default values for an entire object and all of its properties,
but only if your schema provides a default value for the object itself, like so:
.. code-block:: python
schema = {
"type": "object",
"properties": {
"outer-object": {
"type": "object",
"properties" : {
"inner-object": {
"type": "string",
"default": "INNER-DEFAULT"
}
},
"default": {} # <-- MUST PROVIDE DEFAULT OBJECT
}
}
}
obj = {}
DefaultValidatingDraft4Validator(schema).validate(obj)
assert obj == {'outer-object': {'inner-object': 'INNER-DEFAULT'}}
...but if you don't provide a default value for your object,
then it won't be instantiated at all, much less populated with default properties.
.. code-block:: python
del schema["properties"]["outer-object"]["default"]
obj2 = {}
DefaultValidatingDraft4Validator(schema).validate(obj2)
assert obj2 == {} # whoops
How do jsonschema version numbers work? How do jsonschema version numbers work?
--------------------------------------- ---------------------------------------