Package: cfgv
cfgvValidate configuration and produce human readable error messages.InstallationpipinstallcfgvSample error messagesThese are easier to see by example.  Here's an example where I typo'dtruein apre-commitconfiguration.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 strAPIcfgv.validate(value, schema)Perform validation on the schema:raisesValidationErroron failurereturns the value on success (for convenience)cfgv.apply_defaults(value, schema)Returns a new value which sets all missing optional values to their defaults.cfgv.remove_defaults(value, schema)Returns a new value which removes all optional values that are set to their
defaults.cfgv.load_from_filename(filename, schema, load_strategy, exc_tp=ValidationError)Load a file given theload_strategy.  Reraise any errors asexc_tp.  All
defaults will be populated in the resulting value.Most useful when used withfunctools.partialas follows:load_my_cfg=functools.partial(cfgv.load_from_filename,schema=MY_SCHEMA,load_strategy=json.loads,exc_tp=MyError,)Making a schemaA schema validates a container --cfgvprovidesMapandArrayfor
most normal cases.writing your own schema containerIf the built-in containers below don't quite satisfy your usecase, you can
always write your own.  Containers use the following interface:classContainer(object):defcheck(self,v):"""check the passed in value (do not modify `v`)"""defapply_defaults(self,v):"""return a new value with defaults applied (do not modify `v`)"""defremove_defaults(self,v):"""return a new value with defaults removed (do not modify `v`)"""Map(object_name, id_key, *items)The most basic building block for creating a schema is aMapobject_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 asRequiredorOptionalConsider 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)Array(of, allow_empty=True)Used to nest maps inside of arrays.  For arrays of scalars, seecheck_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 objectsValidator objects are used to validate key-value-pairs of aMap.writing your own validatorIf the built-in validators below don't quite satisfy your usecase, you can
always write your own.  Validators use the following interface:classValidator(object):defcheck(self,dct):"""check that your specific key has the appropriate value in `dct`"""defapply_default(self,dct):"""modify `dct` and set the default value if it is missing"""defremove_default(self,dct):"""modify `dct` and remove the default value if it is present"""It may make sense toborrowfunctions from the built in validators.  They
additionally use the following interface(s):self.key: the key to checkself.check_fn: thecheck functionself.default: a default value to set.Required(key, check_fn)Ensure that a key is present in aMapand adheres to thecheck function.RequiredRecurse(key, schema)Similar toRequired, but uses aschema.Optional(key, check_fn, default)If a key is present, check that it adheres to thecheck function.apply_defaultswill set thedefaultif it is not present.remove_defaultswill remove the value if it is equal todefault.OptionalRecurse(key, schema, default)Similar toOptionalbut uses aschema.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.OptionalNoDefault(key, check_fn)LikeOptional, but does notapply_defaultsorremove_defaults.Conditional(key, check_fn, condition_key, condition_value, ensure_absent=False)Ifcondition_keyis equal to thecondition_value, the specifickeywill be checked using thecheck function.Ifensure_absentisTrueand the condition check fails, thekeywill
be checked for absense.Note that thecondition_valueis checked for equality, so any object
implementing__eq__may be used.  A few are provided out of the box
for this purpose, seeequality helpers.ConditionalOptional(key, check_fn, default, condition_key, condition_value, ensure_absent=False)Similar toConditionalandOptional.ConditionalRecurse(key, schema, condition_key, condition_value, ensure_absent=True)Similar toConditional, but uses aschema.NoAdditionalKeys(keys)Use in a mapping to ensure that only thekeysspecified are present.Equality helpersEquality helpers at the very least implement__eq__for their behaviour.They may also implementdef describe_opposite(self):for use in theensure_absent=Trueerror message (otherwise, the__repr__will be used).Not(val)ReturnsTrueif the value is not equal toval.In(*values)ReturnsTrueif the value is contained invalues.NotIn(*values)ReturnsTrueif the value is not contained invalues.Check functionsA number of check functions are provided out of the box.A check function takes a single parameter, thevalue, and either raises aValidationErroror returns nothing.check_any(_)A noop check function.check_type(tp, typename=None)Returns a check function to check for a specific type.  Settingtypenamewill 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_textcheck_one_of(possible)Returns a function that checks that the value is contained inpossible.For example:Required('language',check_one_of(('javascript','python','ruby')))check_regex(v)Ensures thatvis a valid python regular expression.check_array(inner_check)Returns a function that checks that a value is a sequence and that each
value in that sequence adheres to theinner_check.For example:Required('args',check_array(check_string))check_and(*fns)Returns a function that performs multiple checks on a value.For example:Required('language',check_and(check_string,my_check_language))