bytesinner from pytuple

This commit is contained in:
Kangzhi Shi
2020-10-02 09:45:19 +02:00
parent 275b727e9d
commit 3fe8a30ca0
6 changed files with 81 additions and 27 deletions

View File

@@ -71,6 +71,8 @@ class AbstractMemoryTests:
m = None
self.assertEqual(sys.getrefcount(b), oldrefcount)
# TODO: RUSTPYTHON
@unittest.expectedFailure
def test_setitem_writable(self):
if not self.rw_type:
self.skipTest("no writable type to test")
@@ -112,13 +114,11 @@ class AbstractMemoryTests:
self.assertRaises(TypeError, setitem, "a", b"a")
# Not implemented: multidimensional slices
slices = (slice(0,1,1), slice(0,1,2))
# TODO: RUSTPYTHON
# self.assertRaises(NotImplementedError, setitem, slices, b"a")
self.assertRaises(NotImplementedError, setitem, slices, b"a")
# Trying to resize the memory object
exc = ValueError if m.format == 'c' else TypeError
# TODO: RUSTPYTHON
# self.assertRaises(exc, setitem, 0, b"")
# self.assertRaises(exc, setitem, 0, b"ab")
self.assertRaises(exc, setitem, 0, b"")
self.assertRaises(exc, setitem, 0, b"ab")
self.assertRaises(ValueError, setitem, slice(1,1), b"a")
self.assertRaises(ValueError, setitem, slice(0,2), b"a")
@@ -150,6 +150,8 @@ class AbstractMemoryTests:
l = m.tolist()
self.assertEqual(l, list(b"abcdef"))
# TODO: RUSTPYTHON
@unittest.expectedFailure
def test_compare(self):
# memoryviews can compare for equality with other objects
# having the buffer interface.
@@ -174,12 +176,11 @@ class AbstractMemoryTests:
self.assertTrue("abcdef" != m)
# Unordered comparisons
# TODO: RUSTPYTHON
# for c in (m, b"abcdef"):
# self.assertRaises(TypeError, lambda: m < c)
# self.assertRaises(TypeError, lambda: c <= m)
# self.assertRaises(TypeError, lambda: m >= c)
# self.assertRaises(TypeError, lambda: c > m)
for c in (m, b"abcdef"):
self.assertRaises(TypeError, lambda: m < c)
self.assertRaises(TypeError, lambda: c <= m)
self.assertRaises(TypeError, lambda: m >= c)
self.assertRaises(TypeError, lambda: c > m)
def check_attributes_with_type(self, tp):
m = self._view(tp(self._source))
@@ -272,12 +273,11 @@ class AbstractMemoryTests:
with check: m.itemsize
with check: m.ndim
with check: m.readonly
# TODO: RUSTPYTHON
# with check: m.shape
# with check: m.strides
# with check:
# with m:
# pass
with check: m.shape
with check: m.strides
with check:
with m:
pass
# str() and repr() still function
self.assertIn("released memory", str(m))
self.assertIn("released memory", repr(m))

View File

@@ -6,7 +6,7 @@ obj = b"abcde"
a = memoryview(obj)
assert a.obj == obj
# assert a[2:3] == b"c"
assert a[2:3] == b"c"
assert hash(obj) == hash(a)

View File

@@ -3,7 +3,6 @@ use itertools::Itertools;
use num_bigint::BigInt;
use num_traits::ToPrimitive;
use crate::anystr::{self, AnyStr, AnyStrContainer, AnyStrWrapper};
use crate::byteslike::try_bytes_like;
use crate::function::{OptionalArg, OptionalOption};
use crate::obj::objbytearray::PyByteArray;
@@ -21,6 +20,10 @@ use crate::pyobject::{
use crate::sliceable::{PySliceableSequence, PySliceableSequenceMut, SequenceIndex};
use crate::slots::PyComparisonOp;
use crate::vm::VirtualMachine;
use crate::{
anystr::{self, AnyStr, AnyStrContainer, AnyStrWrapper},
obj::objtuple::PyTuple,
};
use rustpython_common::hash;
#[derive(Debug, Default, Clone)]
@@ -41,8 +44,9 @@ impl TryFromObject for PyBytesInner {
}
match_class!(match obj {
// TODO: generic way from &[PyObjectRef]
l @ PyList => l.to_byte_inner(vm),
// TODO: PyTyple
t @ PyTuple => t.to_bytes_inner(vm),
obj => {
let iter = vm.get_method_or_type_error(obj.clone(), "__iter__", || {
format!(

View File

@@ -72,6 +72,7 @@ impl PyList {
self.elements.write()
}
// TODO: more generic way to do so
pub(crate) fn to_byte_inner(&self, vm: &VirtualMachine) -> PyResult<bytesinner::PyBytesInner> {
let mut elements = Vec::<u8>::with_capacity(self.borrow_value().len());
for elem in self.borrow_value().iter() {

View File

@@ -8,8 +8,8 @@ use crate::obj::objslice::PySliceRef;
use crate::obj::objstr::PyStr;
use crate::obj::objtype::PyTypeRef;
use crate::pyobject::{
IdProtocol, PyClassImpl, PyComparisonValue, PyContext, PyObjectRef, PyRef, PyResult,
PyThreadingConstraint, PyValue, TypeProtocol,
IdProtocol, IntoPyObject, PyClassImpl, PyComparisonValue, PyContext, PyObjectRef, PyRef,
PyResult, PyThreadingConstraint, PyValue, TypeProtocol,
};
use crate::sliceable::{convert_slice, saturate_range, wrap_index, SequenceIndex};
use crate::slots::{BufferProtocol, Comparable, Hashable, PyComparisonOp};
@@ -85,9 +85,11 @@ pub struct BufferOptions {
pub len: usize,
pub itemsize: usize,
pub contiguous: bool,
pub format: String,
// TODO: support multiple dimension array
pub ndim: usize,
pub format: String,
pub shape: Vec<usize>,
pub strides: Vec<isize>,
}
impl Default for BufferOptions {
@@ -97,8 +99,10 @@ impl Default for BufferOptions {
len: 0,
itemsize: 1,
contiguous: true,
ndim: 1,
format: "B".to_owned(),
ndim: 1,
shape: Vec::new(),
strides: Vec::new(),
}
}
}
@@ -209,12 +213,35 @@ impl PyMemoryView {
self.try_not_released(vm).map(|_| self.options.ndim)
}
// TODO
#[pyproperty]
fn shape(&self, vm: &VirtualMachine) -> PyResult<PyObjectRef> {
self.try_not_released(vm)
.map(|_| (self.options.len,).into_pyobject(vm))
}
// TODO
#[pyproperty]
fn strides(&self, vm: &VirtualMachine) -> PyResult<PyObjectRef> {
self.try_not_released(vm).map(|_| (0,).into_pyobject(vm))
}
#[pyproperty]
fn format(&self, vm: &VirtualMachine) -> PyResult<PyStr> {
self.try_not_released(vm)
.map(|_| PyStr::from(&self.options.format))
}
#[pymethod(magic)]
fn enter(zelf: PyRef<Self>, vm: &VirtualMachine) -> PyResult<PyRef<Self>> {
zelf.try_not_released(vm).map(|_| zelf)
}
#[pymethod(magic)]
fn exit(&self) {
self.release();
}
// translate the slice index to memory index
fn get_pos(&self, i: isize) -> Option<usize> {
let len = self.options.len;

View File

@@ -1,18 +1,21 @@
use crossbeam_utils::atomic::AtomicCell;
use num_traits::ToPrimitive;
use std::fmt;
use super::objint::PyIntRef;
use super::objiter;
use super::objtype::PyTypeRef;
use crate::function::OptionalArg;
use crate::common::hash::PyHash;
use crate::pyobject::{
self, BorrowValue, Either, IdProtocol, IntoPyObject, PyArithmaticValue, PyClassImpl,
PyComparisonValue, PyContext, PyObjectRef, PyRef, PyResult, PyValue, TypeProtocol,
PyComparisonValue, PyContext, PyObjectRef, PyRef, PyResult, PyValue, TryFromObject,
TypeProtocol,
};
use crate::sequence::{self, SimpleSeq};
use crate::sliceable::PySliceableSequence;
use crate::slots::{Comparable, Hashable, PyComparisonOp};
use crate::vm::{ReprGuard, VirtualMachine};
use rustpython_common::hash::PyHash;
use crate::{bytesinner::PyBytesInner, function::OptionalArg};
/// tuple() -> empty tuple
/// tuple(iterable) -> tuple initialized from iterable's items
@@ -66,6 +69,25 @@ impl PyTuple {
pub(crate) fn fast_getitem(&self, idx: usize) -> PyObjectRef {
self.elements[idx].clone()
}
// TODO: more generic way to do so
pub(crate) fn to_bytes_inner(&self, vm: &VirtualMachine) -> PyResult<PyBytesInner> {
let mut elements = Vec::<u8>::with_capacity(self.borrow_value().len());
for elem in self.borrow_value().iter() {
let py_int = PyIntRef::try_from_object(vm, elem.clone()).map_err(|_| {
vm.new_type_error(format!(
"'{}' object cannot be interpreted as an integer",
elem.class().name
))
})?;
let result = py_int
.borrow_value()
.to_u8()
.ok_or_else(|| vm.new_value_error("bytes must be in range (0, 256)".to_owned()))?;
elements.push(result);
}
Ok(elements.into())
}
}
pub type PyTupleRef = PyRef<PyTuple>;