Skip to content

Reuse stored hashes in dict.fromkeys() - #8503

Merged
youknowone merged 2 commits into
RustPython:mainfrom
fregataa:fromkeys-known-hash
Aug 12, 2026
Merged

Reuse stored hashes in dict.fromkeys()#8503
youknowone merged 2 commits into
RustPython:mainfrom
fregataa:fromkeys-known-hash

Conversation

@fregataa

@fregataa fregataa commented Aug 12, 2026

Copy link
Copy Markdown
Contributor

Summary

dict.fromkeys() recomputed hash for every key even when the source already stored a hash per entry. CPython's _PyDict_FromKeys branches on PyDict_CheckExact / PyAnySet_CheckExact and feeds the hash read from the source table straight into insertdict; RustPython always iterated generically through setitem.

The checks are the exact ones CPython uses: a set or dict subclass may override iter, so reading its table directly would change what the call observes. exact_set_keys_with_hashes() is therefore separate from extract_set(), which stays subclass-inclusive for the set operations.

Summary by CodeRabbit

  • Performance

    • Improved the efficiency of dict.fromkeys when creating dictionaries from existing dictionaries, sets, or frozensets.
    • Existing key hash information is reused where available, reducing unnecessary computation.
  • Compatibility

    • Behavior remains unchanged for other iterable inputs, which continue to be processed normally.

@fregataa
fregataa marked this pull request as draft August 12, 2026 13:17
@coderabbitai

coderabbitai Bot commented Aug 12, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

📝 Walkthrough

Walkthrough

dict.fromkeys now reuses stored hashes from exact dictionaries, sets, and frozensets. Other iterables retain generic iteration and assignment behavior.

Changes

Hash-aware dict.fromkeys

Layer / File(s) Summary
Extract cached set hashes
crates/vm/src/builtins/set.rs
Exact set and frozenset objects expose stored key hashes. Subclasses and other objects do not use this path.
Reuse hashes during dictionary construction
crates/vm/src/builtins/dict.rs, crates/vm/src/builtins/set.rs
dict.fromkeys uses insert_known_hash for exact dictionaries and sets. Other iterables retain generic assignment.
Estimated code review effort: 2 (Simple) ~10 minutes

Possibly related PRs

Suggested reviewers: youknowone, shaharnaveh, bschoenmaeckers

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly identifies the primary change: reusing stored hashes in dict.fromkeys().
Linked Issues check ✅ Passed The changes implement stored-hash reuse for exact dict, set, and frozenset sources while preserving subclass iteration behavior required by issue #8490.
Out of Scope Changes check ✅ Passed The reviewed changes are limited to hash-aware dict.fromkeys() insertion and the supporting exact-set hash helper.
Docstring Coverage ✅ Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@github-actions

Copy link
Copy Markdown
Contributor

📦 Library Dependencies

The following Lib/ modules were modified. Here are their dependencies:

[ ] test: cpython/Lib/test/test_set.py (TODO: 3)

dependencies:

dependent tests: (no tests depend on set)

Legend:

  • [+] path exists in CPython
  • [x] up-to-date, [ ] outdated

Closes RustPython#8490.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
@fregataa
fregataa force-pushed the fromkeys-known-hash branch from fe77067 to 324ecaa Compare August 12, 2026 13:23
@moreal moreal added the z-ca-2026 Tag to track Contribution Academy 2026 label Aug 12, 2026
@fregataa
fregataa marked this pull request as ready for review August 12, 2026 17:06

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

🧹 Nitpick comments (1)
crates/vm/src/builtins/dict.rs (1)

401-410: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Add regression coverage for both paths.

Use a key type that counts __hash__ calls. After creating exact dict, set, and frozenset sources, verify that dict.fromkeys performs no additional key hashing. Also test dictionary and set subclasses that override __iter__; these inputs must use the generic path.

This verifies the stated PR objective for cached hashes and subclass iteration behavior.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@crates/vm/src/builtins/dict.rs` around lines 401 - 410, Add regression tests
covering both branches in dict.fromkeys: with exact dict, set, and frozenset
inputs, use a key type counting __hash__ calls and verify no additional hashing
occurs; with dictionary and set subclasses overriding __iter__, verify the
generic iteration path is used. Anchor the tests to the dict.fromkeys behavior
implemented around fromkeys_known_hashes and preserve the expected cached-hash
and subclass-iteration semantics.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Nitpick comments:
In `@crates/vm/src/builtins/dict.rs`:
- Around line 401-410: Add regression tests covering both branches in
dict.fromkeys: with exact dict, set, and frozenset inputs, use a key type
counting __hash__ calls and verify no additional hashing occurs; with dictionary
and set subclasses overriding __iter__, verify the generic iteration path is
used. Anchor the tests to the dict.fromkeys behavior implemented around
fromkeys_known_hashes and preserve the expected cached-hash and
subclass-iteration semantics.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yml

Review profile: CHILL

Plan: Pro Plus

Run ID: 0a217c01-a5f7-4d77-969d-0817ee391d15

📥 Commits

Reviewing files that changed from the base of the PR and between 24bd3b3 and b13fd86.

⛔ Files ignored due to path filters (1)
  • Lib/test/test_set.py is excluded by !Lib/**
📒 Files selected for processing (2)
  • crates/vm/src/builtins/dict.rs
  • crates/vm/src/builtins/set.rs

@youknowone
youknowone merged commit db5de5e into RustPython:main Aug 12, 2026
28 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

z-ca-2026 Tag to track Contribution Academy 2026

Projects

None yet

Development

Successfully merging this pull request may close these issues.

dict.fromkeys() re-hashes keys taken from a set, frozenset, or dict

3 participants