Files
RustPython/vm/src/function.rs
Joey Hain 7f75e3ee8a Significant improvements to new function definition style
- PyRef<T> type for accepting references to payloads.
- Args<T> type for consuming remaining positional args
  (mirrors python `*args`).
- KwArgs<T> type for consuming remaining keyword args
  (mirrors python `*kwargs`).
- OptArg<T> type for consuming remaining keyword args
  (no python code equivalent, only possible in native functions like in cpython).
- PyIterable<T> for accepting an iterator over a sequence of Ts.
- Arity checking (but TypeError messages need work)
2019-02-27 19:53:20 -08:00

42 lines
997 B
Rust

use std::marker::PhantomData;
use std::ops::Deref;
use crate::obj::objtype;
use crate::pyobject::{PyObjectPayload2, PyObjectRef, PyResult, TryFromObject};
use crate::vm::VirtualMachine;
// TODO: Move PyFuncArgs, FromArgs, etc. here
pub struct PyRef<T> {
// invariant: this obj must always have payload of type T
obj: PyObjectRef,
_payload: PhantomData<T>,
}
impl<T> Deref for PyRef<T>
where
T: PyObjectPayload2,
{
type Target = T;
fn deref(&self) -> &T {
self.obj.payload().expect("unexpected payload for type")
}
}
impl<T> TryFromObject for PyRef<T>
where
T: PyObjectPayload2,
{
fn try_from_object(vm: &mut VirtualMachine, obj: PyObjectRef) -> PyResult<Self> {
if objtype::isinstance(&obj, &T::required_type(&vm.ctx)) {
Ok(PyRef {
obj,
_payload: PhantomData,
})
} else {
Err(vm.new_type_error("wrong type".to_string())) // TODO: better message
}
}
}