Skip to content

Commit 3fe8a30

Browse files
committed
bytesinner from pytuple
1 parent 275b727 commit 3fe8a30

File tree

6 files changed

+81
-27
lines changed

6 files changed

+81
-27
lines changed

Lib/test/test_memoryview.py

Lines changed: 17 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,8 @@ def setitem(value):
7171
m = None
7272
self.assertEqual(sys.getrefcount(b), oldrefcount)
7373

74+
# TODO: RUSTPYTHON
75+
@unittest.expectedFailure
7476
def test_setitem_writable(self):
7577
if not self.rw_type:
7678
self.skipTest("no writable type to test")
@@ -112,13 +114,11 @@ def setitem(key, value):
112114
self.assertRaises(TypeError, setitem, "a", b"a")
113115
# Not implemented: multidimensional slices
114116
slices = (slice(0,1,1), slice(0,1,2))
115-
# TODO: RUSTPYTHON
116-
# self.assertRaises(NotImplementedError, setitem, slices, b"a")
117+
self.assertRaises(NotImplementedError, setitem, slices, b"a")
117118
# Trying to resize the memory object
118119
exc = ValueError if m.format == 'c' else TypeError
119-
# TODO: RUSTPYTHON
120-
# self.assertRaises(exc, setitem, 0, b"")
121-
# self.assertRaises(exc, setitem, 0, b"ab")
120+
self.assertRaises(exc, setitem, 0, b"")
121+
self.assertRaises(exc, setitem, 0, b"ab")
122122
self.assertRaises(ValueError, setitem, slice(1,1), b"a")
123123
self.assertRaises(ValueError, setitem, slice(0,2), b"a")
124124

@@ -150,6 +150,8 @@ def test_tolist(self):
150150
l = m.tolist()
151151
self.assertEqual(l, list(b"abcdef"))
152152

153+
# TODO: RUSTPYTHON
154+
@unittest.expectedFailure
153155
def test_compare(self):
154156
# memoryviews can compare for equality with other objects
155157
# having the buffer interface.
@@ -174,12 +176,11 @@ def test_compare(self):
174176
self.assertTrue("abcdef" != m)
175177

176178
# Unordered comparisons
177-
# TODO: RUSTPYTHON
178-
# for c in (m, b"abcdef"):
179-
# self.assertRaises(TypeError, lambda: m < c)
180-
# self.assertRaises(TypeError, lambda: c <= m)
181-
# self.assertRaises(TypeError, lambda: m >= c)
182-
# self.assertRaises(TypeError, lambda: c > m)
179+
for c in (m, b"abcdef"):
180+
self.assertRaises(TypeError, lambda: m < c)
181+
self.assertRaises(TypeError, lambda: c <= m)
182+
self.assertRaises(TypeError, lambda: m >= c)
183+
self.assertRaises(TypeError, lambda: c > m)
183184

184185
def check_attributes_with_type(self, tp):
185186
m = self._view(tp(self._source))
@@ -272,12 +273,11 @@ def _check_released(self, m, tp):
272273
with check: m.itemsize
273274
with check: m.ndim
274275
with check: m.readonly
275-
# TODO: RUSTPYTHON
276-
# with check: m.shape
277-
# with check: m.strides
278-
# with check:
279-
# with m:
280-
# pass
276+
with check: m.shape
277+
with check: m.strides
278+
with check:
279+
with m:
280+
pass
281281
# str() and repr() still function
282282
self.assertIn("released memory", str(m))
283283
self.assertIn("released memory", repr(m))

extra_tests/snippets/memoryview.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
a = memoryview(obj)
77
assert a.obj == obj
88

9-
# assert a[2:3] == b"c"
9+
assert a[2:3] == b"c"
1010

1111
assert hash(obj) == hash(a)
1212

vm/src/bytesinner.rs

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,6 @@ use itertools::Itertools;
33
use num_bigint::BigInt;
44
use num_traits::ToPrimitive;
55

6-
use crate::anystr::{self, AnyStr, AnyStrContainer, AnyStrWrapper};
76
use crate::byteslike::try_bytes_like;
87
use crate::function::{OptionalArg, OptionalOption};
98
use crate::obj::objbytearray::PyByteArray;
@@ -21,6 +20,10 @@ use crate::pyobject::{
2120
use crate::sliceable::{PySliceableSequence, PySliceableSequenceMut, SequenceIndex};
2221
use crate::slots::PyComparisonOp;
2322
use crate::vm::VirtualMachine;
23+
use crate::{
24+
anystr::{self, AnyStr, AnyStrContainer, AnyStrWrapper},
25+
obj::objtuple::PyTuple,
26+
};
2427
use rustpython_common::hash;
2528

2629
#[derive(Debug, Default, Clone)]
@@ -41,8 +44,9 @@ impl TryFromObject for PyBytesInner {
4144
}
4245

4346
match_class!(match obj {
47+
// TODO: generic way from &[PyObjectRef]
4448
l @ PyList => l.to_byte_inner(vm),
45-
// TODO: PyTyple
49+
t @ PyTuple => t.to_bytes_inner(vm),
4650
obj => {
4751
let iter = vm.get_method_or_type_error(obj.clone(), "__iter__", || {
4852
format!(

vm/src/obj/objlist.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,7 @@ impl PyList {
7272
self.elements.write()
7373
}
7474

75+
// TODO: more generic way to do so
7576
pub(crate) fn to_byte_inner(&self, vm: &VirtualMachine) -> PyResult<bytesinner::PyBytesInner> {
7677
let mut elements = Vec::<u8>::with_capacity(self.borrow_value().len());
7778
for elem in self.borrow_value().iter() {

vm/src/obj/objmemory.rs

Lines changed: 31 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,8 @@ use crate::obj::objslice::PySliceRef;
88
use crate::obj::objstr::PyStr;
99
use crate::obj::objtype::PyTypeRef;
1010
use crate::pyobject::{
11-
IdProtocol, PyClassImpl, PyComparisonValue, PyContext, PyObjectRef, PyRef, PyResult,
12-
PyThreadingConstraint, PyValue, TypeProtocol,
11+
IdProtocol, IntoPyObject, PyClassImpl, PyComparisonValue, PyContext, PyObjectRef, PyRef,
12+
PyResult, PyThreadingConstraint, PyValue, TypeProtocol,
1313
};
1414
use crate::sliceable::{convert_slice, saturate_range, wrap_index, SequenceIndex};
1515
use crate::slots::{BufferProtocol, Comparable, Hashable, PyComparisonOp};
@@ -85,9 +85,11 @@ pub struct BufferOptions {
8585
pub len: usize,
8686
pub itemsize: usize,
8787
pub contiguous: bool,
88+
pub format: String,
8889
// TODO: support multiple dimension array
8990
pub ndim: usize,
90-
pub format: String,
91+
pub shape: Vec<usize>,
92+
pub strides: Vec<isize>,
9193
}
9294

9395
impl Default for BufferOptions {
@@ -97,8 +99,10 @@ impl Default for BufferOptions {
9799
len: 0,
98100
itemsize: 1,
99101
contiguous: true,
100-
ndim: 1,
101102
format: "B".to_owned(),
103+
ndim: 1,
104+
shape: Vec::new(),
105+
strides: Vec::new(),
102106
}
103107
}
104108
}
@@ -209,12 +213,35 @@ impl PyMemoryView {
209213
self.try_not_released(vm).map(|_| self.options.ndim)
210214
}
211215

216+
// TODO
217+
#[pyproperty]
218+
fn shape(&self, vm: &VirtualMachine) -> PyResult<PyObjectRef> {
219+
self.try_not_released(vm)
220+
.map(|_| (self.options.len,).into_pyobject(vm))
221+
}
222+
223+
// TODO
224+
#[pyproperty]
225+
fn strides(&self, vm: &VirtualMachine) -> PyResult<PyObjectRef> {
226+
self.try_not_released(vm).map(|_| (0,).into_pyobject(vm))
227+
}
228+
212229
#[pyproperty]
213230
fn format(&self, vm: &VirtualMachine) -> PyResult<PyStr> {
214231
self.try_not_released(vm)
215232
.map(|_| PyStr::from(&self.options.format))
216233
}
217234

235+
#[pymethod(magic)]
236+
fn enter(zelf: PyRef<Self>, vm: &VirtualMachine) -> PyResult<PyRef<Self>> {
237+
zelf.try_not_released(vm).map(|_| zelf)
238+
}
239+
240+
#[pymethod(magic)]
241+
fn exit(&self) {
242+
self.release();
243+
}
244+
218245
// translate the slice index to memory index
219246
fn get_pos(&self, i: isize) -> Option<usize> {
220247
let len = self.options.len;

vm/src/obj/objtuple.rs

Lines changed: 25 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,21 @@
11
use crossbeam_utils::atomic::AtomicCell;
2+
use num_traits::ToPrimitive;
23
use std::fmt;
34

5+
use super::objint::PyIntRef;
46
use super::objiter;
57
use super::objtype::PyTypeRef;
6-
use crate::function::OptionalArg;
8+
use crate::common::hash::PyHash;
79
use crate::pyobject::{
810
self, BorrowValue, Either, IdProtocol, IntoPyObject, PyArithmaticValue, PyClassImpl,
9-
PyComparisonValue, PyContext, PyObjectRef, PyRef, PyResult, PyValue, TypeProtocol,
11+
PyComparisonValue, PyContext, PyObjectRef, PyRef, PyResult, PyValue, TryFromObject,
12+
TypeProtocol,
1013
};
1114
use crate::sequence::{self, SimpleSeq};
1215
use crate::sliceable::PySliceableSequence;
1316
use crate::slots::{Comparable, Hashable, PyComparisonOp};
1417
use crate::vm::{ReprGuard, VirtualMachine};
15-
use rustpython_common::hash::PyHash;
18+
use crate::{bytesinner::PyBytesInner, function::OptionalArg};
1619

1720
/// tuple() -> empty tuple
1821
/// tuple(iterable) -> tuple initialized from iterable's items
@@ -66,6 +69,25 @@ impl PyTuple {
6669
pub(crate) fn fast_getitem(&self, idx: usize) -> PyObjectRef {
6770
self.elements[idx].clone()
6871
}
72+
73+
// TODO: more generic way to do so
74+
pub(crate) fn to_bytes_inner(&self, vm: &VirtualMachine) -> PyResult<PyBytesInner> {
75+
let mut elements = Vec::<u8>::with_capacity(self.borrow_value().len());
76+
for elem in self.borrow_value().iter() {
77+
let py_int = PyIntRef::try_from_object(vm, elem.clone()).map_err(|_| {
78+
vm.new_type_error(format!(
79+
"'{}' object cannot be interpreted as an integer",
80+
elem.class().name
81+
))
82+
})?;
83+
let result = py_int
84+
.borrow_value()
85+
.to_u8()
86+
.ok_or_else(|| vm.new_value_error("bytes must be in range (0, 256)".to_owned()))?;
87+
elements.push(result);
88+
}
89+
Ok(elements.into())
90+
}
6991
}
7092

7193
pub type PyTupleRef = PyRef<PyTuple>;

0 commit comments

Comments
 (0)