2

I'm so confused right now. I'm using PyYAML for editing some YAML files.

data = yaml.load_all(open('testingyaml.yaml'),Loader=yaml.RoundTripLoader)

My testingyaml.yaml file contains the following content:

spring:
  profiles: dev
  datasource:
    url: jdbc:postgresql://127.0.0.1:5432/nfvgrid
dns:
  enable: false
cassandra:
  host: 192.168.7.151

When I print data it prints the following:

ordereddict([('spring', ordereddict([('profiles', 'dev'), ('datasource', ordereddict([('url', 'jdbc:postgresql://127.0.0.1:5432/nfvgrid')]))])), ('dns', ordereddict([('enable', False)])), ('cassandra', ordereddict([('host', '192.168.7.151')]))])

I further want to perform some operations on this ordered dictionary but python throws an error NameError: name 'ordereddict' is not defined

It's usually OrderedDict but somehow PyYAML returns ordereddict. How should I solve this issue?

4
  • Could it be possible it converts everything to lowercase? Commented Feb 2, 2016 at 22:23
  • What do you get when you do type(data)? My guess is that pyYaml is using some dictionary type of its own, not collections.OrderedDict. Commented Feb 2, 2016 at 22:25
  • Is this pyyaml, or ruamel.yaml? Commented Feb 2, 2016 at 22:26
  • I was mixing ruamel.yaml and pyyaml. Got it all sorted out now! Using simple pyYaml load_all() and it returns data of type "dict" which solves my problem. Thanks a lot for the quick response everyone. Saved my day. Commented Feb 2, 2016 at 22:44

2 Answers 2

4

You are almost certainly not using pyyaml as stated, as it does not have a RoundTripLoader. Instead you are probably using ruamel.yaml.

This alternative uses its own ruamel.ordereddict on python 2 installations, and the native collections.OrderedDict on python 3. This alternative supports most operations that OrderedDict does so there is no reason you cannot manipulate it. See its documentation.

However, if you wish to convert from one to the other, you could do something like:

x = collections.OrderedDict(some_ruamel_ordered_dict.items())
Sign up to request clarification or add additional context in comments.

1 Comment

Thanks a lot. Got it all sorted out now. Going with the basic pyYaml load_all() method and getting the desired output for further processing.
3

There is something strange going on, or you are not using the code example to load that file and then get that print from data. If you are really using yaml.load_all that will give you back a generator object which allows you to step over the 1 or more YAML document in that file. Since you're not using document directive markers, it makes little sense to use load_all():

from __future__ import print_function

import ruamel.yaml as yaml

datas = yaml.load_all(open('testingyaml.yaml'), Loader=yaml.RoundTripLoader)
print(datas, '\n', '-' * 50, sep='')
for data in datas:
    print(data['spring']['profiles'])
print(type(data))

gives: dev The actual type of data in the above example is a ruamel.yaml.comments.CommentedMap which is also what you would get if you did the simpler:

data = yaml.load(open('testingyaml.yaml'), Loader=yaml.RoundTripLoader)
print(type(data))

which prints <class 'ruamel.yaml.comments.CommentedMap'> (not the use of load() instead of loadall().

The CommentedMap is derived from ordereddict

from ruamel.yaml.compat import ordereddict
from ruamel.yaml.comments import CommentedMap
assert issubclass(CommentedMap, ordereddict)

because for roundtripping (you are using the RoundTripLoader) ruamel.yaml needs to preserve the order and have a place to attach any comments and other informations to preserve, which is not possible when using dict. ordereddict is a just a convenience class around ruamel.ordereddict (if available) or OrderedDict ¹.

You can of course import ordereddict yourself as above and use it, but if you don't need roundtripping nor preservation of order in your dictionaries (i.e. are fine with dict) just use the standard loader:

data = yaml.load(open('testingyaml.yaml'))
print(type(data))

prints:

<type 'dict'>

I recommend not to "downgrade" by using PyYAML: it only implements the old 1.1 version of YAML, and although ruamel.yaml is a derivative of PyYAML, since it was derived, it has quite a few issues solved that originally wer filed against, and still pertain to, PyYAML ².


¹ ruamel.ordereddict is a (fast) C implementation of ordered dicts that existed already for a few years before OrderedDict appeared in the standard library, as the standard library version has a small subset of functionality, and until Python 3.5 was (slow) pure Python, switching to OrderedDict was never really an option for me.
² But then I am biased as I am the author of ruamel.yaml (and know that it needs more documentation).

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.