читатель yaml и jinja2

Я хотел бы иметь возможность читать в python файл конфигурации YAML jinja, например, используя библиотеку PyYAML, но я получаю ошибки:

{% set name = "abawaca" %}
{% set version = "1.00" %}

package:
   name: {{ name }}
   version: {{ version }}

source:
   fn: {{ name }}-{{ version }}.tar.gz
   url: https://github.com/CK7/abawaca/archive/v{{ version }}.tar.gz
   sha256: 57465bb291c3a9af93605ffb11d704324079036205e5ac279601c9e98c467529

build:
   number: 0

requirements:
   build:
        - gcc   # [not osx]
        - llvm  # [osx]

person ypriverol    schedule 07.02.2017    source источник
comment
Я обновил свой ответ полным рабочим примером. Извините, что так долго не мог вернуться к этому.   -  person Anthon    schedule 28.04.2017


Ответы (1)


Ваш ввод недействителен YAML, как вы можете легко проверить, например. здесь Сначала следует развернуть конструкции {% %}, а затем обработать YAML, либо сделать ваш файл в действительный YAML.

Это отчасти является следствием выбора jinja2, для которого последовательности макросов {% ... %} начинаются с символа ({), имеющего особое значение в YAML.

Если вам нужно изменить YAML и записать его снова, вы можете определить свои собственные разделители и выбрать их так, чтобы они не имели особого значения в YAML.

{% %} вы должны поместить в блок комментариев YAML, так как на верхнем уровне у вас есть сопоставление и должны быть только пары ключ-значение. Один из способов добиться этого — переопределить начало как #% %# (вам не обязательно менять конец, но я предпочитаю симметрию).

Затем после обновления запустите правильный YAML через небольшой скрипт, который обрабатывает файл и заменяет разделители на те, которые понимает jinja2, или настраивайте среду, чтобы изменить фактические определения, используемые jinja2.

исправил data.yaml:

#% set name = "abawaca" %#
#% set version = "1.00" %#

package:
   name: <{ name }>
   version: 42

source:
   fn: <{ name }>-<{ version }>.tar.gz
   url: https://github.com/CK7/abawaca/archive/v<{ version }>.tar.gz
   sha256: 57465bb291c3a9af93605ffb11d704324079036205e5ac279601c9e98c467529

build:
   number: 0

requirements:
   build:
      - gcc   # [not osx]
      - llvm  # [osx]

Это может быть обработано:

import jinja2
from ruamel import yaml

yaml_file = 'data.yaml'
tmp_file = 'tmp.yaml'

data = yaml.round_trip_load(open(yaml_file))
data['package']['version'] = '<{ version }>'
with open(tmp_file, 'w') as fp:
    yaml.round_trip_dump(data, fp)

environment = jinja2.Environment(
    loader=jinja2.FileSystemLoader(searchpath='.'),
    trim_blocks=True,
    block_start_string='#%', block_end_string='%#',
    variable_start_string='<{', variable_end_string='}>')

    print(environment.get_template(tmp_file).render())

давать:

package:
  name: abawaca
  version: 1.00

source:
  fn: abawaca-1.00.tar.gz
  url: https://github.com/CK7/abawaca/archive/v1.00.tar.gz
  sha256: 57465bb291c3a9af93605ffb11d704324079036205e5ac279601c9e98c467529

build:
  number: 0

requirements:
  build:
  - gcc       # [not osx]
  - llvm      # [osx]

Обратите внимание, что вы должны использовать `ruamel.yaml (отказ от ответственности: я являюсь автором этого пакета), вы не можете сделать это так же легко с PyYAML, поскольку он отбрасывает комментарии при чтении файла YAML. Поскольку все jinja2 в комментариях находятся в начале файла, вы можете обойти это с помощью этого конкретного примера, но в целом это не так.

person Anthon    schedule 07.02.2017
comment
Спасибо @anthon, но знаете ли вы, как программно расширить yaml и прочитать результат с помощью yaml. - person ypriverol; 07.02.2017
comment
Вы можете расширить конструкции, прочитав их через jinja2, вы получите файл и прочитаете этот файл своим парсером. - person Anthon; 07.02.2017
comment
у вас есть пример (фрагмент кода) Я пробовал это раньше и не работал. - person ypriverol; 07.02.2017
comment
Нет, я не использую jinja2 и не использую PyYAML при работе на Python с YAML. - person Anthon; 07.02.2017
comment
Мне понадобится пример, потому что я упоминаю, потому что у меня нет опыта работы с jinja2. - person ypriverol; 07.02.2017
comment
Кто-нибудь может здесь помочь? - person ypriverol; 07.02.2017