无法转储为 "pure" YAML

Unable to dump as "pure" YAML

ruamel.yaml==0.15.37
Python 3.6.2 :: Continuum Analytics, Inc.

当前代码:

from ruamel.yaml import YAML
import sys


yaml = YAML()
kube_context = yaml.load('''
    apiVersion: v1
    clusters: []
    contexts: []
    current-context: ''
    kind: Config
    preferences: {}
    users: []
''')
kube_context['users'].append({'name': '{username}/{cluster}'.format(username='test', cluster='test'), 'user': {'token': 'test'}})
kube_context['clusters'].append({'name': 'test', 'cluster': {'server': 'URL:443'}})
kube_context['contexts'].append({'name': 'test', 'context': {'user': 'test', 'cluster': 'test'}})

yaml.dump(kube_context, sys.stdout)

我的 yaml.dump() 正在生成包含列表和字典对象的输出,而不是完全展开。

当前输出:

apiVersion: v1
clusters: [{name: test, cluster: {server: URL:443}}]
contexts: [{name: test, context: {user: test, cluster: test}}]
current-context: ''
kind: Config
preferences: {}
users: [{name: test/test, user: {token: test}}]

我需要做什么才能使 yaml.dump() 输出完全展开?

预期输出:

apiVersion: v1
clusters: 
  - name: test
    cluster: 
      server: URL:443
contexts: 
  - name: test
    context:
      user: test
      cluster: test
current-context: ''
kind: Config
preferences: {}
users: 
  - name: test/test
    user: 
      token: test

输出是“纯”YAML。您希望节点以 块样式 (indentation-based) 呈现,而不是当前的 流样式 ([]{}-基于)。方法如下:

yaml = YAML(typ="safe")
yaml.default_flow_style = False

(注意Athon对下面typ的评论;您需要将其设置为safeunsafe,这样RoundTripLoader就不会设置空序列的样式)

ruamel.yaml,当使用默认的 YAML()YAML(typ='rt') 时,将保留 flow- or block 样式的序列和映射。没有办法使块样式为空序列或空映射,因此您的 []{} 在加载时被标记为流样式。

流式只能包含流式(而块式可以包含块式或流式)(YAML 1.2 spec 8.2.3):

YAML allows flow nodes to be embedded inside block collections (but not vice-versa).

因此,您在 (flow-style) list/sequence 中插入的 dict/mapping 数据也将表示为 flow-style.

如果你希望一切都是块样式(你称之为 "expanded" 模式),你可以通过调用 .fa 属性(这是仅在集合中可用,因此 try/except):

from ruamel.yaml import YAML
import sys


yaml = YAML()

kube_context = yaml.load('''
    apiVersion: v1
    clusters: []
    contexts: []
    current-context: ''
    kind: Config
    preferences: {}
    users: []
''')
kube_context['users'].append({'name': '{username}/{cluster}'.format(username='test', cluster='test'), 'user': {'token': 'test'}})
kube_context['clusters'].append({'name': 'test', 'cluster': {'server': 'URL:443'}})
kube_context['contexts'].append({'name': 'test', 'context': {'user': 'test', 'cluster': 'test'}})

for k in kube_context:
    try:
        kube_context[k].fa.set_block_style()
    except AttributeError:
        pass

yaml.dump(kube_context, sys.stdout)

这给出:

apiVersion: v1
clusters:
- name: test
  cluster:
    server: URL:443
contexts:
- name: test
  context:
    user: test
    cluster: test
current-context: ''
kind: Config
preferences: {}
users:
- name: test/test
  user:
    token: test

请注意,默认round-trip-mode中不需要设置yaml.default_flow_style = False;并且尽管 block-style 已经设置为键 preferences 的值,但它表示流样式,因为没有其他方式表示空映射。