tanbro / pyyaml-include

yaml include other yaml
https://pypi.org/project/pyyaml-include/
GNU General Public License v3.0
77 stars 20 forks source link

Does not support top level include with other keys #7

Closed renard closed 5 years ago

renard commented 5 years ago

Here is my setup:

The python script (from the README):

import yaml
from yamlinclude import YamlIncludeConstructor

YamlIncludeConstructor.add_to_loader_class(loader_class=yaml.FullLoader)

with open('0.yml') as f:
     data = yaml.load(f, Loader=yaml.FullLoader)

print(data)

0.yml:

!include 1.yml
foo: bar

1.yml:

name: "1"

It seems that mixing toplevel include and other value is not (yet?) supported.

I got this error:

Traceback (most recent call last):
  File "../test.py", line 32, in <module>
    data = yaml.load(f, Loader=yaml.FullLoader)
  File "/usr/local/lib/python2.7/site-packages/yaml/__init__.py", line 114, in load
    return loader.get_single_data()
  File "/usr/local/lib/python2.7/site-packages/yaml/constructor.py", line 43, in get_single_data
    node = self.get_single_node()
  File "/usr/local/lib/python2.7/site-packages/yaml/composer.py", line 36, in get_single_node
    document = self.compose_document()
  File "/usr/local/lib/python2.7/site-packages/yaml/composer.py", line 58, in compose_document
    self.get_event()
  File "/usr/local/lib/python2.7/site-packages/yaml/parser.py", line 118, in get_event
    self.current_event = self.state()
  File "/usr/local/lib/python2.7/site-packages/yaml/parser.py", line 193, in parse_document_end
    token = self.peek_token()
  File "/usr/local/lib/python2.7/site-packages/yaml/scanner.py", line 129, in peek_token
    self.fetch_more_tokens()
  File "/usr/local/lib/python2.7/site-packages/yaml/scanner.py", line 223, in fetch_more_tokens
    return self.fetch_value()
  File "/usr/local/lib/python2.7/site-packages/yaml/scanner.py", line 579, in fetch_value
    self.get_mark())
yaml.scanner.ScannerError: mapping values are not allowed here
  in "0.yml", line 2, column 4
tanbro commented 5 years ago

Oh, it's a bad example in readme, and i'll remove it later.

Till now, !include constructor can NOT be used at the TOP level, unless it's the only one node in whole YAML document.

so:

!include include.d/1.yml

is correct

!include include.d/1.yml
# any other node

is WRONG

but

1: !include include.d/1.yml
2: !include include.d/2.yml
foo: boo

is correct

marcfiu commented 4 years ago

I get the same problem when doing:

thing: !include include.d/1.yml
       name: !include include.d/name.yml

Is that expected?

tanbro commented 3 years ago

I get the same problem when doing:

thing: !include include.d/1.yml
       name: !include include.d/name.yml

Is that expected?

No, it's not a valide YAML, i think.

Because the include constructor can not include YAML files literally -- it loads anoter YAML file, and parses it to a python object, then put it into original YAML document.

So, the above YAML snippet will be taken as:

thing: <included and parsed object>
   name: <another included and parsed object>

which is invalid.

BTW, if want to include literally, a template engine maybe better.