Как установить список со строками в качестве значения yaml при сохранении кавычек? - PullRequest
2 голосов
/ 09 февраля 2020

У меня есть такой код:

import ruamel.yaml
from ruamel.yaml.scalarstring import DoubleQuotedScalarString as dq    
yaml = ruamel.yaml.YAML()
yaml.indent(sequence=2)
yaml.preserve_quotes = True
yaml.default_flow_style=None

CF2_cloudbuild = {
            'steps':[
            {'name': dq("gcr.io/cloud-builders/gcloud"),
            'args': ["functions", "deploy", "publish_resized"],
            'timeout': dq("1600s")}
            ]
            }

with open("file.yaml", 'w') as fp:
    yaml.dump(CF2_cloudbuild, fp)

, и это содержимое file.yaml:

steps:
- name: "gcr.io/cloud-builders/gcloud"
  args: [functions, deploy, publish_resized]
  timeout: "1600s"

, и мне нужно:

steps:
- name: "gcr.io/cloud-builders/gcloud"
  args: ["functions", "deploy", "publish_resized"]
  timeout: "1600s"

чтобы получить формат, совместимый с документацией GCP относительно файлов конфигурации сборки Обзорная информация о конфигурации сборки GCP

Как это получить?
Когда я пытаюсь использовать функциональность [dq("functions"), dq("deploy"), dq("publish_resized")], я получаю :

steps:
- name: "gcr.io/cloud-builders/gcloud"
  args:
  - "functions"
  - "deploy"
  - "publish_resized"
  timeout: "1600s"

, который, я думаю, не совпадает с ["functions", "deploy", "publish_resized"].

1 Ответ

1 голос
/ 09 февраля 2020

Как указывает @Stephen Rauch, два выхода эквивалентны, один, который вам «нужен», имеет последовательность в стиле потока, а тот, который вы получаете, является последовательностью в стиле блока. Любой парсер YAML должен загружать его таким же образом. И если вы явно не добавите двойные кавычки, ruamel.yaml добавит их, если они необходимы (например, для предотвращения загрузки строки true в качестве логического значения).

Но так как вы установили .default_flow_style вы правы, ожидая, что листовой узел в выводе YAML будет иметь стиль потока, и вы, возможно, столкнулись с ошибкой в ​​ruamel.yaml round-tripdumper.

Когда ruamel.yaml загружает ваш ожидаемый результат, то он сохраняет

import sys
import ruamel.yaml

yaml_str = """
steps:
- name: "gcr.io/cloud-builders/gcloud"
  args: ["functions", "deploy", "publish_resized"]
  timeout: "1600s"
"""

yaml = ruamel.yaml.YAML()
yaml.preserve_quotes = True

data = yaml.load(yaml_str)
yaml.dump(data, sys.stdout)

, что дает:

steps:
- name: "gcr.io/cloud-builders/gcloud"
  args: ["functions", "deploy", "publish_resized"]
  timeout: "1600s"

Это потому, что узлы отображения и последовательности не загружаются как dict соответственно. list, его подклассы, которые хранят информацию об их исходном стиле потока / блока.

Вы можете эмулировать это, создав этот подкласс для своего списка:

from ruamel.yaml.scalarstring import DoubleQuotedScalarString as dq
from ruamel.yaml.comments import CommentedSeq

def cs(*elements):
     res = CommentedSeq(*elements)
     res.fa.set_flow_style()
     return res


CF2_cloudbuild = {
            'steps':[
            {'name': dq("gcr.io/cloud-builders/gcloud"),
            'args': cs(dq(l) for l in ["functions", "deploy", "publish_resized"]),
            'timeout': dq("1600s")}
            ]
            }

yaml.dump(CF2_cloudbuild, sys.stdout)

, что дает:

steps:
- name: "gcr.io/cloud-builders/gcloud"
  args: ["functions", "deploy", "publish_resized"]
  timeout: "1600s"

Но, опять же, если синтаксический анализатор YAML, который использует программное обеспечение Cloudbuilder, является совместимым, то ни стиль потока, ни какие-либо из двойных кавычек не нужны в вашем примере. И вы можете положиться на ruamel.yaml на добавление последних, если они необходимы.

...