Skip to content

Commit bbbdaf3

Browse files
authored
Merge pull request #3202 from youknowone/pyiter-more
Remove not very useful iterator utilty functions
2 parents 8d52309 + 0576b2b commit bbbdaf3

File tree

22 files changed

+430
-426
lines changed

22 files changed

+430
-426
lines changed

stdlib/src/json.rs

Lines changed: 50 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -5,13 +5,12 @@ mod machinery;
55
mod _json {
66
use super::machinery;
77
use crate::vm::{
8-
builtins::PyBaseExceptionRef,
9-
builtins::{PyStrRef, PyTypeRef},
8+
builtins::{PyBaseExceptionRef, PyStrRef, PyTypeRef},
109
function::{FuncArgs, OptionalArg},
11-
iterator,
10+
protocol::PyIterReturn,
1211
slots::{Callable, SlotConstructor},
13-
IdProtocol, IntoPyObject, PyObjectRef, PyRef, PyResult, PyValue, TryFromObject,
14-
VirtualMachine,
12+
IdProtocol, IntoPyObject, IntoPyResult, PyObjectRef, PyRef, PyResult, PyValue,
13+
TryFromObject, VirtualMachine,
1514
};
1615
use num_bigint::BigInt;
1716
use std::str::FromStr;
@@ -74,42 +73,48 @@ mod _json {
7473
idx: usize,
7574
scan_once: PyObjectRef,
7675
vm: &VirtualMachine,
77-
) -> PyResult {
78-
let c = s
79-
.chars()
80-
.next()
81-
.ok_or_else(|| iterator::stop_iter_with_value(vm.ctx.new_int(idx), vm))?;
76+
) -> PyResult<PyIterReturn> {
77+
let c = match s.chars().next() {
78+
Some(c) => c,
79+
None => return Ok(PyIterReturn::StopIteration(Some(vm.ctx.new_int(idx)))),
80+
};
8281
let next_idx = idx + c.len_utf8();
8382
match c {
8483
'"' => {
8584
return scanstring(pystr, next_idx, OptionalArg::Present(self.strict), vm)
86-
.map(|x| x.into_pyobject(vm))
85+
.map(|x| PyIterReturn::Return(x.into_pyobject(vm)))
8786
}
8887
'{' => {
8988
// TODO: parse the object in rust
9089
let parse_obj = vm.get_attribute(self.ctx.clone(), "parse_object")?;
91-
return vm.invoke(
92-
&parse_obj,
93-
(
94-
vm.ctx
95-
.new_tuple(vec![pystr.into_object(), vm.ctx.new_int(next_idx)]),
96-
self.strict,
97-
scan_once,
98-
self.object_hook.clone(),
99-
self.object_pairs_hook.clone(),
90+
return PyIterReturn::from_pyresult(
91+
vm.invoke(
92+
&parse_obj,
93+
(
94+
vm.ctx
95+
.new_tuple(vec![pystr.into_object(), vm.ctx.new_int(next_idx)]),
96+
self.strict,
97+
scan_once,
98+
self.object_hook.clone(),
99+
self.object_pairs_hook.clone(),
100+
),
100101
),
102+
vm,
101103
);
102104
}
103105
'[' => {
104106
// TODO: parse the array in rust
105107
let parse_array = vm.get_attribute(self.ctx.clone(), "parse_array")?;
106-
return vm.invoke(
107-
&parse_array,
108-
vec![
109-
vm.ctx
110-
.new_tuple(vec![pystr.into_object(), vm.ctx.new_int(next_idx)]),
111-
scan_once,
112-
],
108+
return PyIterReturn::from_pyresult(
109+
vm.invoke(
110+
&parse_array,
111+
vec![
112+
vm.ctx
113+
.new_tuple(vec![pystr.into_object(), vm.ctx.new_int(next_idx)]),
114+
scan_once,
115+
],
116+
),
117+
vm,
113118
);
114119
}
115120
_ => {}
@@ -118,7 +123,9 @@ mod _json {
118123
macro_rules! parse_const {
119124
($s:literal, $val:expr) => {
120125
if s.starts_with($s) {
121-
return Ok(vm.ctx.new_tuple(vec![$val, vm.ctx.new_int(idx + $s.len())]));
126+
return Ok(PyIterReturn::Return(
127+
vm.ctx.new_tuple(vec![$val, vm.ctx.new_int(idx + $s.len())]),
128+
));
122129
}
123130
};
124131
}
@@ -128,16 +135,18 @@ mod _json {
128135
parse_const!("false", vm.ctx.new_bool(false));
129136

130137
if let Some((res, len)) = self.parse_number(s, vm) {
131-
return Ok(vm.ctx.new_tuple(vec![res?, vm.ctx.new_int(idx + len)]));
138+
return Ok(PyIterReturn::Return(
139+
vm.ctx.new_tuple(vec![res?, vm.ctx.new_int(idx + len)]),
140+
));
132141
}
133142

134143
macro_rules! parse_constant {
135144
($s:literal) => {
136145
if s.starts_with($s) {
137-
return Ok(vm.ctx.new_tuple(vec![
146+
return Ok(PyIterReturn::Return(vm.ctx.new_tuple(vec![
138147
vm.invoke(&self.parse_constant, ($s.to_owned(),))?,
139148
vm.ctx.new_int(idx + $s.len()),
140-
]));
149+
])));
141150
}
142151
};
143152
}
@@ -146,7 +155,7 @@ mod _json {
146155
parse_constant!("Infinity");
147156
parse_constant!("-Infinity");
148157

149-
Err(iterator::stop_iter_with_value(vm.ctx.new_int(idx), vm))
158+
Ok(PyIterReturn::StopIteration(Some(vm.ctx.new_int(idx))))
150159
}
151160

152161
fn parse_number(&self, s: &str, vm: &VirtualMachine) -> Option<(PyResult, usize)> {
@@ -185,16 +194,19 @@ mod _json {
185194
Some((ret, buf.len()))
186195
}
187196

188-
fn call(zelf: &PyRef<Self>, pystr: PyStrRef, idx: isize, vm: &VirtualMachine) -> PyResult {
197+
fn call(
198+
zelf: &PyRef<Self>,
199+
pystr: PyStrRef,
200+
idx: isize,
201+
vm: &VirtualMachine,
202+
) -> PyResult<PyIterReturn> {
189203
if idx < 0 {
190204
return Err(vm.new_value_error("idx cannot be negative".to_owned()));
191205
}
192206
let idx = idx as usize;
193207
let mut chars = pystr.as_str().chars();
194-
if idx > 0 {
195-
chars
196-
.nth(idx - 1)
197-
.ok_or_else(|| iterator::stop_iter_with_value(vm.ctx.new_int(idx), vm))?;
208+
if idx > 0 && chars.nth(idx - 1).is_none() {
209+
return Ok(PyIterReturn::StopIteration(Some(vm.ctx.new_int(idx))));
198210
}
199211
zelf.parse(
200212
chars.as_str(),
@@ -209,7 +221,7 @@ mod _json {
209221
impl Callable for JsonScanner {
210222
fn call(zelf: &PyRef<Self>, args: FuncArgs, vm: &VirtualMachine) -> PyResult {
211223
let (pystr, idx) = args.bind::<(PyStrRef, isize)>(vm)?;
212-
JsonScanner::call(zelf, pystr, idx, vm)
224+
JsonScanner::call(zelf, pystr, idx, vm).into_pyresult(vm)
213225
}
214226
}
215227

vm/src/anystr.rs

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,10 @@
1-
use crate::builtins::int::PyIntRef;
2-
use crate::cformat::CFormatString;
3-
use crate::function::{single_or_tuple_any, OptionalOption, PyIterator};
4-
use crate::vm::VirtualMachine;
5-
use crate::{PyObjectRef, PyResult, TryFromObject, TypeProtocol};
1+
use crate::{
2+
builtins::PyIntRef,
3+
cformat::CFormatString,
4+
function::{single_or_tuple_any, OptionalOption},
5+
protocol::PyIterIter,
6+
PyObjectRef, PyResult, TryFromObject, TypeProtocol, VirtualMachine,
7+
};
68
use num_traits::{cast::ToPrimitive, sign::Signed};
79
use std::str::FromStr;
810

@@ -291,7 +293,7 @@ pub trait AnyStr<'s>: 's {
291293

292294
fn py_join<'a>(
293295
&self,
294-
mut iter: PyIterator<'a, impl AnyStrWrapper<'s, Str = Self> + TryFromObject>,
296+
mut iter: PyIterIter<'a, impl AnyStrWrapper<'s, Str = Self> + TryFromObject>,
295297
) -> PyResult<Self::Container> {
296298
let mut joined = if let Some(elem) = iter.next() {
297299
elem?.as_ref().to_container()

vm/src/builtins/asyncgenerator.rs

Lines changed: 37 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
use super::{PyCode, PyStrRef, PyTypeRef};
22
use crate::{
33
builtins::PyBaseExceptionRef,
4-
coroutine::{Coro, Variant},
4+
coroutine::Coro,
55
frame::FrameRef,
66
function::OptionalArg,
77
protocol::PyIterReturn,
@@ -34,7 +34,7 @@ impl PyAsyncGen {
3434

3535
pub fn new(frame: FrameRef, name: PyStrRef) -> Self {
3636
PyAsyncGen {
37-
inner: Coro::new(frame, Variant::AsyncGen, name),
37+
inner: Coro::new(frame, name),
3838
running_async: AtomicCell::new(false),
3939
}
4040
}
@@ -50,8 +50,8 @@ impl PyAsyncGen {
5050
}
5151

5252
#[pymethod(magic)]
53-
fn repr(zelf: PyRef<Self>) -> String {
54-
zelf.inner.repr(zelf.get_id())
53+
fn repr(zelf: PyRef<Self>, vm: &VirtualMachine) -> String {
54+
zelf.inner.repr(zelf.as_object(), zelf.get_id(), vm)
5555
}
5656

5757
#[pymethod(magic)]
@@ -138,24 +138,24 @@ impl PyValue for PyAsyncGenWrappedValue {
138138
impl PyAsyncGenWrappedValue {}
139139

140140
impl PyAsyncGenWrappedValue {
141-
fn unbox(ag: &PyAsyncGen, val: PyResult, vm: &VirtualMachine) -> PyResult {
142-
if let Err(ref e) = val {
143-
if e.isinstance(&vm.ctx.exceptions.stop_async_iteration)
144-
|| e.isinstance(&vm.ctx.exceptions.generator_exit)
145-
{
146-
ag.inner.closed.store(true);
147-
}
141+
fn unbox(ag: &PyAsyncGen, val: PyResult<PyIterReturn>, vm: &VirtualMachine) -> PyResult {
142+
let (closed, async_done) = match &val {
143+
Ok(PyIterReturn::StopIteration(_)) => (true, true),
144+
Err(e) if e.isinstance(&vm.ctx.exceptions.generator_exit) => (true, true),
145+
Err(_) => (false, true),
146+
_ => (false, false),
147+
};
148+
if closed {
149+
ag.inner.closed.store(true);
150+
}
151+
if async_done {
148152
ag.running_async.store(false);
149153
}
150-
let val = val?;
151-
154+
let val = val?.into_async_pyresult(vm)?;
152155
match_class!(match val {
153156
val @ Self => {
154157
ag.running_async.store(false);
155-
Err(vm.new_exception(
156-
vm.ctx.exceptions.stop_iteration.clone(),
157-
vec![val.0.clone()],
158-
))
158+
Err(vm.new_stop_iteration(Some(val.0.clone())))
159159
}
160160
val => Ok(val),
161161
})
@@ -214,7 +214,7 @@ impl PyAsyncGenASend {
214214
}
215215
}
216216
};
217-
let res = self.ag.inner.send(val, vm);
217+
let res = self.ag.inner.send(self.ag.as_object(), val, vm);
218218
let res = PyAsyncGenWrappedValue::unbox(&self.ag, res, vm);
219219
if res.is_err() {
220220
self.close();
@@ -237,6 +237,7 @@ impl PyAsyncGenASend {
237237
}
238238

239239
let res = self.ag.inner.throw(
240+
self.ag.as_object(),
240241
exc_type,
241242
exc_val.unwrap_or_none(vm),
242243
exc_tb.unwrap_or_none(vm),
@@ -258,8 +259,7 @@ impl PyAsyncGenASend {
258259
impl IteratorIterable for PyAsyncGenASend {}
259260
impl SlotIterator for PyAsyncGenASend {
260261
fn next(zelf: &PyRef<Self>, vm: &VirtualMachine) -> PyResult<PyIterReturn> {
261-
// TODO: Fix zelf.send to return PyIterReturn
262-
PyIterReturn::from_result(zelf.send(vm.ctx.none(), vm), vm)
262+
PyIterReturn::from_pyresult(zelf.send(vm.ctx.none(), vm), vm)
263263
}
264264
}
265265

@@ -304,7 +304,7 @@ impl PyAsyncGenAThrow {
304304
}
305305
if self.ag.inner.closed() {
306306
self.state.store(AwaitableState::Closed);
307-
return Err(vm.new_exception_empty(vm.ctx.exceptions.stop_iteration.clone()));
307+
return Err(vm.new_stop_iteration(None));
308308
}
309309
if !vm.is_none(&val) {
310310
return Err(vm.new_runtime_error(
@@ -315,27 +315,28 @@ impl PyAsyncGenAThrow {
315315
self.ag.running_async.store(true);
316316

317317
let (ty, val, tb) = self.value.clone();
318-
let ret = self.ag.inner.throw(ty, val, tb, vm);
318+
let ret = self.ag.inner.throw(self.ag.as_object(), ty, val, tb, vm);
319319
let ret = if self.aclose {
320320
if self.ignored_close(&ret) {
321321
Err(self.yield_close(vm))
322322
} else {
323-
ret
323+
ret.and_then(|o| o.into_async_pyresult(vm))
324324
}
325325
} else {
326326
PyAsyncGenWrappedValue::unbox(&self.ag, ret, vm)
327327
};
328328
ret.map_err(|e| self.check_error(e, vm))
329329
}
330330
AwaitableState::Iter => {
331-
let ret = self.ag.inner.send(val, vm);
331+
let ret = self.ag.inner.send(self.ag.as_object(), val, vm);
332332
if self.aclose {
333333
match ret {
334-
Ok(v) if v.payload_is::<PyAsyncGenWrappedValue>() => {
334+
Ok(PyIterReturn::Return(v)) if v.payload_is::<PyAsyncGenWrappedValue>() => {
335335
Err(self.yield_close(vm))
336336
}
337-
Ok(v) => Ok(v),
338-
Err(e) => Err(self.check_error(e, vm)),
337+
other => other
338+
.and_then(|o| o.into_async_pyresult(vm))
339+
.map_err(|e| self.check_error(e, vm)),
339340
}
340341
} else {
341342
PyAsyncGenWrappedValue::unbox(&self.ag, ret, vm)
@@ -353,6 +354,7 @@ impl PyAsyncGenAThrow {
353354
vm: &VirtualMachine,
354355
) -> PyResult {
355356
let ret = self.ag.inner.throw(
357+
self.ag.as_object(),
356358
exc_type,
357359
exc_val.unwrap_or_none(vm),
358360
exc_tb.unwrap_or_none(vm),
@@ -362,7 +364,7 @@ impl PyAsyncGenAThrow {
362364
if self.ignored_close(&ret) {
363365
Err(self.yield_close(vm))
364366
} else {
365-
ret
367+
ret.and_then(|o| o.into_async_pyresult(vm))
366368
}
367369
} else {
368370
PyAsyncGenWrappedValue::unbox(&self.ag, ret, vm)
@@ -375,9 +377,11 @@ impl PyAsyncGenAThrow {
375377
self.state.store(AwaitableState::Closed);
376378
}
377379

378-
fn ignored_close(&self, res: &PyResult) -> bool {
379-
res.as_ref()
380-
.map_or(false, |v| v.payload_is::<PyAsyncGenWrappedValue>())
380+
fn ignored_close(&self, res: &PyResult<PyIterReturn>) -> bool {
381+
res.as_ref().map_or(false, |v| match v {
382+
PyIterReturn::Return(obj) => obj.payload_is::<PyAsyncGenWrappedValue>(),
383+
PyIterReturn::StopIteration(_) => false,
384+
})
381385
}
382386
fn yield_close(&self, vm: &VirtualMachine) -> PyBaseExceptionRef {
383387
self.ag.running_async.store(false);
@@ -391,7 +395,7 @@ impl PyAsyncGenAThrow {
391395
&& (exc.isinstance(&vm.ctx.exceptions.stop_async_iteration)
392396
|| exc.isinstance(&vm.ctx.exceptions.generator_exit))
393397
{
394-
vm.new_exception_empty(vm.ctx.exceptions.stop_iteration.clone())
398+
vm.new_stop_iteration(None)
395399
} else {
396400
exc
397401
}
@@ -401,8 +405,7 @@ impl PyAsyncGenAThrow {
401405
impl IteratorIterable for PyAsyncGenAThrow {}
402406
impl SlotIterator for PyAsyncGenAThrow {
403407
fn next(zelf: &PyRef<Self>, vm: &VirtualMachine) -> PyResult<PyIterReturn> {
404-
// TODO: Fix zelf.send to return PyIterReturn
405-
PyIterReturn::from_result(zelf.send(vm.ctx.none(), vm), vm)
408+
PyIterReturn::from_pyresult(zelf.send(vm.ctx.none(), vm), vm)
406409
}
407410
}
408411

0 commit comments

Comments
 (0)