Skip to content

Commit 253cc4e

Browse files
authored
Fix usize not using the same hash as PyInt when used as key into a di… (#5756)
* Fix usize not using the same hash as PyInt when used as key into a dictionary * Fix test that unexpectedly succeed! * Update extra_tests/snippets/builtin_object.py
1 parent 431b900 commit 253cc4e

File tree

4 files changed

+15
-4
lines changed

4 files changed

+15
-4
lines changed

Lib/test/test_fstring.py

-2
Original file line numberDiff line numberDiff line change
@@ -1631,8 +1631,6 @@ def test_empty_format_specifier(self):
16311631
self.assertEqual(f"{x!s:}", "test")
16321632
self.assertEqual(f"{x!r:}", "'test'")
16331633

1634-
# TODO: RUSTPYTHON d[0] error
1635-
@unittest.expectedFailure
16361634
def test_str_format_differences(self):
16371635
d = {
16381636
"a": "string",

common/src/hash.rs

+5
Original file line numberDiff line numberDiff line change
@@ -139,6 +139,11 @@ pub fn hash_bigint(value: &BigInt) -> PyHash {
139139
fix_sentinel(ret)
140140
}
141141

142+
#[inline]
143+
pub fn hash_usize(data: usize) -> PyHash {
144+
fix_sentinel(mod_int(data as i64))
145+
}
146+
142147
#[inline(always)]
143148
pub fn fix_sentinel(x: PyHash) -> PyHash {
144149
if x == SENTINEL { -2 } else { x }

extra_tests/snippets/builtin_object.py

+7
Original file line numberDiff line numberDiff line change
@@ -24,3 +24,10 @@ class MyObject:
2424
assert not hasattr(obj, 'a')
2525
obj.__dict__ = {'a': 1}
2626
assert obj.a == 1
27+
28+
# Value inside the formatter goes through a different path of resolution.
29+
# Check that it still works all the same
30+
d = {
31+
0: "ab",
32+
}
33+
assert "ab ab" == "{k[0]} {vv}".format(k=d, vv=d[0])

vm/src/dict_inner.rs

+3-2
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ use crate::{
1717
object::{Traverse, TraverseFn},
1818
};
1919
use num_traits::ToPrimitive;
20+
use rustpython_common::hash::hash_integer;
2021
use std::{fmt, mem::size_of, ops::ControlFlow};
2122

2223
// HashIndex is intended to be same size with hash::PyHash
@@ -993,8 +994,8 @@ impl DictKey for usize {
993994
*self
994995
}
995996

996-
fn key_hash(&self, vm: &VirtualMachine) -> PyResult<HashValue> {
997-
Ok(vm.state.hash_secret.hash_value(self))
997+
fn key_hash(&self, _vm: &VirtualMachine) -> PyResult<HashValue> {
998+
Ok(hash_usize(*self))
998999
}
9991000

10001001
fn key_is(&self, _other: &PyObject) -> bool {

0 commit comments

Comments
 (0)