Skip to content

Conversation

@angela-tarantula
Copy link

@angela-tarantula angela-tarantula commented Oct 13, 2025

Fixes #151

TL;DR

DiffBuilder currently iterates sets of dict keys, and set iteration order is inherently unordered (and can vary across runs due to hash randomization). This yields non-deterministic patch order even for identical inputs.

What Changes

Iterate the dicts directly, which preserves insertion order (language guarantee in Py≥3.6; implementation detail in CPython 2.7+).

Note

  • Adding an automated test for cross-run nondeterminism would require subprocesses with varied PYTHONHASHSEED. I can follow up with such a test, but I'd rather keep this PR minimal. Also it's kind of a mess to write this kind of test in a backwards-compatible way, down to Python 2.7.

This fixes the issue because it is specified for 3.6 and above. In
python 3.6+, sets are not ordered, but dictionaries are. This means
traversal will be stable across sessions, guaranteeing the same patches
are generated.

For python 3.5 and below, the stability of dictionary traversal is not a
guarantee, unfortunately. But if you use CPython, the reference
implementation of python, it does happen to be an implementation detail.
See https://docs.python.org/2/library/stdtypes.html#dict.items for more
details.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Generated patches aren't always the same

1 participant