【问题标题】:Ruamel yaml bad dumpRuamel yaml 坏转储
【发布时间】:2018-04-05 20:27:13
【问题描述】:

我有一个 Python 脚本,它尝试从“main.yml”文件生成自述文件。

我可以转储 YML 流的每一行,但在每一行,ruamel.yaml 似乎都添加了一行带有“...”字符串的行。

我的 Python:

#!/usr/bin/python

import os, sys
import argparse
import ruamel.yaml

ROLES_PATH="../"
DESC_SCRIPT = 'This program will try to generate MD documentation from variables files of an Ansible role'

parser = argparse.ArgumentParser(description = DESC_SCRIPT)
parser.add_argument("-r", "--role", help="specify the name of existing role")
if len(sys.argv)<2:
   parser.print_help(sys.stderr)
   sys.exit(1)

args = parser.parse_args()

if args.role:
   README=(ROLES_PATH+args.role+"/README.md")
   if os.path.isfile(README):
      print(sys.argv[0]+": README.md already exists for %s" % args.role)
      print(sys.argv[0]+": Exiting... ")
      sys.exit(2)
   if os.path.isdir(ROLES_PATH+args.role):
      print(sys.argv[0]+": Role found")
      print(sys.argv[0]+": Selected role is %s" % args.role)

      readme_file = open(README, 'w')
      readme_file.write("Role Name\n=========\n%s\n\nRequirements\n------------\n- Debian\n\nRole variables (default)\n--------------\n\n" % args.role)

      yml = ruamel.yaml
      yml.YAML.explicit_start = True
      yml.YAML.default_flow_style = None
      yml.YAML.encoding = "utf-8"
      yml.YAML.allow_unicode = True
      yml.YAML.errors = "strict"

      readme_file = open(README, 'a+')
      with open(ROLES_PATH+args.role+"/defaults/main.yml", "r") as stream:
         code = yml.load(stream, Loader=yml.RoundTripLoader)
         print(code)
         for line in code:
            print(type(line))
            print("Line : %s" % line)
            yml.dump(line, readme_file, Dumper=yml.RoundTripDumper)

我的 main.yml :

---
apache_datadir: '/var/www'
apache_security_configuration: '/etc/apache2/conf-available/security.conf'
apache_default_vhost: '/etc/apache2/sites-available/default.conf'
apache_mpm: event
apache_mod_list:
  - headers
  - ssl
  - rewrite

我的 README 生成:

Role Name
=========
ansible-apache

Requirements
------------
- Debian

Role variables (default)
--------------

apache_datadir
...
apache_security_configuration
...
apache_default_vhost
...
apache_mpm
... 
apache_mod_list
...

我不明白为什么每行都会生成“...”。 我试图做类似 "if line is '...'" 的事情,但它不起作用。

【问题讨论】:

  • 你在哪里学习yml.YAML.explicit_start = True?这真是大错特错。

标签: ruamel.yaml


【解决方案1】:

每当您转储一个没有缩进的普通、折叠或文字标量时(即,当它们是唯一要转储的节点时),ruamel.yaml 就会添加这些文档结束标记。这是从 PyYAML 继承的行为。

在内部这是因为属性open_ended 是在Emitter 实例上设置的,虽然您可以重写那里的方法而不是这样做,但将字符串写入readme_file 而不是转储要容易得多字符串为 YAML:

if isinstance(line, str):
    readme_file.write(line + '\n')
else:
    yml.dump(line, readme_file, Dumper=yml.RoundTripDumper)

如果您预先知道所有line 值都将是字符串,那么您根本不需要使用dump。

您似乎还将旧式加载/转储与新的ruamel.yaml API 结合起来。这个:

  yml = ruamel.yaml
  yml.YAML.explicit_start = True
  yml.YAML.default_flow_style = None
  yml.YAML.encoding = "utf-8"
  yml.YAML.allow_unicode = True
  yml.YAML.errors = "strict"

对yml.dump 没有影响。您可能想要做的是:

  yml = ruamel.yaml.YAML()
  yml.explicit_start = True
  yml.default_flow_style = None 
  yml.encoding = "utf-8"     # default when using YAML() or YAML(typ="rt")
  yml.allow_unicode = True   # always default in the new API
  yml.errors = "strict"

然后使用yml.dump(data, file_pointer) 转储(即没有RoundTripDumper)

【讨论】:

    猜你喜欢
    • 2021-02-19
    • 1970-01-01
    • 2021-12-17
    • 1970-01-01
    • 2016-05-27
    • 1970-01-01
    • 2021-11-26
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多