fix sequence_wrapper

This commit is contained in:
Kangzhi Shi
2021-10-16 15:23:05 +02:00
committed by Jeong YunWon
parent c460f06f6e
commit 9cb53919d1
3 changed files with 18 additions and 44 deletions

View File

@@ -59,7 +59,7 @@ impl Constructor for PyMemoryView {
}
}
#[pyimpl(with(Hashable, Comparable, AsBuffer, AsMapping, Constructor))]
#[pyimpl(with(Hashable, Comparable, AsBuffer, AsMapping, AsSequence, Constructor))]
impl PyMemoryView {
fn parse_format(format: &str, vm: &VirtualMachine) -> PyResult<FormatSpec> {
FormatSpec::parse(format.as_bytes(), vm)

View File

@@ -4,6 +4,7 @@ use itertools::Itertools;
use crate::{
builtins::{PyList, PySlice},
common::static_cell,
function::IntoPyObject,
IdProtocol, PyArithmeticValue, PyObjectRef, PyResult, PyValue, TypeProtocol, VirtualMachine,
};
@@ -25,6 +26,15 @@ pub struct PySequenceMethods {
pub contains: Option<fn(&PyObjectRef, &PyObjectRef, &VirtualMachine) -> PyResult<bool>>,
}
impl PySequenceMethods {
pub fn not_implemented() -> &'static Self {
static_cell! {
static NOT_IMPLEMENTED: PySequenceMethods;
}
NOT_IMPLEMENTED.get_or_init(Self::default)
}
}
pub struct PySequence {
obj: PyObjectRef,
methods: Cow<'static, PySequenceMethods>,
@@ -37,13 +47,7 @@ impl PySequence {
return false;
}
cls.mro_find_map(|x| x.slots.as_sequence.load())
.map(|f| {
// FIXME: we may avoid the check if we assume all the builtins
// implement fn item() for the sequence protocol
// all the python class must has __getitem__ if they ident as
// sequence protocol implemented
f(obj, vm).item.is_some()
})
.map(|f| f(obj, vm).item.is_some())
.unwrap_or(false)
}
@@ -287,11 +291,7 @@ impl PySequence {
}
}
pub(crate) fn try_add_for_concat(
a: &PyObjectRef,
b: &PyObjectRef,
vm: &VirtualMachine,
) -> PyResult {
pub fn try_add_for_concat(a: &PyObjectRef, b: &PyObjectRef, vm: &VirtualMachine) -> PyResult {
if PySequence::check(b, vm) {
let ret = vm._add(a, b)?;
if let PyArithmeticValue::Implemented(ret) = PyArithmeticValue::from_object(vm, ret) {
@@ -304,7 +304,7 @@ pub(crate) fn try_add_for_concat(
)))
}
pub(crate) fn try_mul_for_repeat(a: &PyObjectRef, n: usize, vm: &VirtualMachine) -> PyResult {
pub fn try_mul_for_repeat(a: &PyObjectRef, n: usize, vm: &VirtualMachine) -> PyResult {
let ret = vm._mul(a, &n.into_pyobject(vm))?;
if let PyArithmeticValue::Implemented(ret) = PyArithmeticValue::from_object(vm, ret) {
return Ok(ret);
@@ -312,7 +312,7 @@ pub(crate) fn try_mul_for_repeat(a: &PyObjectRef, n: usize, vm: &VirtualMachine)
Err(vm.new_type_error(format!("'{}' object can't be repeated", a.class().name())))
}
pub(crate) fn try_iadd_for_inplace_concat(
pub fn try_iadd_for_inplace_concat(
a: &PyObjectRef,
b: &PyObjectRef,
vm: &VirtualMachine,
@@ -329,11 +329,7 @@ pub(crate) fn try_iadd_for_inplace_concat(
)))
}
pub(crate) fn try_imul_for_inplace_repeat(
a: &PyObjectRef,
n: usize,
vm: &VirtualMachine,
) -> PyResult {
pub fn try_imul_for_inplace_repeat(a: &PyObjectRef, n: usize, vm: &VirtualMachine) -> PyResult {
let ret = vm._imul(a, &n.into_pyobject(vm))?;
if let PyArithmeticValue::Implemented(ret) = PyArithmeticValue::from_object(vm, ret) {
return Ok(ret);

View File

@@ -9,7 +9,6 @@ use crate::{
};
use crossbeam_utils::atomic::AtomicCell;
use num_traits::ToPrimitive;
use rustpython_common::static_cell;
use std::borrow::Cow;
use std::cmp::Ordering;
@@ -207,31 +206,14 @@ fn as_mapping_wrapper(zelf: &PyObject, _vm: &VirtualMachine) -> PyMappingMethods
}
fn as_sequence_wrapper(zelf: &PyObject, _vm: &VirtualMachine) -> Cow<'static, PySequenceMethods> {
static_cell! {
static EMPTY: PySequenceMethods;
}
if !zelf.has_class_attr("__getitem__") {
return Cow::Borrowed(EMPTY.get_or_init(PySequenceMethods::default));
return Cow::Borrowed(PySequenceMethods::not_implemented());
}
Cow::Owned(PySequenceMethods {
length: then_some_closure!(zelf.has_class_attr("__len__"), |zelf, vm| {
vm.obj_len_opt(zelf).unwrap()
}),
concat: then_some_closure!(zelf.has_class_attr("__add__"), |zelf, other, vm| {
try_add_for_concat(zelf, other, vm)
}),
repeat: then_some_closure!(zelf.has_class_attr("__mul__"), |zelf, n, vm| {
try_mul_for_repeat(zelf, n, vm)
}),
inplace_concat: then_some_closure!(
zelf.has_class_attr("__iadd__") || zelf.has_class_attr("__add__"),
|zelf, other, vm| { try_iadd_for_inplace_concat(zelf, other, vm) }
),
inplace_repeat: then_some_closure!(
zelf.has_class_attr("__imul__") || zelf.has_class_attr("__mul__"),
|zelf, n, vm| { try_imul_for_inplace_repeat(zelf, n, vm) }
),
item: Some(|zelf, i, vm| {
vm.call_special_method(zelf.clone(), "__getitem__", (i.into_pyobject(vm),))
}),
@@ -246,8 +228,7 @@ fn as_sequence_wrapper(zelf: &PyObject, _vm: &VirtualMachine) -> Cow<'static, Py
.map(|_| Ok(()))?,
}
),
// TODO: IterSearch
contains: None,
..Default::default()
})
}
@@ -353,9 +334,6 @@ impl PyType {
update_slot!(as_mapping, as_mapping_wrapper);
update_slot!(as_sequence, as_sequence_wrapper);
}
"__add__" | "__iadd__" | "__mul__" | "__imul__" => {
update_slot!(as_sequence, as_sequence_wrapper);
}
"__hash__" => {
update_slot!(hash, hash_wrapper);
}