Skip to main content

build status pre-commit.ci status

cfgv

Validate configuration and produce human readable error messages.

Installation

pip install cfgv

Sample error messages

These 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

API

cfgv.validate(value, schema)

Perform validation on the schema:

  • raises ValidationError on failure
  • returns 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 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,
)

Making a schema

A schema validates a container -- cfgv provides Map and Array for most normal cases.

writing your own schema container

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`)"""

Map(object_name, id_key, *items)

The most basic building block for creating a schema is a Map

  • object_name: will be displayed in error messages
  • id_key: will be used to identify the object in error messages. Set to None if there is no identifying key for the object.
  • items: validator objects such as Required or Optional

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)

Array(of, allow_empty=True)

Used to nest maps inside of arrays. For arrays of scalars, see check_array.

  • of: A Map / Array or other sub-schema.
  • allow_empty: when False, Array will ensure at least one element.

When validated, this will check that each element adheres to the sub-schema.

Validator objects

Validator objects are used to validate key-value-pairs of a Map.

writing your own validator

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 check
  • self.check_fn: the check function
  • self.default: a default value to set.

Required(key, check_fn)

Ensure that a key is present in a Map and adheres to the check function.

RequiredRecurse(key, schema)

Similar to Required, but uses a schema.

Optional(key, check_fn, default)

If a key is present, check that it adheres to the check function.

  • apply_defaults will set the default if it is not present.
  • remove_defaults will remove the value if it is equal to default.

OptionalRecurse(key, schema, default)

Similar to Optional but uses a schema.

  • apply_defaults will set the default if it is not present and then validate it with the schema.
  • remove_defaults will remove defaults using the schema, and then remove the value it if it is equal to default.

OptionalNoDefault(key, check_fn)

Like Optional, but does not apply_defaults or remove_defaults.

Conditional(key, check_fn, condition_key, condition_value, ensure_absent=False)

  • If condition_key is equal to the condition_value, the specific key will be checked using the check function.
  • If ensure_absent is True and the condition check fails, the key will 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.

ConditionalOptional(key, check_fn, default, condition_key, condition_value, ensure_absent=False)

Similar to Conditional and Optional.

ConditionalRecurse(key, schema, condition_key, condition_value, ensure_absent=True)

Similar to Conditional, but uses a schema.

NoAdditionalKeys(keys)

Use in a mapping to ensure that only the keys specified are present.

Equality helpers

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).

Not(val)

Returns True if the value is not equal to val.

In(*values)

Returns True if the value is contained in values.

NotIn(*values)

Returns True if the value is not contained in values.

Check functions

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.

check_any(_)

A noop check function.

check_type(tp, typename=None)

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_bool
  • check_bytes
  • check_int
  • check_string
  • check_text

check_one_of(possible)

Returns a function that checks that the value is contained in possible.

For example:

Required('language', check_one_of(('javascript', 'python', 'ruby')))

check_regex(v)

Ensures that v is 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 the inner_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))

Release files for cfgv 3.4.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for cfgv 3.4.0
File Size Uploaded
cfgv-3.4.0.tar.gz 7.1 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for cfgv 3.4.0
File Interpreter ABI Platform
cfgv-3.4.0-py2.py3-none-any.whl Python 2, Python 3 none any Details

Total release size: 14.4 kB

Release files / cfgv-3.4.0.tar.gz

Download URL cfgv-3.4.0.tar.gz
Size 7.1 kB
Tags Source
SHA-256 checksum
How to use checksums
e52591d4c5f5dead8e0f673fb16db7949d2cfb3f7da4582893288f0ded8fe560
BLAKE2b-256 checksum
How to use checksums
1174539e56497d9bd1d484fd863dd69cbbfa653cd2aa27abfe35653494d85e94
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/4.0.2 CPython/3.10.12

Release files / cfgv-3.4.0-py2.py3-none-any.whl

Download URL cfgv-3.4.0-py2.py3-none-any.whl
Size 7.2 kB
Tags Python 2 Python 3
SHA-256 checksum
How to use checksums
b7265b1f29fd3316bfcd2b330d63d024f2bfd8bcb8b0272f8e19a504856c48f9
BLAKE2b-256 checksum
How to use checksums
c55551844dd50c4fc7a33b653bfaba4c2456f06955289ca770a5dbd5fd267374
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/4.0.2 CPython/3.10.12

Release history Release notifications | RSS feed

3.5.0

2 release files

This release

3.4.0 This release

2 release files

3.3.1

2 release files

3.3.0

2 release files

3.2.0

2 release files

3.1.0

2 release files

3.0.0

2 release files

2.0.1

2 release files

2.0.0

2 release files

1.6.0

2 release files

1.5.0

2 release files

1.4.0

2 release files

1.3.0

2 release files

1.2.0

2 release files

1.1.0

2 release files

1.0.0

2 release files

0.0.4

2 release files

0.0.3

2 release files

0.0.2

2 release files

0.0.1

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page