mirror of
https://github.com/RustPython/RustPython.git
synced 2026-06-09 22:49:57 +09:00
fix sequence_wrapper
This commit is contained in:
committed by
Jeong YunWon
parent
c460f06f6e
commit
9cb53919d1
@@ -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)
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user