Skip to content

Commit a12a3d4

Browse files
committed
PySetResult and IntoPySetResult
1 parent 45b7715 commit a12a3d4

File tree

4 files changed

+43
-22
lines changed

4 files changed

+43
-22
lines changed

vm/src/obj/objgetset.rs

Lines changed: 19 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -4,13 +4,14 @@
44
use super::objtype::PyClassRef;
55
use crate::function::{OptionalArg, OwnedParam, RefParam};
66
use crate::pyobject::{
7-
IntoPyObject, PyClassImpl, PyContext, PyObjectRef, PyRef, PyResult, PyValue, TryFromObject,
7+
IntoPyObject, IntoPySetResult, PyClassImpl, PyContext, PyObjectRef, PyRef, PyResult,
8+
PySetResult, PyValue, TryFromObject,
89
};
910
use crate::slots::PyBuiltinDescriptor;
1011
use crate::vm::VirtualMachine;
1112

1213
pub type PyGetterFunc = Box<dyn Fn(PyObjectRef, &VirtualMachine) -> PyResult>;
13-
pub type PySetterFunc = Box<dyn Fn(PyObjectRef, PyObjectRef, &VirtualMachine) -> PyResult<()>>;
14+
pub type PySetterFunc = Box<dyn Fn(PyObjectRef, PyObjectRef, &VirtualMachine) -> PySetResult>;
1415

1516
pub trait IntoPyGetterFunc<T, R> {
1617
fn into_getter(self) -> PyGetterFunc;
@@ -44,36 +45,41 @@ where
4445
}
4546
}
4647

47-
pub trait IntoPySetterFunc<T, V> {
48+
pub trait IntoPySetterFunc<T, V, R>
49+
where
50+
R: IntoPySetResult,
51+
{
4852
fn into_setter(self) -> PySetterFunc;
4953
}
5054

51-
impl<F, T, V> IntoPySetterFunc<OwnedParam<T>, V> for F
55+
impl<F, T, V, R> IntoPySetterFunc<OwnedParam<T>, V, R> for F
5256
where
53-
F: Fn(T, V, &VirtualMachine) -> PyResult<()> + 'static,
57+
F: Fn(T, V, &VirtualMachine) -> R + 'static,
5458
T: TryFromObject,
5559
V: TryFromObject,
60+
R: IntoPySetResult,
5661
{
5762
fn into_setter(self) -> PySetterFunc {
5863
Box::new(move |obj, value, vm| {
5964
let obj = T::try_from_object(vm, obj)?;
6065
let value = V::try_from_object(vm, value)?;
61-
(self)(obj, value, vm)
66+
(self)(obj, value, vm).into_pysetresult()
6267
})
6368
}
6469
}
6570

66-
impl<F, S, V> IntoPySetterFunc<RefParam<S>, V> for F
71+
impl<F, S, V, R> IntoPySetterFunc<RefParam<S>, V, R> for F
6772
where
68-
F: Fn(&S, V, &VirtualMachine) -> PyResult<()> + 'static,
73+
F: Fn(&S, V, &VirtualMachine) -> R + 'static,
6974
S: PyValue,
7075
V: TryFromObject,
76+
R: IntoPySetResult,
7177
{
7278
fn into_setter(self) -> PySetterFunc {
7379
Box::new(move |obj, value, vm| {
7480
let zelf = PyRef::<S>::try_from_object(vm, obj)?;
7581
let value = V::try_from_object(vm, value)?;
76-
(self)(&zelf, value, vm)
82+
(self)(&zelf, value, vm).into_pysetresult()
7783
})
7884
}
7985
}
@@ -145,10 +151,11 @@ impl PyGetSet {
145151
}
146152
}
147153

148-
pub fn with_get_set<G, S, GT, GR, ST, SV>(name: String, getter: G, setter: S) -> Self
154+
pub fn with_get_set<G, S, GT, GR, ST, SV, SR>(name: String, getter: G, setter: S) -> Self
149155
where
150156
G: IntoPyGetterFunc<GT, GR>,
151-
S: IntoPySetterFunc<ST, SV>,
157+
S: IntoPySetterFunc<ST, SV, SR>,
158+
SR: IntoPySetResult,
152159
{
153160
Self {
154161
name,
@@ -163,7 +170,7 @@ impl PyGetSet {
163170
// Descriptor methods
164171

165172
#[pymethod(magic)]
166-
fn set(&self, obj: PyObjectRef, value: PyObjectRef, vm: &VirtualMachine) -> PyResult<()> {
173+
fn set(&self, obj: PyObjectRef, value: PyObjectRef, vm: &VirtualMachine) -> PySetResult {
167174
if let Some(ref f) = self.setter {
168175
f(obj, value, vm)
169176
} else {

vm/src/obj/objobject.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ use crate::function::{OptionalArg, PyFuncArgs};
99
use crate::pyhash;
1010
use crate::pyobject::{
1111
IdProtocol, ItemProtocol, PyArithmaticValue::*, PyAttributes, PyComparisonValue, PyContext,
12-
PyObject, PyObjectRef, PyResult, PyValue, TryFromObject, TypeProtocol,
12+
PyObject, PyObjectRef, PyResult, PySetResult, PyValue, TryFromObject, TypeProtocol,
1313
};
1414
use crate::slots::PyTpFlags;
1515
use crate::vm::VirtualMachine;
@@ -223,7 +223,7 @@ fn object_class_setter(
223223
instance: PyObjectRef,
224224
_value: PyObjectRef,
225225
vm: &VirtualMachine,
226-
) -> PyResult<()> {
226+
) -> PySetResult {
227227
let type_repr = vm.to_pystr(&instance.class())?;
228228
Err(vm.new_type_error(format!("can't change class of type '{}'", type_repr)))
229229
}

vm/src/obj/objproperty.rs

Lines changed: 3 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,8 @@ use std::cell::RefCell;
66
use super::objtype::PyClassRef;
77
use crate::function::{IntoPyNativeFunc, OptionalArg};
88
use crate::pyobject::{
9-
IdProtocol, PyClassImpl, PyContext, PyObject, PyObjectRef, PyRef, PyResult, PyValue,
10-
TypeProtocol,
9+
IdProtocol, IntoPySetResult, PyClassImpl, PyContext, PyObject, PyObjectRef, PyRef, PyResult,
10+
PyValue, TypeProtocol,
1111
};
1212
use crate::slots::PyBuiltinDescriptor;
1313
use crate::vm::VirtualMachine;
@@ -259,11 +259,6 @@ pub struct PropertyBuilder<'a> {
259259
setter: Option<PyObjectRef>,
260260
}
261261

262-
pub trait PropertySetterResult {}
263-
264-
impl PropertySetterResult for PyResult<()> {}
265-
impl PropertySetterResult for () {}
266-
267262
impl<'a> PropertyBuilder<'a> {
268263
pub fn new(ctx: &'a PyContext) -> Self {
269264
Self {
@@ -282,7 +277,7 @@ impl<'a> PropertyBuilder<'a> {
282277
}
283278
}
284279

285-
pub fn add_setter<I, V, VM, F: IntoPyNativeFunc<(I, V), impl PropertySetterResult, VM>>(
280+
pub fn add_setter<I, V, VM, F: IntoPyNativeFunc<(I, V), impl IntoPySetResult, VM>>(
286281
self,
287282
func: F,
288283
) -> Self {

vm/src/pyobject.rs

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,9 @@ pub type PyObjectRef = Rc<PyObject<dyn PyObjectPayload>>;
6767
/// since exceptions are also python objects.
6868
pub type PyResult<T = PyObjectRef> = Result<T, PyBaseExceptionRef>; // A valid value, or an exception
6969

70+
/// Use this type for functions which return None or an exception.
71+
pub type PySetResult = PyResult<()>; // None, or an exception
72+
7073
/// For attributes we do not use a dict, but a hashmap. This is probably
7174
/// faster, unordered, and only supports strings as keys.
7275
/// TODO: class attributes should maintain insertion order (use IndexMap here)
@@ -1054,6 +1057,22 @@ where
10541057
}
10551058
}
10561059

1060+
pub trait IntoPySetResult {
1061+
fn into_pysetresult(self) -> PySetResult;
1062+
}
1063+
1064+
impl IntoPySetResult for () {
1065+
fn into_pysetresult(self) -> PySetResult {
1066+
Ok(())
1067+
}
1068+
}
1069+
1070+
impl IntoPySetResult for PySetResult {
1071+
fn into_pysetresult(self) -> PySetResult {
1072+
self
1073+
}
1074+
}
1075+
10571076
impl<T> PyObject<T>
10581077
where
10591078
T: Sized + PyObjectPayload,

0 commit comments

Comments
 (0)