Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Skip converting entities while loading a yaml string (using PyYAML)

Tags:

python

yaml

Is there a nice way to prevent the conversion of entities to python objects while loading a YAML string the yaml package? Particularily, I do not want the conversion of timestamp-strings to datetime objects.

Here is an example:

import yaml
yaml.load("""d: 2018-06-17\nn: 42""")

which gives

{'d': datetime.date(2018, 6, 17), 'n': 42}

but I would like to have

{'d': '2018-06-17', n: 42}

where the date string remains as the string and other types are converted. I do not want to change the input string, e.g., by specifying specific data types. Maybe there is an alternative YAML loader/parser package. I'm using python3.6 and PyYAML==3.12.

like image 344
desiato Avatar asked Jun 17 '18 21:06

desiato


People also ask

How do I load a YAML file in Python?

We can read the YAML file using the PyYAML module's yaml. load() function. This function parse and converts a YAML object to a Python dictionary ( dict object). This process is known as Deserializing YAML into a Python.

Can PyYAML parse JSON?

It is often used for configuration files, but can also be used for data exchange. The most used python YAML parser is PyYAML, a library that allows you to load, parse, and write YAML, much like Python's JSON library helps you to work with JSON.

What does YAML dump do?

yaml. dump(data) produces the document as a UTF-8 encoded str object. yaml. dump(data, encoding=('utf-8'|'utf-16-be'|'utf-16-le')) produces a str object in the specified encoding.

Is PyYAML same as YAML?

YAML is a data serialization format designed for human readability and interaction with scripting languages. PyYAML is a YAML parser and emitter for the Python programming language.


1 Answers

YAML has several schema's and since you are using the default (unsafe) load in PyYAML you get all of the constructions to Python objects that it supports, including the one to int that you want, and the one to datetime.time that you don't want.

Since you want the integers to be converted, you cannot use the baseloader:

import yaml
data = yaml.load("""d: 2018-06-17\nn: 42""", Loader=yaml.BaseLoader)
print(data)

as this gives strings everywhere:

{'d': '2018-06-17', 'n': '42'}

It is probably easiest to process the matched datetime objects as strings. In my ruamel.yaml library you can do so by using:

import ruamel.yaml

yaml = ruamel.yaml.YAML(typ='safe')
yaml.constructor.yaml_constructors[u'tag:yaml.org,2002:timestamp'] = \
   yaml.constructor.yaml_constructors[u'tag:yaml.org,2002:str']
data = yaml.load("""d: 2018-06-17\nn: 42""")
print(data)

if you only need to support the old YAML 1.1 specification, you can do the same in PyYAML:

import yaml
import yaml.constructor
yaml.constructor.SafeConstructor.yaml_constructors[u'tag:yaml.org,2002:timestamp'] = \
    yaml.constructor.SafeConstructor.yaml_constructors[u'tag:yaml.org,2002:str']

data = yaml.safe_load("""d: 2018-06-17\nn: 42""")
print(data)

both print:

{'d': '2018-06-17', 'n': 42}
like image 117
Anthon Avatar answered Sep 30 '22 17:09

Anthon