diff --git a/vm/src/obj/objrange.rs b/vm/src/obj/objrange.rs index 3b2c6e68e..acb38e6b8 100644 --- a/vm/src/obj/objrange.rs +++ b/vm/src/obj/objrange.rs @@ -5,6 +5,7 @@ use num_integer::Integer; use num_traits::{One, Signed, Zero}; use crate::function::{OptionalArg, PyFuncArgs}; +use crate::pyhash; use crate::pyobject::{ PyClassImpl, PyContext, PyObjectRef, PyRef, PyResult, PyValue, TryFromObject, TypeProtocol, }; @@ -14,6 +15,7 @@ use super::objint::{PyInt, PyIntRef}; use super::objiter; use super::objslice::{PySlice, PySliceRef}; use super::objtype::{self, PyClassRef}; +use crate::obj::objtuple::PyTuple; /// range(stop) -> range object /// range(start, stop[, step]) -> range object @@ -402,6 +404,27 @@ impl PyRange { } } + #[pymethod(name = "__hash__")] + fn hash(zelf: PyRef, vm: &VirtualMachine) -> PyResult { + let length = zelf.length(); + let len = length.as_bigint().clone(); + let a = length.into_ref(vm).into_object(); + let mut b = vm.get_none(); + let mut c = vm.get_none(); + if !len.is_zero() { + b = zelf.start.clone().into_object(); + if !len.is_one() { + c = zelf.step(vm).into_object(); + } + }; + let tuple = vm + .ctx + .new_tuple(vec![a, b, c]) + .downcast::() + .unwrap(); + tuple.hash(vm) + } + #[pyslot(new)] fn tp_new(args: PyFuncArgs, vm: &VirtualMachine) -> PyResult { let range = if args.args.len() <= 2 { diff --git a/vm/src/obj/objtuple.rs b/vm/src/obj/objtuple.rs index 821871f29..6196b28c6 100644 --- a/vm/src/obj/objtuple.rs +++ b/vm/src/obj/objtuple.rs @@ -179,7 +179,7 @@ impl PyTuple { } #[pymethod(name = "__hash__")] - fn hash(&self, vm: &VirtualMachine) -> PyResult { + pub fn hash(&self, vm: &VirtualMachine) -> PyResult { pyhash::hash_iter(self.elements.iter(), vm) }