Commit fe77067
Reuse stored hashes in dict.fromkeys()
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__.
Take the same fast path in the exact-dict arm of fromkeys, reusing the
insert_known_hash() / keys_with_hashes() pair added for #8489.
ArgIterable::as_object() gives the pre-__iter__ object, so the dispatch
needs no signature change.
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.
Closes #8490. With #8489 already landed, test_do_not_rehash_dict_keys
now passes in both directions, so its expectedFailure marker is dropped
and the 4 subclasses inheriting it stop failing.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>1 parent 24bd3b3 commit fe77067
3 files changed
Lines changed: 43 additions & 5 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
330 | 330 | | |
331 | 331 | | |
332 | 332 | | |
333 | | - | |
334 | 333 | | |
335 | 334 | | |
336 | 335 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
1 | 1 | | |
2 | 2 | | |
3 | | - | |
| 3 | + | |
4 | 4 | | |
5 | 5 | | |
6 | 6 | | |
| |||
9 | 9 | | |
10 | 10 | | |
11 | 11 | | |
12 | | - | |
| 12 | + | |
13 | 13 | | |
14 | 14 | | |
15 | 15 | | |
| |||
356 | 356 | | |
357 | 357 | | |
358 | 358 | | |
| 359 | + | |
| 360 | + | |
| 361 | + | |
| 362 | + | |
| 363 | + | |
| 364 | + | |
| 365 | + | |
| 366 | + | |
| 367 | + | |
| 368 | + | |
| 369 | + | |
| 370 | + | |
| 371 | + | |
| 372 | + | |
359 | 373 | | |
360 | 374 | | |
361 | 375 | | |
| |||
384 | 398 | | |
385 | 399 | | |
386 | 400 | | |
387 | | - | |
388 | | - | |
| 401 | + | |
| 402 | + | |
| 403 | + | |
| 404 | + | |
| 405 | + | |
| 406 | + | |
| 407 | + | |
| 408 | + | |
| 409 | + | |
| 410 | + | |
389 | 411 | | |
390 | 412 | | |
391 | 413 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
605 | 605 | | |
606 | 606 | | |
607 | 607 | | |
| 608 | + | |
| 609 | + | |
| 610 | + | |
| 611 | + | |
| 612 | + | |
| 613 | + | |
| 614 | + | |
| 615 | + | |
| 616 | + | |
| 617 | + | |
| 618 | + | |
| 619 | + | |
| 620 | + | |
| 621 | + | |
| 622 | + | |
| 623 | + | |
| 624 | + | |
608 | 625 | | |
609 | 626 | | |
610 | 627 | | |
| |||
0 commit comments