mirror of
https://github.com/RustPython/RustPython.git
synced 2026-06-02 19:39:49 +09:00
Merge pull request #2218 from youknowone/cleanup-none
clean up singletons - especially None
This commit is contained in:
@@ -4,6 +4,9 @@
|
||||
use crate::pyobject::PyObjectRef;
|
||||
use crate::vm::VirtualMachine;
|
||||
|
||||
/// Built-in functions, exceptions, and other objects.
|
||||
///
|
||||
/// Noteworthy: None is the `nil' object; Ellipsis represents `...' in slices.
|
||||
#[pymodule(name = "builtins")]
|
||||
mod decl {
|
||||
use num_bigint::Sign;
|
||||
|
||||
@@ -10,10 +10,10 @@ use crate::obj::objbytes::PyBytes;
|
||||
use crate::obj::objint::{self, PyInt, PyIntRef};
|
||||
use crate::obj::objlist::PyList;
|
||||
use crate::obj::objmemory::PyMemoryView;
|
||||
use crate::obj::objnone::PyNoneRef;
|
||||
use crate::obj::objsequence::{
|
||||
get_saturated_pos, PySliceableSequence, PySliceableSequenceMut, SequenceIndex,
|
||||
};
|
||||
use crate::obj::objsingletons::PyNoneRef;
|
||||
use crate::obj::objslice::PySliceRef;
|
||||
use crate::obj::objstr::{self, PyString, PyStringRef};
|
||||
use crate::pyobject::{
|
||||
|
||||
@@ -1,14 +1,14 @@
|
||||
use crate::common::cell::PyRwLock;
|
||||
use crate::function::PyFuncArgs;
|
||||
use crate::obj::objnone::PyNone;
|
||||
use crate::obj::objsingletons::{PyNone, PyNoneRef};
|
||||
use crate::obj::objstr::{PyString, PyStringRef};
|
||||
use crate::obj::objtraceback::PyTracebackRef;
|
||||
use crate::obj::objtuple::{PyTuple, PyTupleRef};
|
||||
use crate::obj::objtype::{self, PyClass, PyClassRef};
|
||||
use crate::py_io::{self, Write};
|
||||
use crate::pyobject::{
|
||||
BorrowValue, PyClassDef, PyClassImpl, PyContext, PyIterable, PyObjectRef, PyRef, PyResult,
|
||||
PyValue, TryFromObject, TypeProtocol,
|
||||
BorrowValue, IntoPyObject, PyClassDef, PyClassImpl, PyContext, PyIterable, PyObjectRef, PyRef,
|
||||
PyResult, PyValue, TryFromObject, TypeProtocol,
|
||||
};
|
||||
use crate::types::create_type_with_slots;
|
||||
use crate::VirtualMachine;
|
||||
@@ -371,7 +371,7 @@ pub fn split(
|
||||
exc: PyBaseExceptionRef,
|
||||
vm: &VirtualMachine,
|
||||
) -> (PyObjectRef, PyObjectRef, PyObjectRef) {
|
||||
let tb = exc.traceback().map_or(vm.get_none(), |tb| tb.into_object());
|
||||
let tb = exc.traceback().into_pyobject(vm);
|
||||
(exc.class().into_object(), exc.into_object(), tb)
|
||||
}
|
||||
|
||||
@@ -626,35 +626,22 @@ fn import_error_init(exc_self: PyObjectRef, args: PyFuncArgs, vm: &VirtualMachin
|
||||
vm.set_attr(
|
||||
&exc_self,
|
||||
"name",
|
||||
args.kwargs
|
||||
.get("name")
|
||||
.cloned()
|
||||
.unwrap_or_else(|| vm.get_none()),
|
||||
vm.unwrap_or_none(args.kwargs.get("name").cloned()),
|
||||
)?;
|
||||
vm.set_attr(
|
||||
&exc_self,
|
||||
"path",
|
||||
args.kwargs
|
||||
.get("path")
|
||||
.cloned()
|
||||
.unwrap_or_else(|| vm.get_none()),
|
||||
vm.unwrap_or_none(args.kwargs.get("path").cloned()),
|
||||
)?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn none_getter(_obj: PyObjectRef, vm: &VirtualMachine) -> PyObjectRef {
|
||||
vm.get_none()
|
||||
fn none_getter(_obj: PyObjectRef, vm: &VirtualMachine) -> PyNoneRef {
|
||||
vm.ctx.none.clone()
|
||||
}
|
||||
|
||||
fn make_arg_getter(idx: usize) -> impl Fn(PyBaseExceptionRef, &VirtualMachine) -> PyObjectRef {
|
||||
move |exc, vm| {
|
||||
exc.args
|
||||
.read()
|
||||
.borrow_value()
|
||||
.get(idx)
|
||||
.cloned()
|
||||
.unwrap_or_else(|| vm.get_none())
|
||||
}
|
||||
fn make_arg_getter(idx: usize) -> impl Fn(PyBaseExceptionRef) -> Option<PyObjectRef> {
|
||||
move |exc| exc.args.read().borrow_value().get(idx).cloned()
|
||||
}
|
||||
|
||||
fn key_error_str(exc: PyBaseExceptionRef, vm: &VirtualMachine) -> PyStringRef {
|
||||
@@ -669,17 +656,16 @@ fn key_error_str(exc: PyBaseExceptionRef, vm: &VirtualMachine) -> PyStringRef {
|
||||
}
|
||||
}
|
||||
|
||||
fn system_exit_code(exc: PyBaseExceptionRef, vm: &VirtualMachine) -> PyObjectRef {
|
||||
match exc.args.read().borrow_value().first() {
|
||||
Some(code) => match_class!(match code {
|
||||
fn system_exit_code(exc: PyBaseExceptionRef) -> Option<PyObjectRef> {
|
||||
exc.args.read().borrow_value().first().map(|code| {
|
||||
match_class!(match code {
|
||||
ref tup @ PyTuple => match tup.borrow_value() {
|
||||
[x] => x.clone(),
|
||||
_ => code.clone(),
|
||||
},
|
||||
other => other.clone(),
|
||||
}),
|
||||
None => vm.get_none(),
|
||||
}
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
pub fn init(ctx: &PyContext) {
|
||||
|
||||
@@ -170,7 +170,7 @@ impl Frame {
|
||||
stack: Vec::new(),
|
||||
blocks: Vec::new(),
|
||||
}),
|
||||
trace: PyMutex::new(vm.get_none()),
|
||||
trace: PyMutex::new(vm.ctx.none()),
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -540,14 +540,11 @@ impl ExecutingFrame<'_> {
|
||||
let exit = self.pop_value();
|
||||
|
||||
let args = if let Some(exc) = exc {
|
||||
let exc_type = exc.class().into_object();
|
||||
let exc_val = exc.clone();
|
||||
let exc_tb = exc.traceback().map_or(vm.get_none(), |tb| tb.into_object());
|
||||
vec![exc_type, exc_val.into_object(), exc_tb]
|
||||
exceptions::split(exc, vm)
|
||||
} else {
|
||||
vec![vm.ctx.none(), vm.ctx.none(), vm.ctx.none()]
|
||||
(vm.ctx.none(), vm.ctx.none(), vm.ctx.none())
|
||||
};
|
||||
let exit_res = vm.invoke(&exit, args)?;
|
||||
let exit_res = vm.invoke(&exit, vec![args.0, args.1, args.2])?;
|
||||
self.push_value(exit_res);
|
||||
|
||||
Ok(None)
|
||||
@@ -1287,7 +1284,7 @@ impl ExecutingFrame<'_> {
|
||||
.ctx
|
||||
.new_pyfunction(code_obj, scope, defaults, kw_only_defaults);
|
||||
|
||||
vm.set_attr(&func_obj, "__doc__", vm.get_none())?;
|
||||
vm.set_attr(&func_obj, "__doc__", vm.ctx.none())?;
|
||||
|
||||
let name = qualified_name
|
||||
.borrow_value()
|
||||
@@ -1296,11 +1293,7 @@ impl ExecutingFrame<'_> {
|
||||
.unwrap();
|
||||
vm.set_attr(&func_obj, "__name__", vm.ctx.new_str(name))?;
|
||||
vm.set_attr(&func_obj, "__qualname__", qualified_name)?;
|
||||
let module = self
|
||||
.scope
|
||||
.globals
|
||||
.get_item_option("__name__", vm)?
|
||||
.unwrap_or_else(|| vm.get_none());
|
||||
let module = vm.unwrap_or_none(self.scope.globals.get_item_option("__name__", vm)?);
|
||||
vm.set_attr(&func_obj, "__module__", module)?;
|
||||
vm.set_attr(&func_obj, "__annotations__", annotations)?;
|
||||
|
||||
|
||||
@@ -394,6 +394,12 @@ pub enum OptionalArg<T = PyObjectRef> {
|
||||
|
||||
impl_option_like!(OptionalArg, Present, Missing);
|
||||
|
||||
impl OptionalArg<PyObjectRef> {
|
||||
pub fn unwrap_or_none(self, vm: &VirtualMachine) -> PyObjectRef {
|
||||
self.unwrap_or_else(|| vm.ctx.none())
|
||||
}
|
||||
}
|
||||
|
||||
pub type OptionalOption<T> = OptionalArg<Option<T>>;
|
||||
|
||||
impl<T> OptionalOption<T> {
|
||||
|
||||
@@ -11,7 +11,6 @@ pub mod objcomplex;
|
||||
pub mod objcoroinner;
|
||||
pub mod objcoroutine;
|
||||
pub mod objdict;
|
||||
pub mod objellipsis;
|
||||
pub mod objenumerate;
|
||||
pub mod objfilter;
|
||||
pub mod objfloat;
|
||||
@@ -27,12 +26,12 @@ pub mod objmappingproxy;
|
||||
pub mod objmemory;
|
||||
pub mod objmodule;
|
||||
pub mod objnamespace;
|
||||
pub mod objnone;
|
||||
pub mod objobject;
|
||||
pub mod objproperty;
|
||||
pub mod objrange;
|
||||
pub mod objsequence;
|
||||
pub mod objset;
|
||||
pub mod objsingletons;
|
||||
pub mod objslice;
|
||||
pub mod objstaticmethod;
|
||||
pub mod objstr;
|
||||
|
||||
@@ -39,9 +39,7 @@ impl PyAsyncGen {
|
||||
|
||||
// TODO: fix function names situation
|
||||
#[pyproperty(magic)]
|
||||
fn name(&self, vm: &VirtualMachine) -> PyObjectRef {
|
||||
vm.get_none()
|
||||
}
|
||||
fn name(&self) {}
|
||||
|
||||
#[pymethod(name = "__aiter__")]
|
||||
fn aiter(zelf: PyRef<Self>, _vm: &VirtualMachine) -> PyRef<Self> {
|
||||
@@ -50,7 +48,7 @@ impl PyAsyncGen {
|
||||
|
||||
#[pymethod(name = "__anext__")]
|
||||
fn anext(zelf: PyRef<Self>, vm: &VirtualMachine) -> PyAsyncGenASend {
|
||||
Self::asend(zelf, vm.get_none(), vm)
|
||||
Self::asend(zelf, vm.ctx.none(), vm)
|
||||
}
|
||||
|
||||
#[pymethod]
|
||||
@@ -76,8 +74,8 @@ impl PyAsyncGen {
|
||||
state: AtomicCell::new(AwaitableState::Init),
|
||||
value: (
|
||||
exc_type,
|
||||
exc_val.unwrap_or_else(|| vm.get_none()),
|
||||
exc_tb.unwrap_or_else(|| vm.get_none()),
|
||||
exc_val.unwrap_or_none(vm),
|
||||
exc_tb.unwrap_or_none(vm),
|
||||
),
|
||||
}
|
||||
}
|
||||
@@ -90,8 +88,8 @@ impl PyAsyncGen {
|
||||
state: AtomicCell::new(AwaitableState::Init),
|
||||
value: (
|
||||
vm.ctx.exceptions.generator_exit.clone().into_object(),
|
||||
vm.get_none(),
|
||||
vm.get_none(),
|
||||
vm.ctx.none(),
|
||||
vm.ctx.none(),
|
||||
),
|
||||
}
|
||||
}
|
||||
@@ -185,7 +183,7 @@ impl PyAsyncGenASend {
|
||||
|
||||
#[pymethod(name = "__next__")]
|
||||
fn next(&self, vm: &VirtualMachine) -> PyResult {
|
||||
self.send(vm.get_none(), vm)
|
||||
self.send(vm.ctx.none(), vm)
|
||||
}
|
||||
|
||||
#[pymethod]
|
||||
@@ -236,8 +234,8 @@ impl PyAsyncGenASend {
|
||||
|
||||
let res = self.ag.inner.throw(
|
||||
exc_type,
|
||||
exc_val.unwrap_or_else(|| vm.get_none()),
|
||||
exc_tb.unwrap_or_else(|| vm.get_none()),
|
||||
exc_val.unwrap_or_none(vm),
|
||||
exc_tb.unwrap_or_none(vm),
|
||||
vm,
|
||||
);
|
||||
let res = PyAsyncGenWrappedValue::unbox(&self.ag, res, vm);
|
||||
@@ -281,7 +279,7 @@ impl PyAsyncGenAThrow {
|
||||
|
||||
#[pymethod(name = "__next__")]
|
||||
fn next(&self, vm: &VirtualMachine) -> PyResult {
|
||||
self.send(vm.get_none(), vm)
|
||||
self.send(vm.ctx.none(), vm)
|
||||
}
|
||||
|
||||
#[pymethod]
|
||||
@@ -353,8 +351,8 @@ impl PyAsyncGenAThrow {
|
||||
) -> PyResult {
|
||||
let ret = self.ag.inner.throw(
|
||||
exc_type,
|
||||
exc_val.unwrap_or_else(|| vm.get_none()),
|
||||
exc_tb.unwrap_or_else(|| vm.get_none()),
|
||||
exc_val.unwrap_or_none(vm),
|
||||
exc_tb.unwrap_or_none(vm),
|
||||
vm,
|
||||
);
|
||||
let res = if self.aclose {
|
||||
|
||||
@@ -3,9 +3,7 @@ use std::fmt;
|
||||
use crate::function::{OptionalArg, PyFuncArgs, PyNativeFunc};
|
||||
use crate::obj::objstr::PyStringRef;
|
||||
use crate::obj::objtype::PyClassRef;
|
||||
use crate::pyobject::{
|
||||
IdProtocol, PyClassImpl, PyContext, PyObjectRef, PyResult, PyValue, TypeProtocol,
|
||||
};
|
||||
use crate::pyobject::{PyClassImpl, PyContext, PyObjectRef, PyResult, PyValue, TypeProtocol};
|
||||
use crate::slots::{SlotCall, SlotDescriptor};
|
||||
use crate::vm::VirtualMachine;
|
||||
|
||||
@@ -118,7 +116,7 @@ impl SlotDescriptor for PyBuiltinMethod {
|
||||
Ok(obj) => obj,
|
||||
Err(result) => return result,
|
||||
};
|
||||
if obj.is(&vm.get_none()) && !Self::_cls_is(&cls, &obj.class()) {
|
||||
if vm.is_none(&obj) && !Self::_cls_is(&cls, &obj.class()) {
|
||||
Ok(zelf.into_object())
|
||||
} else {
|
||||
Ok(vm.ctx.new_bound_method(zelf.into_object(), obj))
|
||||
|
||||
@@ -139,8 +139,8 @@ impl Coro {
|
||||
f.gen_throw(
|
||||
vm,
|
||||
vm.ctx.exceptions.generator_exit.clone().into_object(),
|
||||
vm.get_none(),
|
||||
vm.get_none(),
|
||||
vm.ctx.none(),
|
||||
vm.ctx.none(),
|
||||
)
|
||||
});
|
||||
self.closed.store(true);
|
||||
|
||||
@@ -37,7 +37,7 @@ impl PyCoroutine {
|
||||
// TODO: fix function names situation
|
||||
#[pyproperty(magic)]
|
||||
fn name(&self, vm: &VirtualMachine) -> PyObjectRef {
|
||||
vm.get_none()
|
||||
vm.ctx.none()
|
||||
}
|
||||
|
||||
#[pymethod]
|
||||
@@ -55,8 +55,8 @@ impl PyCoroutine {
|
||||
) -> PyResult {
|
||||
self.inner.throw(
|
||||
exc_type,
|
||||
exc_val.unwrap_or_else(|| vm.get_none()),
|
||||
exc_tb.unwrap_or_else(|| vm.get_none()),
|
||||
exc_val.unwrap_or_none(vm),
|
||||
exc_tb.unwrap_or_none(vm),
|
||||
vm,
|
||||
)
|
||||
}
|
||||
@@ -116,7 +116,7 @@ impl PyCoroutineWrapper {
|
||||
|
||||
#[pymethod(name = "__next__")]
|
||||
fn next(&self, vm: &VirtualMachine) -> PyResult {
|
||||
self.coro.send(vm.get_none(), vm)
|
||||
self.coro.send(vm.ctx.none(), vm)
|
||||
}
|
||||
|
||||
#[pymethod]
|
||||
|
||||
@@ -136,7 +136,7 @@ impl PyDict {
|
||||
vm: &VirtualMachine,
|
||||
) -> PyResult<PyRef<Self>> {
|
||||
let dict = DictContentType::default();
|
||||
let value = value.unwrap_or_else(|| vm.ctx.none());
|
||||
let value = value.unwrap_or_none(vm);
|
||||
for elem in iterable.iter(vm)? {
|
||||
let elem = elem?;
|
||||
dict.insert(vm, elem, value.clone())?;
|
||||
@@ -314,7 +314,7 @@ impl PyDict {
|
||||
) -> PyResult {
|
||||
match self.entries.get(vm, &key)? {
|
||||
Some(value) => Ok(value),
|
||||
None => Ok(default.unwrap_or_else(|| vm.ctx.none())),
|
||||
None => Ok(default.unwrap_or_none(vm)),
|
||||
}
|
||||
}
|
||||
|
||||
@@ -328,7 +328,7 @@ impl PyDict {
|
||||
match self.entries.get(vm, &key)? {
|
||||
Some(value) => Ok(value),
|
||||
None => {
|
||||
let set_value = default.unwrap_or_else(|| vm.ctx.none());
|
||||
let set_value = default.unwrap_or_none(vm);
|
||||
self.entries.insert(vm, key, set_value.clone())?;
|
||||
Ok(set_value)
|
||||
}
|
||||
|
||||
@@ -1,42 +0,0 @@
|
||||
use super::objtype::{issubclass, PyClassRef};
|
||||
use crate::pyobject::{PyClassImpl, PyContext, PyResult, PyValue};
|
||||
use crate::vm::VirtualMachine;
|
||||
|
||||
pub(crate) fn init(context: &PyContext) {
|
||||
PyEllipsis::extend_class(context, &context.types.ellipsis_type);
|
||||
}
|
||||
|
||||
#[pyclass(module = false, name = "EllipsisType")]
|
||||
#[derive(Debug)]
|
||||
pub struct PyEllipsis;
|
||||
|
||||
impl PyValue for PyEllipsis {
|
||||
fn class(vm: &VirtualMachine) -> PyClassRef {
|
||||
vm.ctx.types.ellipsis_type.clone()
|
||||
}
|
||||
}
|
||||
|
||||
#[pyimpl]
|
||||
impl PyEllipsis {
|
||||
#[pyslot]
|
||||
fn tp_new(cls: PyClassRef, vm: &VirtualMachine) -> PyResult {
|
||||
if issubclass(&cls, &vm.ctx.types.ellipsis_type) {
|
||||
Ok(vm.ctx.ellipsis())
|
||||
} else {
|
||||
Err(vm.new_type_error(format!(
|
||||
"ellipsis.__new__({ty}): {ty} is not a subtype of ellipsis",
|
||||
ty = cls,
|
||||
)))
|
||||
}
|
||||
}
|
||||
|
||||
#[pymethod(magic)]
|
||||
fn repr(&self) -> String {
|
||||
"Ellipsis".to_owned()
|
||||
}
|
||||
|
||||
#[pymethod(magic)]
|
||||
fn reduce(&self) -> String {
|
||||
"Ellipsis".to_owned()
|
||||
}
|
||||
}
|
||||
@@ -1,7 +1,7 @@
|
||||
use super::objbool;
|
||||
use super::objiter;
|
||||
use super::objtype::PyClassRef;
|
||||
use crate::pyobject::{IdProtocol, PyClassImpl, PyContext, PyObjectRef, PyRef, PyResult, PyValue};
|
||||
use crate::pyobject::{PyClassImpl, PyContext, PyObjectRef, PyRef, PyResult, PyValue};
|
||||
use crate::vm::VirtualMachine;
|
||||
|
||||
pub type PyFilterRef = PyRef<PyFilter>;
|
||||
@@ -47,7 +47,7 @@ impl PyFilter {
|
||||
let iterator = &self.iterator;
|
||||
loop {
|
||||
let next_obj = objiter::call_next(vm, iterator)?;
|
||||
let predicate_value = if predicate.is(&vm.get_none()) {
|
||||
let predicate_value = if vm.is_none(predicate) {
|
||||
next_obj.clone()
|
||||
} else {
|
||||
// the predicate itself can raise StopIteration which does stop the filter
|
||||
|
||||
@@ -30,7 +30,7 @@ impl FrameRef {
|
||||
// CPython' Frame.f_trace is set to None when deleted.
|
||||
// The strange behavior is mimicked here make bdb.py happy about it.
|
||||
if value.to_string() == "f_trace" {
|
||||
self.set_f_trace(vm.get_none());
|
||||
self.set_f_trace(vm.ctx.none());
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
@@ -15,8 +15,8 @@ use crate::obj::objgenerator::PyGenerator;
|
||||
#[cfg(feature = "jit")]
|
||||
use crate::pyobject::IntoPyObject;
|
||||
use crate::pyobject::{
|
||||
BorrowValue, IdProtocol, ItemProtocol, PyClassImpl, PyContext, PyObjectRef, PyRef, PyResult,
|
||||
PyValue, TypeProtocol,
|
||||
BorrowValue, ItemProtocol, PyClassImpl, PyContext, PyObjectRef, PyRef, PyResult, PyValue,
|
||||
TypeProtocol,
|
||||
};
|
||||
use crate::scope::Scope;
|
||||
use crate::slots::{SlotCall, SlotDescriptor};
|
||||
@@ -48,7 +48,7 @@ impl SlotDescriptor for PyFunction {
|
||||
cls: OptionalArg<PyObjectRef>,
|
||||
) -> PyResult {
|
||||
let (zelf, obj) = Self::_unwrap(zelf, obj, vm)?;
|
||||
if obj.is(&vm.get_none()) && !Self::_cls_is(&cls, &obj.class()) {
|
||||
if vm.is_none(&obj) && !Self::_cls_is(&cls, &obj.class()) {
|
||||
Ok(zelf.into_object())
|
||||
} else {
|
||||
Ok(vm.ctx.new_bound_method(zelf.into_object(), obj))
|
||||
|
||||
@@ -40,7 +40,7 @@ impl PyGenerator {
|
||||
// TODO: fix function names situation
|
||||
#[pyproperty(magic)]
|
||||
fn name(&self, vm: &VirtualMachine) -> PyObjectRef {
|
||||
vm.get_none()
|
||||
vm.ctx.none()
|
||||
}
|
||||
|
||||
#[pymethod(name = "__iter__")]
|
||||
@@ -50,7 +50,7 @@ impl PyGenerator {
|
||||
|
||||
#[pymethod(name = "__next__")]
|
||||
fn next(&self, vm: &VirtualMachine) -> PyResult {
|
||||
self.send(vm.get_none(), vm)
|
||||
self.send(vm.ctx.none(), vm)
|
||||
}
|
||||
|
||||
#[pymethod]
|
||||
@@ -68,8 +68,8 @@ impl PyGenerator {
|
||||
) -> PyResult {
|
||||
self.inner.throw(
|
||||
exc_type,
|
||||
exc_val.unwrap_or_else(|| vm.get_none()),
|
||||
exc_tb.unwrap_or_else(|| vm.get_none()),
|
||||
exc_val.unwrap_or_none(vm),
|
||||
exc_tb.unwrap_or_none(vm),
|
||||
vm,
|
||||
)
|
||||
}
|
||||
|
||||
@@ -494,7 +494,7 @@ impl PyInt {
|
||||
match precision {
|
||||
OptionalArg::Missing => (),
|
||||
OptionalArg::Present(ref value) => {
|
||||
if !vm.get_none().is(value) {
|
||||
if !vm.is_none(value) {
|
||||
// Only accept int type ndigits
|
||||
let _ndigits = value.payload_if_subclass::<PyInt>(vm).ok_or_else(|| {
|
||||
vm.new_type_error(format!(
|
||||
|
||||
@@ -98,11 +98,7 @@ pub fn stop_iter_with_value(val: PyObjectRef, vm: &VirtualMachine) -> PyBaseExce
|
||||
|
||||
pub fn stop_iter_value(vm: &VirtualMachine, exc: &PyBaseExceptionRef) -> PyResult {
|
||||
let args = exc.args();
|
||||
let val = args
|
||||
.borrow_value()
|
||||
.first()
|
||||
.cloned()
|
||||
.unwrap_or_else(|| vm.get_none());
|
||||
let val = vm.unwrap_or_none(args.borrow_value().first().cloned());
|
||||
Ok(val)
|
||||
}
|
||||
|
||||
|
||||
@@ -57,12 +57,15 @@ impl PyMappingProxy {
|
||||
}
|
||||
|
||||
#[pymethod]
|
||||
fn get(&self, key: PyObjectRef, default: OptionalArg, vm: &VirtualMachine) -> PyResult {
|
||||
fn get(
|
||||
&self,
|
||||
key: PyObjectRef,
|
||||
default: OptionalArg,
|
||||
vm: &VirtualMachine,
|
||||
) -> PyResult<Option<PyObjectRef>> {
|
||||
let default = default.into_option();
|
||||
Ok(self
|
||||
.get_inner(key, vm)?
|
||||
.or(default)
|
||||
.unwrap_or_else(|| vm.get_none()))
|
||||
let value = self.get_inner(key, vm)?.or(default);
|
||||
Ok(value)
|
||||
}
|
||||
|
||||
#[pymethod(name = "__getitem__")]
|
||||
|
||||
@@ -3,7 +3,8 @@ use super::objstr::{PyString, PyStringRef};
|
||||
use super::objtype::PyClassRef;
|
||||
use crate::function::{OptionalOption, PyFuncArgs};
|
||||
use crate::pyobject::{
|
||||
BorrowValue, ItemProtocol, PyClassImpl, PyContext, PyObjectRef, PyRef, PyResult, PyValue,
|
||||
BorrowValue, IntoPyObject, ItemProtocol, PyClassImpl, PyContext, PyObjectRef, PyRef, PyResult,
|
||||
PyValue,
|
||||
};
|
||||
use crate::vm::VirtualMachine;
|
||||
|
||||
@@ -31,13 +32,13 @@ pub fn init_module_dict(
|
||||
.set_item("__doc__", doc, vm)
|
||||
.expect("Failed to set __doc__ on module");
|
||||
module_dict
|
||||
.set_item("__package__", vm.get_none(), vm)
|
||||
.set_item("__package__", vm.ctx.none(), vm)
|
||||
.expect("Failed to set __package__ on module");
|
||||
module_dict
|
||||
.set_item("__loader__", vm.get_none(), vm)
|
||||
.set_item("__loader__", vm.ctx.none(), vm)
|
||||
.expect("Failed to set __loader__ on module");
|
||||
module_dict
|
||||
.set_item("__spec__", vm.get_none(), vm)
|
||||
.set_item("__spec__", vm.ctx.none(), vm)
|
||||
.expect("Failed to set __spec__ on module");
|
||||
}
|
||||
|
||||
@@ -63,8 +64,7 @@ impl PyModuleRef {
|
||||
vm,
|
||||
&self.as_object().dict().unwrap(),
|
||||
name.into_object(),
|
||||
doc.flatten()
|
||||
.map_or_else(|| vm.get_none(), PyRef::into_object),
|
||||
doc.flatten().into_pyobject(vm),
|
||||
);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
@@ -140,9 +140,7 @@ impl PyBaseObject {
|
||||
}
|
||||
|
||||
#[pyclassmethod(magic)]
|
||||
fn init_subclass(_cls: PyClassRef, vm: &VirtualMachine) -> PyResult {
|
||||
Ok(vm.ctx.none())
|
||||
}
|
||||
fn init_subclass(_cls: PyClassRef) {}
|
||||
|
||||
#[pymethod(magic)]
|
||||
pub fn dir(obj: PyObjectRef, vm: &VirtualMachine) -> PyResult<PyList> {
|
||||
@@ -176,9 +174,7 @@ impl PyBaseObject {
|
||||
}
|
||||
|
||||
#[pymethod(magic)]
|
||||
fn init(_args: PyFuncArgs, vm: &VirtualMachine) -> PyResult {
|
||||
Ok(vm.ctx.none())
|
||||
}
|
||||
fn init(_args: PyFuncArgs) {}
|
||||
|
||||
#[pyproperty(name = "__class__")]
|
||||
fn get_class(obj: PyObjectRef) -> PyObjectRef {
|
||||
|
||||
@@ -6,7 +6,7 @@ use crate::common::cell::PyRwLock;
|
||||
use super::objtype::PyClassRef;
|
||||
use crate::function::OptionalArg;
|
||||
use crate::pyobject::{
|
||||
IdProtocol, PyClassImpl, PyContext, PyObjectRef, PyRef, PyResult, PyValue, TypeProtocol,
|
||||
PyClassImpl, PyContext, PyObjectRef, PyRef, PyResult, PyValue, TypeProtocol,
|
||||
};
|
||||
use crate::slots::SlotDescriptor;
|
||||
use crate::vm::VirtualMachine;
|
||||
@@ -198,7 +198,7 @@ impl PyProperty {
|
||||
|
||||
/// Take a python object and turn it into an option object, where python None maps to rust None.
|
||||
fn py_none_to_option(vm: &VirtualMachine, value: &PyObjectRef) -> Option<PyObjectRef> {
|
||||
if vm.ctx.none().is(value) {
|
||||
if vm.is_none(value) {
|
||||
None
|
||||
} else {
|
||||
Some(value.clone())
|
||||
|
||||
@@ -369,21 +369,21 @@ impl PyRange {
|
||||
fn hash(zelf: PyRef<Self>, vm: &VirtualMachine) -> PyResult<PyHash> {
|
||||
let length = zelf.length();
|
||||
let elements = if length.is_zero() {
|
||||
vec![vm.ctx.new_int(length), vm.get_none(), vm.get_none()]
|
||||
[vm.ctx.new_int(length), vm.ctx.none(), vm.ctx.none()]
|
||||
} else if length.is_one() {
|
||||
vec![
|
||||
[
|
||||
vm.ctx.new_int(length),
|
||||
zelf.start().into_object(),
|
||||
vm.get_none(),
|
||||
vm.ctx.none(),
|
||||
]
|
||||
} else {
|
||||
vec![
|
||||
[
|
||||
vm.ctx.new_int(length),
|
||||
zelf.start().into_object(),
|
||||
zelf.step().into_object(),
|
||||
]
|
||||
};
|
||||
pyobject::hash_iter(&elements, vm)
|
||||
pyobject::hash_iter(elements.iter(), vm)
|
||||
}
|
||||
|
||||
#[pyslot]
|
||||
|
||||
@@ -5,7 +5,7 @@ use num_traits::{One, Signed, ToPrimitive, Zero};
|
||||
|
||||
use super::objint::{PyInt, PyIntRef};
|
||||
use super::objlist::PyList;
|
||||
use super::objnone::PyNone;
|
||||
use super::objsingletons::PyNone;
|
||||
use super::objslice::{PySlice, PySliceRef};
|
||||
use super::objtuple::PyTuple;
|
||||
use crate::function::OptionalArg;
|
||||
|
||||
@@ -556,15 +556,15 @@ impl PySet {
|
||||
}
|
||||
|
||||
#[pymethod]
|
||||
fn update(&self, others: Args<PyIterable>, vm: &VirtualMachine) -> PyResult {
|
||||
fn update(&self, others: Args<PyIterable>, vm: &VirtualMachine) -> PyResult<()> {
|
||||
self.inner.update(others, vm)?;
|
||||
Ok(vm.get_none())
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[pymethod]
|
||||
fn intersection_update(&self, others: Args<PyIterable>, vm: &VirtualMachine) -> PyResult {
|
||||
fn intersection_update(&self, others: Args<PyIterable>, vm: &VirtualMachine) -> PyResult<()> {
|
||||
self.inner.intersection_update(others, vm)?;
|
||||
Ok(vm.get_none())
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[pymethod(name = "__iand__")]
|
||||
@@ -574,9 +574,9 @@ impl PySet {
|
||||
}
|
||||
|
||||
#[pymethod]
|
||||
fn difference_update(&self, others: Args<PyIterable>, vm: &VirtualMachine) -> PyResult {
|
||||
fn difference_update(&self, others: Args<PyIterable>, vm: &VirtualMachine) -> PyResult<()> {
|
||||
self.inner.difference_update(others, vm)?;
|
||||
Ok(vm.get_none())
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[pymethod(name = "__isub__")]
|
||||
@@ -590,9 +590,9 @@ impl PySet {
|
||||
&self,
|
||||
others: Args<PyIterable>,
|
||||
vm: &VirtualMachine,
|
||||
) -> PyResult {
|
||||
) -> PyResult<()> {
|
||||
self.inner.symmetric_difference_update(others, vm)?;
|
||||
Ok(vm.get_none())
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[pymethod(name = "__ixor__")]
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
use super::objtype::PyClassRef;
|
||||
use crate::pyobject::{
|
||||
IntoPyObject, PyClassImpl, PyContext, PyObjectRef, PyRef, PyResult, PyValue, TypeProtocol,
|
||||
IntoPyObject, PyClassImpl, PyContext, PyObjectRef, PyRef, PyValue, TypeProtocol,
|
||||
};
|
||||
use crate::vm::VirtualMachine;
|
||||
|
||||
@@ -11,7 +11,7 @@ pub type PyNoneRef = PyRef<PyNone>;
|
||||
|
||||
impl PyValue for PyNone {
|
||||
fn class(vm: &VirtualMachine) -> PyClassRef {
|
||||
vm.ctx.none().class()
|
||||
vm.ctx.none.class()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -39,35 +39,37 @@ impl PyNone {
|
||||
vm.ctx.none.clone()
|
||||
}
|
||||
|
||||
#[pymethod(name = "__repr__")]
|
||||
fn repr(&self) -> PyResult<String> {
|
||||
Ok("None".to_owned())
|
||||
#[pymethod(magic)]
|
||||
fn repr(&self) -> String {
|
||||
"None".to_owned()
|
||||
}
|
||||
|
||||
#[pymethod(name = "__bool__")]
|
||||
fn bool(&self) -> PyResult<bool> {
|
||||
Ok(false)
|
||||
#[pymethod(magic)]
|
||||
fn bool(&self) -> bool {
|
||||
false
|
||||
}
|
||||
}
|
||||
|
||||
#[pymethod(name = "__eq__")]
|
||||
fn eq(&self, rhs: PyObjectRef, vm: &VirtualMachine) -> PyObjectRef {
|
||||
if vm.is_none(&rhs) {
|
||||
vm.ctx.new_bool(true)
|
||||
} else {
|
||||
vm.ctx.not_implemented()
|
||||
}
|
||||
#[pyclass(module = false, name = "NotImplementedType")]
|
||||
#[derive(Debug)]
|
||||
pub struct PyNotImplemented;
|
||||
pub type PyNotImplementedRef = PyRef<PyNotImplemented>;
|
||||
|
||||
impl PyValue for PyNotImplemented {
|
||||
fn class(vm: &VirtualMachine) -> PyClassRef {
|
||||
vm.ctx.not_implemented.class()
|
||||
}
|
||||
}
|
||||
|
||||
#[pymethod(name = "__ne__")]
|
||||
fn ne(&self, rhs: PyObjectRef, vm: &VirtualMachine) -> PyObjectRef {
|
||||
if vm.is_none(&rhs) {
|
||||
vm.ctx.new_bool(false)
|
||||
} else {
|
||||
vm.ctx.not_implemented()
|
||||
}
|
||||
#[pyimpl]
|
||||
impl PyNotImplemented {
|
||||
#[pymethod(magic)]
|
||||
fn repr(&self) -> String {
|
||||
"PyNotImplemented".to_owned()
|
||||
}
|
||||
}
|
||||
|
||||
pub fn init(context: &PyContext) {
|
||||
PyNone::extend_class(context, &context.none.class());
|
||||
PyNotImplemented::extend_class(context, &context.not_implemented.class());
|
||||
}
|
||||
@@ -1,9 +1,11 @@
|
||||
// sliceobject.{h,c} in CPython
|
||||
|
||||
use super::objint::PyInt;
|
||||
use super::objtype::PyClassRef;
|
||||
use crate::function::{OptionalArg, PyFuncArgs};
|
||||
use crate::pyobject::{
|
||||
BorrowValue, IdProtocol, PyClassImpl, PyContext, PyObjectRef, PyRef, PyResult, PyValue,
|
||||
TryIntoRef,
|
||||
BorrowValue, IntoPyObject, PyClassImpl, PyContext, PyObjectRef, PyRef, PyResult, PyValue,
|
||||
TryIntoRef, TypeProtocol,
|
||||
};
|
||||
use crate::vm::VirtualMachine;
|
||||
use num_bigint::{BigInt, ToBigInt};
|
||||
@@ -25,19 +27,11 @@ impl PyValue for PySlice {
|
||||
|
||||
pub type PySliceRef = PyRef<PySlice>;
|
||||
|
||||
fn get_property_value(vm: &VirtualMachine, value: &Option<PyObjectRef>) -> PyObjectRef {
|
||||
if let Some(value) = value {
|
||||
value.clone()
|
||||
} else {
|
||||
vm.get_none()
|
||||
}
|
||||
}
|
||||
|
||||
#[pyimpl]
|
||||
impl PySlice {
|
||||
#[pyproperty(name = "start")]
|
||||
fn start(&self, vm: &VirtualMachine) -> PyObjectRef {
|
||||
get_property_value(vm, &self.start)
|
||||
self.start.clone().into_pyobject(vm)
|
||||
}
|
||||
|
||||
#[pyproperty(name = "stop")]
|
||||
@@ -47,7 +41,7 @@ impl PySlice {
|
||||
|
||||
#[pyproperty(name = "step")]
|
||||
fn step(&self, vm: &VirtualMachine) -> PyObjectRef {
|
||||
get_property_value(vm, &self.step)
|
||||
self.step.clone().into_pyobject(vm)
|
||||
}
|
||||
|
||||
#[pymethod(name = "__repr__")]
|
||||
@@ -321,7 +315,7 @@ impl PySlice {
|
||||
}
|
||||
|
||||
fn to_index_value(vm: &VirtualMachine, obj: &PyObjectRef) -> PyResult<Option<BigInt>> {
|
||||
if obj.is(&vm.ctx.none) {
|
||||
if vm.is_none(obj) {
|
||||
return Ok(None);
|
||||
}
|
||||
|
||||
@@ -333,7 +327,35 @@ fn to_index_value(vm: &VirtualMachine, obj: &PyObjectRef) -> PyResult<Option<Big
|
||||
Ok(Some(result.borrow_value().clone()))
|
||||
}
|
||||
|
||||
pub fn init(context: &PyContext) {
|
||||
let slice_type = &context.types.slice_type;
|
||||
PySlice::extend_class(context, slice_type);
|
||||
#[pyclass(module = false, name = "EllipsisType")]
|
||||
#[derive(Debug)]
|
||||
pub struct PyEllipsis;
|
||||
|
||||
impl PyValue for PyEllipsis {
|
||||
fn class(vm: &VirtualMachine) -> PyClassRef {
|
||||
vm.ctx.ellipsis.class()
|
||||
}
|
||||
}
|
||||
|
||||
#[pyimpl]
|
||||
impl PyEllipsis {
|
||||
#[pyslot]
|
||||
fn tp_new(_cls: PyClassRef, vm: &VirtualMachine) -> PyRef<Self> {
|
||||
vm.ctx.ellipsis.clone()
|
||||
}
|
||||
|
||||
#[pymethod(magic)]
|
||||
fn repr(&self) -> String {
|
||||
"Ellipsis".to_owned()
|
||||
}
|
||||
|
||||
#[pymethod(magic)]
|
||||
fn reduce(&self) -> String {
|
||||
"Ellipsis".to_owned()
|
||||
}
|
||||
}
|
||||
|
||||
pub fn init(context: &PyContext) {
|
||||
PySlice::extend_class(context, &context.types.slice_type);
|
||||
PyEllipsis::extend_class(context, &context.ellipsis.class());
|
||||
}
|
||||
|
||||
@@ -1011,7 +1011,7 @@ impl PyString {
|
||||
}
|
||||
if let OptionalArg::Present(none_str) = none_str {
|
||||
for c in none_str.value.chars() {
|
||||
new_dict.set_item(vm.ctx.new_int(c as u32), vm.get_none(), vm)?;
|
||||
new_dict.set_item(vm.ctx.new_int(c as u32), vm.ctx.none(), vm)?;
|
||||
}
|
||||
}
|
||||
Ok(new_dict.into_pyobject(vm))
|
||||
@@ -1311,7 +1311,7 @@ mod tests {
|
||||
Interpreter::default().enter(|vm| {
|
||||
let table = vm.ctx.new_dict();
|
||||
table.set_item("a", vm.ctx.new_str("🎅"), &vm).unwrap();
|
||||
table.set_item("b", vm.get_none(), &vm).unwrap();
|
||||
table.set_item("b", vm.ctx.none(), &vm).unwrap();
|
||||
table.set_item("c", vm.ctx.new_str("xda"), &vm).unwrap();
|
||||
let translated = PyString::maketrans(
|
||||
table.into_object(),
|
||||
|
||||
@@ -122,7 +122,7 @@ impl PySuper {
|
||||
vm.new_type_error(format!("super argument {} was not supplied", first_arg))
|
||||
})?
|
||||
} else {
|
||||
vm.get_none()
|
||||
vm.ctx.none()
|
||||
}
|
||||
};
|
||||
|
||||
@@ -147,7 +147,7 @@ impl SlotDescriptor for PySuper {
|
||||
.into_ref(vm)
|
||||
.into_object())
|
||||
} else {
|
||||
let obj = zelf.obj.clone().map_or(vm.get_none(), |(o, _)| o);
|
||||
let obj = vm.unwrap_or_none(zelf.obj.clone().map(|(o, _)| o));
|
||||
vm.invoke(
|
||||
zelf_class.as_object(),
|
||||
vec![zelf.typ.clone().into_object(), obj],
|
||||
|
||||
@@ -194,7 +194,7 @@ impl PyClassRef {
|
||||
} else if let Some(ref descriptor) = attr_class.get_attr("__get__") {
|
||||
drop(mcl);
|
||||
// TODO: is this nessessary?
|
||||
return vm.invoke(descriptor, vec![attr, vm.get_none(), self.into_object()]);
|
||||
return vm.invoke(descriptor, vec![attr, vm.ctx.none(), self.into_object()]);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -41,7 +41,7 @@ pub type PyWeakRef = PyRef<PyWeak>;
|
||||
impl SlotCall for PyWeak {
|
||||
fn call(&self, args: PyFuncArgs, vm: &VirtualMachine) -> PyResult {
|
||||
args.bind::<()>(vm)?;
|
||||
Ok(self.upgrade().unwrap_or_else(|| vm.get_none()))
|
||||
Ok(vm.unwrap_or_none(self.upgrade()))
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -7,7 +7,7 @@ use crate::obj::{
|
||||
objbool, objdict::PyDictRef, objfloat, objint, objlist::PyList, objstr, objtuple::PyTuple,
|
||||
objtype,
|
||||
};
|
||||
use crate::pyobject::{BorrowValue, IdProtocol, ItemProtocol, PyObjectRef, TypeProtocol};
|
||||
use crate::pyobject::{BorrowValue, ItemProtocol, PyObjectRef, TypeProtocol};
|
||||
use crate::VirtualMachine;
|
||||
|
||||
#[inline]
|
||||
@@ -96,7 +96,7 @@ impl<'s> serde::Serialize for PyObjectSerializer<'s> {
|
||||
map.serialize_entry(&self.clone_with_object(key), &self.clone_with_object(&e))?;
|
||||
}
|
||||
map.end()
|
||||
} else if self.pyobject.is(&self.vm.get_none()) {
|
||||
} else if self.vm.is_none(&self.pyobject) {
|
||||
serializer.serialize_none()
|
||||
} else {
|
||||
Err(serde::ser::Error::custom(format!(
|
||||
@@ -187,7 +187,7 @@ impl<'de> Visitor<'de> for PyObjectDeserializer<'de> {
|
||||
where
|
||||
E: serde::de::Error,
|
||||
{
|
||||
Ok(self.vm.get_none())
|
||||
Ok(self.vm.ctx.none())
|
||||
}
|
||||
|
||||
fn visit_seq<A>(self, mut access: A) -> Result<Self::Value, A::Error>
|
||||
|
||||
@@ -20,7 +20,6 @@ use crate::obj::objcode;
|
||||
use crate::obj::objcode::PyCodeRef;
|
||||
use crate::obj::objcomplex::PyComplex;
|
||||
use crate::obj::objdict::{PyDict, PyDictRef};
|
||||
use crate::obj::objellipsis::PyEllipsis;
|
||||
use crate::obj::objfloat::PyFloat;
|
||||
use crate::obj::objfunction::{PyBoundMethod, PyFunction};
|
||||
use crate::obj::objgetset::{IntoPyGetterFunc, IntoPySetterFunc, PyGetSet};
|
||||
@@ -28,9 +27,10 @@ use crate::obj::objint::{PyInt, PyIntRef};
|
||||
use crate::obj::objiter;
|
||||
use crate::obj::objlist::PyList;
|
||||
use crate::obj::objnamespace::PyNamespace;
|
||||
use crate::obj::objnone::{PyNone, PyNoneRef};
|
||||
use crate::obj::objobject;
|
||||
use crate::obj::objset::PySet;
|
||||
use crate::obj::objsingletons::{PyNone, PyNoneRef, PyNotImplemented, PyNotImplementedRef};
|
||||
use crate::obj::objslice::PyEllipsis;
|
||||
use crate::obj::objstaticmethod::PyStaticMethod;
|
||||
use crate::obj::objstr;
|
||||
use crate::obj::objtuple::{PyTuple, PyTupleRef};
|
||||
@@ -38,7 +38,7 @@ use crate::obj::objtype::{self, PyClass, PyClassRef};
|
||||
pub use crate::pyobjectrc::{PyObjectRc, PyObjectWeak};
|
||||
use crate::scope::Scope;
|
||||
use crate::slots::{PyClassSlots, PyTpFlags};
|
||||
use crate::types::{create_type, create_type_with_slots, initialize_types, TypeZoo};
|
||||
use crate::types::{create_type_with_slots, initialize_types, TypeZoo};
|
||||
use crate::vm::VirtualMachine;
|
||||
use rustpython_common::cell::{PyRwLock, PyRwLockReadGuard};
|
||||
use rustpython_common::rc::PyRc;
|
||||
@@ -106,17 +106,6 @@ pub struct PyContext {
|
||||
tp_new_wrapper: PyObjectRef,
|
||||
}
|
||||
|
||||
pub type PyNotImplementedRef = PyRef<PyNotImplemented>;
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct PyNotImplemented;
|
||||
|
||||
impl PyValue for PyNotImplemented {
|
||||
fn class(vm: &VirtualMachine) -> PyClassRef {
|
||||
vm.ctx.not_implemented().class()
|
||||
}
|
||||
}
|
||||
|
||||
// Basic objects:
|
||||
impl PyContext {
|
||||
pub const INT_CACHE_POOL_MIN: i32 = -5;
|
||||
@@ -134,13 +123,12 @@ impl PyContext {
|
||||
let none_type = PyNone::create_bare_type(&types.type_type, types.object_type.clone());
|
||||
let none = create_object(PyNone, &none_type);
|
||||
|
||||
let ellipsis = create_object(PyEllipsis, &types.ellipsis_type);
|
||||
let ellipsis_type =
|
||||
PyEllipsis::create_bare_type(&types.type_type, types.object_type.clone());
|
||||
let ellipsis = create_object(PyEllipsis, &ellipsis_type);
|
||||
|
||||
let not_implemented_type = create_type(
|
||||
"NotImplementedType",
|
||||
&types.type_type,
|
||||
types.object_type.clone(),
|
||||
);
|
||||
let not_implemented_type =
|
||||
PyNotImplemented::create_bare_type(&types.type_type, types.object_type.clone());
|
||||
let not_implemented = create_object(PyNotImplemented, ¬_implemented_type);
|
||||
|
||||
let int_cache_pool = (Self::INT_CACHE_POOL_MIN..=Self::INT_CACHE_POOL_MAX)
|
||||
@@ -951,7 +939,7 @@ impl TryFromObject for PyObjectRef {
|
||||
|
||||
impl<T: TryFromObject> TryFromObject for Option<T> {
|
||||
fn try_from_object(vm: &VirtualMachine, obj: PyObjectRef) -> PyResult<Self> {
|
||||
if vm.get_none().is(&obj) {
|
||||
if vm.is_none(&obj) {
|
||||
Ok(None)
|
||||
} else {
|
||||
T::try_from_object(vm, obj).map(Some)
|
||||
|
||||
@@ -105,7 +105,7 @@ pub trait SlotDescriptor: PyValue {
|
||||
vm: &VirtualMachine,
|
||||
) -> PyResult<(PyRef<Self>, PyObjectRef)> {
|
||||
let zelf = Self::_zelf(zelf, vm)?;
|
||||
let obj = obj.unwrap_or_else(|| vm.get_none());
|
||||
let obj = vm.unwrap_or_none(obj);
|
||||
Ok((zelf, obj))
|
||||
}
|
||||
|
||||
|
||||
@@ -11,7 +11,7 @@ use rustpython_parser::{ast, mode::Mode, parser};
|
||||
|
||||
use crate::obj::objlist::PyListRef;
|
||||
use crate::obj::objtype::PyClassRef;
|
||||
use crate::pyobject::{PyObjectRef, PyRef, PyResult, PyValue};
|
||||
use crate::pyobject::{IntoPyObject, PyObjectRef, PyRef, PyResult, PyValue};
|
||||
use crate::slots::PyTpFlags;
|
||||
use crate::vm::VirtualMachine;
|
||||
|
||||
@@ -204,7 +204,7 @@ fn statement_to_ast(vm: &VirtualMachine, statement: &ast::Statement) -> PyResult
|
||||
names,
|
||||
} => node!(vm, ImportFrom, {
|
||||
level => vm.ctx.new_int(*level),
|
||||
module => optional_string_to_py_obj(vm, module),
|
||||
module => module.as_ref().into_pyobject(vm),
|
||||
names => map_ast(alias_to_ast, vm, names)?
|
||||
}),
|
||||
Nonlocal { names } => node!(vm, Nonlocal, {
|
||||
@@ -247,7 +247,7 @@ fn statement_to_ast(vm: &VirtualMachine, statement: &ast::Statement) -> PyResult
|
||||
fn alias_to_ast(vm: &VirtualMachine, alias: &ast::ImportSymbol) -> PyResult<AstNodeRef> {
|
||||
Ok(node!(vm, alias, {
|
||||
name => vm.ctx.new_str(&alias.symbol),
|
||||
asname => optional_string_to_py_obj(vm, &alias.alias)
|
||||
asname => alias.alias.as_ref().into_pyobject(vm),
|
||||
}))
|
||||
}
|
||||
|
||||
@@ -274,7 +274,7 @@ fn with_item_to_ast(vm: &VirtualMachine, with_item: &ast::WithItem) -> PyResult<
|
||||
fn handler_to_ast(vm: &VirtualMachine, handler: &ast::ExceptHandler) -> PyResult<AstNodeRef> {
|
||||
let node = node!(vm, ExceptHandler, {
|
||||
typ => optional_expression_to_ast(vm, &handler.typ)?,
|
||||
name => optional_string_to_py_obj(vm, &handler.name),
|
||||
name => handler.name.as_ref().into_pyobject(vm),
|
||||
body => statements_to_ast(vm, &handler.body)?,
|
||||
});
|
||||
Ok(node)
|
||||
@@ -297,12 +297,11 @@ fn optional_expressions_to_ast(
|
||||
}
|
||||
|
||||
fn optional_expression_to_ast(vm: &VirtualMachine, value: &Option<ast::Expression>) -> PyResult {
|
||||
let value = if let Some(value) = value {
|
||||
expression_to_ast(vm, value)?.into_object()
|
||||
} else {
|
||||
vm.ctx.none()
|
||||
};
|
||||
Ok(value)
|
||||
let ast = value
|
||||
.as_ref()
|
||||
.map(|expr| expression_to_ast(vm, expr))
|
||||
.transpose()?;
|
||||
Ok(ast.into_pyobject(vm))
|
||||
}
|
||||
|
||||
fn expressions_to_ast(vm: &VirtualMachine, expressions: &[ast::Expression]) -> PyResult<PyListRef> {
|
||||
@@ -439,11 +438,8 @@ fn expression_to_ast(vm: &VirtualMachine, expression: &ast::Expression) -> PyRes
|
||||
let mut keys = Vec::new();
|
||||
let mut values = Vec::new();
|
||||
for (k, v) in elements {
|
||||
if let Some(k) = k {
|
||||
keys.push(expression_to_ast(vm, k)?.into_object());
|
||||
} else {
|
||||
keys.push(vm.ctx.none());
|
||||
}
|
||||
let k = k.as_ref().map(|k| expression_to_ast(vm, k)).transpose()?;
|
||||
keys.push(k.into_pyobject(vm));
|
||||
values.push(expression_to_ast(vm, v)?.into_object());
|
||||
}
|
||||
|
||||
@@ -484,13 +480,12 @@ fn expression_to_ast(vm: &VirtualMachine, expression: &ast::Expression) -> PyRes
|
||||
})
|
||||
}
|
||||
Yield { value } => {
|
||||
let py_value = if let Some(value) = value {
|
||||
expression_to_ast(vm, value)?.into_object()
|
||||
} else {
|
||||
vm.ctx.none()
|
||||
};
|
||||
let py_value = value
|
||||
.as_ref()
|
||||
.map(|v| expression_to_ast(vm, v))
|
||||
.transpose()?;
|
||||
node!(vm, Yield, {
|
||||
value => py_value
|
||||
value => py_value.into_pyobject(vm)
|
||||
})
|
||||
}
|
||||
YieldFrom { value } => {
|
||||
@@ -559,20 +554,20 @@ fn parameters_to_ast(vm: &VirtualMachine, args: &ast::Parameters) -> PyResult<As
|
||||
|
||||
fn vararg_to_ast(vm: &VirtualMachine, vararg: &ast::Varargs) -> PyResult {
|
||||
let py_node = match vararg {
|
||||
ast::Varargs::None => vm.get_none(),
|
||||
ast::Varargs::Unnamed => vm.get_none(),
|
||||
ast::Varargs::None => vm.ctx.none(),
|
||||
ast::Varargs::Unnamed => vm.ctx.none(),
|
||||
ast::Varargs::Named(parameter) => parameter_to_ast(vm, parameter)?.into_object(),
|
||||
};
|
||||
Ok(py_node)
|
||||
}
|
||||
|
||||
fn parameter_to_ast(vm: &VirtualMachine, parameter: &ast::Parameter) -> PyResult<AstNodeRef> {
|
||||
let py_annotation = if let Some(annotation) = ¶meter.annotation {
|
||||
expression_to_ast(vm, annotation)?.into_object()
|
||||
} else {
|
||||
vm.ctx.none()
|
||||
};
|
||||
|
||||
let py_annotation = parameter
|
||||
.annotation
|
||||
.as_ref()
|
||||
.map(|expr| expression_to_ast(vm, expr))
|
||||
.transpose()?
|
||||
.into_pyobject(vm);
|
||||
let py_node = node!(vm, arg, {
|
||||
arg => vm.ctx.new_str(¶meter.arg),
|
||||
annotation => py_annotation
|
||||
@@ -584,17 +579,9 @@ fn parameter_to_ast(vm: &VirtualMachine, parameter: &ast::Parameter) -> PyResult
|
||||
Ok(py_node)
|
||||
}
|
||||
|
||||
fn optional_string_to_py_obj(vm: &VirtualMachine, name: &Option<String>) -> PyObjectRef {
|
||||
if let Some(name) = name {
|
||||
vm.ctx.new_str(name)
|
||||
} else {
|
||||
vm.ctx.none()
|
||||
}
|
||||
}
|
||||
|
||||
fn keyword_to_ast(vm: &VirtualMachine, keyword: &ast::Keyword) -> PyResult<AstNodeRef> {
|
||||
Ok(node!(vm, keyword, {
|
||||
arg => optional_string_to_py_obj(vm, &keyword.name),
|
||||
arg => keyword.name.as_ref().into_pyobject(vm),
|
||||
value => expression_to_ast(vm, &keyword.value)?
|
||||
}))
|
||||
}
|
||||
|
||||
@@ -11,33 +11,30 @@ mod decl {
|
||||
use rustpython_compiler::compile;
|
||||
|
||||
#[pyfunction]
|
||||
fn dis(obj: PyObjectRef, vm: &VirtualMachine) -> PyResult {
|
||||
// Method or function:
|
||||
if let Ok(co) = vm.get_attribute(obj.clone(), "__code__") {
|
||||
return disassemble(co, vm);
|
||||
}
|
||||
|
||||
// String:
|
||||
if let Ok(co_str) = PyStringRef::try_from_object(vm, obj.clone()) {
|
||||
let code = vm
|
||||
.compile(
|
||||
co_str.borrow_value(),
|
||||
compile::Mode::Exec,
|
||||
"<string>".to_owned(),
|
||||
)
|
||||
.map_err(|err| vm.new_syntax_error(&err))?
|
||||
.into_object();
|
||||
return disassemble(code, vm);
|
||||
}
|
||||
|
||||
disassemble(obj, vm)
|
||||
fn dis(obj: PyObjectRef, vm: &VirtualMachine) -> PyResult<()> {
|
||||
let co = if let Ok(co) = vm.get_attribute(obj.clone(), "__code__") {
|
||||
// Method or function:
|
||||
co
|
||||
} else if let Ok(co_str) = PyStringRef::try_from_object(vm, obj.clone()) {
|
||||
// String:
|
||||
vm.compile(
|
||||
co_str.borrow_value(),
|
||||
compile::Mode::Exec,
|
||||
"<string>".to_owned(),
|
||||
)
|
||||
.map_err(|err| vm.new_syntax_error(&err))?
|
||||
.into_object()
|
||||
} else {
|
||||
obj
|
||||
};
|
||||
disassemble(co, vm)
|
||||
}
|
||||
|
||||
#[pyfunction]
|
||||
fn disassemble(co: PyObjectRef, vm: &VirtualMachine) -> PyResult {
|
||||
fn disassemble(co: PyObjectRef, vm: &VirtualMachine) -> PyResult<()> {
|
||||
let code = &PyCodeRef::try_from_object(vm, co)?.code;
|
||||
print!("{}", code);
|
||||
Ok(vm.get_none())
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[pyattr(name = "COMPILER_FLAG_NAMES")]
|
||||
|
||||
@@ -67,9 +67,8 @@ impl PyHasher {
|
||||
}
|
||||
|
||||
#[pymethod(name = "update")]
|
||||
fn update(&self, data: PyBytesRef, vm: &VirtualMachine) -> PyResult {
|
||||
fn update(&self, data: PyBytesRef) {
|
||||
self.borrow_value_mut().input(data.borrow_value());
|
||||
Ok(vm.get_none())
|
||||
}
|
||||
|
||||
#[pymethod(name = "digest")]
|
||||
@@ -94,74 +93,70 @@ fn hashlib_new(
|
||||
vm: &VirtualMachine,
|
||||
) -> PyResult<PyHasher> {
|
||||
match name.borrow_value() {
|
||||
"md5" => md5(data, vm),
|
||||
"sha1" => sha1(data, vm),
|
||||
"sha224" => sha224(data, vm),
|
||||
"sha256" => sha256(data, vm),
|
||||
"sha384" => sha384(data, vm),
|
||||
"sha512" => sha512(data, vm),
|
||||
"sha3_224" => sha3_224(data, vm),
|
||||
"sha3_256" => sha3_256(data, vm),
|
||||
"sha3_384" => sha3_384(data, vm),
|
||||
"sha3_512" => sha3_512(data, vm),
|
||||
// TODO: "shake128" => shake128(data, vm),
|
||||
// TODO: "shake256" => shake256(data, vm),
|
||||
"blake2b" => blake2b(data, vm),
|
||||
"blake2s" => blake2s(data, vm),
|
||||
"md5" => md5(data),
|
||||
"sha1" => sha1(data),
|
||||
"sha224" => sha224(data),
|
||||
"sha256" => sha256(data),
|
||||
"sha384" => sha384(data),
|
||||
"sha512" => sha512(data),
|
||||
"sha3_224" => sha3_224(data),
|
||||
"sha3_256" => sha3_256(data),
|
||||
"sha3_384" => sha3_384(data),
|
||||
"sha3_512" => sha3_512(data),
|
||||
// TODO: "shake128" => shake128(data, ),
|
||||
// TODO: "shake256" => shake256(data, ),
|
||||
"blake2b" => blake2b(data),
|
||||
"blake2s" => blake2s(data),
|
||||
other => Err(vm.new_value_error(format!("Unknown hashing algorithm: {}", other))),
|
||||
}
|
||||
}
|
||||
|
||||
fn init(
|
||||
hasher: PyHasher,
|
||||
data: OptionalArg<PyBytesRef>,
|
||||
vm: &VirtualMachine,
|
||||
) -> PyResult<PyHasher> {
|
||||
fn init(hasher: PyHasher, data: OptionalArg<PyBytesRef>) -> PyResult<PyHasher> {
|
||||
if let OptionalArg::Present(data) = data {
|
||||
hasher.update(data, vm)?;
|
||||
hasher.update(data);
|
||||
}
|
||||
|
||||
Ok(hasher)
|
||||
}
|
||||
|
||||
fn md5(data: OptionalArg<PyBytesRef>, vm: &VirtualMachine) -> PyResult<PyHasher> {
|
||||
init(PyHasher::new("md5", HashWrapper::md5()), data, vm)
|
||||
fn md5(data: OptionalArg<PyBytesRef>) -> PyResult<PyHasher> {
|
||||
init(PyHasher::new("md5", HashWrapper::md5()), data)
|
||||
}
|
||||
|
||||
fn sha1(data: OptionalArg<PyBytesRef>, vm: &VirtualMachine) -> PyResult<PyHasher> {
|
||||
init(PyHasher::new("sha1", HashWrapper::sha1()), data, vm)
|
||||
fn sha1(data: OptionalArg<PyBytesRef>) -> PyResult<PyHasher> {
|
||||
init(PyHasher::new("sha1", HashWrapper::sha1()), data)
|
||||
}
|
||||
|
||||
fn sha224(data: OptionalArg<PyBytesRef>, vm: &VirtualMachine) -> PyResult<PyHasher> {
|
||||
init(PyHasher::new("sha224", HashWrapper::sha224()), data, vm)
|
||||
fn sha224(data: OptionalArg<PyBytesRef>) -> PyResult<PyHasher> {
|
||||
init(PyHasher::new("sha224", HashWrapper::sha224()), data)
|
||||
}
|
||||
|
||||
fn sha256(data: OptionalArg<PyBytesRef>, vm: &VirtualMachine) -> PyResult<PyHasher> {
|
||||
init(PyHasher::new("sha256", HashWrapper::sha256()), data, vm)
|
||||
fn sha256(data: OptionalArg<PyBytesRef>) -> PyResult<PyHasher> {
|
||||
init(PyHasher::new("sha256", HashWrapper::sha256()), data)
|
||||
}
|
||||
|
||||
fn sha384(data: OptionalArg<PyBytesRef>, vm: &VirtualMachine) -> PyResult<PyHasher> {
|
||||
init(PyHasher::new("sha384", HashWrapper::sha384()), data, vm)
|
||||
fn sha384(data: OptionalArg<PyBytesRef>) -> PyResult<PyHasher> {
|
||||
init(PyHasher::new("sha384", HashWrapper::sha384()), data)
|
||||
}
|
||||
|
||||
fn sha512(data: OptionalArg<PyBytesRef>, vm: &VirtualMachine) -> PyResult<PyHasher> {
|
||||
init(PyHasher::new("sha512", HashWrapper::sha512()), data, vm)
|
||||
fn sha512(data: OptionalArg<PyBytesRef>) -> PyResult<PyHasher> {
|
||||
init(PyHasher::new("sha512", HashWrapper::sha512()), data)
|
||||
}
|
||||
|
||||
fn sha3_224(data: OptionalArg<PyBytesRef>, vm: &VirtualMachine) -> PyResult<PyHasher> {
|
||||
init(PyHasher::new("sha3_224", HashWrapper::sha3_224()), data, vm)
|
||||
fn sha3_224(data: OptionalArg<PyBytesRef>) -> PyResult<PyHasher> {
|
||||
init(PyHasher::new("sha3_224", HashWrapper::sha3_224()), data)
|
||||
}
|
||||
|
||||
fn sha3_256(data: OptionalArg<PyBytesRef>, vm: &VirtualMachine) -> PyResult<PyHasher> {
|
||||
init(PyHasher::new("sha3_256", HashWrapper::sha3_256()), data, vm)
|
||||
fn sha3_256(data: OptionalArg<PyBytesRef>) -> PyResult<PyHasher> {
|
||||
init(PyHasher::new("sha3_256", HashWrapper::sha3_256()), data)
|
||||
}
|
||||
|
||||
fn sha3_384(data: OptionalArg<PyBytesRef>, vm: &VirtualMachine) -> PyResult<PyHasher> {
|
||||
init(PyHasher::new("sha3_384", HashWrapper::sha3_384()), data, vm)
|
||||
fn sha3_384(data: OptionalArg<PyBytesRef>) -> PyResult<PyHasher> {
|
||||
init(PyHasher::new("sha3_384", HashWrapper::sha3_384()), data)
|
||||
}
|
||||
|
||||
fn sha3_512(data: OptionalArg<PyBytesRef>, vm: &VirtualMachine) -> PyResult<PyHasher> {
|
||||
init(PyHasher::new("sha3_512", HashWrapper::sha3_512()), data, vm)
|
||||
fn sha3_512(data: OptionalArg<PyBytesRef>) -> PyResult<PyHasher> {
|
||||
init(PyHasher::new("sha3_512", HashWrapper::sha3_512()), data)
|
||||
}
|
||||
|
||||
fn shake128(_data: OptionalArg<PyBytesRef>, vm: &VirtualMachine) -> PyResult<PyHasher> {
|
||||
@@ -172,14 +167,14 @@ fn shake256(_data: OptionalArg<PyBytesRef>, vm: &VirtualMachine) -> PyResult<PyH
|
||||
Err(vm.new_not_implemented_error("shake256".to_owned()))
|
||||
}
|
||||
|
||||
fn blake2b(data: OptionalArg<PyBytesRef>, vm: &VirtualMachine) -> PyResult<PyHasher> {
|
||||
fn blake2b(data: OptionalArg<PyBytesRef>) -> PyResult<PyHasher> {
|
||||
// TODO: handle parameters
|
||||
init(PyHasher::new("blake2b", HashWrapper::blake2b()), data, vm)
|
||||
init(PyHasher::new("blake2b", HashWrapper::blake2b()), data)
|
||||
}
|
||||
|
||||
fn blake2s(data: OptionalArg<PyBytesRef>, vm: &VirtualMachine) -> PyResult<PyHasher> {
|
||||
fn blake2s(data: OptionalArg<PyBytesRef>) -> PyResult<PyHasher> {
|
||||
// TODO: handle parameters
|
||||
init(PyHasher::new("blake2s", HashWrapper::blake2s()), data, vm)
|
||||
init(PyHasher::new("blake2s", HashWrapper::blake2s()), data)
|
||||
}
|
||||
|
||||
pub fn make_module(vm: &VirtualMachine) -> PyObjectRef {
|
||||
|
||||
@@ -67,7 +67,7 @@ fn imp_create_builtin(spec: PyObjectRef, vm: &VirtualMachine) -> PyResult {
|
||||
} else if let Some(make_module_func) = vm.state.stdlib_inits.get(name) {
|
||||
Ok(make_module_func(vm))
|
||||
} else {
|
||||
Ok(vm.get_none())
|
||||
Ok(vm.ctx.none())
|
||||
}
|
||||
}
|
||||
|
||||
@@ -108,7 +108,7 @@ fn imp_fix_co_filename(_code: PyObjectRef, _path: PyStringRef) {
|
||||
|
||||
fn imp_source_hash(_key: u64, _source: PyBytesRef, vm: &VirtualMachine) -> PyResult {
|
||||
// TODO:
|
||||
Ok(vm.get_none())
|
||||
Ok(vm.ctx.none())
|
||||
}
|
||||
|
||||
pub fn make_module(vm: &VirtualMachine) -> PyObjectRef {
|
||||
|
||||
@@ -963,11 +963,7 @@ fn text_io_wrapper_init(
|
||||
|
||||
// let readuniversal = args.newline.map_or_else(true, |s| s.borrow_value().is_empty());
|
||||
|
||||
vm.set_attr(
|
||||
&instance,
|
||||
"encoding",
|
||||
self_encoding.map_or_else(|| vm.get_none(), |s| vm.ctx.new_str(s)),
|
||||
)?;
|
||||
vm.set_attr(&instance, "encoding", self_encoding.into_pyobject(vm))?;
|
||||
vm.set_attr(&instance, "errors", errors)?;
|
||||
vm.set_attr(&instance, "buffer", args.buffer)?;
|
||||
|
||||
@@ -1022,11 +1018,7 @@ fn text_io_wrapper_read(
|
||||
return Err(vm.new_value_error("not readable".to_owned()));
|
||||
}
|
||||
|
||||
let bytes = vm.call_method(
|
||||
&raw,
|
||||
"read",
|
||||
vec![size.flatten().unwrap_or_else(|| vm.get_none())],
|
||||
)?;
|
||||
let bytes = vm.call_method(&raw, "read", vec![vm.unwrap_or_none(size.flatten())])?;
|
||||
let bytes = PyBytesLike::try_from_object(vm, bytes)?;
|
||||
//format bytes into string
|
||||
let rust_string = String::from_utf8(bytes.to_cow().into_owned()).map_err(|e| {
|
||||
@@ -1079,11 +1071,7 @@ fn text_io_wrapper_readline(
|
||||
return Err(vm.new_value_error("not readable".to_owned()));
|
||||
}
|
||||
|
||||
let bytes = vm.call_method(
|
||||
&raw,
|
||||
"readline",
|
||||
vec![size.flatten().unwrap_or_else(|| vm.get_none())],
|
||||
)?;
|
||||
let bytes = vm.call_method(&raw, "readline", vec![vm.unwrap_or_none(size.flatten())])?;
|
||||
let bytes = PyBytesLike::try_from_object(vm, bytes)?;
|
||||
//format bytes into string
|
||||
let rust_string = String::from_utf8(bytes.to_cow().into_owned()).map_err(|e| {
|
||||
@@ -1224,7 +1212,7 @@ pub fn io_open(
|
||||
Args::new(vec![file, vm.ctx.new_str(mode.clone())]),
|
||||
KwArgs::new(maplit::hashmap! {
|
||||
"closefd".to_owned() => vm.ctx.new_bool(opts.closefd),
|
||||
"opener".to_owned() => opts.opener.unwrap_or_else(|| vm.get_none()),
|
||||
"opener".to_owned() => vm.unwrap_or_none(opts.opener),
|
||||
}),
|
||||
)),
|
||||
)?;
|
||||
|
||||
@@ -732,7 +732,7 @@ mod decl {
|
||||
PyObjectRef,
|
||||
) = args.bind(vm)?;
|
||||
|
||||
let start = if !start.is(&vm.get_none()) {
|
||||
let start = if !vm.is_none(&start) {
|
||||
pyobject_to_opt_usize(start, &vm).ok_or_else(|| {
|
||||
vm.new_value_error(
|
||||
"Indices for islice() must be None or an integer: 0 <= x <= sys.maxsize.".to_owned(),
|
||||
@@ -742,7 +742,7 @@ mod decl {
|
||||
0usize
|
||||
};
|
||||
|
||||
let step = if !step.is(&vm.get_none()) {
|
||||
let step = if !vm.is_none(&step) {
|
||||
pyobject_to_opt_usize(step, &vm).ok_or_else(|| {
|
||||
vm.new_value_error(
|
||||
"Step for islice() must be a positive integer or None.".to_owned(),
|
||||
@@ -756,7 +756,7 @@ mod decl {
|
||||
}
|
||||
};
|
||||
|
||||
let stop = if !stop.is(&vm.get_none()) {
|
||||
let stop = if !vm.is_none(&stop) {
|
||||
Some(pyobject_to_opt_usize(stop, &vm).ok_or_else(|| {
|
||||
vm.new_value_error(
|
||||
"Stop argument for islice() must be None or an integer: 0 <= x <= sys.maxsize."
|
||||
@@ -847,7 +847,7 @@ mod decl {
|
||||
|
||||
loop {
|
||||
let obj = call_next(vm, iterable)?;
|
||||
let pred_value = if predicate.is(&vm.get_none()) {
|
||||
let pred_value = if vm.is_none(predicate) {
|
||||
obj.clone()
|
||||
} else {
|
||||
vm.invoke(predicate, vec![obj.clone()])?
|
||||
@@ -893,7 +893,7 @@ mod decl {
|
||||
|
||||
PyItertoolsAccumulate {
|
||||
iterable: iter,
|
||||
binop: binop.unwrap_or_else(|| vm.get_none()),
|
||||
binop: binop.unwrap_or_none(vm),
|
||||
acc_value: PyRwLock::new(None),
|
||||
}
|
||||
.into_ref_with_type(vm, cls)
|
||||
@@ -909,7 +909,7 @@ mod decl {
|
||||
let next_acc_value = match acc_value {
|
||||
None => obj,
|
||||
Some(value) => {
|
||||
if self.binop.is(&vm.get_none()) {
|
||||
if vm.is_none(&self.binop) {
|
||||
vm._add(value, obj)?
|
||||
} else {
|
||||
vm.invoke(&self.binop, vec![value, obj])?
|
||||
@@ -1502,11 +1502,7 @@ mod decl {
|
||||
args: ZiplongestArgs,
|
||||
vm: &VirtualMachine,
|
||||
) -> PyResult<PyRef<Self>> {
|
||||
let fillvalue = match args.fillvalue.into_option() {
|
||||
Some(i) => i,
|
||||
None => vm.get_none(),
|
||||
};
|
||||
|
||||
let fillvalue = args.fillvalue.unwrap_or_none(vm);
|
||||
let iterators = iterables
|
||||
.into_iter()
|
||||
.map(|iterable| get_iter(vm, &iterable))
|
||||
|
||||
@@ -104,10 +104,8 @@ mod _json {
|
||||
.new_tuple(vec![pystr.into_object(), vm.ctx.new_int(next_idx)]),
|
||||
vm.ctx.new_bool(self.strict),
|
||||
scan_once,
|
||||
self.object_hook.clone().unwrap_or_else(|| vm.get_none()),
|
||||
self.object_pairs_hook
|
||||
.clone()
|
||||
.unwrap_or_else(|| vm.get_none()),
|
||||
vm.unwrap_or_none(self.object_hook.clone()),
|
||||
vm.unwrap_or_none(self.object_pairs_hook.clone()),
|
||||
],
|
||||
);
|
||||
}
|
||||
@@ -134,7 +132,7 @@ mod _json {
|
||||
};
|
||||
}
|
||||
|
||||
parse_const!("null", vm.get_none());
|
||||
parse_const!("null", vm.ctx.none());
|
||||
parse_const!("true", vm.ctx.new_bool(true));
|
||||
parse_const!("false", vm.ctx.new_bool(false));
|
||||
|
||||
|
||||
@@ -23,8 +23,8 @@ use crate::obj::objstr::{PyString, PyStringRef};
|
||||
use crate::obj::objtuple::PyTupleRef;
|
||||
use crate::obj::objtype::PyClassRef;
|
||||
use crate::pyobject::{
|
||||
BorrowValue, Either, ItemProtocol, PyClassImpl, PyObjectRef, PyRef, PyResult, PyStructSequence,
|
||||
PyValue, TryFromObject, TypeProtocol,
|
||||
BorrowValue, Either, IntoPyObject, ItemProtocol, PyClassImpl, PyObjectRef, PyRef, PyResult,
|
||||
PyStructSequence, PyValue, TryFromObject, TypeProtocol,
|
||||
};
|
||||
use crate::vm::VirtualMachine;
|
||||
|
||||
@@ -155,10 +155,7 @@ impl IntoPyException for io::Error {
|
||||
},
|
||||
};
|
||||
let os_error = vm.new_exception_msg(exc_type, self.to_string());
|
||||
let errno = match self.raw_os_error() {
|
||||
Some(errno) => vm.ctx.new_int(errno),
|
||||
None => vm.get_none(),
|
||||
};
|
||||
let errno = self.raw_os_error().into_pyobject(vm);
|
||||
vm.set_attr(os_error.as_object(), "errno", errno).unwrap();
|
||||
os_error
|
||||
}
|
||||
|
||||
@@ -13,7 +13,9 @@ use crate::function::{Args, OptionalArg};
|
||||
use crate::obj::objint::{PyInt, PyIntRef};
|
||||
use crate::obj::objstr::{PyString, PyStringRef};
|
||||
use crate::obj::objtype::PyClassRef;
|
||||
use crate::pyobject::{BorrowValue, PyClassImpl, PyObjectRef, PyResult, PyValue, TryFromObject};
|
||||
use crate::pyobject::{
|
||||
BorrowValue, IntoPyObject, PyClassImpl, PyObjectRef, PyResult, PyValue, TryFromObject,
|
||||
};
|
||||
use crate::vm::VirtualMachine;
|
||||
|
||||
#[pyclass(module = "re", name = "Pattern")]
|
||||
@@ -95,10 +97,10 @@ fn re_match(
|
||||
string: PyStringRef,
|
||||
flags: OptionalArg<usize>,
|
||||
vm: &VirtualMachine,
|
||||
) -> PyResult {
|
||||
) -> PyResult<Option<PyMatch>> {
|
||||
let flags = extract_flags(flags);
|
||||
let regex = make_regex(vm, pattern.borrow_value(), flags)?;
|
||||
do_match(vm, ®ex, string)
|
||||
Ok(do_match(®ex, string))
|
||||
}
|
||||
|
||||
fn re_search(
|
||||
@@ -106,10 +108,10 @@ fn re_search(
|
||||
string: PyStringRef,
|
||||
flags: OptionalArg<usize>,
|
||||
vm: &VirtualMachine,
|
||||
) -> PyResult {
|
||||
) -> PyResult<Option<PyMatch>> {
|
||||
let flags = extract_flags(flags);
|
||||
let regex = make_regex(vm, pattern.borrow_value(), flags)?;
|
||||
do_search(vm, ®ex, string)
|
||||
Ok(do_search(®ex, string))
|
||||
}
|
||||
|
||||
fn re_sub(
|
||||
@@ -119,11 +121,11 @@ fn re_sub(
|
||||
count: OptionalArg<usize>,
|
||||
flags: OptionalArg<usize>,
|
||||
vm: &VirtualMachine,
|
||||
) -> PyResult {
|
||||
) -> PyResult<String> {
|
||||
let flags = extract_flags(flags);
|
||||
let regex = make_regex(vm, pattern.borrow_value(), flags)?;
|
||||
let limit = count.unwrap_or(0);
|
||||
do_sub(vm, ®ex, repl, string, limit)
|
||||
Ok(do_sub(®ex, repl, string, limit))
|
||||
}
|
||||
|
||||
fn re_findall(
|
||||
@@ -150,38 +152,34 @@ fn re_split(
|
||||
}
|
||||
|
||||
fn do_sub(
|
||||
vm: &VirtualMachine,
|
||||
pattern: &PyPattern,
|
||||
repl: PyStringRef,
|
||||
search_text: PyStringRef,
|
||||
limit: usize,
|
||||
) -> PyResult {
|
||||
) -> String {
|
||||
let out = pattern.regex.replacen(
|
||||
search_text.borrow_value().as_bytes(),
|
||||
limit,
|
||||
repl.borrow_value().as_bytes(),
|
||||
);
|
||||
let out = String::from_utf8_lossy(&out).into_owned();
|
||||
Ok(vm.ctx.new_str(out))
|
||||
String::from_utf8_lossy(&out).into_owned()
|
||||
}
|
||||
|
||||
fn do_match(vm: &VirtualMachine, pattern: &PyPattern, search_text: PyStringRef) -> PyResult {
|
||||
fn do_match(pattern: &PyPattern, search_text: PyStringRef) -> Option<PyMatch> {
|
||||
// I really wish there was a better way to do this; I don't think there is
|
||||
let mut regex = r"\A".to_owned();
|
||||
regex.push_str(pattern.regex.as_str());
|
||||
let regex = Regex::new(®ex).unwrap();
|
||||
|
||||
match regex.captures(search_text.borrow_value().as_bytes()) {
|
||||
None => Ok(vm.get_none()),
|
||||
Some(captures) => Ok(create_match(vm, search_text.clone(), captures)),
|
||||
}
|
||||
let mut regex_text = r"\A".to_owned();
|
||||
regex_text.push_str(pattern.regex.as_str());
|
||||
let regex = Regex::new(®ex_text).unwrap();
|
||||
regex
|
||||
.captures(search_text.borrow_value().as_bytes())
|
||||
.map(|captures| create_match(search_text.clone(), captures))
|
||||
}
|
||||
|
||||
fn do_search(vm: &VirtualMachine, regex: &PyPattern, search_text: PyStringRef) -> PyResult {
|
||||
match regex.regex.captures(search_text.borrow_value().as_bytes()) {
|
||||
None => Ok(vm.get_none()),
|
||||
Some(captures) => Ok(create_match(vm, search_text.clone(), captures)),
|
||||
}
|
||||
fn do_search(regex: &PyPattern, search_text: PyStringRef) -> Option<PyMatch> {
|
||||
regex
|
||||
.regex
|
||||
.captures(search_text.borrow_value().as_bytes())
|
||||
.map(|captures| create_match(search_text.clone(), captures))
|
||||
}
|
||||
|
||||
fn do_findall(vm: &VirtualMachine, pattern: &PyPattern, search_text: PyStringRef) -> PyResult {
|
||||
@@ -255,8 +253,7 @@ fn do_split(
|
||||
let split = output
|
||||
.into_iter()
|
||||
.map(|v| {
|
||||
v.map(|v| vm.ctx.new_str(String::from_utf8_lossy(v).into_owned()))
|
||||
.unwrap_or_else(|| vm.get_none())
|
||||
vm.unwrap_or_none(v.map(|v| vm.ctx.new_str(String::from_utf8_lossy(v).into_owned())))
|
||||
})
|
||||
.collect();
|
||||
Ok(vm.ctx.new_list(split))
|
||||
@@ -286,12 +283,12 @@ fn make_regex(vm: &VirtualMachine, pattern: &str, flags: PyRegexFlags) -> PyResu
|
||||
}
|
||||
|
||||
/// Take a found regular expression and convert it to proper match object.
|
||||
fn create_match(vm: &VirtualMachine, haystack: PyStringRef, captures: Captures) -> PyObjectRef {
|
||||
fn create_match(haystack: PyStringRef, captures: Captures) -> PyMatch {
|
||||
let captures = captures
|
||||
.iter()
|
||||
.map(|opt| opt.map(|m| m.start()..m.end()))
|
||||
.collect();
|
||||
PyMatch { haystack, captures }.into_object(vm)
|
||||
PyMatch { haystack, captures }
|
||||
}
|
||||
|
||||
fn extract_flags(flags: OptionalArg<usize>) -> PyRegexFlags {
|
||||
@@ -319,13 +316,13 @@ fn re_purge(_vm: &VirtualMachine) {}
|
||||
#[pyimpl]
|
||||
impl PyPattern {
|
||||
#[pymethod(name = "match")]
|
||||
fn match_(&self, text: PyStringRef, vm: &VirtualMachine) -> PyResult {
|
||||
do_match(vm, self, text)
|
||||
fn match_(&self, text: PyStringRef) -> Option<PyMatch> {
|
||||
do_match(self, text)
|
||||
}
|
||||
|
||||
#[pymethod(name = "search")]
|
||||
fn search(&self, text: PyStringRef, vm: &VirtualMachine) -> PyResult {
|
||||
do_search(vm, self, text)
|
||||
fn search(&self, text: PyStringRef) -> Option<PyMatch> {
|
||||
do_search(self, text)
|
||||
}
|
||||
|
||||
#[pymethod(name = "sub")]
|
||||
@@ -384,8 +381,8 @@ impl PyMatch {
|
||||
Ok(end)
|
||||
}
|
||||
|
||||
fn subgroup(&self, bounds: Range<usize>, vm: &VirtualMachine) -> PyObjectRef {
|
||||
vm.ctx.new_str(&self.haystack.borrow_value()[bounds])
|
||||
fn subgroup(&self, bounds: Range<usize>) -> String {
|
||||
self.haystack.borrow_value()[bounds].to_owned()
|
||||
}
|
||||
|
||||
fn get_bounds(&self, id: PyObjectRef, vm: &VirtualMachine) -> PyResult<Option<Range<usize>>> {
|
||||
@@ -403,27 +400,27 @@ impl PyMatch {
|
||||
})
|
||||
}
|
||||
|
||||
fn get_group(&self, id: PyObjectRef, vm: &VirtualMachine) -> PyResult {
|
||||
fn get_group(&self, id: PyObjectRef, vm: &VirtualMachine) -> PyResult<Option<String>> {
|
||||
let bounds = self.get_bounds(id, vm)?;
|
||||
let group = match bounds {
|
||||
Some(bounds) => self.subgroup(bounds, vm),
|
||||
None => vm.get_none(),
|
||||
};
|
||||
Ok(group)
|
||||
Ok(bounds.map(|b| self.subgroup(b)))
|
||||
}
|
||||
|
||||
#[pymethod]
|
||||
fn group(&self, groups: Args, vm: &VirtualMachine) -> PyResult {
|
||||
let mut groups = groups.into_vec();
|
||||
match groups.len() {
|
||||
0 => Ok(self.subgroup(self.captures[0].clone().unwrap(), vm)),
|
||||
1 => self.get_group(groups.pop().unwrap(), vm),
|
||||
len => {
|
||||
let mut output = Vec::with_capacity(len);
|
||||
for id in groups {
|
||||
output.push(self.get_group(id, vm)?);
|
||||
}
|
||||
Ok(vm.ctx.new_tuple(output))
|
||||
0 => Ok(self
|
||||
.subgroup(self.captures[0].clone().unwrap())
|
||||
.into_pyobject(vm)),
|
||||
1 => self
|
||||
.get_group(groups.pop().unwrap(), vm)
|
||||
.map(|g| g.into_pyobject(vm)),
|
||||
_ => {
|
||||
let output: Result<Vec<_>, _> = groups
|
||||
.into_iter()
|
||||
.map(|id| self.get_group(id, vm).map(|g| g.into_pyobject(vm)))
|
||||
.collect();
|
||||
Ok(vm.ctx.new_tuple(output?))
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -435,11 +432,12 @@ impl PyMatch {
|
||||
.captures
|
||||
.iter()
|
||||
.map(|capture| {
|
||||
capture
|
||||
.as_ref()
|
||||
.map(|bounds| self.subgroup(bounds.clone(), vm))
|
||||
.or_else(|| default.clone())
|
||||
.unwrap_or_else(|| vm.get_none())
|
||||
vm.unwrap_or_none(
|
||||
capture
|
||||
.as_ref()
|
||||
.map(|bounds| self.subgroup(bounds.clone()).into_pyobject(vm))
|
||||
.or_else(|| default.clone()),
|
||||
)
|
||||
})
|
||||
.collect();
|
||||
vm.ctx.new_tuple(groups)
|
||||
|
||||
@@ -112,7 +112,7 @@ pub fn check_signals(vm: &VirtualMachine) -> PyResult<()> {
|
||||
if triggerd {
|
||||
let handler = &signal_handlers[signum];
|
||||
if vm.is_callable(handler) {
|
||||
vm.invoke(handler, vec![vm.ctx.new_int(signum), vm.get_none()])?;
|
||||
vm.invoke(handler, vec![vm.ctx.new_int(signum), vm.ctx.none()])?;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -156,7 +156,7 @@ pub fn make_module(vm: &VirtualMachine) -> PyObjectRef {
|
||||
} else if handler == SIG_IGN {
|
||||
sig_ign.clone()
|
||||
} else {
|
||||
vm.get_none()
|
||||
vm.ctx.none()
|
||||
};
|
||||
vm.signal_handlers.as_ref().unwrap().borrow_mut()[signum] = py_handler;
|
||||
}
|
||||
|
||||
@@ -545,10 +545,7 @@ fn socket_getaddrinfo(opts: GAIOptions, vm: &VirtualMachine) -> PyResult {
|
||||
vm.ctx.new_int(ai.address),
|
||||
vm.ctx.new_int(ai.socktype),
|
||||
vm.ctx.new_int(ai.protocol),
|
||||
match ai.canonname {
|
||||
Some(s) => vm.ctx.new_str(s),
|
||||
None => vm.get_none(),
|
||||
},
|
||||
ai.canonname.into_pyobject(vm),
|
||||
get_addr_tuple(ai.sockaddr).into_pyobject(vm),
|
||||
])
|
||||
})
|
||||
@@ -786,7 +783,7 @@ pub fn make_module(vm: &VirtualMachine) -> PyObjectRef {
|
||||
"htons" => ctx.new_function(u16::to_be),
|
||||
"ntohl" => ctx.new_function(u32::from_be),
|
||||
"ntohs" => ctx.new_function(u16::from_be),
|
||||
"getdefaulttimeout" => ctx.new_function(|vm: &VirtualMachine| vm.get_none()),
|
||||
"getdefaulttimeout" => ctx.new_function(|vm: &VirtualMachine| vm.ctx.none()),
|
||||
"has_ipv6" => ctx.new_bool(false),
|
||||
"inet_pton" => ctx.new_function(socket_inet_pton),
|
||||
"inet_ntop" => ctx.new_function(socket_inet_ntop),
|
||||
|
||||
@@ -668,10 +668,7 @@ fn cert_to_py(vm: &VirtualMachine, cert: &X509Ref, binary: bool) -> PyResult {
|
||||
let name_to_py = |name: &x509::X509NameRef| {
|
||||
name.entries()
|
||||
.map(|entry| {
|
||||
let txt = match obj2txt(entry.object(), false) {
|
||||
Some(s) => vm.ctx.new_str(s),
|
||||
None => vm.get_none(),
|
||||
};
|
||||
let txt = obj2txt(entry.object(), false).into_pyobject(vm);
|
||||
let data = vm.ctx.new_str(entry.data().as_utf8()?.to_owned());
|
||||
Ok(vm.ctx.new_tuple(vec![vm.ctx.new_tuple(vec![txt, data])]))
|
||||
})
|
||||
|
||||
@@ -239,7 +239,7 @@ fn reg_to_py(value: RegValue, vm: &VirtualMachine) -> PyResult {
|
||||
}
|
||||
RegType::REG_BINARY | _ => {
|
||||
if value.bytes.is_empty() {
|
||||
Ok(vm.get_none())
|
||||
Ok(vm.ctx.none())
|
||||
} else {
|
||||
Ok(vm.ctx.new_bytes(value.bytes))
|
||||
}
|
||||
|
||||
@@ -170,10 +170,9 @@ fn sys_gettrace(vm: &VirtualMachine) -> PyObjectRef {
|
||||
vm.trace_func.borrow().clone()
|
||||
}
|
||||
|
||||
fn sys_settrace(tracefunc: PyObjectRef, vm: &VirtualMachine) -> PyObjectRef {
|
||||
fn sys_settrace(tracefunc: PyObjectRef, vm: &VirtualMachine) {
|
||||
vm.trace_func.replace(tracefunc);
|
||||
update_use_tracing(vm);
|
||||
vm.ctx.none()
|
||||
}
|
||||
|
||||
fn update_use_tracing(vm: &VirtualMachine) {
|
||||
@@ -187,7 +186,7 @@ fn sys_getrecursionlimit(vm: &VirtualMachine) -> usize {
|
||||
vm.recursion_limit.get()
|
||||
}
|
||||
|
||||
fn sys_setrecursionlimit(recursion_limit: i32, vm: &VirtualMachine) -> PyResult {
|
||||
fn sys_setrecursionlimit(recursion_limit: i32, vm: &VirtualMachine) -> PyResult<()> {
|
||||
let recursion_limit = recursion_limit
|
||||
.to_usize()
|
||||
.filter(|&u| u >= 1)
|
||||
@@ -198,7 +197,7 @@ fn sys_setrecursionlimit(recursion_limit: i32, vm: &VirtualMachine) -> PyResult
|
||||
|
||||
if recursion_limit > recursion_depth + 1 {
|
||||
vm.recursion_limit.set(recursion_limit);
|
||||
Ok(vm.ctx.none())
|
||||
Ok(())
|
||||
} else {
|
||||
Err(vm.new_recursion_error(format!(
|
||||
"cannot set the recursion limit to {} at the recursion depth {}: the limit is too low",
|
||||
@@ -212,12 +211,11 @@ fn sys_intern(value: PyStringRef) -> PyStringRef {
|
||||
value
|
||||
}
|
||||
|
||||
fn sys_exc_info(vm: &VirtualMachine) -> PyObjectRef {
|
||||
let (ty, val, tb) = match vm.current_exception() {
|
||||
fn sys_exc_info(vm: &VirtualMachine) -> (PyObjectRef, PyObjectRef, PyObjectRef) {
|
||||
match vm.current_exception() {
|
||||
Some(exception) => exceptions::split(exception, vm),
|
||||
None => (vm.get_none(), vm.get_none(), vm.get_none()),
|
||||
};
|
||||
vm.ctx.new_tuple(vec![ty, val, tb])
|
||||
None => (vm.ctx.none(), vm.ctx.none(), vm.ctx.none()),
|
||||
}
|
||||
}
|
||||
|
||||
fn sys_git_info(vm: &VirtualMachine) -> PyObjectRef {
|
||||
@@ -229,7 +227,7 @@ fn sys_git_info(vm: &VirtualMachine) -> PyObjectRef {
|
||||
}
|
||||
|
||||
fn sys_exit(code: OptionalArg<PyObjectRef>, vm: &VirtualMachine) -> PyResult {
|
||||
let code = code.unwrap_or_else(|| vm.get_none());
|
||||
let code = code.unwrap_or_none(vm);
|
||||
Err(vm.new_exception(vm.ctx.exceptions.system_exit.clone(), vec![code]))
|
||||
}
|
||||
|
||||
@@ -243,7 +241,7 @@ fn sys_displayhook(obj: PyObjectRef, vm: &VirtualMachine) -> PyResult<()> {
|
||||
return Ok(());
|
||||
}
|
||||
// set to none to avoid recursion while printing
|
||||
vm.set_attr(&vm.builtins, "_", vm.get_none())?;
|
||||
vm.set_attr(&vm.builtins, "_", vm.ctx.none())?;
|
||||
// TODO: catch encoding errors
|
||||
let repr = vm.to_repr(&obj)?.into_object();
|
||||
builtins::builtin_print(Args::new(vec![repr]), Default::default(), vm)?;
|
||||
@@ -651,7 +649,7 @@ settrace() -- set the global debug tracing function
|
||||
"meta_path" => ctx.new_list(vec![]),
|
||||
"path_hooks" => ctx.new_list(vec![]),
|
||||
"path_importer_cache" => ctx.new_dict(),
|
||||
"pycache_prefix" => vm.get_none(),
|
||||
"pycache_prefix" => vm.ctx.none(),
|
||||
"dont_write_bytecode" => vm.ctx.new_bool(vm.state.settings.dont_write_bytecode),
|
||||
"setprofile" => ctx.new_function(sys_setprofile),
|
||||
"setrecursionlimit" => ctx.new_function(sys_setrecursionlimit),
|
||||
|
||||
@@ -8,7 +8,6 @@ use crate::obj::objcode;
|
||||
use crate::obj::objcomplex;
|
||||
use crate::obj::objcoroutine;
|
||||
use crate::obj::objdict;
|
||||
use crate::obj::objellipsis;
|
||||
use crate::obj::objenumerate;
|
||||
use crate::obj::objfilter;
|
||||
use crate::obj::objfloat;
|
||||
@@ -24,11 +23,11 @@ use crate::obj::objmappingproxy;
|
||||
use crate::obj::objmemory;
|
||||
use crate::obj::objmodule;
|
||||
use crate::obj::objnamespace;
|
||||
use crate::obj::objnone;
|
||||
use crate::obj::objobject;
|
||||
use crate::obj::objproperty;
|
||||
use crate::obj::objrange;
|
||||
use crate::obj::objset;
|
||||
use crate::obj::objsingletons;
|
||||
use crate::obj::objslice;
|
||||
use crate::obj::objstaticmethod;
|
||||
use crate::obj::objstr;
|
||||
@@ -66,7 +65,6 @@ pub struct TypeZoo {
|
||||
pub coroutine_wrapper_type: PyClassRef,
|
||||
pub dict_type: PyClassRef,
|
||||
pub enumerate_type: PyClassRef,
|
||||
pub ellipsis_type: PyClassRef,
|
||||
pub filter_type: PyClassRef,
|
||||
pub float_type: PyClassRef,
|
||||
pub frame_type: PyClassRef,
|
||||
@@ -166,7 +164,6 @@ impl TypeZoo {
|
||||
dict_reversevalueiterator_type: create_type!(objdict::PyDictReverseValueIterator),
|
||||
dict_itemiterator_type: create_type!(objdict::PyDictItemIterator),
|
||||
dict_reverseitemiterator_type: create_type!(objdict::PyDictReverseItemIterator),
|
||||
ellipsis_type: create_type!(objellipsis::PyEllipsis),
|
||||
enumerate_type: create_type!(objenumerate::PyEnumerate),
|
||||
filter_type: create_type!(objfilter::PyFilter),
|
||||
float_type: create_type!(objfloat::PyFloat),
|
||||
@@ -361,7 +358,6 @@ pub fn initialize_types(context: &PyContext) {
|
||||
objslice::init(&context);
|
||||
objsuper::init(&context);
|
||||
objiter::init(&context);
|
||||
objellipsis::init(&context);
|
||||
objenumerate::init(&context);
|
||||
objfilter::init(&context);
|
||||
objmap::init(&context);
|
||||
@@ -371,7 +367,7 @@ pub fn initialize_types(context: &PyContext) {
|
||||
objframe::init(&context);
|
||||
objweakref::init(&context);
|
||||
objweakproxy::init(&context);
|
||||
objnone::init(&context);
|
||||
objsingletons::init(&context);
|
||||
objmodule::init(&context);
|
||||
objnamespace::init(&context);
|
||||
objmappingproxy::init(&context);
|
||||
|
||||
35
vm/src/vm.rs
35
vm/src/vm.rs
@@ -268,9 +268,9 @@ impl VirtualMachine {
|
||||
&vm,
|
||||
&builtins_dict,
|
||||
vm.ctx.new_str("builtins"),
|
||||
vm.get_none(),
|
||||
vm.ctx.none(),
|
||||
);
|
||||
objmodule::init_module_dict(&vm, &sysmod_dict, vm.ctx.new_str("sys"), vm.get_none());
|
||||
objmodule::init_module_dict(&vm, &sysmod_dict, vm.ctx.new_str("sys"), vm.ctx.none());
|
||||
vm
|
||||
}
|
||||
|
||||
@@ -335,8 +335,8 @@ impl VirtualMachine {
|
||||
wasm_id: self.wasm_id.clone(),
|
||||
exceptions: RefCell::new(vec![]),
|
||||
import_func: self.import_func.clone(),
|
||||
profile_func: RefCell::new(self.get_none()),
|
||||
trace_func: RefCell::new(self.get_none()),
|
||||
profile_func: RefCell::new(self.ctx.none()),
|
||||
trace_func: RefCell::new(self.ctx.none()),
|
||||
use_tracing: Cell::new(false),
|
||||
recursion_limit: self.recursion_limit.clone(),
|
||||
signal_handlers: None,
|
||||
@@ -446,7 +446,7 @@ impl VirtualMachine {
|
||||
self,
|
||||
&dict,
|
||||
self.new_pyobj(name.to_owned()),
|
||||
self.get_none(),
|
||||
self.ctx.none(),
|
||||
);
|
||||
PyObject::new(PyModule {}, self.ctx.types.module_type.clone(), Some(dict))
|
||||
}
|
||||
@@ -663,13 +663,9 @@ impl VirtualMachine {
|
||||
Scope::with_builtins(None, self.ctx.new_dict(), self)
|
||||
}
|
||||
|
||||
pub fn get_none(&self) -> PyObjectRef {
|
||||
self.ctx.none()
|
||||
}
|
||||
|
||||
/// Test whether a python object is `None`.
|
||||
pub fn is_none(&self, obj: &PyObjectRef) -> bool {
|
||||
obj.is(&self.get_none())
|
||||
obj.is(&self.ctx.none)
|
||||
}
|
||||
pub fn option_if_none(&self, obj: PyObjectRef) -> Option<PyObjectRef> {
|
||||
if self.is_none(&obj) {
|
||||
@@ -678,6 +674,9 @@ impl VirtualMachine {
|
||||
Some(obj)
|
||||
}
|
||||
}
|
||||
pub fn unwrap_or_none(&self, obj: Option<PyObjectRef>) -> PyObjectRef {
|
||||
obj.unwrap_or_else(|| self.ctx.none())
|
||||
}
|
||||
|
||||
pub fn get_locals(&self) -> PyDictRef {
|
||||
self.current_scope().get_locals()
|
||||
@@ -767,7 +766,7 @@ impl VirtualMachine {
|
||||
frame.scope.globals.clone().into_object(),
|
||||
)
|
||||
} else {
|
||||
(self.get_none(), self.get_none())
|
||||
(self.ctx.none(), self.ctx.none())
|
||||
};
|
||||
let from_list = self
|
||||
.ctx
|
||||
@@ -824,11 +823,7 @@ impl VirtualMachine {
|
||||
} else if let Some(ref descriptor) = descr_class.get_attr("__get__") {
|
||||
Some(self.invoke(
|
||||
descriptor,
|
||||
vec![
|
||||
descr,
|
||||
obj.unwrap_or_else(|| self.get_none()),
|
||||
cls.unwrap_or_else(|| self.get_none()),
|
||||
],
|
||||
vec![descr, self.unwrap_or_none(obj), self.unwrap_or_none(cls)],
|
||||
))
|
||||
} else {
|
||||
None
|
||||
@@ -910,8 +905,7 @@ impl VirtualMachine {
|
||||
|
||||
let frame = frame_ref.unwrap().as_object().clone();
|
||||
let event = self.ctx.new_str(event.to_string());
|
||||
let arg = self.get_none();
|
||||
let args = vec![frame, event, arg];
|
||||
let args = vec![frame, event, self.ctx.none()];
|
||||
|
||||
// temporarily disable tracing, during the call to the
|
||||
// tracing function itself.
|
||||
@@ -1164,10 +1158,7 @@ impl VirtualMachine {
|
||||
) -> PyResult {
|
||||
let codecsmodule = self.import("_codecs", &[], 0)?;
|
||||
let func = self.get_attribute(codecsmodule, func)?;
|
||||
let mut args = vec![
|
||||
obj,
|
||||
encoding.map_or_else(|| self.get_none(), |s| s.into_object()),
|
||||
];
|
||||
let mut args = vec![obj, encoding.into_pyobject(self)];
|
||||
if let Some(errors) = errors {
|
||||
args.push(errors.into_object());
|
||||
}
|
||||
|
||||
@@ -9,7 +9,8 @@ use rustpython_vm::function::{OptionalArg, PyFuncArgs};
|
||||
use rustpython_vm::import::import_file;
|
||||
use rustpython_vm::obj::{objdict::PyDictRef, objstr::PyStringRef, objtype::PyClassRef};
|
||||
use rustpython_vm::pyobject::{
|
||||
BorrowValue, PyCallable, PyClassImpl, PyObject, PyObjectRef, PyRef, PyResult, PyValue,
|
||||
BorrowValue, IntoPyObject, PyCallable, PyClassImpl, PyObject, PyObjectRef, PyRef, PyResult,
|
||||
PyValue,
|
||||
};
|
||||
use rustpython_vm::VirtualMachine;
|
||||
|
||||
@@ -146,12 +147,12 @@ fn browser_request_animation_frame(func: PyCallable, vm: &VirtualMachine) -> PyR
|
||||
Ok(vm.ctx.new_int(id))
|
||||
}
|
||||
|
||||
fn browser_cancel_animation_frame(id: i32, vm: &VirtualMachine) -> PyResult {
|
||||
fn browser_cancel_animation_frame(id: i32, vm: &VirtualMachine) -> PyResult<()> {
|
||||
window()
|
||||
.cancel_animation_frame(id)
|
||||
.map_err(|err| convert::js_py_typeerror(vm, err))?;
|
||||
|
||||
Ok(vm.get_none())
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[pyclass(module = "browser", name = "Promise")]
|
||||
@@ -270,11 +271,9 @@ impl Document {
|
||||
let elem = self
|
||||
.doc
|
||||
.query_selector(query.borrow_value())
|
||||
.map_err(|err| convert::js_py_typeerror(vm, err))?;
|
||||
let elem = match elem {
|
||||
Some(elem) => Element { elem }.into_object(vm),
|
||||
None => vm.get_none(),
|
||||
};
|
||||
.map_err(|err| convert::js_py_typeerror(vm, err))?
|
||||
.map(|elem| Element { elem })
|
||||
.into_pyobject(vm);
|
||||
Ok(elem)
|
||||
}
|
||||
}
|
||||
@@ -302,7 +301,7 @@ impl Element {
|
||||
) -> PyObjectRef {
|
||||
match self.elem.get_attribute(attr.borrow_value()) {
|
||||
Some(s) => vm.ctx.new_str(s),
|
||||
None => default.into_option().unwrap_or_else(|| vm.get_none()),
|
||||
None => default.unwrap_or_none(vm),
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -216,10 +216,10 @@ pub fn js_to_py(vm: &VirtualMachine, js_val: JsValue) -> PyObjectRef {
|
||||
js_err_to_py_err(vm, err).into_object()
|
||||
} else if js_val.is_undefined() {
|
||||
// Because `JSON.stringify(undefined)` returns undefined
|
||||
vm.get_none()
|
||||
vm.ctx.none()
|
||||
} else {
|
||||
py_serde::deserialize(vm, serde_wasm_bindgen::Deserializer::from(js_val))
|
||||
.unwrap_or_else(|_| vm.get_none())
|
||||
.unwrap_or_else(|_| vm.ctx.none())
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user