Skip to content

Commit e49d714

Browse files
committed
Add PyValuePayload trait and use it for PyObject.payload
1 parent 8ec1af5 commit e49d714

File tree

3 files changed

+31
-14
lines changed

3 files changed

+31
-14
lines changed

vm/src/obj/objobject.rs

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ use super::objtype;
44
use crate::obj::objproperty::PropertyBuilder;
55
use crate::pyobject::{
66
AttributeProtocol, DictProtocol, IdProtocol, PyAttributes, PyContext, PyFuncArgs, PyObject,
7-
PyObjectRef, PyRef, PyResult, TypeProtocol,
7+
PyObjectRef, PyRef, PyResult, PyValue, TypeProtocol,
88
};
99
use crate::vm::VirtualMachine;
1010
use std::cell::RefCell;
@@ -13,6 +13,12 @@ use std::collections::HashMap;
1313
#[derive(Clone, Debug)]
1414
pub struct PyInstance;
1515

16+
impl PyValue for PyInstance {
17+
fn required_type(_ctx: &PyContext) -> PyObjectRef {
18+
panic!("no specific type for PyInstance, don't type check me")
19+
}
20+
}
21+
1622
pub type PyInstanceRef = PyRef<PyInstance>;
1723

1824
pub fn new_instance(vm: &mut VirtualMachine, mut args: PyFuncArgs) -> PyResult {

vm/src/pyobject.rs

Lines changed: 22 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -591,11 +591,7 @@ impl PyContext {
591591
}
592592

593593
pub fn new_instance(&self, class: PyObjectRef, dict: Option<PyAttributes>) -> PyObjectRef {
594-
let dict = if let Some(dict) = dict {
595-
dict
596-
} else {
597-
PyAttributes::new()
598-
};
594+
let dict = dict.unwrap_or_default();
599595
PyObject {
600596
typ: Some(class),
601597
dict: Some(RefCell::new(dict)),
@@ -665,7 +661,7 @@ impl Default for PyContext {
665661
pub struct PyObject {
666662
pub typ: Option<PyObjectRef>,
667663
pub dict: Option<RefCell<PyAttributes>>, // __dict__ member
668-
pub payload: Box<dyn Any>,
664+
pub payload: Box<dyn PyValuePayload>,
669665
}
670666

671667
impl Default for PyObject {
@@ -1526,7 +1522,7 @@ impl PyValue for PyIteratorValue {
15261522
}
15271523

15281524
impl PyObject {
1529-
pub fn new<T: PyValue>(payload: T, typ: PyObjectRef) -> PyObjectRef {
1525+
pub fn new<T: PyValuePayload>(payload: T, typ: PyObjectRef) -> PyObjectRef {
15301526
PyObject {
15311527
typ: Some(typ),
15321528
dict: Some(RefCell::new(PyAttributes::new())),
@@ -1541,16 +1537,31 @@ impl PyObject {
15411537
}
15421538

15431539
pub fn payload<T: PyValue>(&self) -> Option<&T> {
1544-
self.payload.downcast_ref()
1540+
let payload: &dyn Any = &self.payload;
1541+
payload.downcast_ref()
15451542
}
15461543
}
15471544

1548-
// The intention is for this to replace `PyObjectPayload` once everything is
1549-
// converted to use `PyObjectPayload::AnyRustvalue`.
1550-
pub trait PyValue: Any + fmt::Debug {
1545+
pub trait PyValue: fmt::Debug + 'static {
15511546
fn required_type(ctx: &PyContext) -> PyObjectRef;
15521547
}
15531548

1549+
pub trait PyValuePayload: Any + fmt::Debug + 'static {
1550+
fn required_type(&self, ctx: &PyContext) -> PyObjectRef;
1551+
}
1552+
1553+
impl<T: PyValue + 'static> PyValuePayload for T {
1554+
fn required_type(&self, ctx: &PyContext) -> PyObjectRef {
1555+
T::required_type(ctx)
1556+
}
1557+
}
1558+
1559+
impl PyValuePayload for () {
1560+
fn required_type(&self, _ctx: &PyContext) -> PyObjectRef {
1561+
panic!("No specific python type for rust unit, don't type check")
1562+
}
1563+
}
1564+
15541565
impl FromPyObjectRef for PyRef<PyClass> {
15551566
fn from_pyobj(obj: &PyObjectRef) -> Self {
15561567
if let Some(_) = obj.payload::<PyClass>() {

vm/src/stdlib/re.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -197,15 +197,15 @@ fn match_end(vm: &mut VirtualMachine, args: PyFuncArgs) -> PyResult {
197197
/// Retrieve inner rust regex from python object:
198198
fn get_regex<'a>(obj: &'a PyObjectRef) -> &'a Regex {
199199
// TODO: Regex shouldn't be stored in payload directly, create newtype wrapper
200-
if let Some(regex) = obj.payload.downcast_ref::<Regex>() {
200+
if let Some(regex) = obj.payload::<Regex>() {
201201
return regex;
202202
}
203203
panic!("Inner error getting regex {:?}", obj);
204204
}
205205

206206
/// Retrieve inner rust match from python object:
207207
fn get_match<'a>(obj: &'a PyObjectRef) -> &'a PyMatch {
208-
if let Some(value) = obj.payload.downcast_ref::<PyMatch>() {
208+
if let Some(value) = obj.payload::<PyMatch>() {
209209
return value;
210210
}
211211
panic!("Inner error getting match {:?}", obj);

0 commit comments

Comments
 (0)