Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is it possible to emit valid YAML with anchors / references disabled using Ruby or Python?

Tags:

python

ruby

yaml

Is it possible to disable creating anchors and references (and effectively list redundant data explicitly) either in PyYAML or Ruby's Psych engine?

Perhaps I missed something while searching the web, but it seems there are not many options available in Psych and I was not able to determine if PyYAML allows for that either.

The rationale is I have to serialize some data and pass it in a readable form to a not-really-technical co-worker for manual validation. Some data is redundant but I need it listed in a most explicit manner for readability (anchors and references are a nice concept for efficiency, but not for human-readability).

Ruby and Python are my tools of choice, but if there is some other reasonably simple way of 'unfolding' YAML documents, it might just do.

like image 243
moon.musick Avatar asked Jan 09 '14 09:01

moon.musick


People also ask

How do I use anchors in YAML?

Introducing YAML anchors We define an anchor using the &some_name syntax immediately before the YAML node we want that anchor to point to. We can then use the *some_name syntax later in the YAML to reference that anchor as many times as we want.

What is * id001?

&id001 - example of an anchor, placed with the first occurrence of data. *id001 - example of an alias, replaces subsequent occurrence of data.

What are YAML aliases?

YAML Aliases allow you to assign a name to a value or block of data and recall the assigned data by its name in the YAML file. Aliases should work for any file written in YAML.


1 Answers

I found this related ticket on the PyYAML website (http://pyyaml.org/ticket/91), it looks like anchors can be disabled by using a custom dumper along the lines of:

import yaml

class ExplicitDumper(yaml.SafeDumper):
    """
    A dumper that will never emit aliases.
    """

    def ignore_aliases(self, data):
        return True

So, for example, the following outputs can be achieved using the standard dumper and the new explicit dumper:

>>> yaml.dump([1L, 1L])
"[&id001 !!python/long '1', *id001]\n"

>>> yaml.dump([1L, 1L], Dumper=ExplicitDumper)
'[1, 1]\n'

You can customise further properties to ensure pretty-printing etc. in the yaml.dump(...) call.

like image 120
Brett Lempereur Avatar answered Sep 23 '22 01:09

Brett Lempereur