From 264bc4356bba027668e28a386b14406ad8851354 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Sun, 28 Dec 2025 05:21:26 +0000 Subject: [PATCH 1/5] Initial plan From fa233e254f4bdf46f088155dcaa9830b6bc18994 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Sun, 28 Dec 2025 05:40:18 +0000 Subject: [PATCH 2/5] Fix hash wrapper overflow handling Co-authored-by: youknowone <69878+youknowone@users.noreply.github.com> --- crates/vm/src/types/slot.rs | 9 ++------- extra_tests/snippets/builtin_hash.py | 8 ++++++++ 2 files changed, 10 insertions(+), 7 deletions(-) diff --git a/crates/vm/src/types/slot.rs b/crates/vm/src/types/slot.rs index b7c20041d00..8285f7c4744 100644 --- a/crates/vm/src/types/slot.rs +++ b/crates/vm/src/types/slot.rs @@ -5,7 +5,7 @@ use crate::{ AsObject, Py, PyObject, PyObjectRef, PyPayload, PyRef, PyResult, VirtualMachine, builtins::{PyInt, PyStr, PyStrInterned, PyStrRef, PyType, PyTypeRef}, bytecode::ComparisonOperator, - common::hash::PyHash, + common::hash::{hash_bigint, PyHash}, convert::ToPyObject, function::{ Either, FromArgs, FuncArgs, OptionalArg, PyComparisonValue, PyMethodDef, PySetterValue, @@ -18,7 +18,6 @@ use crate::{ vm::Context, }; use crossbeam_utils::atomic::AtomicCell; -use malachite_bigint::BigInt; use num_traits::{Signed, ToPrimitive}; use std::{any::Any, any::TypeId, borrow::Borrow, cmp::Ordering, ops::Deref}; @@ -411,11 +410,7 @@ fn hash_wrapper(zelf: &PyObject, vm: &VirtualMachine) -> PyResult { let py_int = hash_obj .downcast_ref::() .ok_or_else(|| vm.new_type_error("__hash__ method should return an integer"))?; - let big_int = py_int.as_bigint(); - let hash: PyHash = big_int - .to_i64() - .unwrap_or_else(|| (big_int % BigInt::from(u64::MAX)).to_i64().unwrap()); - Ok(hash) + Ok(hash_bigint(py_int.as_bigint())) } /// Marks a type as unhashable. Similar to PyObject_HashNotImplemented in CPython diff --git a/extra_tests/snippets/builtin_hash.py b/extra_tests/snippets/builtin_hash.py index 96ccc46ba80..9b2c8388790 100644 --- a/extra_tests/snippets/builtin_hash.py +++ b/extra_tests/snippets/builtin_hash.py @@ -12,6 +12,14 @@ class A: assert type(hash(1.1)) is int assert type(hash("")) is int + +class Evil: + def __hash__(self): + return 1 << 63 + + +assert hash(Evil()) == 4 + with assert_raises(TypeError): hash({}) From 2767232bcc037226f7bb07a6eb8c46a93f3ae4a3 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Sun, 28 Dec 2025 05:48:57 +0000 Subject: [PATCH 3/5] Auto-format: cargo fmt --all --- crates/vm/src/types/slot.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/crates/vm/src/types/slot.rs b/crates/vm/src/types/slot.rs index 8285f7c4744..e04c0b717ee 100644 --- a/crates/vm/src/types/slot.rs +++ b/crates/vm/src/types/slot.rs @@ -5,7 +5,7 @@ use crate::{ AsObject, Py, PyObject, PyObjectRef, PyPayload, PyRef, PyResult, VirtualMachine, builtins::{PyInt, PyStr, PyStrInterned, PyStrRef, PyType, PyTypeRef}, bytecode::ComparisonOperator, - common::hash::{hash_bigint, PyHash}, + common::hash::{PyHash, hash_bigint}, convert::ToPyObject, function::{ Either, FromArgs, FuncArgs, OptionalArg, PyComparisonValue, PyMethodDef, PySetterValue, From 7fb03b2fc81f2ce8c605cf1ddae8dc3991d70e46 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Sun, 28 Dec 2025 06:16:22 +0000 Subject: [PATCH 4/5] Adjust __hash__ wrapper conversion Co-authored-by: youknowone <69878+youknowone@users.noreply.github.com> --- crates/vm/src/types/slot.rs | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/crates/vm/src/types/slot.rs b/crates/vm/src/types/slot.rs index e04c0b717ee..fd9e8ba7191 100644 --- a/crates/vm/src/types/slot.rs +++ b/crates/vm/src/types/slot.rs @@ -5,7 +5,7 @@ use crate::{ AsObject, Py, PyObject, PyObjectRef, PyPayload, PyRef, PyResult, VirtualMachine, builtins::{PyInt, PyStr, PyStrInterned, PyStrRef, PyType, PyTypeRef}, bytecode::ComparisonOperator, - common::hash::{PyHash, hash_bigint}, + common::hash::{fix_sentinel, hash_bigint, PyHash}, convert::ToPyObject, function::{ Either, FromArgs, FuncArgs, OptionalArg, PyComparisonValue, PyMethodDef, PySetterValue, @@ -410,7 +410,12 @@ fn hash_wrapper(zelf: &PyObject, vm: &VirtualMachine) -> PyResult { let py_int = hash_obj .downcast_ref::() .ok_or_else(|| vm.new_type_error("__hash__ method should return an integer"))?; - Ok(hash_bigint(py_int.as_bigint())) + let big_int = py_int.as_bigint(); + let hash = big_int + .to_i64() + .map(fix_sentinel) + .unwrap_or_else(|| hash_bigint(big_int)); + Ok(hash) } /// Marks a type as unhashable. Similar to PyObject_HashNotImplemented in CPython From a14d5c1f91358f79464169ffbd09dd17c65e29e7 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Sun, 28 Dec 2025 06:45:10 +0000 Subject: [PATCH 5/5] Auto-format: cargo fmt --all --- crates/vm/src/types/slot.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/crates/vm/src/types/slot.rs b/crates/vm/src/types/slot.rs index fd9e8ba7191..9823f189a26 100644 --- a/crates/vm/src/types/slot.rs +++ b/crates/vm/src/types/slot.rs @@ -5,7 +5,7 @@ use crate::{ AsObject, Py, PyObject, PyObjectRef, PyPayload, PyRef, PyResult, VirtualMachine, builtins::{PyInt, PyStr, PyStrInterned, PyStrRef, PyType, PyTypeRef}, bytecode::ComparisonOperator, - common::hash::{fix_sentinel, hash_bigint, PyHash}, + common::hash::{PyHash, fix_sentinel, hash_bigint}, convert::ToPyObject, function::{ Either, FromArgs, FuncArgs, OptionalArg, PyComparisonValue, PyMethodDef, PySetterValue,