Skip to content
This repository was archived by the owner on Feb 10, 2025. It is now read-only.

Conversation

@yjbanov
Copy link
Contributor

@yjbanov yjbanov commented Sep 18, 2019

Preserve parsed key order in YamlMap.

Fixes dart-lang/tools#1909

@yjbanov yjbanov requested review from kevmoo and rakudrama September 18, 2019 03:47
Copy link
Contributor

@kevmoo kevmoo left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We should add test(s) to make sure the new behavior is maintained!

@yjbanov
Copy link
Contributor Author

yjbanov commented Sep 18, 2019

@kevmoo any ideas how to test this? A test would have to rely on implementation details of HashMap and LinkedHashMap. Coincidentally, in many cases the two behave identically, which is why current tests do not fail. In fact, until I tried processing a large pubspec.yaml file I never noticed a difference.

@rakudrama
Copy link

To test order, I would create a collections of maps with all permutations of 4 or 5 simple keys, and check they are invariant through a round-trip.

@yjbanov
Copy link
Contributor Author

yjbanov commented Sep 18, 2019

@rakudrama that triggered a failure pretty quickly. Thanks for the suggestion. Implemented.

@yjbanov
Copy link
Contributor Author

yjbanov commented Sep 18, 2019

Oops! I did something wrong to the whitespace in that file. Fixing.

@yjbanov
Copy link
Contributor Author

yjbanov commented Sep 18, 2019

Fixed.

CHANGELOG.md Outdated
@@ -1,3 +1,9 @@
## 2.2.0

* BREAKING CHANGE: Make `YamlMap` preserve parsed key order.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe flag this as "possibly" breaking? It's not likely to affect most folks, right?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It is only mildly breaking in the sense that if anything is broken the fix should be trivial. However, strictly speaking it could break everyone. For example, I found that it breaks some test in the analyzer, which everyone depends on. I expect that the change will propagate gradually with minimal disruption.

IOW, done :)

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We can't land things like this that just break our own code. It'll prevent internal rolls.

Is someone working with the analyzer team to fix? That need to happen before landing PRs like this.

fyi - @natebosch

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I ran internal global presubmit for this change before landing and only found a couple of analyzer test failures that looked easily fixable.

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for running the global, but someone needs to fix those before/as we land these.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is there a document listing packages that follow this rule? This seems to pop up randomly. About a year ago package:quiver broke package:build. There doesn't seem to be a clear way for package authors to be proactive about it (e.g. we didn't even know quiver was a dependency of build).

@yjbanov yjbanov merged commit 5137026 into dart-archive:master Sep 18, 2019
@yjbanov
Copy link
Contributor Author

yjbanov commented Sep 18, 2019

@kevmoo can you please push a pub release?

@natebosch
Copy link
Contributor

Apparently this wasn't a good idea. The yaml spec explicitly forbids attaching meaning to the order of keys:

https://yaml.org/spec/1.2/spec.html#id2765608

@yjbanov
Copy link
Contributor Author

yjbanov commented Oct 25, 2019

Apparently this wasn't a good idea. The yaml spec explicitly forbids attaching meaning to the order of keys

Attaching meaning to key order ≠ preserving key order in the parser. Remember that the spec also says "YAML is easily readable by humans" (https://yaml.org/spec/1.2/spec.html#id2708649). This means that if we allow programs to output YAML, then it must also be "readable by humans". Now what happens if the input to such program is another YAML document? The order of keys in the input document was specifically chosen by a human such that it looks readable to them. If the program ingests this YAML and arbitrarily reorders the key, then the output will violate the spec too by being non-human readable.

Now, if you are parsing YAML for purposes other than outputting it back to YAML, such as when you read a pubspec.yaml to upload a package to pub, then yes, please do not rely on the order of keys. However, for a YAML parser to mess up keys upfront seems very counter to the spirit of the YAML spec.

@kevmoo
Copy link
Contributor

kevmoo commented Oct 26, 2019 via email

mosuem pushed a commit to dart-lang/tools that referenced this pull request Dec 11, 2024
Preserve key order in YamlMap when parsing YAML.
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

None yet

Development

Successfully merging this pull request may close these issues.

Order of map is nondeterministic, making read+write randomize the file

6 participants