如何从PyYAML异常获取详细信息?

Wallyk

我想优雅地通知用户确切的他们被破坏的YAML文件存在缺陷的位置。的288行python-3.4.1/lib/python-3.4/yaml/scanner.py报告了常见的解析错误并通过引发异常来处理该错误:

raise ScannerError("while scanning a simple key", key.mark,
                   "could not found expected ':'", self.get_mark())

我正在努力举报。

try:
    parsed_yaml = yaml.safe_load(txt)

except yaml.YAMLError as exc:
    print ("scanner error 1")
    if hasattr(exc, 'problem_mark'):
        mark = exc.problem_mark
        print("Error parsing Yaml file at line %s, column %s." %
                                            (mark.line, mark.column+1))
    else:
        print ("Something went wrong while parsing yaml file")
    return

这给

$ yaml_parse.py
scanner error 1
Error parsing Yaml file line 1508, column 9.

但是,如何获取错误文本以及其中的内容key.mark和其他标记?

更有用的是,如何检查PyYaml来源以找出答案?ScannerError类似乎忽略了这些参数(从scanner.py第32行开始):

class ScannerError(MarkedYAMLError):
     pass
安通

ScannerError类没有定义的方法(的pass。就像一个空操作语句的工作,使得它在功能基类相同的MarkedYAMLError,那就是谁存储数据的一个来源。error.py

class MarkedYAMLError(YAMLError):
    def __init__(self, context=None, context_mark=None,
                 problem=None, problem_mark=None, note=None):
        self.context = context
        self.context_mark = context_mark
        self.problem = problem
        self.problem_mark = problem_mark
        self.note = note

    def __str__(self):
        lines = []
        if self.context is not None:
            lines.append(self.context)
        if self.context_mark is not None  \
           and (self.problem is None or self.problem_mark is None
                or self.context_mark.name != self.problem_mark.name
                or self.context_mark.line != self.problem_mark.line
                or self.context_mark.column != self.problem_mark.column):
            lines.append(str(self.context_mark))
        if self.problem is not None:
            lines.append(self.problem)
        if self.problem_mark is not None:
            lines.append(str(self.problem_mark))
        if self.note is not None:
            lines.append(self.note)
        return '\n'.join(lines)

如果以文件开头txt.yaml

hallo: 1
bye

和一个test.py

import ruamel.yaml as yaml
txt = open('txt.yaml')
data = yaml.load(txt, yaml.SafeLoader)

您将得到不太描述性的错误:

...
ruamel.yaml.scanner.ScannerError: while scanning a simple key
  in "txt.yaml", line 2, column 1
could not find expected ':'
  in "txt.yaml", line 3, column 1

但是,如果您更改第二行test.py

import ruamel.yaml as yaml
txt = open('txt.yaml').read()
data = yaml.load(txt, yaml.SafeLoader)

您会得到更有趣的错误描述:

...
ruamel.yaml.scanner.ScannerError: while scanning a simple key
  in "<byte string>", line 2, column 1:
    bye
    ^
could not find expected ':'
  in "<byte string>", line 3, column 1:

    ^

之所以存在差异,是因为get_mark()(中的reader.py)如果未处理流,则有更多指向的上下文:

def get_mark(self):
    if self.stream is None:
        return Mark(self.name, self.index, self.line, self.column,
                    self.buffer, self.pointer)
    else:
        return Mark(self.name, self.index, self.line, self.column,
                    None, None)

该数据进入context_mark属性。要为错误提供更多上下文时,请查看该内容。但是如上所示,仅当您从缓冲区而不是从stream解析YAML输入时,该方法才有效

搜索YAML源是一项艰巨的任务,各种类的所有方法都附加到它们是父类的Loader或Dumper上。跟踪此内容的最佳帮助是使用grepon def method_name(,因为至少方法名称都是与众不同的(因为它们必须起作用)。


在上面,我使用了增强的PyYAML版本ruamel.yaml,出于此答案的目的,它们应该相同。

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章

如何获取异常详细信息

如何获取运行时错误的完整信息而不是<超时获取异常详细信息>?

如何获取Windows文件详细信息?

如何获取Facebook Post详细信息?

如何从API获取版本详细信息

如何获取WooCommerce订单详细信息

如何获取推文的详细信息?

如何获取Java文件的“详细信息”

如何从班级中获取详细信息

如何使用Hangfire获取失败的后台作业的异常详细信息

如何从方法获取异常详细信息和方法返回的值

抛出异常的详细信息

Oracle异常详细信息

从Azure Worker角色获取异常详细信息

在 IIS 上发布后如何查看异常的详细信息

如何对未处理的异常使用“问题详细信息”响应?

如何从详细信息页面Angular 9中的单个对象(本地JSON)获取详细信息

如何在Android中获取“当前周”详细信息以及“季度详细信息”?

tcpdump:tcpdump如何获取主机名详细信息?

如何从C程序获取NIC详细信息?

如何从json api获取特定用户详细信息

如何实现PlaceAutocompleteFragment和PlaceAutocompleteActivity以获取位置详细信息

如何从img文件获取内核详细信息

如何通过Rails中的关联获取详细信息?

如何从 ExtentReport 获取测试步骤的详细信息

单击AppointmentPane时如何获取约会详细信息-JFXtras

重定向时如何获取表行详细信息

Powershell:如何获取防病毒产品详细信息

阅读提要,我如何从中获取详细信息