python - 妖艳 : give error line in yaml file

标签 python validation yaml voluptuous

我经常使用 voluptulous 来验证 yaml 描述文件。通常,这些错误很难破译,尤其是对于普通用户而言。

我正在寻找一种方法来使错误更具可读性。一种方法是确定 YAML 文件中的哪一行受到影响。

from voluptuous import Schema 
import yaml 
from io import StringIO

Validate = Schema({
    'name': str,
    'age': int,
})

data = """
name: John
age: oops
"""

data = Validate(yaml.load(StringIO(data)))

在上面的示例中,我收到此错误:

MultipleInvalid: expected int for dictionary value @ data['age']

我更喜欢这样的错误:

Error: validation failed on line 2, data.age should be an integer.

有没有一种优雅的方式来实现这一点?

最佳答案

问题在于,在 yaml.load 的 API 边界上,源的所有表征信息都已丢失。 Validate 得到一个Python dict,但不知道它来自哪里,而且dict不包含这些信息。

但是,您可以自己实现这一点。 voluptious' Invalid 错误带有一个 path,它是要遵循的键列表。有了这个路径,您可以再次将 YAML 解析为节点(携带表示信息)并发现项目的位置:

import yaml

def line_from(path, yaml_input):
  node = yaml.compose(yaml_input)
  for item in path:
    for entry in node.value:
      if entry[0].value == item:
        node = entry[1]
        break
    else: raise ValueError("unknown path element: " + item)
  return node.start_mark.line

# demostrating this on more complex input than yours

data = """
spam:
  egg:
    sausage:
      spam
"""

print(line_from(["spam", "egg", "sausage"], data))
# gives 4

有了这个,你就可以做

try:
  data = Validate(yaml.load(StringIO(data)))
except Invalid as e:
  line = line_from(e.path, data)
  path = "data." + ".".join(e.path)
  print(f"Error: validation failed on line {line} ({path}): {e.error_message}")

我将到目前为止这个答案,因为它向您展示了如何发现错误的起源行。您可能需要将其扩展为:

  • 处理 YAML 序列(我的代码假设每个中间节点都是一个 MappingNodeSequenceNode 将在其 value 列表中包含单个节点键值元组)
  • 处理 MultipleInvalid 为每个内部错误发出消息
  • 如果您确实愿意,请将预期 int 重写为应该是一个整数(不知道该怎么做)
  • 打印错误后中止

关于python - 妖艳 : give error line in yaml file,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/71007929/

相关文章:

python - 如何在python 3中找到任意列表中缺失的数字?

python - 如何使用 ffmpeg 将 rawvideo 传输到 v4l2loopback?

javascript - 使用多个选择框进行 Jquery 表单验证

python - f 字符串给出 SyntaxError?

python - 将两层模型拟合到 python 中的风剖面数据

java - 尝试为出生年份创建 do while 循环

Spring Mvc @InitBinder 验证

python - Ansible:根据特定事实对主机进行计数

amazon-web-services - 取决于 cloudforamtion yml 模板中的 if else 语句

java - Dropwizard 1.0.0-rc2 registerDefaultExceptionMappers 无法识别的字段