Validate configuration and produce human readable error messages.
pip install cfgvThese are easier to see by example. Here's an example where I typo'd true
in a pre-commit configuration.
pre_commit.clientlib.InvalidConfigError:
==> File /home/asottile/workspace/pre-commit/.pre-commit-config.yaml
==> At Config()
==> At key: repos
==> At Repository(repo='https://github.com/pre-commit/pre-commit-hooks')
==> At key: hooks
==> At Hook(id='flake8')
==> At key: always_run
=====> Expected bool got str
Perform validation on the schema:
- raises
ValidationErroron failure - returns the value on success (for convenience)
Returns a new value which sets all missing optional values to their defaults.
Returns a new value which removes all optional values that are set to their defaults.
Load a file given the load_strategy. Reraise any errors as exc_tp. All
defaults will be populated in the resulting value.
Most useful when used with functools.partial as follows:
load_my_cfg = functools.partial(
cfgv.load_from_filename,
schema=MY_SCHEMA,
load_strategy=json.loads,
exc_tp=MyError,
)A schema validates a container -- cfgv provides Map and Array for
most normal cases.
If the built-in containers below don't quite satisfy your usecase, you can always write your own. Containers use the following interface:
class Container(object):
def check(self, v):
"""check the passed in value (do not modify `v`)"""
def apply_defaults(self, v):
"""return a new value with defaults applied (do not modify `v`)"""
def remove_defaults(self, v):
"""return a new value with defaults removed (do not modify `v`)"""The most basic building block for creating a schema is a Map
object_name: will be displayed in error messagesid_key: will be used to identify the object in error messages. Set toNoneif there is no identifying key for the object.items: validator objects such asRequiredorOptional
Consider the following schema:
Map(
'Repo', 'url',
Required('url', check_any),
)In an error message, the map may be displayed as:
Repo(url='https://github.com/pre-commit/pre-commit')Repo(url=MISSING)(if the key is not present)
Used to nest maps inside of arrays. For arrays of scalars, see check_array.
of: AMap/Arrayor other sub-schema.allow_empty: whenFalse,Arraywill ensure at least one element.
When validated, this will check that each element adheres to the sub-schema.
Validator objects are used to validate key-value-pairs of a Map.
If the built-in validators below don't quite satisfy your usecase, you can always write your own. Validators use the following interface:
class Validator(object):
def check(self, dct):
"""check that your specific key has the appropriate value in `dct`"""
def apply_default(self, dct):
"""modify `dct` and set the default value if it is missing"""
def remove_default(self, dct):
"""modify `dct` and remove the default value if it is present"""It may make sense to borrow functions from the built in validators. They additionally use the following interface(s):
self.key: the key to checkself.check_fn: the check functionself.default: a default value to set.
Ensure that a key is present in a Map and adheres to the
check function.
Similar to Required, but uses a schema.
If a key is present, check that it adheres to the check function.
apply_defaultswill set thedefaultif it is not present.remove_defaultswill remove the value if it is equal todefault.
Similar to Optional but uses a schema.
apply_defaultswill set thedefaultif it is not present and then validate it with the schema.remove_defaultswill remove defaults using the schema, and then remove the value it if it is equal todefault.
Like Optional, but does not apply_defaults or remove_defaults.
- If
condition_keyis equal to thecondition_value, the specifickeywill be checked using the check function. - If
ensure_absentisTrueand the condition check fails, thekeywill be checked for absense.
Note that the condition_value is checked for equality, so any object
implementing __eq__ may be used. A few are provided out of the box
for this purpose, see equality helpers.
Similar to Conditional and Optional.
Similar to Conditional, but uses a schema.
Use in a mapping to ensure that only the keys specified are present.
Equality helpers at the very least implement __eq__ for their behaviour.
They may also implement def describe_opposite(self): for use in the
ensure_absent=True error message (otherwise, the __repr__ will be used).
Returns True if the value is not equal to val.
Returns True if the value is contained in values.
Returns True if the value is not contained in values.
A number of check functions are provided out of the box.
A check function takes a single parameter, the value, and either raises a
ValidationError or returns nothing.
A noop check function.
Returns a check function to check for a specific type. Setting typename
will replace the type's name in the error message.
For example:
Required('key', check_type(int))
# 'Expected bytes' in both python2 and python3.
Required('key', check_type(bytes, typename='bytes'))Several type checking functions are provided out of the box:
check_boolcheck_bytescheck_intcheck_stringcheck_text
Returns a function that checks that the value is contained in possible.
For example:
Required('language', check_one_of(('javascript', 'python', 'ruby')))Ensures that v is a valid python regular expression.
Returns a function that checks that a value is a sequence and that each
value in that sequence adheres to the inner_check.
For example:
Required('args', check_array(check_string))Returns a function that performs multiple checks on a value.
For example:
Required('language', check_and(check_string, my_check_language))