Skip to content

Preserve insertion order in dissoc's set-based branch - #654

Open
Alex0AI wants to merge 1 commit into
pytoolz:masterfrom
Alex0AI:fix/dissoc-insertion-order
Open

Alex0AI wants to merge 1 commit into
pytoolz:masterfrom
Alex0AI:fix/dissoc-insertion-order

Conversation

@Alex0AI

@Alex0AI Alex0AI commented Oct 23, 2026

Copy link
Copy Markdown

Summary

Preserve source iteration order in the set-based branch of dissoc().

The function currently copies and deletes when relatively few keys are supplied, but constructs a set of surviving keys and iterates that set when len(keys) >= len(d) * .6. As a result, the order of a returned dict or OrderedDict depends on which internal strategy is selected. Duplicate or nonexistent removal keys can trigger the reordering even when few or no entries are actually removed.

For example:

from collections import OrderedDict
from toolz import dissoc

source = OrderedDict((i, str(i)) for i in range(9, -1, -1))
result = dissoc(source, 9, 8, 7, 6, 5, 4, factory=OrderedDict)
print(list(result))
# Before: [0, 1, 2, 3]
# Expected / after: [3, 2, 1, 0]

The fix retains the existing remaining-key set, but iterates the source mapping and copies surviving entries in source order. Overall linear complexity is unchanged. The docstring states the insertion-order behavior.

Validation

Sixteen regression cases cover dict and OrderedDict inputs and output factories, small/large removal sets, absent keys, repeated keys, result type, and unchanged source items. Before the fix: 12 failures and 4 passing controls. After the fix:

  • python -m pytest --doctest-modules toolz/ -q --tb=short: 284 passed, 2 skipped on Windows / CPython 3.13.5. The skips are an explicitly skipped doctest and a Python 3.14-only annotationlib test.
  • 18 benchmark-directory tests passed. The Shakespeare word-count benchmark could not be validated against its complete external fixture: Windows has no wget executable, and attempts to fetch the Project Gutenberg text over HTTPS were interrupted/timed out. An incomplete download was removed; no fixture is included in this PR.
  • CI's pycodestyle options passed, excluding the local virtual environment in addition to the repository's listed exclusions.
  • git diff --check passed.

Other interpreter/platform combinations were not tested locally. Prepared with OpenAI Codex assistance for investigation, implementation, tests and this description.

This branch has not been deployed

No deployments
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.

1 participant