我想优雅地通知用户确切的他们被破坏的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上。跟踪此内容的最佳帮助是使用grep
on def method_name(
,因为至少方法名称都是与众不同的(因为它们必须起作用)。
在上面,我使用了增强的PyYAML版本ruamel.yaml,出于此答案的目的,它们应该相同。
本文收集自互联网,转载请注明来源。
如有侵权,请联系 [email protected] 删除。
我来说两句