Basic usage of ccorp-ruamel-yaml-include in Python to include YAML

Viewed 429

I am trying to use ccorp-ruamel-yaml-include to process !include directives in a YAML file. I have tried to follow the worked example in the source files, but receive a cryptic error. Is there a tutorial on how to use this package, or can someone point out my error in the following example?

With the two YAML files, founder.yaml

founder: &alice
   name: Alice P. Smith
   birthdate: 29 February 1970
   pref-pronouns: she/her

and org.yaml

!exclude includes:
- !include founder.yaml

organization:
 name: The Eudaimonia Fund
 tagline: Promoting a better life for all
 founder: <<: *alice
 board:
   - name: Jane Person
     birthdate: September 1, 1970
     role: secretary
   - <<: *alice
     role: chair

and this script,

#!/usr/bin/python

import ruamel.yaml

from ccorp.ruamel.yaml.include import YAML

reader = YAML(typ='safe', pure=True)
reader.allow_duplicate_keys = True

with open('org.yaml', 'r') as g:
    data = reader.load(g)

print("Ccorp Ruamel Yaml Include") 
print(data)

The response is:

Traceback (most recent call last):
  File "ccorp-ruamel-yaml-test.py", line 11, in <module>
    data = reader.load(g)
  File "/Users/<uname>/Library/Python/3.8/lib/python/site-packages/ruamel/yaml/main.py", line 343, in load
    return constructor.get_single_data()
  File "/Users/<uname>/Library/Python/3.8/lib/python/site-packages/ruamel/yaml/constructor.py", line 111, in get_single_data
    node = self.composer.get_single_node()
  File "/Users/<uname>/Library/Python/3.8/lib/python/site-packages/ruamel/yaml/composer.py", line 78, in get_single_node
    document = self.compose_document()
  File "/Users/<uname>/Library/Python/3.8/lib/python/site-packages/ruamel/yaml/composer.py", line 101, in compose_document
    node = self.compose_node(None, None)
  File "/Users/<uname>/Library/Python/3.8/lib/python/site-packages/ruamel/yaml/composer.py", line 138, in compose_node
    node = self.compose_mapping_node(anchor)
  File "/usr/local/lib/python3.8/site-packages/ccorp/ruamel/yaml/include/__init__.py", line 38, in compose_mapping_node
    return self.__compose_dispatch(anchor, MappingNode, super().compose_mapping_node)
  File "/usr/local/lib/python3.8/site-packages/ccorp/ruamel/yaml/include/__init__.py", line 27, in __compose_dispatch
    return compositor(anchor)
  File "/Users/<uname>/Library/Python/3.8/lib/python/site-packages/ruamel/yaml/composer.py", line 218, in compose_mapping_node
    item_value = self.compose_node(node, item_key)
  File "/Users/<uname>/Library/Python/3.8/lib/python/site-packages/ruamel/yaml/composer.py", line 136, in compose_node
    node = self.compose_sequence_node(anchor)
  File "/usr/local/lib/python3.8/site-packages/ccorp/ruamel/yaml/include/__init__.py", line 35, in compose_sequence_node
    return self.__compose_dispatch(anchor, SequenceNode, super().compose_sequence_node)
  File "/usr/local/lib/python3.8/site-packages/ccorp/ruamel/yaml/include/__init__.py", line 27, in __compose_dispatch
    return compositor(anchor)
  File "/Users/<uname>/Library/Python/3.8/lib/python/site-packages/ruamel/yaml/composer.py", line 180, in compose_sequence_node
    node.value.append(self.compose_node(node, index))
  File "/Users/<uname>/Library/Python/3.8/lib/python/site-packages/ruamel/yaml/composer.py", line 134, in compose_node
    node = self.compose_scalar_node(anchor)
  File "/usr/local/lib/python3.8/site-packages/ccorp/ruamel/yaml/include/__init__.py", line 32, in compose_scalar_node
    return self.__compose_dispatch(anchor, ScalarNode, super().compose_scalar_node)
  File "/usr/local/lib/python3.8/site-packages/ccorp/ruamel/yaml/include/__init__.py", line 29, in __compose_dispatch
    return compositor(self, anchor)
  File "/usr/local/lib/python3.8/site-packages/ccorp/ruamel/yaml/include/__init__.py", line 106, in include_compositor
    yaml = self.loader.fork()
  File "/usr/local/lib/python3.8/site-packages/ccorp/ruamel/yaml/include/__init__.py", line 99, in fork
    yaml = type(self)(typ=self.typ, pure=self.pure)
  File "/usr/local/lib/python3.8/site-packages/ccorp/ruamel/yaml/include/__init__.py", line 64, in __init__
    raise Exception("Can't do typ={} parsing w/ composition time directives!".format(kwargs['typ']))
Exception: Can't do typ=['safe'] parsing w/ composition time directives!

Removing one or both arguments (typ=['safe'] or pure=True) from the initialization of the reader on line 7 produces the same errors.

What have I done wrong?

2 Answers

The error looks a bit cryptic but it is accurate. Include is a composition-time extension, in other words one that happens during the composition phase of interpreting the yaml, and you can’t use those in safe mode.

You are on the right track in looking at the init arguments, safe mode is the default so taking them out doesn’t help, but you need to put in ones that allow extensions, I can’t remember exactly the details off the top of my head

Looks like there is type mismatch between ruamel.yaml and ccorp.ruamel.yaml.include.

in ruamel.yaml, the 'typ' type is a list (line 65).

In example.py, it should be

yaml = YAML(typ=['safe'], pure=True)

As well as in init.py

if 'typ' not in kwargs:
    kwargs['typ'] = ['safe']
elif kwargs['typ'] not in (['safe'], ['unsafe']):

After doing these two changes, it works fine.

Related