PyYAML 在我的单元测试中显示"ScannerError: mapping values are not allowed here"



我正在尝试使用unittest测试许多Python 2.7类。

这里有一个例外:

ScannerError: mapping values are not allowed here
in "<unicode string>", line 3, column 32:
... file1_with_path: '../../testdata/concat1.csv'

以下是错误消息涉及的示例:

class TestConcatTransform(unittest.TestCase):
def setUp(self):
filename1 = os.path.dirname(os.path.realpath(__file__)) + '/../../testdata/concat1.pkl'
self.df1 = pd.read_pickle(filename1)
filename2 = os.path.dirname(os.path.realpath(__file__)) + '/../../testdata/concat2.pkl'
self.df2 = pd.read_pickle(filename2)
self.yamlconfig =  u'''
--- !ConcatTransform
file1_with_path: '../../testdata/concat1.csv'
file2_with_path: '../../testdata/concat2.csv'
skip_header_lines: [0]
duplicates: ['%allcolumns']
outtype: 'dataframe'
client: 'testdata'
addcolumn: []
'''
self.testconcat = yaml.load(self.yamlconfig)

出了什么问题?

我不清楚的是,我的目录结构是:

app
app/etl
app/tests

ConcatTransformapp/etl/concattransform.py中,而TestConcatTransformapp/tests中。我使用以下导入将ConcatTransform导入TestConcatTransform单元测试:

from app.etl import concattransform

PyYAML如何将该类与yamlconfig中定义的类相关联?

YAML文档可以以文档开始标记---开始,但必须在一行的开头,您的文档在输入的第二行缩进八个位置。这导致---被解释为多行纯(即无引号(标量的开始,并且在这样的标量中不能有:(冒号+空格(。在带引号的标量中只能有:。如果你的文档在根级别没有映射或序列,就像你的文档没有一样,那么整个文档只能由一个标量组成。

如果您想像现在一样保持源代码的缩进,我建议您使用textwrap中的dedent

以下运行无错误:

import ruamel.yaml
from textwrap import dedent
yaml_config = dedent(u'''
--- !ConcatTransform
file1_with_path: '../../testdata/concat1.csv'
file2_with_path: '../../testdata/concat2.csv'
skip_header_lines: [0]
duplicates: ['%allcolumns']
outtype: 'dataframe'
client: 'testdata'
addcolumn: []
''')
yaml = ruamel.yaml.YAML()
data = yaml.load(yaml_config)

您应该养成在第一个三引号的末尾加上反斜杠((的习惯,因此您的YAML文档也是如此。如果您这样做,您的错误实际上会指示第2行,因为文档不再以空行开头。


在加载过程中,YAML解析器会对标记!ConcatTransform进行处理。对象的构造函数可能已在PyYAML加载程序中注册,在导入过程中使用PyYAML的add_constructor将该标记关联起来。

不幸的是,他们用默认的、不安全的加载程序注册了构造函数,这是不必要的,他们本可以用SafeLoader注册,从而不会强迫用户冒非受控输入问题的风险。

相关内容

最新更新