跳转到主要内容

验证配置并生成可读的错误消息。

项目描述

build status pre-commit.ci status

cfgv

验证配置并生成可读的错误消息。

安装

pip install cfgv

示例错误消息

以下是一些示例。这是一个示例,我在pre-commit配置中打字错误了true

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)

在模式上执行验证

  • 失败时引发ValidationError
  • 成功时返回值(方便起见)

cfgv.apply_defaults(value, schema)

返回一个新值,将所有缺失的可选值设置为它们的默认值。

cfgv.remove_defaults(value, schema)

返回一个新值,移除所有设置为默认值的可选值。

cfgv.load_from_filename(filename, schema, load_strategy, exc_tp=ValidationError)

根据load_strategy加载文件。重新引发任何错误作为exc_tp。所有默认值都将填充到结果值中。

当与functools.partial一起使用时最有用,如下所示

load_my_cfg = functools.partial(
    cfgv.load_from_filename,
    schema=MY_SCHEMA,
    load_strategy=json.loads,
    exc_tp=MyError,
)

创建模式

模式验证一个容器 —— cfgv为大多数正常情况提供了MapArray

编写自己的模式容器

如果以下内置容器不能完全满足您的用例,您始终可以编写自己的。容器使用以下接口

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)

创建模式的最基本构建块是Map

  • object_name:将在错误消息中显示
  • id_key:将在错误消息中用于标识对象。如果没有标识键,则设置为None
  • items:验证对象,例如RequiredOptional

考虑以下模式

Map(
    'Repo', 'url',
    Required('url', check_any),
)

在错误消息中,映射可能显示为

  • Repo(url='https://github.com/pre-commit/pre-commit')
  • Repo(url=MISSING)(如果键不存在)

Array(of, allow_empty=True)

用于在数组内部嵌套映射。对于标量数组,请参阅check_array

  • of:一个Map / Array或其他子模式。
  • allow_empty:当False时,Array将确保至少有一个元素。

验证时,这将检查每个元素是否遵循子模式。

验证器对象

验证器对象用于验证Map的键值对。

编写自己的验证器

如果下面的内置验证器不能满足您的用例,您始终可以编写自己的。验证器使用以下接口

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

可能有必要从内置验证器中借用函数。它们还使用以下接口

  • self.key:要检查的键
  • self.check_fn:检查函数
  • self.default:要设置的默认值。

Required(key, check_fn)

确保在Map中存在键并遵循检查函数。

RequiredRecurse(key, schema)

类似于Required,但使用一个schema

Optional(key, check_fn, default)

如果键存在,检查它是否遵循检查函数。

  • apply_defaults将在不存在时设置default
  • remove_defaults将移除等于default的值。

OptionalRecurse(key, schema, default)

类似于Optional,但使用一个schema

  • apply_defaults将在不存在时设置default,然后使用该模式进行验证。
  • remove_defaults将使用该模式移除默认值,然后如果它等于default,则移除该值。

OptionalNoDefault(key, check_fn)

类似于Optional,但不使用apply_defaultsremove_defaults

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

  • 如果condition_key等于condition_value,则将使用检查函数检查特定的key
  • 如果ensure_absentTrue且条件检查失败,则将检查key是否存在。

请注意,condition_value将用于检查等价性,因此可以用于任何实现__eq__的对象。为此提供了一些内置帮助程序,请参阅等价性帮助程序

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

类似于ConditionalOptional

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

类似于Conditional,但使用一个schema

NoAdditionalKeys(keys)

用于确保映射中仅存在指定的keys

等价性帮助程序

等价性帮助程序至少实现其行为的__eq__

它们还可以实现def describe_opposite(self):,用于在ensure_absent=True错误消息中使用(否则将使用__repr__)。

Not(val)

如果值不等于val,则返回True

In(*values)

如果值包含在values中,则返回True

NotIn(*values)

如果值不包含在values中,则返回True

检查函数

提供了一些内置的检查函数。

检查函数接受一个参数,即value,要么引发ValidationError,要么返回空值。

check_any(_)

一个空操作检查函数。

check_type(tp, typename=None)

返回一个检查特定类型的函数。设置typename将替换错误消息中的类型名称。

例如

Required('key', check_type(int))
# 'Expected bytes' in both python2 and python3.
Required('key', check_type(bytes, typename='bytes'))

提供了一些内置的类型检查函数

  • check_bool
  • check_bytes
  • check_int
  • check_string
  • check_text

check_one_of(possible)

返回一个函数,用于检查值是否包含在 possible 中。

例如

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

check_regex(v)

确保 v 是有效的 Python 正则表达式。

check_array(inner_check)

返回一个函数,用于检查一个值是否是序列,并且该序列中的每个值都符合 inner_check

例如

Required('args', check_array(check_string))

check_and(*fns)

返回一个函数,对值执行多个检查。

例如

Required('language', check_and(check_string, my_check_language))

由以下机构支持

AWS AWS 云计算和安全赞助商 Datadog Datadog 监控 Fastly Fastly CDN Google Google 下载分析 Microsoft Microsoft PSF 赞助商 Pingdom Pingdom 监控 Sentry Sentry 错误日志 StatusPage StatusPage 状态页面