Why does the YAML spec mandate a space after the colon?
Asked Answered
O

2

21

The YAML spec clearly states:

Mappings use a colon and space (“: ”) to mark each key: value pair.

So this is legal:

foo: bar

But this, Ain't:

foo:bar

I see many people online that are ranting about the space. I think they have a point. I got burned by it several times myself.

Why is the space mandatory? What was the design consideration behind it?

Oscine answered 8/2, 2017 at 21:44 Comment(0)
E
27

It's easy to miss, because that specification uses the bizarre convention of only highlighting the last character of an internal link, but the “: ” in the section you quote is actually a link to another section of the specification which answers your question:

Normally, YAML insists the “:” mapping value indicator be separated from the value by white space. A benefit of this restriction is that the “:” character can be used inside plain scalars, as long as it is not followed by white space. This allows for unquoted URLs and timestamps. It is also a potential source for confusion as “a:1” is a plain scalar and not a key: value pair.

So the motivation is that you can write lists such as this without requiring any quoting:

useful_values:
- 2:30
- http://example.com
- localhost:8080

If the space was optional, this could end up being ambiguous, and interpreted as a set of key-value pairs.

Aside: Here's a snippet of JS to make the link formatting on that document less useless.

document.styleSheets[0].insertRule('a[href^="#"] { color: #00A !important; text-decoration: underline !important; background: none !important; }', 0);
Edgardoedge answered 8/2, 2017 at 21:55 Comment(2)
I wonder why yamllint.com goes against the spec and says that "key:value" is valid yaml syntax.Friede
We just break the spec on this, and on the requirement that indentation always be made of spaces, by preprocessing all YAML input text with a custom function. It only takes about 20 lines of code and, boy, is it worth it in eliminated headaches for our customers that compose YAML.Charliecharline
L
2

Actually, space after column is not always mandatory. It is optional if two conditions are met:

  1. Flow style syntax is used (aka JSON / one-liner / {} / []);
  2. The key is quoted.

This syntax is valid (pyyaml=5.3.1):

{"x":abc}

Output: {'x': 'abc'}

But be careful:

{x:abc}  # {'x:abc': None}
  # Can't separate key from value if not quoted
---
{x:"abc"}  # {'x:"abc"': None}
  # Same problem

More edge cases with colon and space:

x:::abc  # 'x:::abc'
    # Scalar, not a key-value
---
x:: :abc  # {'x:': ':abc'}
    # Avoid this, use quotes to be safe if `:` is
    # involved in either key or value.
---
{x:: :abc}  # Error: while parsing a flow node expected the node
            # content, but found ':'
    # Parsing logic for flow syntax can be surprising.
---
{"x:":":abc"}  # {'x:': ':abc'}
    # Follow the "least surprise principle" - stick to JSON syntax.
Lowermost answered 29/1, 2022 at 20:11 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.