Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

pyYAML Errors on "!" in a string

First, a disclaimer: I'm not too familiar with YAML. I'm trying to parse a YAML doc into Key Value Pairs (don't worry about how I'm doing it. I've got that bit handled)

My file used to look something like:

world:
     people:
          name:Suzy
          address:chez-bob

Then, someone went and changed it.

world:
     people:
          name:!$uzy
          address:chez-bob

And I get this parse error:

yaml.constructor.ConstructorError: could not determine a constructor for the tag '!$uzy'

What does this even mean? How would I go about getting it to just interpret !$ as just two characters? I just want a dictionary of string keys and values! Also, editing the yaml files is not an option. Problem must be fixed in the code using the parser.

like image 235
Rokujolady Avatar asked Nov 08 '12 01:11

Rokujolady


People also ask

What does PyYAML do?

PyYAML is a YAML parser and emitter for Python. Using the PyYAML module, we can perform various actions such as reading and writing complex configuration YAML files, serializing and persisting YMAL data. Use it to convert the YAML file into a Python dictionary.

Does YAML support tuple?

Support for Python builtin types and mappings of other types onto YAML syntax. Objects of commonly used Python builtin types may be tersely expressed in YamlConfig. Supported types are str, unicode, int, long, float, decimal. Decimal, bool, complex, dict, list and tuple.

What does YAML dump return?

dump will write the produced YAML document into the file. Otherwise, yaml. dump returns the produced document.

How do I create a nested YAML file in Python?

Creating a nested YAML file in python is relatively simple. First, you need to create a dictionary containing all the data you want to store in the YAML file. This dictionary contains three keys: 'foo', 'baz', and 'nested'. The value associated with the 'nested' key is a dictionary containing two key-value pairs.


2 Answers

Exclamation mark is a prefix for YAML tags. The parser has to implement a constructor for it by the tag name. There are some default tags like !!bool, !!int, etc. and even some Python specific tags like !!python/tuple.

You can define your own constructors and even constructors for multiple tags caught by a prefix. By defining the prefix to '', you can catch all the tags and ignore them. You can return the tag and its value from the constructor to just treat it all as text.

>>> import yaml
>>> def default_ctor(loader, tag_suffix, node):
...     print loader
...     print tag_suffix
...     print node
...     return tag_suffix + ' ' + node.value
...
>>> yaml.add_multi_constructor('', default_ctor)
>>> yaml.load(y)
<yaml.loader.Loader object at 0xb76ce8ec>
!$uzy
ScalarNode(tag=u'!$uzy', value=u'')
{'world': {'people': {'name': '!$uzy', 'address': 'chez-bob'}}}
>>>
like image 78
kichik Avatar answered Sep 16 '22 15:09

kichik


If a value starts with "!", you must enclose the value in single or double quotes; otherwise it is interpreted as a YAML tag.

world:
     people:
          name: "!$uzy"
          address: chez-bob
like image 30
Kirill Simonov Avatar answered Sep 20 '22 15:09

Kirill Simonov