Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What is the difference between ! and !! in yaml?

I'm trying to load a YAML that looks like this:

dist: !!opencv-matrix
   rows: 380
   cols: 380
   dt: f
   data: [ 0., 0., -1.88644529e+18, 2.45423365e+00, 11698176.,
       2.03862047e+00, -8.85501460e+10, 2.54738545e+00, 1.71208843e+20,
       ...
       2.44447327e+00 ]

The loading code is just:

import yaml
y = yaml.load(s)

where s is the YAML loaded into a string.

I get this error:

yaml.constructor.ConstructorError: could not determine a constructor for the tag 'tag:yaml.org,2002:opencv-matrix'
  in "<string>", line 382, column 7:
    dist: !!opencv-matrix

This is fair enough, so I add the constructor for that tag:

def opencv_matrix(loader, node):
    mapping = loader.construct_mapping(node)
    mat = np.array(mapping["data"])
    mat.resize(mapping["rows"], mapping["cols"])
    return mat

yaml.add_constructor(u"!!opencv-matrix", opencv_matrix)
y = yaml.load(s)

I still get the error. However, if I replace !!opencv_matrix with !opencv_matrix, then everything works.

What's going on here?

like image 513
mpenkov Avatar asked Apr 12 '13 05:04

mpenkov


People also ask

What does |- mean in YAML?

All YAML files (regardless of their association with Ansible or not) can optionally begin with --- and end with ... . This is part of the YAML format and indicates the start and end of a document. All members of a list are lines beginning at the same indentation level starting with a "- " (a dash and a space):

What is hyphen in YAML?

Summary. Items of a list in YAML are represented by preceding it with - (hyphen). Key value pairs in YAML are represented as <key>:<value> . YAML is case sensitive. YAML uses spaces and indentations to define document structure.

Is .YML and .YAML same?

YAML - yaml vs yml file Yaml files created with yaml and yml file extensions, Both are the same in interpretation and syntax. Nowadays, there is no OS system level enforcement to have 3 letters in extensions. Most of the yaml users are using . yaml as their preferred choice.

Is YAML better than JSON?

YAML is better suitable for configuration than JSON, whereas JSON is suitable for serialization format and transferring the data for API. JSON is good for human readability and suitable for serialization. It is explicit and can transmit the data over HTTP.


1 Answers

Secondary tags like !!opencv-matrix are actually shorthand for tag:yaml.org,2002:opencv-matrix (mentioned in the reference card). It looks like PyYAML's add_constructor method doesn't correctly handle this shorthand notation.

This may be a bug, depending on how secondary tags are interpreted (see second part below). I've submitted a bug report here, and hopefully it will be addressed.

Primary tags like !opencv-matrix are defined explicitly, and loading seem to work without any problems in PyYAML.

It works for me if you replace !!opencv-matrix with tag:yaml.org,2002:opencv-matrix in the add_constructor call.


As for the original question, AFAIK primary tags (!) are for user-defined types, while secondary tags (!!) are meant to represent standard language-independent types defined here (hence the long and fancy format).

If this is an OpenCV-generated file, then maybe it would probably be simpler if these tags were changed to primary tags in the application.

like image 193
marshall.ward Avatar answered Sep 24 '22 20:09

marshall.ward