lifetime bounded TryFromBorrwoedObject

This commit is contained in:
Jeong YunWon
2023-03-16 00:20:54 +09:00
parent 0f24d66234
commit f314328294
15 changed files with 53 additions and 38 deletions

View File

@@ -86,8 +86,8 @@ python_person.name: {}",
name: String,
}
impl TryFromBorrowedObject for PythonPerson {
fn try_from_borrowed_object(vm: &VirtualMachine, obj: &PyObject) -> PyResult<Self> {
impl<'a> TryFromBorrowedObject<'a> for PythonPerson {
fn try_from_borrowed_object(vm: &VirtualMachine, obj: &'a PyObject) -> PyResult<Self> {
let name = obj.get_attr("name", vm)?.try_into_value::<String>(vm)?;
Ok(PythonPerson { name })
}

View File

@@ -72,8 +72,8 @@ mod mmap {
Copy = 3,
}
impl TryFromBorrowedObject for AccessMode {
fn try_from_borrowed_object(vm: &VirtualMachine, obj: &PyObject) -> PyResult<Self> {
impl<'a> TryFromBorrowedObject<'a> for AccessMode {
fn try_from_borrowed_object(vm: &VirtualMachine, obj: &'a PyObject) -> PyResult<Self> {
let i = u32::try_from_borrowed_object(vm, obj)?;
Ok(match i {
0 => Self::Default,

View File

@@ -129,8 +129,8 @@ mod resource {
}
struct Limits(libc::rlimit);
impl TryFromBorrowedObject for Limits {
fn try_from_borrowed_object(vm: &VirtualMachine, obj: &PyObject) -> PyResult<Self> {
impl<'a> TryFromBorrowedObject<'a> for Limits {
fn try_from_borrowed_object(vm: &VirtualMachine, obj: &'a PyObject) -> PyResult<Self> {
let seq: Vec<libc::rlim_t> = obj.try_to_value(vm)?;
match *seq {
[cur, max] => Ok(Self(libc::rlimit {

View File

@@ -41,8 +41,8 @@ enum NormalizeForm {
Nfkd,
}
impl TryFromBorrowedObject for NormalizeForm {
fn try_from_borrowed_object(vm: &VirtualMachine, obj: &PyObject) -> PyResult<Self> {
impl<'a> TryFromBorrowedObject<'a> for NormalizeForm {
fn try_from_borrowed_object(vm: &VirtualMachine, obj: &'a PyObject) -> PyResult<Self> {
obj.try_value_with(
|form: &PyStr| {
Ok(match form.as_str() {

View File

@@ -581,8 +581,8 @@ mod zlib {
}
}
impl TryFromBorrowedObject for Level {
fn try_from_borrowed_object(vm: &VirtualMachine, obj: &PyObject) -> PyResult<Self> {
impl<'a> TryFromBorrowedObject<'a> for Level {
fn try_from_borrowed_object(vm: &VirtualMachine, obj: &'a PyObject) -> PyResult<Self> {
let int: i32 = obj.try_index(vm)?.try_to_primitive(vm)?;
Ok(Self::new(int))
}

View File

@@ -19,8 +19,8 @@ impl ToPyObject for bool {
}
}
impl TryFromBorrowedObject for bool {
fn try_from_borrowed_object(vm: &VirtualMachine, obj: &PyObject) -> PyResult<bool> {
impl<'a> TryFromBorrowedObject<'a> for bool {
fn try_from_borrowed_object(vm: &VirtualMachine, obj: &'a PyObject) -> PyResult<bool> {
if obj.fast_isinstance(vm.ctx.types.int_type) {
Ok(get_value(obj))
} else {

View File

@@ -742,8 +742,8 @@ impl IterNext for PyBytesIterator {
}
}
impl TryFromBorrowedObject for PyBytes {
fn try_from_borrowed_object(vm: &VirtualMachine, obj: &PyObject) -> PyResult<Self> {
impl<'a> TryFromBorrowedObject<'a> for PyBytes {
fn try_from_borrowed_object(vm: &VirtualMachine, obj: &'a PyObject) -> PyResult<Self> {
PyBytesInner::try_from_borrowed_object(vm, obj).map(|x| x.into())
}
}

View File

@@ -72,8 +72,8 @@ impl_into_pyobject_int!(isize i8 i16 i32 i64 i128 usize u8 u16 u32 u64 u128 BigI
macro_rules! impl_try_from_object_int {
($(($t:ty, $to_prim:ident),)*) => {$(
impl TryFromBorrowedObject for $t {
fn try_from_borrowed_object(vm: &VirtualMachine, obj: &PyObject) -> PyResult<Self> {
impl<'a> TryFromBorrowedObject<'a> for $t {
fn try_from_borrowed_object(vm: &VirtualMachine, obj: &'a PyObject) -> PyResult<Self> {
obj.try_value_with(|int: &PyInt| {
int.try_to_primitive(vm)
}, vm)

View File

@@ -42,8 +42,8 @@ use unic_ucd_category::GeneralCategory;
use unic_ucd_ident::{is_xid_continue, is_xid_start};
use unicode_casing::CharExt;
impl TryFromBorrowedObject for String {
fn try_from_borrowed_object(vm: &VirtualMachine, obj: &PyObject) -> PyResult<Self> {
impl<'a> TryFromBorrowedObject<'a> for String {
fn try_from_borrowed_object(vm: &VirtualMachine, obj: &'a PyObject) -> PyResult<Self> {
obj.try_value_with(|pystr: &PyStr| Ok(pystr.as_str().to_owned()), vm)
}
}

View File

@@ -30,8 +30,8 @@ impl From<Vec<u8>> for PyBytesInner {
}
}
impl TryFromBorrowedObject for PyBytesInner {
fn try_from_borrowed_object(vm: &VirtualMachine, obj: &PyObject) -> PyResult<Self> {
impl<'a> TryFromBorrowedObject<'a> for PyBytesInner {
fn try_from_borrowed_object(vm: &VirtualMachine, obj: &'a PyObject) -> PyResult<Self> {
bytes_from_object(vm, obj).map(Self::from)
}
}

View File

@@ -1,7 +1,7 @@
use crate::{
builtins::PyFloat,
object::{AsObject, PyObject, PyObjectRef, PyPayload, PyRef, PyResult},
vm::VirtualMachine,
Py, VirtualMachine,
};
use num_traits::ToPrimitive;
@@ -15,7 +15,7 @@ pub trait TryFromObject: Sized {
}
/// Rust-side only version of TryFromObject to reduce unnecessary Rc::clone
impl<T: TryFromBorrowedObject> TryFromObject for T {
impl<T: for<'a> TryFromBorrowedObject<'a>> TryFromObject for T {
fn try_from_object(vm: &VirtualMachine, obj: PyObjectRef) -> PyResult<Self> {
TryFromBorrowedObject::try_from_borrowed_object(vm, &obj)
}
@@ -31,9 +31,9 @@ impl PyObjectRef {
}
impl PyObject {
pub fn try_to_value<T>(&self, vm: &VirtualMachine) -> PyResult<T>
pub fn try_to_value<'a, T: 'a>(&'a self, vm: &VirtualMachine) -> PyResult<T>
where
T: TryFromBorrowedObject,
T: TryFromBorrowedObject<'a>,
{
T::try_from_borrowed_object(vm, self)
}
@@ -55,9 +55,12 @@ impl PyObject {
}
/// Lower-cost variation of `TryFromObject`
pub trait TryFromBorrowedObject: Sized {
pub trait TryFromBorrowedObject<'a>: Sized
where
Self: 'a,
{
/// Attempt to convert a Python object to a value of this type.
fn try_from_borrowed_object(vm: &VirtualMachine, obj: &PyObject) -> PyResult<Self>;
fn try_from_borrowed_object(vm: &VirtualMachine, obj: &'a PyObject) -> PyResult<Self>;
}
impl<T> TryFromObject for PyRef<T>
@@ -93,12 +96,24 @@ impl<T: TryFromObject> TryFromObject for Option<T> {
}
}
impl<T: TryFromObject> TryFromBorrowedObject for Vec<T> {
fn try_from_borrowed_object(vm: &VirtualMachine, value: &PyObject) -> PyResult<Self> {
impl<'a, T: 'a + TryFromObject> TryFromBorrowedObject<'a> for Vec<T> {
fn try_from_borrowed_object(vm: &VirtualMachine, value: &'a PyObject) -> PyResult<Self> {
vm.extract_elements_with(value, |obj| T::try_from_object(vm, obj))
}
}
impl<'a, T: PyPayload> TryFromBorrowedObject<'a> for &'a Py<T> {
fn try_from_borrowed_object(vm: &VirtualMachine, obj: &'a PyObject) -> PyResult<Self> {
let class = T::class(vm);
if obj.fast_isinstance(class) {
obj.downcast_ref()
.ok_or_else(|| vm.new_downcast_runtime_error(class, &obj))
} else {
Err(vm.new_downcast_type_error(class, &obj))
}
}
}
impl TryFromObject for std::time::Duration {
fn try_from_object(vm: &VirtualMachine, obj: PyObjectRef) -> PyResult<Self> {
use std::time::Duration;

View File

@@ -65,8 +65,8 @@ impl From<ArgBytesLike> for PyBuffer {
}
}
impl TryFromBorrowedObject for ArgBytesLike {
fn try_from_borrowed_object(vm: &VirtualMachine, obj: &PyObject) -> PyResult<Self> {
impl<'a> TryFromBorrowedObject<'a> for ArgBytesLike {
fn try_from_borrowed_object(vm: &VirtualMachine, obj: &'a PyObject) -> PyResult<Self> {
let buffer = PyBuffer::try_from_borrowed_object(vm, obj)?;
if buffer.desc.is_contiguous() {
Ok(Self(buffer))
@@ -107,8 +107,8 @@ impl From<ArgMemoryBuffer> for PyBuffer {
}
}
impl TryFromBorrowedObject for ArgMemoryBuffer {
fn try_from_borrowed_object(vm: &VirtualMachine, obj: &PyObject) -> PyResult<Self> {
impl<'a> TryFromBorrowedObject<'a> for ArgMemoryBuffer {
fn try_from_borrowed_object(vm: &VirtualMachine, obj: &'a PyObject) -> PyResult<Self> {
let buffer = PyBuffer::try_from_borrowed_object(vm, obj)?;
if !buffer.desc.is_contiguous() {
Err(vm.new_type_error("non-contiguous buffer is not a bytes-like object".to_owned()))

View File

@@ -28,8 +28,8 @@ pub enum ArgByteOrder {
Little,
}
impl TryFromBorrowedObject for ArgByteOrder {
fn try_from_borrowed_object(vm: &VirtualMachine, obj: &PyObject) -> PyResult<Self> {
impl<'a> TryFromBorrowedObject<'a> for ArgByteOrder {
fn try_from_borrowed_object(vm: &VirtualMachine, obj: &'a PyObject) -> PyResult<Self> {
obj.try_value_with(
|s: &PyStr| match s.as_str() {
"big" => Ok(Self::Big),

View File

@@ -136,8 +136,8 @@ impl PyBuffer {
}
}
impl TryFromBorrowedObject for PyBuffer {
fn try_from_borrowed_object(vm: &VirtualMachine, obj: &PyObject) -> PyResult<Self> {
impl<'a> TryFromBorrowedObject<'a> for PyBuffer {
fn try_from_borrowed_object(vm: &VirtualMachine, obj: &'a PyObject) -> PyResult<Self> {
let cls = obj.class();
let as_buffer = cls.mro_find_map(|cls| cls.slots.as_buffer);
if let Some(f) = as_buffer {

View File

@@ -435,8 +435,8 @@ mod unix {
#[pyattr]
use libc::{CLOCK_PROF, CLOCK_UPTIME};
impl TryFromBorrowedObject for ClockId {
fn try_from_borrowed_object(vm: &VirtualMachine, obj: &PyObject) -> PyResult<Self> {
impl<'a> TryFromBorrowedObject<'a> for ClockId {
fn try_from_borrowed_object(vm: &VirtualMachine, obj: &'a PyObject) -> PyResult<Self> {
obj.try_to_value(vm).map(ClockId::from_raw)
}
}