Skip to content

Commit 4d24cd1

Browse files
committed
objint - add support for subclasses of int.
1 parent aa18896 commit 4d24cd1

File tree

1 file changed

+27
-7
lines changed

1 file changed

+27
-7
lines changed

vm/src/obj/objint.rs

Lines changed: 27 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -3,13 +3,14 @@ use super::objstr;
33
use super::objtype;
44
use crate::format::FormatSpec;
55
use crate::pyobject::{
6-
FromPyObjectRef, IntoPyObject, PyContext, PyFuncArgs, PyObject, PyObjectPayload, PyObjectRef,
7-
PyResult, TryFromObject, TypeProtocol,
6+
FromPyObjectRef, IdProtocol, IntoPyObject, PyAttributes, PyContext, PyFuncArgs, PyObject,
7+
PyObjectPayload, PyObjectRef, PyResult, TryFromObject, TypeProtocol,
88
};
99
use crate::vm::VirtualMachine;
1010
use num_bigint::{BigInt, ToBigInt};
1111
use num_integer::Integer;
1212
use num_traits::{Pow, Signed, ToPrimitive, Zero};
13+
use std::cell::RefCell;
1314
use std::hash::{Hash, Hasher};
1415

1516
// This proxy allows for easy switching between types.
@@ -77,7 +78,14 @@ fn int_new(vm: &mut VirtualMachine, args: PyFuncArgs) -> PyResult {
7778
None => Zero::zero(),
7879
};
7980
Ok(PyObject::new(
80-
PyObjectPayload::Integer { value: val },
81+
if cls.is(&vm.ctx.int_type()) {
82+
PyObjectPayload::Integer { value: val }
83+
} else {
84+
PyObjectPayload::Instance {
85+
dict: RefCell::new(PyAttributes::new()),
86+
parent_payload: Some(Box::new(PyObjectPayload::Integer { value: val })),
87+
}
88+
},
8189
cls.clone(),
8290
))
8391
}
@@ -112,10 +120,22 @@ pub fn to_int(vm: &mut VirtualMachine, obj: &PyObjectRef, base: u32) -> PyResult
112120

113121
// Retrieve inner int value:
114122
pub fn get_value(obj: &PyObjectRef) -> IntType {
115-
if let PyObjectPayload::Integer { value } = &obj.payload {
116-
value.clone()
117-
} else {
118-
panic!("Inner error getting int {:?}", obj);
123+
match &obj.payload {
124+
PyObjectPayload::Integer { ref value } => value.clone(),
125+
PyObjectPayload::Instance {
126+
ref parent_payload, ..
127+
} => {
128+
if let Some(parent_payload) = parent_payload {
129+
if let PyObjectPayload::Integer { ref value } = **parent_payload {
130+
value.clone()
131+
} else {
132+
panic!("Inner error getting parent int {:?}", obj);
133+
}
134+
} else {
135+
panic!("Inner error getting parent int {:?}", obj);
136+
}
137+
}
138+
_ => panic!("Inner error getting int {:?}", obj),
119139
}
120140
}
121141

0 commit comments

Comments
 (0)