From 253cc4e8469cbbd158d971fa5965081aa9ad3963 Mon Sep 17 00:00:00 2001 From: Hanif Ariffin Date: Thu, 1 May 2025 13:55:19 +0800 Subject: [PATCH] =?UTF-8?q?Fix=20usize=20not=20using=20the=20same=20hash?= =?UTF-8?q?=20as=20PyInt=20when=20used=20as=20key=20into=20a=20di=E2=80=A6?= =?UTF-8?q?=20(#5756)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * 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 --- Lib/test/test_fstring.py | 2 -- common/src/hash.rs | 5 +++++ extra_tests/snippets/builtin_object.py | 7 +++++++ vm/src/dict_inner.rs | 5 +++-- 4 files changed, 15 insertions(+), 4 deletions(-) diff --git a/Lib/test/test_fstring.py b/Lib/test/test_fstring.py index c0c987ca2..c727b5b22 100644 --- a/Lib/test/test_fstring.py +++ b/Lib/test/test_fstring.py @@ -1631,8 +1631,6 @@ x = ( self.assertEqual(f"{x!s:}", "test") self.assertEqual(f"{x!r:}", "'test'") - # TODO: RUSTPYTHON d[0] error - @unittest.expectedFailure def test_str_format_differences(self): d = { "a": "string", diff --git a/common/src/hash.rs b/common/src/hash.rs index 88af9b6f5..9fea1e717 100644 --- a/common/src/hash.rs +++ b/common/src/hash.rs @@ -139,6 +139,11 @@ pub fn hash_bigint(value: &BigInt) -> PyHash { fix_sentinel(ret) } +#[inline] +pub fn hash_usize(data: usize) -> PyHash { + fix_sentinel(mod_int(data as i64)) +} + #[inline(always)] pub fn fix_sentinel(x: PyHash) -> PyHash { if x == SENTINEL { -2 } else { x } diff --git a/extra_tests/snippets/builtin_object.py b/extra_tests/snippets/builtin_object.py index 5a12afbf4..0cb6f31d6 100644 --- a/extra_tests/snippets/builtin_object.py +++ b/extra_tests/snippets/builtin_object.py @@ -24,3 +24,10 @@ assert obj.__ne__(obj) is False assert not hasattr(obj, 'a') obj.__dict__ = {'a': 1} assert obj.a == 1 + +# Value inside the formatter goes through a different path of resolution. +# Check that it still works all the same +d = { + 0: "ab", +} +assert "ab ab" == "{k[0]} {vv}".format(k=d, vv=d[0]) diff --git a/vm/src/dict_inner.rs b/vm/src/dict_inner.rs index 56ebc5eba..a165c7669 100644 --- a/vm/src/dict_inner.rs +++ b/vm/src/dict_inner.rs @@ -17,6 +17,7 @@ use crate::{ object::{Traverse, TraverseFn}, }; use num_traits::ToPrimitive; +use rustpython_common::hash::hash_integer; use std::{fmt, mem::size_of, ops::ControlFlow}; // HashIndex is intended to be same size with hash::PyHash @@ -993,8 +994,8 @@ impl DictKey for usize { *self } - fn key_hash(&self, vm: &VirtualMachine) -> PyResult { - Ok(vm.state.hash_secret.hash_value(self)) + fn key_hash(&self, _vm: &VirtualMachine) -> PyResult { + Ok(hash_usize(*self)) } fn key_is(&self, _other: &PyObject) -> bool {