From fcc6635b1f931cce994506fe82eaa50fd84eb6fd Mon Sep 17 00:00:00 2001 From: Jack Park Date: Fri, 18 Oct 2019 06:50:46 +0700 Subject: [PATCH] Implemented range.__reduce__ --- tests/snippets/builtin_range.py | 6 ++++++ vm/src/obj/objrange.rs | 16 ++++++++++++++-- 2 files changed, 20 insertions(+), 2 deletions(-) diff --git a/tests/snippets/builtin_range.py b/tests/snippets/builtin_range.py index e0918bd3f..6bd279c71 100644 --- a/tests/snippets/builtin_range.py +++ b/tests/snippets/builtin_range.py @@ -102,6 +102,12 @@ assert list(reversed(range(5))) == [4, 3, 2, 1, 0] assert list(reversed(range(5, 0, -1))) == [1, 2, 3, 4, 5] assert list(reversed(range(1,10,5))) == [6, 1] +# __reduce__ +assert range(10).__reduce__()[0] == range +assert range(10).__reduce__()[1] == (0, 10, 1) +assert range(10, 1, -2).__reduce__()[0] == range +assert range(10, 1, -2).__reduce__()[1] == (10, 1, -2) + # range retains the original int refs i = 2**64 assert range(i).stop is i diff --git a/vm/src/obj/objrange.rs b/vm/src/obj/objrange.rs index e71d03255..3b7ffee1f 100644 --- a/vm/src/obj/objrange.rs +++ b/vm/src/obj/objrange.rs @@ -7,14 +7,16 @@ 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, + PyClassImpl, PyContext, PyObjectRef, PyRef, PyResult, PyValue, TryFromObject, TypeProtocol, IntoPyObject }; use crate::vm::VirtualMachine; use super::objint::{PyInt, PyIntRef}; use super::objiter; use super::objslice::{PySlice, PySliceRef}; -use super::objtype::{self, PyClassRef}; +use super::objtype::{self, PyClassRef, PyClass}; +use super::objtuple::{PyTuple, PyTupleRef}; +use super::objsequence::{get_elements_tuple}; /// range(stop) -> range object /// range(start, stop[, step]) -> range object @@ -286,6 +288,16 @@ impl PyRange { Ok(vm.ctx.not_implemented()) } + #[pymethod(name = "__reduce__")] + fn reduce(&self, vm: &VirtualMachine) -> (PyClassRef, PyTuple) { + let range_paramters: Vec = vec![&self.start, &self.stop, &self.step] + .iter() + .map(|x| x.as_object().clone()) + .collect(); + let range_paramters_tuple = PyTuple::from(range_paramters); + (vm.ctx.range_type(), range_paramters_tuple) + } + #[pymethod(name = "index")] fn index(&self, needle: PyObjectRef, vm: &VirtualMachine) -> PyResult { if let Ok(int) = needle.downcast::() {