PyO3 / pyproject-toml-rs

pyproject.toml parser in Rust
MIT License
19 stars 8 forks source link

Preserving insertion order in optional dependencies #5

Closed cnpryer closed 1 year ago

cnpryer commented 1 year ago

Hi! Love this project. Thanks so much for building it.

When serializing PyProjectToml to a String using toml_edit::ser::to_string_pretty the original order of each optional dependency group isn't guaranteed to be preserved.

I put together a MWE here: https://github.com/cnpryer/pyproject-toml-rs-mwe.

use pyproject_toml::PyProjectToml;

fn main() {
  let pyproject_toml_str = r#"[build-system]
  requires = ["hatchling"]
  build-backend = "hatchling.build"

  [project]
  name = "mock_project"
  version = "0.0.1"
  description = ""
  dependencies = ["click==8.1.3"]

  [[project.authors]]
  name = "Chris Pryer"
  email = "cnpryer@gmail.com"

  [project.optional-dependencies]
  dev = [
      "pytest>=6",
      "black==22.8.0",
      "isort==5.12.0",
  ]
  test = []
  "#;
  let pyproject_toml = PyProjectToml::new(pyproject_toml_str).expect("failed to parse toml");

  // Not every run will evaluate true
  assert_eq!(
      pyproject_toml_str,
      toml_edit::ser::to_string_pretty(&pyproject_toml).expect("failed to serialize toml")
  );
}

I'd assume this would also be the case for other data backed by HashMaps.

IIRC toml solves this by using BTreeMap instead.

messense commented 1 year ago

Feel free to send a PR, thanks!

And to preserve insertion order, perhaps we should use IndexMap.

cnpryer commented 1 year ago

If that's your preference, sounds good to me :)

messense commented 1 year ago

FYI, toml also uses indexmap to preserve insertion order: https://github.com/toml-rs/toml/blob/457e745a46e56205bab39c20e3dc72785ad2376e/crates/toml/Cargo.toml#L46-L49

cnpryer commented 1 year ago

FYI, toml also uses indexmap to preserve insertion order: https://github.com/toml-rs/toml/blob/457e745a46e56205bab39c20e3dc72785ad2376e/crates/toml/Cargo.toml#L46-L49

heh I just saw this. Thanks!