strictyaml
strictyaml copied to clipboard
What is the rationale for disabling flow-style arrays?
The docs/why/flow-style-removed.md
outlines the reasonable argument for disabling flow-style mappings:
- The difference between inline mappings and explicit mappings is confusing.
- The curly brackets can denote different things when used as a part of complex toolchain. Notably, Django and Jinja use
{{stuff-like-this}}
for templating; the python itself uses{stuff-like-this}
.
However, I cannot help but notice that all of those arguments are related to flow-style mappings and use only them as examples. Meanwhile, all counterarguments are related to the flow-style arrays, not flow-style mappings.
Is there a reason for disallowing inline arrays? I don't think anybody uses square brackets for templating, and the both forms of arrays seem natural for me, and easy to understand.
The inspection of code does not show anything problematic: https://github.com/crdoconnor/strictyaml/blob/3b535705d283bcac667e3bdc59be052d9325b13c/strictyaml/parser.py#L210
It seems easy enough to disallow FlowMappingStartToken while tolerating FlowSequenceStartToken.
Sorry to leave this hanging. I should have responded earlier.
Is there a reason for disallowing inline arrays?
The rationale is pretty much the same as for mapping:
-
There's already one, obvious way to represent lists - a dash on each line. I tend to follow the rule of there should be one obvious way of doing things (i.e. the zen of python). This also means that a serializer doesn't have to "think" or be told about whether to represent a list of things using dash notation or flow style - there is only one way of representing a list.
-
Related : a goal of StrictYAML was that it should be viewable and editable by non-programmers. I tend to find that non-programmers get confused by this notation (obvious though it is to programmers).
-
It can be syntactically confusing - especially if you are trying to distinguish strings that have [ and ] vs arrays. I have seen square brackets used for templating as well as several other things that you might want to put in a yaml value.
There are some down sides - notably, that [] is quite a neat way of representing an empty list and for lists that are short it's nice and compact and readable.
For me [a, b, c]
feels more clean, convenient and obvious than multiline description with dash on each line (at least, for most of my use-cases).
should be viewable and editable by non-programmers
That's fair.
and for lists that are short it's nice and compact and readable.
I don't think it's about length. I think it mainly depends on entries' complexity:
target_numbers:
- 1
- 2
- 3
- 4
- 5
- 6
feels too verbose, but target_numbers: [1, 2, 3, 4, 5, 6]
feels natural.
On the other hand,
possible_clients:
- name: John
last_name: Doe
country: US
- name: Jane
last_name: Doe
country: UK
- name: Hans
last_name: Smith
country: DE
- name: Stas
last_name: Medvedev
country: RU
feels OK, while flow-style would be very clunky. (Note that the length of first list is 6, but the length of second one is 4)
Strings occupy middle ground, where both fruits: ['apple', 'banana', 'watermellon']
and
fruits:
- apple
- banana
- watermelon
look natural.
Maybe some restriction based on type would be reasonable?
For me [a, b, c] feels more clean, convenient and obvious than multiline description with dash on each line (at least, for most of my use-cases).
Understood.
For what it's worth, you can achieve much the same effect with the comma separated validator: https://hitchdev.com/strictyaml/using/alpha/scalar/comma-separated/
key: a, b, c
Does this fit your use case?
That's great! It does fit my use case, maybe even better than [a, b, c]
(even the empty list, I think?).
I suggest you expand on docs/why/flow-style-removed.md
and mention comma separated validator as possibly superior alternative to flow-style arrays.
Will do, yes. Thanks for the tip.
I just got an error related to this issue, because I wrote []
, an empty array. I use lists with dashes everywhere, except when I need to write an empty array. All answers on the internet on how to write an empty array in YAML point me to []
, which makes StrictYAML perhaps way too strict. I understand if StrictYAML prevents notation which is cryptic or leads to errors, but this is apparently a recommended way how to do something in YAML and it doesn't work. I can't think of another way to write an empty array myself, and I'm quite proficient in both JSON and YAML. Is there any at all?
Update:
I tried speakers: []
, speakers: ,
, no luck. Obviously things like
speakers:
-
or
speakers:
end up with a validation error, as this is an array with a single empty string. My schema is an array of 0 to infinity items which are integers.
Update:
I had to rewrite my whole YAML document to use comma-separated integers instead of classic lists. I'm a big fan of StrictYAML, but I don't think this is the best design decision. Perhaps disallowing [1, 2, 3]
is correct direction, but I'd keep []
as a shortcut as it's pretty straightforward and widely used. Also I really don't think there's another way how to make a list empty. Let's say you have 30 lists in your document and only 1 is empty, the others you'd like to have with items on separate lines for better readability. I don't think this is currently possible.
I came across the same problem as @honzajavorek : there seems to be no good way of representing an empty array using StrictYAML.
Admittedly, I haven't thought much about this... but my favorite solution would be to make an exception to the no-flow-style rule for empty arrays (and maybe empty mappings?). Something like this:
In [1]: import strictyaml
In [2]: strictyaml.load("hello:\n- world").data
Out[2]: {'hello': ['world']}
In [3]: strictyaml.load("hello: [world]").data
FlowMappingDisallowed: While scanning
in "<unicode string>", line 1, column 8:
hello: [world]
^ (line: 1)
Found ugly disallowed JSONesque flow mapping (surround with ' and ' to make text appear literally)
in "<unicode string>", line 1, column 9:
hello: [world]
^ (line: 1)
# Currently, this raises FlowMappingDisallowed
In [4]: strictyaml.load("hello: []").data
Out[4]: {'hello': []}
# Currently, this raises YAMLSerializationError: Empty lists are not serializable to StrictYAML unless schema is used.
In [5]: strictyaml.as_document({'hello': []}).as_yaml()
Out[5]: 'hello: []\n'
# Currently, this produces 'hello:\n', which other YAML parsers can't interpret correctly
In [6]: strictyaml.as_document({'hello': []}, strictyaml.Map({'hello': strictyaml.EmptyList()})).as_yaml()
Out[6]: 'hello: []\n'
I might be able to contribute tests and code for this. Let me know if you'd accept a pull request.