mirror of
https://github.com/RustPython/RustPython.git
synced 2026-10-29 03:04:38 +08:00
Merge pull request #3626 from youknowone/type-protocol
Replace TypeProcotol to AsPyObject
This commit is contained in:
87 files changed
+386
-396
No files matched your search
+3
-3
@@ -52,7 +52,7 @@ use rustpython_vm::{
|
||||
scope::Scope,
|
||||
stdlib::{atexit, sys},
|
||||
AsPyObject, InitParameter, Interpreter, PyObjectRef, PyResult, PySettings, TryFromObject,
|
||||
TypeProtocol, VirtualMachine,
|
||||
VirtualMachine,
|
||||
};
|
||||
use std::{env, path::Path, process, str::FromStr};
|
||||
|
||||
@@ -106,7 +106,7 @@ where
|
||||
// See if any exception leaked out:
|
||||
let exitcode = match res {
|
||||
Ok(()) => 0,
|
||||
Err(err) if err.isinstance(&vm.ctx.exceptions.system_exit) => {
|
||||
Err(err) if err.fast_isinstance(&vm.ctx.exceptions.system_exit) => {
|
||||
let args = err.args();
|
||||
match args.as_slice() {
|
||||
[] => 0,
|
||||
@@ -652,7 +652,7 @@ fn get_importer(path: &str, vm: &VirtualMachine) -> PyResult<Option<PyObjectRef>
|
||||
importer = Some(imp);
|
||||
break;
|
||||
}
|
||||
Err(e) if e.isinstance(&vm.ctx.exceptions.import_error) => continue,
|
||||
Err(e) if e.fast_isinstance(&vm.ctx.exceptions.import_error) => continue,
|
||||
Err(e) => return Err(e),
|
||||
}
|
||||
}
|
||||
|
||||
+2
-2
@@ -6,7 +6,7 @@ use rustpython_vm::{
|
||||
builtins::PyBaseExceptionRef,
|
||||
compile::{self, CompileError, CompileErrorType},
|
||||
scope::Scope,
|
||||
PyResult, TypeProtocol, VirtualMachine,
|
||||
AsPyObject, PyResult, VirtualMachine,
|
||||
};
|
||||
|
||||
enum ShellExecResult {
|
||||
@@ -127,7 +127,7 @@ pub fn run_shell(vm: &VirtualMachine, scope: Scope) -> PyResult<()> {
|
||||
};
|
||||
|
||||
if let Err(exc) = result {
|
||||
if exc.isinstance(&vm.ctx.exceptions.system_exit) {
|
||||
if exc.fast_isinstance(&vm.ctx.exceptions.system_exit) {
|
||||
repl.save_history(&repl_history_path).unwrap();
|
||||
return Err(exc);
|
||||
}
|
||||
|
||||
+4
-4
@@ -34,7 +34,7 @@ mod array {
|
||||
PyComparisonOp,
|
||||
},
|
||||
AsPyObject, PyObject, PyObjectRef, PyObjectView, PyRef, PyResult, PyValue,
|
||||
TryFromBorrowedObject, TryFromObject, TypeProtocol, VirtualMachine,
|
||||
TryFromBorrowedObject, TryFromObject, VirtualMachine,
|
||||
},
|
||||
};
|
||||
use itertools::Itertools;
|
||||
@@ -1115,7 +1115,7 @@ mod array {
|
||||
return Self::reduce(zelf, vm);
|
||||
}
|
||||
let array = zelf.read();
|
||||
let cls = zelf.as_object().clone_class();
|
||||
let cls = zelf.class().clone();
|
||||
let typecode = vm.ctx.new_str(array.typecode_str());
|
||||
let bytes = vm.ctx.new_bytes(array.get_bytes().to_vec());
|
||||
let code = MachineFormatCode::from_typecode(array.typecode()).unwrap();
|
||||
@@ -1135,7 +1135,7 @@ mod array {
|
||||
vm: &VirtualMachine,
|
||||
) -> PyResult<(PyObjectRef, PyTupleRef, Option<PyDictRef>)> {
|
||||
let array = zelf.read();
|
||||
let cls = zelf.as_object().clone_class();
|
||||
let cls = zelf.class().clone();
|
||||
let typecode = vm.ctx.new_str(array.typecode_str());
|
||||
let values = if array.typecode() == 'u' {
|
||||
let s = Self::_wchar_bytes_to_string(array.get_bytes(), array.itemsize(), vm)?;
|
||||
@@ -1444,7 +1444,7 @@ mod array {
|
||||
}
|
||||
|
||||
fn check_array_type(typ: PyTypeRef, vm: &VirtualMachine) -> PyResult<PyTypeRef> {
|
||||
if !typ.issubclass(PyArray::class(vm)) {
|
||||
if !typ.fast_issubclass(PyArray::class(vm)) {
|
||||
return Err(
|
||||
vm.new_type_error(format!("{} is not a subtype of array.array", typ.name()))
|
||||
);
|
||||
|
||||
+1
-1
@@ -16,7 +16,7 @@ mod _csv {
|
||||
match_class,
|
||||
protocol::{PyIter, PyIterReturn},
|
||||
types::{IterNext, IterNextIterable},
|
||||
PyObjectRef, PyObjectView, PyResult, PyValue, TryFromObject, TypeProtocol, VirtualMachine,
|
||||
AsPyObject, PyObjectRef, PyObjectView, PyResult, PyValue, TryFromObject, VirtualMachine,
|
||||
};
|
||||
use itertools::{self, Itertools};
|
||||
use std::fmt;
|
||||
|
||||
+1
-1
@@ -246,7 +246,7 @@ mod _json {
|
||||
) -> PyBaseExceptionRef {
|
||||
let get_error = || -> PyResult<_> {
|
||||
let cls = vm.try_class("json", "JSONDecodeError")?;
|
||||
let exc = vm.invoke(cls.as_object(), (e.msg, s, e.pos))?;
|
||||
let exc = vm.invoke(&cls, (e.msg, s, e.pos))?;
|
||||
exc.try_into_value(vm)
|
||||
};
|
||||
match get_error() {
|
||||
|
||||
+1
-1
@@ -6,7 +6,7 @@ mod math {
|
||||
builtins::{try_bigint_to_f64, try_f64_to_bigint, PyFloat, PyInt, PyIntRef},
|
||||
function::{ArgIntoFloat, ArgIterable, OptionalArg, PosArgs},
|
||||
utils::Either,
|
||||
PyObject, PyObjectRef, PyRef, PyResult, TypeProtocol, VirtualMachine,
|
||||
AsPyObject, PyObject, PyObjectRef, PyRef, PyResult, VirtualMachine,
|
||||
};
|
||||
use num_bigint::BigInt;
|
||||
use num_traits::{One, Signed, Zero};
|
||||
|
||||
@@ -16,7 +16,7 @@ pub(crate) mod _struct {
|
||||
match_class,
|
||||
protocol::PyIterReturn,
|
||||
types::{Constructor, IterNext, IterNextIterable},
|
||||
PyObjectRef, PyObjectView, PyResult, PyValue, TryFromObject, TypeProtocol, VirtualMachine,
|
||||
AsPyObject, PyObjectRef, PyObjectView, PyResult, PyValue, TryFromObject, VirtualMachine,
|
||||
};
|
||||
use crossbeam_utils::atomic::AtomicCell;
|
||||
|
||||
|
||||
@@ -266,7 +266,7 @@ mod decl {
|
||||
common::lock::PyMutex,
|
||||
function::{IntoPyObject, OptionalArg},
|
||||
stdlib::io::Fildes,
|
||||
PyValue, TypeProtocol,
|
||||
AsPyObject, PyValue,
|
||||
};
|
||||
use libc::pollfd;
|
||||
use num_traits::ToPrimitive;
|
||||
|
||||
@@ -18,7 +18,7 @@ mod _socket {
|
||||
OptionalOption,
|
||||
},
|
||||
utils::{Either, ToCString},
|
||||
PyObjectRef, PyResult, PyValue, TryFromBorrowedObject, TryFromObject, TypeProtocol,
|
||||
AsPyObject, PyObjectRef, PyResult, PyValue, TryFromBorrowedObject, TryFromObject,
|
||||
VirtualMachine,
|
||||
};
|
||||
use crossbeam_utils::atomic::AtomicCell;
|
||||
@@ -154,7 +154,7 @@ mod _socket {
|
||||
type CastFrom = libc::c_longlong;
|
||||
|
||||
// should really just be to_index() but test_socket tests the error messages explicitly
|
||||
if obj.isinstance(&vm.ctx.types.float_type) {
|
||||
if obj.fast_isinstance(&vm.ctx.types.float_type) {
|
||||
return Err(vm.new_type_error("integer argument expected, got float".to_owned()));
|
||||
}
|
||||
let int = vm
|
||||
|
||||
+1
-1
@@ -3,7 +3,7 @@ use crate::{
|
||||
cformat::CFormatString,
|
||||
function::{single_or_tuple_any, OptionalOption},
|
||||
protocol::PyIterIter,
|
||||
PyObjectRef, PyResult, TryFromObject, TypeProtocol, VirtualMachine,
|
||||
AsPyObject, PyObjectRef, PyResult, TryFromObject, VirtualMachine,
|
||||
};
|
||||
use num_traits::{cast::ToPrimitive, sign::Signed};
|
||||
use std::str::FromStr;
|
||||
|
||||
@@ -7,7 +7,7 @@ use crate::{
|
||||
protocol::PyIterReturn,
|
||||
pyclass::PyClassImpl,
|
||||
types::{Constructor, IterNext, IterNextIterable, Unconstructible},
|
||||
AsPyObject, PyContext, PyObjectRef, PyRef, PyResult, PyValue, TypeProtocol, VirtualMachine,
|
||||
AsPyObject, PyContext, PyObjectRef, PyRef, PyResult, PyValue, VirtualMachine,
|
||||
};
|
||||
|
||||
use crossbeam_utils::atomic::AtomicCell;
|
||||
@@ -147,7 +147,7 @@ impl PyAsyncGenWrappedValue {
|
||||
fn unbox(ag: &PyAsyncGen, val: PyResult<PyIterReturn>, vm: &VirtualMachine) -> PyResult {
|
||||
let (closed, async_done) = match &val {
|
||||
Ok(PyIterReturn::StopIteration(_)) => (true, true),
|
||||
Err(e) if e.isinstance(&vm.ctx.exceptions.generator_exit) => (true, true),
|
||||
Err(e) if e.fast_isinstance(&vm.ctx.exceptions.generator_exit) => (true, true),
|
||||
Err(_) => (false, true),
|
||||
_ => (false, false),
|
||||
};
|
||||
@@ -398,8 +398,8 @@ impl PyAsyncGenAThrow {
|
||||
self.ag.running_async.store(false);
|
||||
self.state.store(AwaitableState::Closed);
|
||||
if self.aclose
|
||||
&& (exc.isinstance(&vm.ctx.exceptions.stop_async_iteration)
|
||||
|| exc.isinstance(&vm.ctx.exceptions.generator_exit))
|
||||
&& (exc.fast_isinstance(&vm.ctx.exceptions.stop_async_iteration)
|
||||
|| exc.fast_isinstance(&vm.ctx.exceptions.generator_exit))
|
||||
{
|
||||
vm.new_stop_iteration(None)
|
||||
} else {
|
||||
|
||||
@@ -4,7 +4,7 @@ use crate::{
|
||||
function::{FuncArgs, IntoPyNativeFunc, PyNativeFunc},
|
||||
pyclass::PyClassImpl,
|
||||
types::{Callable, Constructor, GetDescriptor, Unconstructible},
|
||||
PyContext, PyObjectRef, PyRef, PyResult, PyValue, TypeProtocol, VirtualMachine,
|
||||
AsPyObject, PyContext, PyObjectRef, PyRef, PyResult, PyValue, VirtualMachine,
|
||||
};
|
||||
use std::fmt;
|
||||
|
||||
|
||||
@@ -34,7 +34,7 @@ use crate::{
|
||||
},
|
||||
utils::Either,
|
||||
AsPyObject, PyContext, PyObject, PyObjectRef, PyObjectView, PyObjectWrap, PyRef, PyResult,
|
||||
PyValue, TryFromBorrowedObject, TryFromObject, TypeProtocol, VirtualMachine,
|
||||
PyValue, TryFromBorrowedObject, TryFromObject, VirtualMachine,
|
||||
};
|
||||
use bstr::ByteSlice;
|
||||
use std::{borrow::Cow, mem::size_of};
|
||||
@@ -688,7 +688,7 @@ impl PyByteArray {
|
||||
) -> (PyTypeRef, PyTupleRef, Option<PyDictRef>) {
|
||||
let bytes = PyBytes::from(zelf.borrow_buf().to_vec()).into_pyobject(vm);
|
||||
(
|
||||
zelf.as_object().clone_class(),
|
||||
zelf.class().clone(),
|
||||
PyTuple::new_ref(vec![bytes], &vm.ctx),
|
||||
zelf.as_object().dict(),
|
||||
)
|
||||
|
||||
@@ -23,7 +23,7 @@ use crate::{
|
||||
},
|
||||
utils::Either,
|
||||
AsPyObject, PyContext, PyObject, PyObjectRef, PyObjectView, PyObjectWrap, PyRef, PyResult,
|
||||
PyValue, TryFromBorrowedObject, TryFromObject, TypeProtocol, VirtualMachine,
|
||||
PyValue, TryFromBorrowedObject, TryFromObject, VirtualMachine,
|
||||
};
|
||||
use bstr::ByteSlice;
|
||||
use std::{borrow::Cow, mem::size_of, ops::Deref};
|
||||
@@ -544,7 +544,7 @@ impl PyBytes {
|
||||
) -> (PyTypeRef, PyTupleRef, Option<PyDictRef>) {
|
||||
let bytes = PyBytes::from(zelf.inner.elements.clone()).into_pyobject(vm);
|
||||
(
|
||||
zelf.as_object().clone_class(),
|
||||
zelf.class().clone(),
|
||||
PyTuple::new_ref(vec![bytes], &vm.ctx),
|
||||
zelf.as_object().dict(),
|
||||
)
|
||||
@@ -638,7 +638,7 @@ impl Comparable for PyBytes {
|
||||
) -> PyResult<PyComparisonValue> {
|
||||
Ok(if let Some(res) = op.identical_optimization(zelf, other) {
|
||||
res.into()
|
||||
} else if other.isinstance(&vm.ctx.types.memoryview_type)
|
||||
} else if other.fast_isinstance(&vm.ctx.types.memoryview_type)
|
||||
&& op != PyComparisonOp::Eq
|
||||
&& op != PyComparisonOp::Ne
|
||||
{
|
||||
|
||||
@@ -3,7 +3,7 @@ use crate::{
|
||||
builtins::PyBoundMethod,
|
||||
pyclass::PyClassImpl,
|
||||
types::{Constructor, GetDescriptor},
|
||||
PyContext, PyObjectRef, PyRef, PyResult, PyValue, TypeProtocol, VirtualMachine,
|
||||
AsPyObject, PyContext, PyObjectRef, PyRef, PyResult, PyValue, VirtualMachine,
|
||||
};
|
||||
|
||||
/// classmethod(function) -> method
|
||||
@@ -52,7 +52,7 @@ impl GetDescriptor for PyClassMethod {
|
||||
vm: &VirtualMachine,
|
||||
) -> PyResult {
|
||||
let (zelf, obj) = Self::_unwrap(zelf, obj, vm)?;
|
||||
let cls = cls.unwrap_or_else(|| obj.clone_class().into());
|
||||
let cls = cls.unwrap_or_else(|| obj.class().clone().into());
|
||||
Ok(PyBoundMethod::new_ref(cls, zelf.callable.clone(), &vm.ctx).into())
|
||||
}
|
||||
}
|
||||
|
||||
@@ -7,8 +7,7 @@ use crate::{
|
||||
bytecode::{self, BorrowedConstant, Constant, ConstantBag},
|
||||
function::FuncArgs,
|
||||
pyclass::{PyClassImpl, StaticType},
|
||||
AsPyObject, PyContext, PyObject, PyObjectRef, PyRef, PyResult, PyValue, TypeProtocol,
|
||||
VirtualMachine,
|
||||
AsPyObject, PyContext, PyObject, PyObjectRef, PyRef, PyResult, PyValue, VirtualMachine,
|
||||
};
|
||||
use num_traits::Zero;
|
||||
use std::{fmt, ops::Deref};
|
||||
|
||||
@@ -7,8 +7,7 @@ use crate::{
|
||||
},
|
||||
pyclass::PyClassImpl,
|
||||
types::{Comparable, Constructor, Hashable, PyComparisonOp},
|
||||
AsPyObject, PyContext, PyObject, PyObjectRef, PyRef, PyResult, PyValue, TypeProtocol,
|
||||
VirtualMachine,
|
||||
AsPyObject, PyContext, PyObject, PyObjectRef, PyRef, PyResult, PyValue, VirtualMachine,
|
||||
};
|
||||
use num_complex::Complex64;
|
||||
use num_traits::Zero;
|
||||
@@ -159,7 +158,7 @@ impl Constructor for PyComplex {
|
||||
OptionalArg::Present(obj) => {
|
||||
if let Some(c) = obj.try_complex(vm)? {
|
||||
c
|
||||
} else if obj.class().issubclass(&vm.ctx.types.str_type) {
|
||||
} else if obj.class().fast_issubclass(&vm.ctx.types.str_type) {
|
||||
return Err(
|
||||
vm.new_type_error("complex() second arg can't be a string".to_owned())
|
||||
);
|
||||
|
||||
@@ -22,7 +22,7 @@ use crate::{
|
||||
},
|
||||
vm::{ReprGuard, VirtualMachine},
|
||||
AsPyObject, PyContext, PyObject, PyObjectRef, PyObjectView, PyRef, PyResult, PyValue,
|
||||
TryFromObject, TypeProtocol,
|
||||
TryFromObject,
|
||||
};
|
||||
use rustpython_common::lock::PyMutex;
|
||||
use std::{borrow::Cow, fmt};
|
||||
@@ -558,7 +558,9 @@ impl PyObjectView<PyDict> {
|
||||
} else {
|
||||
match self.as_object().get_item(key.clone(), vm) {
|
||||
Ok(value) => Ok(Some(value)),
|
||||
Err(e) if e.isinstance(&vm.ctx.exceptions.key_error) => self.missing_opt(key, vm),
|
||||
Err(e) if e.fast_isinstance(&vm.ctx.exceptions.key_error) => {
|
||||
self.missing_opt(key, vm)
|
||||
}
|
||||
Err(e) => Err(e),
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5,7 +5,7 @@ use crate::{
|
||||
protocol::{PyIter, PyIterReturn},
|
||||
pyclass::PyClassImpl,
|
||||
types::{Constructor, IterNext, IterNextIterable},
|
||||
PyContext, PyObjectRef, PyRef, PyResult, PyValue, TypeProtocol, VirtualMachine,
|
||||
AsPyObject, PyContext, PyObjectRef, PyRef, PyResult, PyValue, VirtualMachine,
|
||||
};
|
||||
use num_bigint::BigInt;
|
||||
use num_traits::Zero;
|
||||
@@ -56,7 +56,7 @@ impl PyEnumerate {
|
||||
#[pymethod(magic)]
|
||||
fn reduce(zelf: PyRef<Self>) -> (PyTypeRef, (PyIter, BigInt)) {
|
||||
(
|
||||
zelf.clone_class(),
|
||||
zelf.class().clone(),
|
||||
(zelf.iterator.clone(), zelf.counter.read().clone()),
|
||||
)
|
||||
}
|
||||
|
||||
@@ -10,7 +10,7 @@ use crate::{
|
||||
pyclass::PyClassImpl,
|
||||
types::{Comparable, Constructor, Hashable, PyComparisonOp},
|
||||
AsPyObject, PyContext, PyObject, PyObjectRef, PyRef, PyResult, PyValue, TryFromBorrowedObject,
|
||||
TryFromObject, TypeProtocol, VirtualMachine,
|
||||
TryFromObject, VirtualMachine,
|
||||
};
|
||||
use num_bigint::{BigInt, ToBigInt};
|
||||
use num_complex::Complex64;
|
||||
|
||||
@@ -14,8 +14,7 @@ use crate::{
|
||||
pyclass::PyClassImpl,
|
||||
scope::Scope,
|
||||
types::{Callable, Comparable, Constructor, GetAttr, GetDescriptor, PyComparisonOp},
|
||||
AsPyObject, PyContext, PyObject, PyObjectRef, PyRef, PyResult, PyValue, TypeProtocol,
|
||||
VirtualMachine,
|
||||
AsPyObject, PyContext, PyObject, PyObjectRef, PyRef, PyResult, PyValue, VirtualMachine,
|
||||
};
|
||||
#[cfg(feature = "jit")]
|
||||
use crate::{common::lock::OnceCell, function::IntoPyObject};
|
||||
@@ -462,7 +461,8 @@ impl Comparable for PyBoundMethod {
|
||||
|
||||
impl GetAttr for PyBoundMethod {
|
||||
fn getattro(zelf: PyRef<Self>, name: PyStrRef, vm: &VirtualMachine) -> PyResult {
|
||||
if let Some(obj) = zelf.get_class_attr(name.as_str()) {
|
||||
let class_attr = zelf.get_class_attr(name.as_str());
|
||||
if let Some(obj) = class_attr {
|
||||
return vm.call_if_get_descriptor(obj, zelf.into());
|
||||
}
|
||||
zelf.function.clone().get_attr(name, vm)
|
||||
@@ -507,6 +507,7 @@ impl PyBoundMethod {
|
||||
impl PyBoundMethod {
|
||||
#[pymethod(magic)]
|
||||
fn repr(&self, vm: &VirtualMachine) -> PyResult<String> {
|
||||
#[allow(clippy::needless_match)] // False positive on nightly
|
||||
let funcname =
|
||||
if let Some(qname) = vm.get_attribute_opt(self.function.clone(), "__qualname__")? {
|
||||
Some(qname)
|
||||
@@ -545,7 +546,7 @@ impl PyBoundMethod {
|
||||
fn qualname(&self, vm: &VirtualMachine) -> PyResult {
|
||||
if self
|
||||
.function
|
||||
.isinstance(&vm.ctx.types.builtin_function_or_method_type)
|
||||
.fast_isinstance(&vm.ctx.types.builtin_function_or_method_type)
|
||||
{
|
||||
// Special case: we work with `__new__`, which is not really a method.
|
||||
// It is a function, so its `__qualname__` is just `__new__`.
|
||||
|
||||
@@ -2,7 +2,7 @@ use crate::{
|
||||
builtins::{float, int, pybool, PyBaseExceptionRef, PyDictRef, PyFunction, PyStrRef},
|
||||
bytecode::CodeFlags,
|
||||
function::{FuncArgs, IntoPyObject},
|
||||
AsPyObject, PyObject, PyObjectRef, PyResult, TryFromObject, TypeProtocol, VirtualMachine,
|
||||
AsPyObject, PyObject, PyObjectRef, PyResult, TryFromObject, VirtualMachine,
|
||||
};
|
||||
use num_traits::ToPrimitive;
|
||||
use rustpython_jit::{AbiValue, Args, CompiledCode, JitArgumentError, JitType};
|
||||
|
||||
@@ -6,7 +6,7 @@ use crate::{
|
||||
pyclass::PyClassImpl,
|
||||
types::{AsMapping, Callable, Comparable, Constructor, GetAttr, Hashable, PyComparisonOp},
|
||||
AsPyObject, PyContext, PyObject, PyObjectRef, PyObjectView, PyRef, PyResult, PyValue,
|
||||
TryFromObject, TypeProtocol, VirtualMachine,
|
||||
TryFromObject, VirtualMachine,
|
||||
};
|
||||
use std::fmt;
|
||||
|
||||
@@ -102,7 +102,7 @@ impl PyGenericAlias {
|
||||
|
||||
Ok(format!(
|
||||
"{}[{}]",
|
||||
repr_item(self.origin.as_object().to_owned(), vm)?,
|
||||
repr_item(self.origin.clone().into(), vm)?,
|
||||
if self.args.len() == 0 {
|
||||
"()".to_owned()
|
||||
} else {
|
||||
@@ -118,17 +118,17 @@ impl PyGenericAlias {
|
||||
|
||||
#[pyproperty(magic)]
|
||||
fn parameters(&self) -> PyObjectRef {
|
||||
self.parameters.as_object().to_owned()
|
||||
self.parameters.clone().into()
|
||||
}
|
||||
|
||||
#[pyproperty(magic)]
|
||||
fn args(&self) -> PyObjectRef {
|
||||
self.args.as_object().to_owned()
|
||||
self.args.clone().into()
|
||||
}
|
||||
|
||||
#[pyproperty(magic)]
|
||||
fn origin(&self) -> PyObjectRef {
|
||||
self.origin.as_object().to_owned()
|
||||
self.origin.clone().into()
|
||||
}
|
||||
|
||||
#[pymethod(magic)]
|
||||
@@ -323,8 +323,8 @@ impl Callable for PyGenericAlias {
|
||||
fn call(zelf: &crate::PyObjectView<Self>, args: FuncArgs, vm: &VirtualMachine) -> PyResult {
|
||||
PyType::call(&zelf.origin, args, vm).map(|obj| {
|
||||
if let Err(exc) = obj.set_attr("__orig_class__", zelf.to_owned(), vm) {
|
||||
if !exc.isinstance(&vm.ctx.exceptions.attribute_error)
|
||||
&& !exc.isinstance(&vm.ctx.exceptions.type_error)
|
||||
if !exc.fast_isinstance(&vm.ctx.exceptions.attribute_error)
|
||||
&& !exc.fast_isinstance(&vm.ctx.exceptions.type_error)
|
||||
{
|
||||
return Err(exc);
|
||||
}
|
||||
|
||||
@@ -7,7 +7,7 @@ use crate::{
|
||||
pyclass::PyClassImpl,
|
||||
pyobject::PyThreadingConstraint,
|
||||
types::{Constructor, GetDescriptor, Unconstructible},
|
||||
PyContext, PyObjectRef, PyRef, PyResult, PyValue, TryFromObject, TypeProtocol, VirtualMachine,
|
||||
AsPyObject, PyContext, PyObjectRef, PyRef, PyResult, PyValue, TryFromObject, VirtualMachine,
|
||||
};
|
||||
|
||||
pub type PyGetterFunc = Box<py_dyn_fn!(dyn Fn(&VirtualMachine, PyObjectRef) -> PyResult)>;
|
||||
|
||||
@@ -10,7 +10,7 @@ use crate::{
|
||||
pyclass::PyClassImpl,
|
||||
types::{Comparable, Constructor, Hashable, PyComparisonOp},
|
||||
AsPyObject, PyContext, PyObject, PyObjectRef, PyRef, PyResult, PyValue, TryFromBorrowedObject,
|
||||
TypeProtocol, VirtualMachine,
|
||||
VirtualMachine,
|
||||
};
|
||||
use bstr::ByteSlice;
|
||||
use num_bigint::{BigInt, BigUint, Sign};
|
||||
|
||||
@@ -16,7 +16,7 @@ use crate::{
|
||||
utils::collection_repr,
|
||||
vm::{ReprGuard, VirtualMachine},
|
||||
AsPyObject, PyContext, PyObject, PyObjectRef, PyObjectView, PyObjectWrap, PyRef, PyResult,
|
||||
PyValue, TypeProtocol,
|
||||
PyValue,
|
||||
};
|
||||
use std::{borrow::Cow, fmt, ops::DerefMut};
|
||||
|
||||
|
||||
@@ -6,7 +6,7 @@ use crate::{
|
||||
protocol::{PyMapping, PyMappingMethods, PySequence, PySequenceMethods},
|
||||
pyclass::PyClassImpl,
|
||||
types::{AsMapping, AsSequence, Constructor, Iterable},
|
||||
PyContext, PyObject, PyObjectRef, PyRef, PyResult, PyValue, TryFromObject, TypeProtocol,
|
||||
AsPyObject, PyContext, PyObject, PyObjectRef, PyRef, PyResult, PyValue, TryFromObject,
|
||||
VirtualMachine,
|
||||
};
|
||||
|
||||
|
||||
@@ -19,7 +19,7 @@ use crate::{
|
||||
types::{AsBuffer, AsMapping, AsSequence, Comparable, Constructor, Hashable, PyComparisonOp},
|
||||
utils::Either,
|
||||
AsPyObject, PyContext, PyObject, PyObjectRef, PyObjectView, PyObjectWrap, PyRef, PyResult,
|
||||
PyValue, TryFromBorrowedObject, TryFromObject, TypeProtocol, VirtualMachine,
|
||||
PyValue, TryFromBorrowedObject, TryFromObject, VirtualMachine,
|
||||
};
|
||||
use crossbeam_utils::atomic::AtomicCell;
|
||||
use itertools::Itertools;
|
||||
|
||||
@@ -42,7 +42,8 @@ impl PyModule {
|
||||
|
||||
#[pymethod(magic)]
|
||||
fn init(zelf: PyRef<Self>, args: ModuleInitArgs, vm: &VirtualMachine) {
|
||||
debug_assert!(crate::TypeProtocol::class(zelf.as_object())
|
||||
debug_assert!(zelf
|
||||
.class()
|
||||
.slots
|
||||
.flags
|
||||
.has_feature(crate::types::PyTypeFlags::HAS_DICT));
|
||||
@@ -51,7 +52,7 @@ impl PyModule {
|
||||
|
||||
fn getattr_inner(zelf: &PyObjectView<Self>, name: PyStrRef, vm: &VirtualMachine) -> PyResult {
|
||||
if let Some(attr) =
|
||||
vm.generic_getattribute_opt(zelf.as_object().to_owned(), name.clone(), None)?
|
||||
vm.generic_getattribute_opt(zelf.to_owned().into(), name.clone(), None)?
|
||||
{
|
||||
return Ok(attr);
|
||||
}
|
||||
|
||||
@@ -5,7 +5,7 @@ use crate::{
|
||||
pyclass::PyClassImpl,
|
||||
types::{Comparable, Constructor, PyComparisonOp},
|
||||
vm::ReprGuard,
|
||||
AsPyObject, PyContext, PyObject, PyRef, PyResult, PyValue, TypeProtocol, VirtualMachine,
|
||||
AsPyObject, PyContext, PyObject, PyRef, PyResult, PyValue, VirtualMachine,
|
||||
};
|
||||
|
||||
/// A simple attribute-based namespace.
|
||||
|
||||
@@ -5,7 +5,7 @@ use crate::{
|
||||
pyclass::PyClassImpl,
|
||||
types::PyComparisonOp,
|
||||
utils::Either,
|
||||
AsPyObject, PyContext, PyObject, PyObjectRef, PyResult, PyValue, TypeProtocol, VirtualMachine,
|
||||
AsPyObject, PyContext, PyObject, PyObjectRef, PyResult, PyValue, VirtualMachine,
|
||||
};
|
||||
|
||||
/// object()
|
||||
@@ -255,7 +255,7 @@ impl PyBaseObject {
|
||||
|
||||
#[pyproperty(name = "__class__")]
|
||||
fn get_class(obj: PyObjectRef) -> PyTypeRef {
|
||||
obj.clone_class()
|
||||
obj.class().clone()
|
||||
}
|
||||
|
||||
#[pyproperty(name = "__class__", setter)]
|
||||
@@ -300,7 +300,7 @@ impl PyBaseObject {
|
||||
fn reduce_ex(obj: PyObjectRef, proto: usize, vm: &VirtualMachine) -> PyResult {
|
||||
if let Some(reduce) = vm.get_attribute_opt(obj.clone(), "__reduce__")? {
|
||||
let object_reduce = vm.ctx.types.object_type.get_attr("__reduce__").unwrap();
|
||||
let typ_obj: PyObjectRef = obj.clone_class().into();
|
||||
let typ_obj: PyObjectRef = obj.class().clone().into();
|
||||
let class_reduce = typ_obj.get_attr("__reduce__", vm)?;
|
||||
if !class_reduce.is(&object_reduce) {
|
||||
return vm.invoke(&reduce, ());
|
||||
@@ -355,7 +355,7 @@ pub fn generic_setattr(
|
||||
dict.set_item(attr_name, value, vm)?;
|
||||
} else {
|
||||
dict.del_item(attr_name.clone(), vm).map_err(|e| {
|
||||
if e.isinstance(&vm.ctx.exceptions.key_error) {
|
||||
if e.fast_isinstance(&vm.ctx.exceptions.key_error) {
|
||||
vm.new_attribute_error(format!(
|
||||
"'{}' object has no attribute '{}'",
|
||||
obj.class().name(),
|
||||
|
||||
@@ -4,8 +4,8 @@
|
||||
use super::PyTypeRef;
|
||||
use crate::common::lock::PyRwLock;
|
||||
use crate::{
|
||||
function::FuncArgs, pyclass::PyClassImpl, types::GetDescriptor, PyContext, PyObjectRef, PyRef,
|
||||
PyResult, PyValue, TryFromObject, TypeProtocol, VirtualMachine,
|
||||
function::FuncArgs, pyclass::PyClassImpl, types::GetDescriptor, AsPyObject, PyContext,
|
||||
PyObjectRef, PyRef, PyResult, PyValue, TryFromObject, VirtualMachine,
|
||||
};
|
||||
|
||||
/// Property attribute.
|
||||
@@ -185,7 +185,7 @@ impl PyProperty {
|
||||
deleter: PyRwLock::new(zelf.fdel()),
|
||||
doc: PyRwLock::new(None),
|
||||
}
|
||||
.into_ref_with_type(vm, TypeProtocol::clone_class(&zelf))
|
||||
.into_ref_with_type(vm, zelf.class().clone())
|
||||
}
|
||||
|
||||
#[pymethod]
|
||||
@@ -200,7 +200,7 @@ impl PyProperty {
|
||||
deleter: PyRwLock::new(zelf.fdel()),
|
||||
doc: PyRwLock::new(None),
|
||||
}
|
||||
.into_ref_with_type(vm, TypeProtocol::clone_class(&zelf))
|
||||
.into_ref_with_type(vm, zelf.class().clone())
|
||||
}
|
||||
|
||||
#[pymethod]
|
||||
@@ -215,7 +215,7 @@ impl PyProperty {
|
||||
deleter: PyRwLock::new(deleter.or_else(|| zelf.fdel())),
|
||||
doc: PyRwLock::new(None),
|
||||
}
|
||||
.into_ref_with_type(vm, TypeProtocol::clone_class(&zelf))
|
||||
.into_ref_with_type(vm, zelf.class().clone())
|
||||
}
|
||||
|
||||
#[pyproperty(magic)]
|
||||
|
||||
@@ -4,7 +4,7 @@ use crate::{
|
||||
pyclass::PyClassImpl,
|
||||
types::Constructor,
|
||||
AsPyObject, PyContext, PyObject, PyObjectRef, PyResult, PyValue, TryFromBorrowedObject,
|
||||
TypeProtocol, VirtualMachine,
|
||||
VirtualMachine,
|
||||
};
|
||||
use num_bigint::Sign;
|
||||
use num_traits::Zero;
|
||||
@@ -18,7 +18,7 @@ impl IntoPyObject for bool {
|
||||
|
||||
impl TryFromBorrowedObject for bool {
|
||||
fn try_from_borrowed_object(vm: &VirtualMachine, obj: &PyObject) -> PyResult<bool> {
|
||||
if obj.isinstance(&vm.ctx.types.int_type) {
|
||||
if obj.fast_isinstance(&vm.ctx.types.int_type) {
|
||||
Ok(get_value(obj))
|
||||
} else {
|
||||
Err(vm.new_type_error(format!("Expected type bool, not {}", obj.class().name())))
|
||||
@@ -40,7 +40,7 @@ impl PyObjectRef {
|
||||
// If descriptor returns Error, propagate it further
|
||||
let method = method_or_err?;
|
||||
let bool_obj = vm.invoke(&method, ())?;
|
||||
if !bool_obj.isinstance(&vm.ctx.types.bool_type) {
|
||||
if !bool_obj.fast_isinstance(&vm.ctx.types.bool_type) {
|
||||
return Err(vm.new_type_error(format!(
|
||||
"__bool__ should return bool, returned type {}",
|
||||
bool_obj.class().name()
|
||||
@@ -97,7 +97,7 @@ impl Constructor for PyBool {
|
||||
type Args = OptionalArg<PyObjectRef>;
|
||||
|
||||
fn py_new(zelf: PyTypeRef, x: Self::Args, vm: &VirtualMachine) -> PyResult {
|
||||
if !zelf.isinstance(&vm.ctx.types.type_type) {
|
||||
if !zelf.fast_isinstance(&vm.ctx.types.type_type) {
|
||||
let actual_class = zelf.class();
|
||||
let actual_type = &actual_class.name();
|
||||
return Err(vm.new_type_error(format!(
|
||||
@@ -129,7 +129,9 @@ impl PyBool {
|
||||
#[pymethod(name = "__ror__")]
|
||||
#[pymethod(magic)]
|
||||
fn or(lhs: PyObjectRef, rhs: PyObjectRef, vm: &VirtualMachine) -> PyObjectRef {
|
||||
if lhs.isinstance(&vm.ctx.types.bool_type) && rhs.isinstance(&vm.ctx.types.bool_type) {
|
||||
if lhs.fast_isinstance(&vm.ctx.types.bool_type)
|
||||
&& rhs.fast_isinstance(&vm.ctx.types.bool_type)
|
||||
{
|
||||
let lhs = get_value(&lhs);
|
||||
let rhs = get_value(&rhs);
|
||||
(lhs || rhs).into_pyobject(vm)
|
||||
@@ -141,7 +143,9 @@ impl PyBool {
|
||||
#[pymethod(name = "__rand__")]
|
||||
#[pymethod(magic)]
|
||||
fn and(lhs: PyObjectRef, rhs: PyObjectRef, vm: &VirtualMachine) -> PyObjectRef {
|
||||
if lhs.isinstance(&vm.ctx.types.bool_type) && rhs.isinstance(&vm.ctx.types.bool_type) {
|
||||
if lhs.fast_isinstance(&vm.ctx.types.bool_type)
|
||||
&& rhs.fast_isinstance(&vm.ctx.types.bool_type)
|
||||
{
|
||||
let lhs = get_value(&lhs);
|
||||
let rhs = get_value(&rhs);
|
||||
(lhs && rhs).into_pyobject(vm)
|
||||
@@ -153,7 +157,9 @@ impl PyBool {
|
||||
#[pymethod(name = "__rxor__")]
|
||||
#[pymethod(magic)]
|
||||
fn xor(lhs: PyObjectRef, rhs: PyObjectRef, vm: &VirtualMachine) -> PyObjectRef {
|
||||
if lhs.isinstance(&vm.ctx.types.bool_type) && rhs.isinstance(&vm.ctx.types.bool_type) {
|
||||
if lhs.fast_isinstance(&vm.ctx.types.bool_type)
|
||||
&& rhs.fast_isinstance(&vm.ctx.types.bool_type)
|
||||
{
|
||||
let lhs = get_value(&lhs);
|
||||
let rhs = get_value(&rhs);
|
||||
(lhs ^ rhs).into_pyobject(vm)
|
||||
@@ -168,7 +174,7 @@ pub(crate) fn init(context: &PyContext) {
|
||||
}
|
||||
|
||||
// pub fn not(vm: &VirtualMachine, obj: &PyObject) -> PyResult<bool> {
|
||||
// if obj.isinstance(&vm.ctx.types.bool_type) {
|
||||
// if obj.fast_isinstance(&vm.ctx.types.bool_type) {
|
||||
// let value = get_value(obj);
|
||||
// Ok(!value)
|
||||
// } else {
|
||||
|
||||
@@ -19,7 +19,7 @@ use crate::{
|
||||
Iterable, PyComparisonOp, Unconstructible,
|
||||
},
|
||||
AsPyObject, PyContext, PyObject, PyObjectRef, PyObjectView, PyRef, PyResult, PyValue,
|
||||
TryFromBorrowedObject, TypeProtocol, VirtualMachine,
|
||||
TryFromBorrowedObject, VirtualMachine,
|
||||
};
|
||||
use ascii::{AsciiStr, AsciiString};
|
||||
use bstr::ByteSlice;
|
||||
|
||||
@@ -8,7 +8,7 @@ use crate::{
|
||||
function::OptionalArg,
|
||||
pyclass::PyClassImpl,
|
||||
types::{Constructor, GetAttr, GetDescriptor},
|
||||
AsPyObject, PyContext, PyObjectRef, PyRef, PyResult, PyValue, TypeProtocol, VirtualMachine,
|
||||
AsPyObject, PyContext, PyObjectRef, PyRef, PyResult, PyValue, VirtualMachine,
|
||||
};
|
||||
|
||||
#[pyclass(module = false, name = "super")]
|
||||
@@ -174,26 +174,23 @@ impl GetDescriptor for PySuper {
|
||||
Ok(PySuper::new(zelf.typ.clone(), obj, vm)?.into_object(vm))
|
||||
} else {
|
||||
let obj = vm.unwrap_or_none(zelf.obj.clone().map(|(o, _)| o));
|
||||
vm.invoke(
|
||||
zelf.as_object().clone_class().as_object(),
|
||||
(zelf.typ.clone(), obj),
|
||||
)
|
||||
vm.invoke(&zelf.class(), (zelf.typ.clone(), obj))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn supercheck(ty: PyTypeRef, obj: PyObjectRef, vm: &VirtualMachine) -> PyResult<PyTypeRef> {
|
||||
if let Ok(cls) = obj.clone().downcast::<PyType>() {
|
||||
if cls.issubclass(&ty) {
|
||||
if cls.fast_issubclass(&ty) {
|
||||
return Ok(cls);
|
||||
}
|
||||
}
|
||||
if obj.isinstance(&ty) {
|
||||
return Ok(obj.clone_class());
|
||||
if obj.fast_isinstance(&ty) {
|
||||
return Ok(obj.class().clone());
|
||||
}
|
||||
let class_attr = obj.get_attr("__class__", vm)?;
|
||||
if let Ok(cls) = class_attr.downcast::<PyType>() {
|
||||
if !cls.is(&ty) && cls.issubclass(&ty) {
|
||||
if !cls.is(&ty) && cls.fast_issubclass(&ty) {
|
||||
return Ok(cls);
|
||||
}
|
||||
}
|
||||
|
||||
+15
-14
@@ -12,8 +12,7 @@ use crate::{
|
||||
pyclass::{PyClassImpl, StaticType},
|
||||
pyobject::PyLease,
|
||||
types::{Callable, GetAttr, PyTypeFlags, PyTypeSlots, SetAttr},
|
||||
AsPyObject, PyContext, PyObjectRef, PyObjectWeak, PyRef, PyResult, PyValue, TypeProtocol,
|
||||
VirtualMachine,
|
||||
AsPyObject, PyContext, PyObjectRef, PyObjectWeak, PyRef, PyResult, PyValue, VirtualMachine,
|
||||
};
|
||||
use itertools::Itertools;
|
||||
use std::{
|
||||
@@ -212,7 +211,7 @@ impl PyTypeRef {
|
||||
/// Determines if `subclass` is actually a subclass of `cls`, this doesn't call __subclasscheck__,
|
||||
/// so only use this if `cls` is known to have not overridden the base __subclasscheck__ magic
|
||||
/// method.
|
||||
pub fn issubclass(&self, cls: &impl Borrow<crate::PyObject>) -> bool {
|
||||
pub fn fast_issubclass(&self, cls: &impl Borrow<crate::PyObject>) -> bool {
|
||||
self.as_object().is(cls.borrow()) || self.mro.iter().any(|c| c.is(cls.borrow()))
|
||||
}
|
||||
|
||||
@@ -230,7 +229,7 @@ impl PyType {
|
||||
// bound method for every type
|
||||
pub(crate) fn __new__(zelf: PyRef<Self>, args: FuncArgs, vm: &VirtualMachine) -> PyResult {
|
||||
let (subtype, args): (PyRef<Self>, FuncArgs) = args.bind(vm)?;
|
||||
if !subtype.issubclass(&zelf) {
|
||||
if !subtype.fast_issubclass(&zelf) {
|
||||
return Err(vm.new_type_error(format!(
|
||||
"{zelf}.__new__({subtype}): {subtype} is not a subtype of {zelf}",
|
||||
zelf = zelf.name(),
|
||||
@@ -279,12 +278,12 @@ impl PyType {
|
||||
|
||||
#[pymethod(magic)]
|
||||
fn instancecheck(zelf: PyRef<Self>, obj: PyObjectRef) -> bool {
|
||||
obj.isinstance(&zelf)
|
||||
obj.fast_isinstance(&zelf)
|
||||
}
|
||||
|
||||
#[pymethod(magic)]
|
||||
fn subclasscheck(zelf: PyRef<Self>, subclass: PyTypeRef) -> bool {
|
||||
subclass.issubclass(&zelf)
|
||||
subclass.fast_issubclass(&zelf)
|
||||
}
|
||||
|
||||
#[pyclassmethod(magic)]
|
||||
@@ -338,7 +337,7 @@ impl PyType {
|
||||
.cloned()
|
||||
// We need to exclude this method from going into recursion:
|
||||
.and_then(|found| {
|
||||
if found.isinstance(&vm.ctx.types.getset_type) {
|
||||
if found.fast_isinstance(&vm.ctx.types.getset_type) {
|
||||
None
|
||||
} else {
|
||||
Some(found)
|
||||
@@ -355,7 +354,7 @@ impl PyType {
|
||||
.cloned()
|
||||
// We need to exclude this method from going into recursion:
|
||||
.and_then(|found| {
|
||||
if found.isinstance(&vm.ctx.types.getset_type) {
|
||||
if found.fast_isinstance(&vm.ctx.types.getset_type) {
|
||||
None
|
||||
} else {
|
||||
Some(found)
|
||||
@@ -416,7 +415,7 @@ impl PyType {
|
||||
|
||||
let is_type_type = metatype.is(&vm.ctx.types.type_type);
|
||||
if is_type_type && args.args.len() == 1 && args.kwargs.is_empty() {
|
||||
return Ok(args.args[0].clone_class().into());
|
||||
return Ok(args.args[0].class().clone().into());
|
||||
}
|
||||
|
||||
if args.args.len() != 3 {
|
||||
@@ -719,7 +718,9 @@ impl Callable for PyType {
|
||||
vm_trace!("type_call: {:?}", zelf);
|
||||
let obj = call_slot_new(zelf.to_owned(), zelf.to_owned(), args.clone(), vm)?;
|
||||
|
||||
if (zelf.is(&vm.ctx.types.type_type) && args.kwargs.is_empty()) || !obj.isinstance(zelf) {
|
||||
if (zelf.is(&vm.ctx.types.type_type) && args.kwargs.is_empty())
|
||||
|| !obj.fast_isinstance(zelf)
|
||||
{
|
||||
return Ok(obj);
|
||||
}
|
||||
|
||||
@@ -748,7 +749,7 @@ fn find_base_dict_descr(cls: &PyTypeRef, vm: &VirtualMachine) -> Option<PyObject
|
||||
|
||||
fn subtype_get_dict(obj: PyObjectRef, vm: &VirtualMachine) -> PyResult {
|
||||
// TODO: obj.class().as_pyref() need to be supported
|
||||
let cls = obj.clone_class();
|
||||
let cls = obj.class().clone();
|
||||
let ret = match find_base_dict_descr(&cls, vm) {
|
||||
Some(descr) => vm.call_get_descriptor(descr, obj).unwrap_or_else(|_| {
|
||||
Err(vm.new_type_error(format!(
|
||||
@@ -762,7 +763,7 @@ fn subtype_get_dict(obj: PyObjectRef, vm: &VirtualMachine) -> PyResult {
|
||||
}
|
||||
|
||||
fn subtype_set_dict(obj: PyObjectRef, value: PyObjectRef, vm: &VirtualMachine) -> PyResult<()> {
|
||||
let cls = obj.clone_class();
|
||||
let cls = obj.class().clone();
|
||||
match find_base_dict_descr(&cls, vm) {
|
||||
Some(descr) => {
|
||||
let descr_set = descr
|
||||
@@ -870,9 +871,9 @@ fn calculate_meta_class(
|
||||
let mut winner = metatype;
|
||||
for base in bases {
|
||||
let base_type = base.class();
|
||||
if winner.issubclass(&base_type) {
|
||||
if winner.fast_issubclass(&base_type) {
|
||||
continue;
|
||||
} else if base_type.issubclass(&winner) {
|
||||
} else if base_type.fast_issubclass(&winner) {
|
||||
winner = PyLease::into_pyref(base_type);
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -7,7 +7,7 @@ use crate::{
|
||||
pyclass::PyClassImpl,
|
||||
types::{AsMapping, Comparable, GetAttr, Hashable, Iterable, PyComparisonOp},
|
||||
AsPyObject, PyContext, PyObject, PyObjectRef, PyObjectView, PyRef, PyResult, PyValue,
|
||||
TryFromObject, TypeProtocol, VirtualMachine,
|
||||
TryFromObject, VirtualMachine,
|
||||
};
|
||||
use std::fmt;
|
||||
|
||||
|
||||
@@ -10,7 +10,7 @@ use crate::{
|
||||
Iterable, PyComparisonOp, Unconstructible,
|
||||
},
|
||||
AsPyObject, PyContext, PyObject, PyObjectRef, PyObjectView, PyRef, PyResult, PyValue,
|
||||
TryFromObject, TypeProtocol, VirtualMachine,
|
||||
TryFromObject, VirtualMachine,
|
||||
};
|
||||
use crossbeam_utils::atomic::AtomicCell;
|
||||
use num_bigint::{BigInt, Sign};
|
||||
|
||||
+24
-13
@@ -18,7 +18,6 @@ use crate::{
|
||||
utils::collection_repr,
|
||||
vm::{ReprGuard, VirtualMachine},
|
||||
AsPyObject, PyContext, PyObject, PyObjectRef, PyRef, PyResult, PyValue, TryFromObject,
|
||||
TypeProtocol,
|
||||
};
|
||||
use std::borrow::Cow;
|
||||
use std::{fmt, ops::Deref};
|
||||
@@ -344,7 +343,7 @@ impl PySetInner {
|
||||
)
|
||||
// If operation raised KeyError, report original set (set.remove)
|
||||
.map_err(|op_err| {
|
||||
if op_err.isinstance(&vm.ctx.exceptions.key_error) {
|
||||
if op_err.fast_isinstance(&vm.ctx.exceptions.key_error) {
|
||||
vm.new_key_error(item.to_owned())
|
||||
} else {
|
||||
op_err
|
||||
@@ -368,7 +367,7 @@ fn reduce_set(
|
||||
vm: &VirtualMachine,
|
||||
) -> PyResult<(PyTypeRef, PyTupleRef, Option<PyDictRef>)> {
|
||||
Ok((
|
||||
zelf.clone_class(),
|
||||
zelf.class().clone(),
|
||||
vm.new_tuple((extract_set(zelf)
|
||||
.unwrap_or(&PySetInner::default())
|
||||
.elements(),)),
|
||||
@@ -573,9 +572,9 @@ impl PySet {
|
||||
}
|
||||
|
||||
#[pymethod(magic)]
|
||||
fn ior(zelf: PyRef<Self>, iterable: SetIterable, vm: &VirtualMachine) -> PyResult {
|
||||
fn ior(zelf: PyRef<Self>, iterable: SetIterable, vm: &VirtualMachine) -> PyResult<PyRef<Self>> {
|
||||
zelf.inner.update(iterable.iterable, vm)?;
|
||||
Ok(zelf.as_object().to_owned())
|
||||
Ok(zelf)
|
||||
}
|
||||
|
||||
#[pymethod]
|
||||
@@ -595,9 +594,13 @@ impl PySet {
|
||||
}
|
||||
|
||||
#[pymethod(magic)]
|
||||
fn iand(zelf: PyRef<Self>, iterable: SetIterable, vm: &VirtualMachine) -> PyResult {
|
||||
fn iand(
|
||||
zelf: PyRef<Self>,
|
||||
iterable: SetIterable,
|
||||
vm: &VirtualMachine,
|
||||
) -> PyResult<PyRef<Self>> {
|
||||
zelf.inner.intersection_update(iterable.iterable, vm)?;
|
||||
Ok(zelf.as_object().to_owned())
|
||||
Ok(zelf)
|
||||
}
|
||||
|
||||
#[pymethod]
|
||||
@@ -607,9 +610,13 @@ impl PySet {
|
||||
}
|
||||
|
||||
#[pymethod(magic)]
|
||||
fn isub(zelf: PyRef<Self>, iterable: SetIterable, vm: &VirtualMachine) -> PyResult {
|
||||
fn isub(
|
||||
zelf: PyRef<Self>,
|
||||
iterable: SetIterable,
|
||||
vm: &VirtualMachine,
|
||||
) -> PyResult<PyRef<Self>> {
|
||||
zelf.inner.difference_update(iterable.iterable, vm)?;
|
||||
Ok(zelf.as_object().to_owned())
|
||||
Ok(zelf)
|
||||
}
|
||||
|
||||
#[pymethod]
|
||||
@@ -623,10 +630,14 @@ impl PySet {
|
||||
}
|
||||
|
||||
#[pymethod(magic)]
|
||||
fn ixor(zelf: PyRef<Self>, iterable: SetIterable, vm: &VirtualMachine) -> PyResult {
|
||||
fn ixor(
|
||||
zelf: PyRef<Self>,
|
||||
iterable: SetIterable,
|
||||
vm: &VirtualMachine,
|
||||
) -> PyResult<PyRef<Self>> {
|
||||
zelf.inner
|
||||
.symmetric_difference_update(iterable.iterable, vm)?;
|
||||
Ok(zelf.as_object().to_owned())
|
||||
Ok(zelf)
|
||||
}
|
||||
|
||||
#[pymethod(magic)]
|
||||
@@ -933,8 +944,8 @@ struct SetIterable {
|
||||
impl TryFromObject for SetIterable {
|
||||
fn try_from_object(vm: &VirtualMachine, obj: PyObjectRef) -> PyResult<Self> {
|
||||
let class = obj.class();
|
||||
if class.issubclass(&vm.ctx.types.set_type)
|
||||
|| class.issubclass(&vm.ctx.types.frozenset_type)
|
||||
if class.fast_issubclass(&vm.ctx.types.set_type)
|
||||
|| class.fast_issubclass(&vm.ctx.types.frozenset_type)
|
||||
{
|
||||
// the class lease needs to be drop to be able to return the object
|
||||
drop(class);
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
use super::PyTypeRef;
|
||||
use crate::{
|
||||
function::IntoPyObject, pyclass::PyClassImpl, types::Constructor, PyContext, PyObjectRef,
|
||||
PyResult, PyValue, TypeProtocol, VirtualMachine,
|
||||
function::IntoPyObject, pyclass::PyClassImpl, types::Constructor, AsPyObject, PyContext,
|
||||
PyObjectRef, PyResult, PyValue, VirtualMachine,
|
||||
};
|
||||
|
||||
#[pyclass(module = false, name = "NoneType")]
|
||||
@@ -87,6 +87,6 @@ impl PyNotImplemented {
|
||||
}
|
||||
|
||||
pub fn init(context: &PyContext) {
|
||||
PyNone::extend_class(context, &context.none.clone_class());
|
||||
PyNotImplemented::extend_class(context, &context.not_implemented.clone_class());
|
||||
PyNone::extend_class(context, &context.none.class());
|
||||
PyNotImplemented::extend_class(context, &context.not_implemented.class());
|
||||
}
|
||||
@@ -4,8 +4,7 @@ use crate::{
|
||||
function::{FuncArgs, IntoPyObject, OptionalArg, PyComparisonValue},
|
||||
pyclass::PyClassImpl,
|
||||
types::{Comparable, Constructor, Hashable, PyComparisonOp, Unhashable},
|
||||
AsPyObject, PyContext, PyObject, PyObjectRef, PyRef, PyResult, PyValue, TypeProtocol,
|
||||
VirtualMachine,
|
||||
AsPyObject, PyContext, PyObject, PyObjectRef, PyRef, PyResult, PyValue, VirtualMachine,
|
||||
};
|
||||
use num_bigint::{BigInt, ToBigInt};
|
||||
use num_traits::{One, Signed, ToPrimitive, Zero};
|
||||
@@ -205,7 +204,7 @@ impl PySlice {
|
||||
(Option<PyObjectRef>, PyObjectRef, Option<PyObjectRef>),
|
||||
)> {
|
||||
Ok((
|
||||
zelf.clone_class(),
|
||||
zelf.class().clone(),
|
||||
(zelf.start.clone(), zelf.stop.clone(), zelf.step.clone()),
|
||||
))
|
||||
}
|
||||
@@ -452,5 +451,5 @@ impl PyEllipsis {
|
||||
|
||||
pub fn init(context: &PyContext) {
|
||||
PySlice::extend_class(context, &context.types.slice_type);
|
||||
PyEllipsis::extend_class(context, &context.ellipsis.clone_class());
|
||||
PyEllipsis::extend_class(context, &context.ellipsis.class().clone());
|
||||
}
|
||||
@@ -15,7 +15,6 @@ use crate::{
|
||||
utils::collection_repr,
|
||||
vm::{ReprGuard, VirtualMachine},
|
||||
AsPyObject, PyContext, PyObject, PyObjectRef, PyRef, PyResult, PyValue, TryFromObject,
|
||||
TypeProtocol,
|
||||
};
|
||||
use std::{borrow::Cow, fmt, marker::PhantomData};
|
||||
|
||||
|
||||
@@ -8,7 +8,7 @@ use crate::{
|
||||
pyclass::PyClassImpl,
|
||||
types::{Callable, Comparable, Constructor, Hashable, PyComparisonOp},
|
||||
AsPyObject, PyContext, PyObject, PyObjectRef, PyObjectWrap, PyRef, PyResult, PyValue,
|
||||
TypeProtocol, VirtualMachine,
|
||||
VirtualMachine,
|
||||
};
|
||||
|
||||
pub use crate::pyobject::PyWeak;
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
use super::PyTypeRef;
|
||||
use crate::{
|
||||
builtins::PyTupleRef,
|
||||
function::{ArgIntoBool, IntoPyObject, OptionalArg, PosArgs},
|
||||
function::{ArgIntoBool, OptionalArg, PosArgs},
|
||||
protocol::{PyIter, PyIterReturn},
|
||||
pyclass::PyClassImpl,
|
||||
types::{Constructor, IterNext, IterNextIterable},
|
||||
PyContext, PyObjectRef, PyRef, PyResult, PyValue, TryFromObject, TypeProtocol, VirtualMachine,
|
||||
AsPyObject, PyContext, PyObjectRef, PyRef, PyResult, PyValue, TryFromObject, VirtualMachine,
|
||||
};
|
||||
use rustpython_common::atomic::{self, PyAtomic, Radium};
|
||||
|
||||
@@ -42,7 +42,7 @@ impl Constructor for PyZip {
|
||||
impl PyZip {
|
||||
#[pymethod(magic)]
|
||||
fn reduce(zelf: PyRef<Self>, vm: &VirtualMachine) -> PyResult<PyTupleRef> {
|
||||
let cls = zelf.clone_class().into_pyobject(vm);
|
||||
let cls = zelf.class().clone();
|
||||
let iterators = zelf
|
||||
.iterators
|
||||
.iter()
|
||||
|
||||
+7
-7
@@ -7,7 +7,7 @@ use crate::{
|
||||
function::ArgIntoFloat,
|
||||
protocol::PyBuffer,
|
||||
stdlib::builtins,
|
||||
PyObjectRef, PyResult, TryFromBorrowedObject, TryFromObject, TypeProtocol, VirtualMachine,
|
||||
AsPyObject, PyObjectRef, PyResult, TryFromBorrowedObject, TryFromObject, VirtualMachine,
|
||||
};
|
||||
use itertools::Itertools;
|
||||
use num_bigint::{BigInt, Sign};
|
||||
@@ -449,7 +449,7 @@ impl CFormatSpec {
|
||||
let type_name = obj.class().name().to_string();
|
||||
let value = ArgIntoFloat::try_from_object(vm, obj)
|
||||
.map_err(|e| {
|
||||
if e.isinstance(&vm.ctx.exceptions.type_error) {
|
||||
if e.fast_isinstance(&vm.ctx.exceptions.type_error) {
|
||||
// formatfloat in bytesobject.c generates its own specific exception
|
||||
// text in this case, mirror it here.
|
||||
vm.new_type_error(format!("float argument required, not {}", type_name))
|
||||
@@ -692,9 +692,9 @@ impl CFormatBytes {
|
||||
let mut result = vec![];
|
||||
|
||||
let is_mapping = values_obj.class().has_attr("__getitem__")
|
||||
&& !values_obj.isinstance(&vm.ctx.types.tuple_type)
|
||||
&& !values_obj.isinstance(&vm.ctx.types.bytes_type)
|
||||
&& !values_obj.isinstance(&vm.ctx.types.bytearray_type);
|
||||
&& !values_obj.fast_isinstance(&vm.ctx.types.tuple_type)
|
||||
&& !values_obj.fast_isinstance(&vm.ctx.types.bytes_type)
|
||||
&& !values_obj.fast_isinstance(&vm.ctx.types.bytearray_type);
|
||||
|
||||
if num_specifiers == 0 {
|
||||
// literal only
|
||||
@@ -844,8 +844,8 @@ impl CFormatString {
|
||||
let mut result = String::new();
|
||||
|
||||
let is_mapping = values_obj.class().has_attr("__getitem__")
|
||||
&& !values_obj.isinstance(&vm.ctx.types.tuple_type)
|
||||
&& !values_obj.isinstance(&vm.ctx.types.str_type);
|
||||
&& !values_obj.fast_isinstance(&vm.ctx.types.tuple_type)
|
||||
&& !values_obj.fast_isinstance(&vm.ctx.types.str_type);
|
||||
|
||||
if num_specifiers == 0 {
|
||||
// literal only
|
||||
|
||||
+10
-11
@@ -2,8 +2,7 @@ use crate::{
|
||||
builtins::{PyBaseExceptionRef, PyBytesRef, PyStr, PyStrRef, PyTuple, PyTupleRef},
|
||||
common::{ascii, lock::PyRwLock},
|
||||
function::IntoPyObject,
|
||||
AsPyObject, PyContext, PyObject, PyObjectRef, PyResult, PyValue, TryFromObject, TypeProtocol,
|
||||
VirtualMachine,
|
||||
AsPyObject, PyContext, PyObject, PyObjectRef, PyResult, PyValue, TryFromObject, VirtualMachine,
|
||||
};
|
||||
use std::{borrow::Cow, collections::HashMap, fmt::Write, ops::Range};
|
||||
|
||||
@@ -360,12 +359,12 @@ fn extract_unicode_error_range(err: &PyObject, vm: &VirtualMachine) -> PyResult<
|
||||
|
||||
#[inline]
|
||||
fn is_decode_err(err: &PyObject, vm: &VirtualMachine) -> bool {
|
||||
err.isinstance(&vm.ctx.exceptions.unicode_decode_error)
|
||||
err.fast_isinstance(&vm.ctx.exceptions.unicode_decode_error)
|
||||
}
|
||||
#[inline]
|
||||
fn is_encode_ish_err(err: &PyObject, vm: &VirtualMachine) -> bool {
|
||||
err.isinstance(&vm.ctx.exceptions.unicode_encode_error)
|
||||
|| err.isinstance(&vm.ctx.exceptions.unicode_translate_error)
|
||||
err.fast_isinstance(&vm.ctx.exceptions.unicode_encode_error)
|
||||
|| err.fast_isinstance(&vm.ctx.exceptions.unicode_translate_error)
|
||||
}
|
||||
|
||||
fn bad_err_type(err: PyObjectRef, vm: &VirtualMachine) -> PyBaseExceptionRef {
|
||||
@@ -394,12 +393,12 @@ fn ignore_errors(err: PyObjectRef, vm: &VirtualMachine) -> PyResult<(PyObjectRef
|
||||
fn replace_errors(err: PyObjectRef, vm: &VirtualMachine) -> PyResult<(String, usize)> {
|
||||
// char::REPLACEMENT_CHARACTER as a str
|
||||
let replacement_char = "\u{FFFD}";
|
||||
let replace = if err.isinstance(&vm.ctx.exceptions.unicode_encode_error) {
|
||||
let replace = if err.fast_isinstance(&vm.ctx.exceptions.unicode_encode_error) {
|
||||
"?"
|
||||
} else if err.isinstance(&vm.ctx.exceptions.unicode_decode_error) {
|
||||
} else if err.fast_isinstance(&vm.ctx.exceptions.unicode_decode_error) {
|
||||
let range = extract_unicode_error_range(&err, vm)?;
|
||||
return Ok((replacement_char.to_owned(), range.end));
|
||||
} else if err.isinstance(&vm.ctx.exceptions.unicode_translate_error) {
|
||||
} else if err.fast_isinstance(&vm.ctx.exceptions.unicode_translate_error) {
|
||||
replacement_char
|
||||
} else {
|
||||
return Err(bad_err_type(err, vm));
|
||||
@@ -457,7 +456,7 @@ fn backslashreplace_errors(err: PyObjectRef, vm: &VirtualMachine) -> PyResult<(S
|
||||
}
|
||||
|
||||
fn namereplace_errors(err: PyObjectRef, vm: &VirtualMachine) -> PyResult<(String, usize)> {
|
||||
if err.isinstance(&vm.ctx.exceptions.unicode_encode_error) {
|
||||
if err.fast_isinstance(&vm.ctx.exceptions.unicode_encode_error) {
|
||||
let range = extract_unicode_error_range(&err, vm)?;
|
||||
let s = PyStrRef::try_from_object(vm, err.get_attr("object", vm)?)?;
|
||||
let s_after_start =
|
||||
@@ -551,7 +550,7 @@ fn get_standard_encoding(encoding: &str) -> (usize, StandardEncoding) {
|
||||
}
|
||||
|
||||
fn surrogatepass_errors(err: PyObjectRef, vm: &VirtualMachine) -> PyResult<(String, usize)> {
|
||||
if err.isinstance(&vm.ctx.exceptions.unicode_encode_error) {
|
||||
if err.fast_isinstance(&vm.ctx.exceptions.unicode_encode_error) {
|
||||
let range = extract_unicode_error_range(&err, vm)?;
|
||||
let s = PyStrRef::try_from_object(vm, err.clone().get_attr("object", vm)?)?;
|
||||
let s_encoding = PyStrRef::try_from_object(vm, err.clone().get_attr("encoding", vm)?)?;
|
||||
@@ -663,7 +662,7 @@ fn surrogatepass_errors(err: PyObjectRef, vm: &VirtualMachine) -> PyResult<(Stri
|
||||
}
|
||||
|
||||
fn surrogateescape_errors(err: PyObjectRef, vm: &VirtualMachine) -> PyResult<(String, usize)> {
|
||||
if err.isinstance(&vm.ctx.exceptions.unicode_encode_error) {
|
||||
if err.fast_isinstance(&vm.ctx.exceptions.unicode_encode_error) {
|
||||
let range = extract_unicode_error_range(&err, vm)?;
|
||||
let s = PyStrRef::try_from_object(vm, err.clone().get_attr("object", vm)?)?;
|
||||
let s_after_start =
|
||||
|
||||
+6
-6
@@ -1,5 +1,5 @@
|
||||
use crate::{
|
||||
pyobject::{PyObject, PyObjectRef, PyRef, PyResult, PyValue, TypeProtocol},
|
||||
pyobject::{AsPyObject, PyObject, PyObjectRef, PyRef, PyResult, PyValue},
|
||||
vm::VirtualMachine,
|
||||
};
|
||||
|
||||
@@ -16,7 +16,7 @@ pub unsafe trait TransmuteFromObject: Sized {
|
||||
unsafe impl<T: PyValue> TransmuteFromObject for PyRef<T> {
|
||||
fn check(vm: &VirtualMachine, obj: &PyObject) -> PyResult<()> {
|
||||
let class = T::class(vm);
|
||||
if obj.isinstance(class) {
|
||||
if obj.fast_isinstance(class) {
|
||||
if obj.payload_is::<T>() {
|
||||
Ok(())
|
||||
} else {
|
||||
@@ -68,7 +68,7 @@ impl PyObject {
|
||||
{
|
||||
let class = T::class(vm);
|
||||
let special;
|
||||
let py_ref = if self.isinstance(class) {
|
||||
let py_ref = if self.fast_isinstance(class) {
|
||||
self.downcast_ref()
|
||||
.ok_or_else(|| vm.new_downcast_runtime_error(class, self))?
|
||||
} else {
|
||||
@@ -93,12 +93,12 @@ where
|
||||
#[inline]
|
||||
fn try_from_object(vm: &VirtualMachine, obj: PyObjectRef) -> PyResult<Self> {
|
||||
let class = T::class(vm);
|
||||
if obj.isinstance(class) {
|
||||
if obj.fast_isinstance(class) {
|
||||
obj.downcast()
|
||||
.map_err(|obj| vm.new_downcast_runtime_error(class, obj))
|
||||
.map_err(|obj| vm.new_downcast_runtime_error(class, &obj))
|
||||
} else {
|
||||
T::special_retrieve(vm, &obj)
|
||||
.unwrap_or_else(|| Err(vm.new_downcast_type_error(class, obj)))
|
||||
.unwrap_or_else(|| Err(vm.new_downcast_type_error(class, &obj)))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+4
-4
@@ -3,7 +3,7 @@ use crate::{
|
||||
common::lock::PyMutex,
|
||||
frame::{ExecutionResult, FrameRef},
|
||||
protocol::PyIterReturn,
|
||||
AsPyObject, PyObject, PyObjectRef, PyResult, TypeProtocol, VirtualMachine,
|
||||
AsPyObject, PyObject, PyObjectRef, PyResult, VirtualMachine,
|
||||
};
|
||||
use crossbeam_utils::atomic::AtomicCell;
|
||||
|
||||
@@ -112,13 +112,13 @@ impl Coro {
|
||||
match result {
|
||||
Ok(exec_res) => Ok(exec_res.into_iter_return(vm)),
|
||||
Err(e) => {
|
||||
if e.isinstance(&vm.ctx.exceptions.stop_iteration) {
|
||||
if e.fast_isinstance(&vm.ctx.exceptions.stop_iteration) {
|
||||
let err =
|
||||
vm.new_runtime_error(format!("{} raised StopIteration", gen_name(gen, vm)));
|
||||
err.set_cause(Some(e));
|
||||
Err(err)
|
||||
} else if gen.class().is(&vm.ctx.types.async_generator)
|
||||
&& e.isinstance(&vm.ctx.exceptions.stop_async_iteration)
|
||||
&& e.fast_isinstance(&vm.ctx.exceptions.stop_async_iteration)
|
||||
{
|
||||
let err = vm
|
||||
.new_runtime_error("async generator raised StopAsyncIteration".to_owned());
|
||||
@@ -194,5 +194,5 @@ impl Coro {
|
||||
}
|
||||
|
||||
pub fn is_gen_exit(exc: &PyBaseExceptionRef, vm: &VirtualMachine) -> bool {
|
||||
exc.isinstance(&vm.ctx.exceptions.generator_exit)
|
||||
exc.fast_isinstance(&vm.ctx.exceptions.generator_exit)
|
||||
}
|
||||
@@ -10,8 +10,7 @@ use crate::common::{
|
||||
use crate::{
|
||||
builtins::{PyInt, PyStr, PyStrRef},
|
||||
function::IntoPyObject,
|
||||
AsPyObject, PyObject, PyObjectRef, PyObjectWrap, PyRefExact, PyResult, TypeProtocol,
|
||||
VirtualMachine,
|
||||
AsPyObject, PyObject, PyObjectRef, PyRefExact, PyResult, VirtualMachine,
|
||||
};
|
||||
use num_traits::ToPrimitive;
|
||||
use std::{fmt, mem::size_of, ops::ControlFlow};
|
||||
@@ -847,7 +846,7 @@ impl DictKey for usize {
|
||||
}
|
||||
} else {
|
||||
let int = vm.ctx.new_int(*self);
|
||||
vm.bool_eq(&int.into_object(), other_key)
|
||||
vm.bool_eq(int.as_ref(), other_key)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+11
-11
@@ -9,8 +9,7 @@ use crate::{
|
||||
pyclass::{PyClassImpl, StaticType},
|
||||
stdlib::sys,
|
||||
suggestion::offer_suggestions,
|
||||
AsPyObject, PyContext, PyObjectRef, PyRef, PyResult, PyValue, TryFromObject, TypeProtocol,
|
||||
VirtualMachine,
|
||||
AsPyObject, PyContext, PyObjectRef, PyRef, PyResult, PyValue, TryFromObject, VirtualMachine,
|
||||
};
|
||||
use crossbeam_utils::atomic::AtomicCell;
|
||||
use itertools::Itertools;
|
||||
@@ -80,7 +79,7 @@ impl VirtualMachine {
|
||||
// This function should not be called directly,
|
||||
// use `wite_exception` as a public interface.
|
||||
// It is similar to `print_exception_recursive` from `CPython`.
|
||||
seen.insert(exc.as_object().get_id());
|
||||
seen.insert(exc.get_id());
|
||||
|
||||
#[allow(clippy::manual_map)]
|
||||
if let Some((cause_or_context, msg)) = if let Some(cause) = exc.cause() {
|
||||
@@ -103,11 +102,11 @@ impl VirtualMachine {
|
||||
} else {
|
||||
None
|
||||
} {
|
||||
if !seen.contains(&cause_or_context.as_object().get_id()) {
|
||||
if !seen.contains(&cause_or_context.get_id()) {
|
||||
self.write_exception_recursive(output, &cause_or_context, seen)?;
|
||||
writeln!(output, "{}", msg)?;
|
||||
} else {
|
||||
seen.insert(cause_or_context.as_object().get_id());
|
||||
seen.insert(cause_or_context.get_id());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -183,7 +182,8 @@ impl VirtualMachine {
|
||||
exc: PyBaseExceptionRef,
|
||||
) -> (PyObjectRef, PyObjectRef, PyObjectRef) {
|
||||
let tb = exc.traceback().into_pyobject(self);
|
||||
(exc.clone_class().into(), exc.into(), tb)
|
||||
let class = exc.class().clone();
|
||||
(class.into(), exc.into(), tb)
|
||||
}
|
||||
|
||||
/// Similar to PyErr_NormalizeException in CPython
|
||||
@@ -207,7 +207,7 @@ impl VirtualMachine {
|
||||
args: Vec<PyObjectRef>,
|
||||
) -> PyResult<PyBaseExceptionRef> {
|
||||
// TODO: fast-path built-in exceptions by directly instantiating them? Is that really worth it?
|
||||
let res = self.invoke(cls.as_object(), args)?;
|
||||
let res = self.invoke(&cls, args)?;
|
||||
PyBaseExceptionRef::try_from_object(self, res)
|
||||
}
|
||||
}
|
||||
@@ -264,7 +264,7 @@ impl TryFromObject for ExceptionCtor {
|
||||
fn try_from_object(vm: &VirtualMachine, obj: PyObjectRef) -> PyResult<Self> {
|
||||
obj.downcast::<PyType>()
|
||||
.and_then(|cls| {
|
||||
if cls.issubclass(&vm.ctx.exceptions.base_exception_type) {
|
||||
if cls.fast_issubclass(&vm.ctx.exceptions.base_exception_type) {
|
||||
Ok(Self::Class(cls))
|
||||
} else {
|
||||
Err(cls.into())
|
||||
@@ -303,7 +303,7 @@ impl ExceptionCtor {
|
||||
// if the "type" is an instance and the value isn't, use the "type"
|
||||
(Self::Instance(exc), None) => Ok(exc),
|
||||
// if the value is an instance of the type, use the instance value
|
||||
(Self::Class(cls), Some(exc)) if exc.isinstance(&cls) => Ok(exc),
|
||||
(Self::Class(cls), Some(exc)) if exc.fast_isinstance(&cls) => Ok(exc),
|
||||
// otherwise; construct an exception of the type using the value as args
|
||||
(Self::Class(cls), _) => {
|
||||
let args = match_class!(match value {
|
||||
@@ -494,9 +494,9 @@ impl PyBaseException {
|
||||
}
|
||||
|
||||
#[pymethod]
|
||||
fn with_traceback(zelf: PyRef<Self>, tb: Option<PyTracebackRef>) -> PyResult {
|
||||
fn with_traceback(zelf: PyRef<Self>, tb: Option<PyTracebackRef>) -> PyResult<PyRef<Self>> {
|
||||
*zelf.traceback.write() = tb;
|
||||
Ok(zelf.as_object().to_owned())
|
||||
Ok(zelf)
|
||||
}
|
||||
|
||||
#[pymethod(magic)]
|
||||
|
||||
+1
-1
@@ -3,7 +3,7 @@ use crate::{
|
||||
common::float_ops,
|
||||
function::{FuncArgs, IntoPyException},
|
||||
stdlib::builtins,
|
||||
PyObject, PyObjectRef, PyResult, TypeProtocol, VirtualMachine,
|
||||
AsPyObject, PyObject, PyObjectRef, PyResult, VirtualMachine,
|
||||
};
|
||||
use itertools::{Itertools, PeekingNext};
|
||||
use num_bigint::{BigInt, Sign};
|
||||
|
||||
+15
-24
@@ -16,7 +16,7 @@ use crate::{
|
||||
stdlib::builtins,
|
||||
types::PyComparisonOp,
|
||||
AsPyObject, PyMethod, PyObject, PyObjectRef, PyObjectWrap, PyRef, PyResult, PyValue,
|
||||
TryFromObject, TypeProtocol, VirtualMachine,
|
||||
TryFromObject, VirtualMachine,
|
||||
};
|
||||
use indexmap::IndexMap;
|
||||
use itertools::Itertools;
|
||||
@@ -187,9 +187,9 @@ impl FrameRef {
|
||||
if !code.varnames.is_empty() {
|
||||
let fastlocals = self.fastlocals.lock();
|
||||
for (k, v) in itertools::zip(&map[..j], &**fastlocals) {
|
||||
match locals.mapping().ass_subscript(k.as_object(), v.clone(), vm) {
|
||||
match locals.mapping().ass_subscript(k, v.clone(), vm) {
|
||||
Ok(()) => {}
|
||||
Err(e) if e.isinstance(&vm.ctx.exceptions.key_error) => {}
|
||||
Err(e) if e.fast_isinstance(&vm.ctx.exceptions.key_error) => {}
|
||||
Err(e) => return Err(e),
|
||||
}
|
||||
}
|
||||
@@ -198,13 +198,11 @@ impl FrameRef {
|
||||
let map_to_dict = |keys: &[PyStrRef], values: &[PyCellRef]| {
|
||||
for (k, v) in itertools::zip(keys, values) {
|
||||
if let Some(value) = v.get() {
|
||||
locals
|
||||
.mapping()
|
||||
.ass_subscript(k.as_object(), Some(value), vm)?;
|
||||
locals.mapping().ass_subscript(k, Some(value), vm)?;
|
||||
} else {
|
||||
match locals.mapping().ass_subscript(k.as_object(), None, vm) {
|
||||
match locals.mapping().ass_subscript(k, None, vm) {
|
||||
Ok(()) => {}
|
||||
Err(e) if e.isinstance(&vm.ctx.exceptions.key_error) => {}
|
||||
Err(e) if e.fast_isinstance(&vm.ctx.exceptions.key_error) => {}
|
||||
Err(e) => return Err(e),
|
||||
}
|
||||
}
|
||||
@@ -406,7 +404,7 @@ impl ExecutingFrame<'_> {
|
||||
return ret.map(ExecutionResult::Yield).or_else(|err| {
|
||||
self.pop_value();
|
||||
self.update_lasti(|i| *i += 1);
|
||||
if err.isinstance(&vm.ctx.exceptions.stop_iteration) {
|
||||
if err.fast_isinstance(&vm.ctx.exceptions.stop_iteration) {
|
||||
let val = vm.unwrap_or_none(err.get_arg(0));
|
||||
self.push_value(val);
|
||||
self.run(vm)
|
||||
@@ -498,7 +496,7 @@ impl ExecutingFrame<'_> {
|
||||
}
|
||||
bytecode::Instruction::LoadNameAny(idx) => {
|
||||
let name = &self.code.names[*idx as usize];
|
||||
let value = self.locals.mapping().subscript(name.as_object(), vm).ok();
|
||||
let value = self.locals.mapping().subscript(name, vm).ok();
|
||||
self.push_value(match value {
|
||||
Some(x) => x,
|
||||
None => self.load_global_or_builtin(name, vm)?,
|
||||
@@ -522,7 +520,7 @@ impl ExecutingFrame<'_> {
|
||||
bytecode::Instruction::LoadClassDeref(i) => {
|
||||
let i = *i as usize;
|
||||
let name = self.code.freevars[i - self.code.cellvars.len()].clone();
|
||||
let value = self.locals.mapping().subscript(name.as_object(), vm).ok();
|
||||
let value = self.locals.mapping().subscript(&name, vm).ok();
|
||||
self.push_value(match value {
|
||||
Some(v) => v,
|
||||
None => self.cells_frees[i]
|
||||
@@ -539,9 +537,7 @@ impl ExecutingFrame<'_> {
|
||||
bytecode::Instruction::StoreLocal(idx) => {
|
||||
let name = &self.code.names[*idx as usize];
|
||||
let value = self.pop_value();
|
||||
self.locals
|
||||
.mapping()
|
||||
.ass_subscript(name.as_object(), Some(value), vm)?;
|
||||
self.locals.mapping().ass_subscript(name, Some(value), vm)?;
|
||||
Ok(None)
|
||||
}
|
||||
bytecode::Instruction::StoreGlobal(idx) => {
|
||||
@@ -561,14 +557,11 @@ impl ExecutingFrame<'_> {
|
||||
}
|
||||
bytecode::Instruction::DeleteLocal(idx) => {
|
||||
let name = &self.code.names[*idx as usize];
|
||||
let res = self
|
||||
.locals
|
||||
.mapping()
|
||||
.ass_subscript(name.as_object(), None, vm);
|
||||
let res = self.locals.mapping().ass_subscript(name, None, vm);
|
||||
|
||||
match res {
|
||||
Ok(()) => {}
|
||||
Err(e) if e.isinstance(&vm.ctx.exceptions.key_error) => {
|
||||
Err(e) if e.fast_isinstance(&vm.ctx.exceptions.key_error) => {
|
||||
return Err(
|
||||
vm.new_name_error(format!("name '{}' is not defined", name), name)
|
||||
)
|
||||
@@ -581,7 +574,7 @@ impl ExecutingFrame<'_> {
|
||||
let name = &self.code.names[*idx as usize];
|
||||
match self.globals.del_item(name.clone(), vm) {
|
||||
Ok(()) => {}
|
||||
Err(e) if e.isinstance(&vm.ctx.exceptions.key_error) => {
|
||||
Err(e) if e.fast_isinstance(&vm.ctx.exceptions.key_error) => {
|
||||
return Err(
|
||||
vm.new_name_error(format!("name '{}' is not defined", name), name)
|
||||
)
|
||||
@@ -916,7 +909,7 @@ impl ExecutingFrame<'_> {
|
||||
bytecode::Instruction::EndAsyncFor => {
|
||||
let exc = self.pop_value();
|
||||
self.pop_value(); // async iterator we were calling __anext__ on
|
||||
if exc.isinstance(&vm.ctx.exceptions.stop_async_iteration) {
|
||||
if exc.fast_isinstance(&vm.ctx.exceptions.stop_async_iteration) {
|
||||
vm.take_exception().expect("Should have exception in stack");
|
||||
Ok(None)
|
||||
} else {
|
||||
@@ -1185,9 +1178,7 @@ impl ExecutingFrame<'_> {
|
||||
for (k, v) in dict {
|
||||
let k = PyStrRef::try_from_object(vm, k)?;
|
||||
if filter_pred(k.as_str()) {
|
||||
self.locals
|
||||
.mapping()
|
||||
.ass_subscript(k.as_object(), Some(v), vm)?;
|
||||
self.locals.mapping().ass_subscript(&k, Some(v), vm)?;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+2
-2
@@ -6,7 +6,7 @@ mod number;
|
||||
use crate::{
|
||||
builtins::{PyBaseExceptionRef, PyTupleRef, PyTypeRef},
|
||||
pyobject::PyThreadingConstraint,
|
||||
PyObject, PyObjectPayload, PyObjectRef, PyRef, PyResult, PyValue, TryFromObject, TypeProtocol,
|
||||
AsPyObject, PyObject, PyObjectPayload, PyObjectRef, PyRef, PyResult, PyValue, TryFromObject,
|
||||
VirtualMachine,
|
||||
};
|
||||
use indexmap::IndexMap;
|
||||
@@ -183,7 +183,7 @@ impl FuncArgs {
|
||||
) -> PyResult<Option<PyObjectRef>> {
|
||||
match self.get_optional_kwarg(key) {
|
||||
Some(kwarg) => {
|
||||
if kwarg.isinstance(&ty) {
|
||||
if kwarg.fast_isinstance(&ty) {
|
||||
Ok(Some(kwarg))
|
||||
} else {
|
||||
let expected_ty_name = &ty.name();
|
||||
|
||||
@@ -3,7 +3,7 @@ use crate::{
|
||||
builtins::{iter::PySequenceIterator, PyDict, PyDictRef},
|
||||
protocol::PyIter,
|
||||
protocol::{PyIterIter, PyMapping, PyMappingMethods},
|
||||
PyObject, PyObjectRef, PyObjectWrap, PyResult, PyValue, TryFromObject, TypeProtocol,
|
||||
AsPyObject, PyObject, PyObjectRef, PyObjectWrap, PyResult, PyValue, TryFromObject,
|
||||
VirtualMachine,
|
||||
};
|
||||
use std::{borrow::Borrow, marker::PhantomData};
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
use crate::{PyObjectRef, PyResult, TryFromObject, TypeProtocol, VirtualMachine};
|
||||
use crate::{AsPyObject, PyObjectRef, PyResult, TryFromObject, VirtualMachine};
|
||||
use num_complex::Complex64;
|
||||
|
||||
/// A Python complex-like object.
|
||||
|
||||
+2
-2
@@ -8,7 +8,7 @@ use crate::{
|
||||
scope::Scope,
|
||||
version::get_git_revision,
|
||||
vm::{InitParameter, VirtualMachine},
|
||||
PyObjectRef, PyRef, PyResult, PyValue, TryFromObject, TypeProtocol,
|
||||
AsPyObject, PyObjectRef, PyRef, PyResult, PyValue, TryFromObject,
|
||||
};
|
||||
use rand::Rng;
|
||||
|
||||
@@ -189,7 +189,7 @@ pub fn remove_importlib_frames(
|
||||
vm: &VirtualMachine,
|
||||
exc: &PyBaseExceptionRef,
|
||||
) -> PyBaseExceptionRef {
|
||||
let always_trim = exc.isinstance(&vm.ctx.exceptions.import_error);
|
||||
let always_trim = exc.fast_isinstance(&vm.ctx.exceptions.import_error);
|
||||
|
||||
if let Some(tb) = exc.traceback() {
|
||||
let trimmed_tb = remove_importlib_frames_inner(vm, Some(tb), always_trim).0;
|
||||
|
||||
+3
-5
@@ -89,13 +89,11 @@ mod pyobject {
|
||||
pub use self::convert::{TryFromBorrowedObject, TryFromObject};
|
||||
// pyobject items
|
||||
pub use self::pyobject::{
|
||||
PyContext, PyMethod, PyObjectPayload, PyObjectWrap, PyRefExact, PyResult, PyStructSequence,
|
||||
PyValue, TypeProtocol,
|
||||
AsPyObject, PyContext, PyMethod, PyObjectPayload, PyObjectWrap, PyRefExact, PyResult,
|
||||
PyStructSequence, PyValue,
|
||||
};
|
||||
// pyobjectrc items
|
||||
pub use self::pyobject::{
|
||||
AsPyObject, PyObject, PyObjectRef, PyObjectView, PyObjectWeak, PyRef, PyWeakRef,
|
||||
};
|
||||
pub use self::pyobject::{PyObject, PyObjectRef, PyObjectView, PyObjectWeak, PyRef, PyWeakRef};
|
||||
pub use self::vm::{InitParameter, Interpreter, PySettings, VirtualMachine};
|
||||
pub use rustpython_bytecode as bytecode;
|
||||
pub use rustpython_common as common;
|
||||
|
||||
@@ -8,8 +8,8 @@ use crate::{
|
||||
},
|
||||
sliceable::wrap_index,
|
||||
types::{Constructor, Unconstructible},
|
||||
PyObject, PyObjectPayload, PyObjectRef, PyObjectView, PyObjectWrap, PyRef, PyResult, PyValue,
|
||||
TryFromBorrowedObject, TypeProtocol, VirtualMachine,
|
||||
AsPyObject, PyObject, PyObjectPayload, PyObjectRef, PyObjectView, PyObjectWrap, PyRef,
|
||||
PyResult, PyValue, TryFromBorrowedObject, VirtualMachine,
|
||||
};
|
||||
use itertools::Itertools;
|
||||
use std::{borrow::Cow, fmt::Debug, ops::Range};
|
||||
|
||||
@@ -2,7 +2,7 @@ use crate::{
|
||||
builtins::iter::PySequenceIterator,
|
||||
function::{IntoPyObject, IntoPyResult},
|
||||
AsPyObject, PyObject, PyObjectRef, PyObjectWrap, PyResult, PyValue, TryFromObject,
|
||||
TypeProtocol, VirtualMachine,
|
||||
VirtualMachine,
|
||||
};
|
||||
use std::borrow::Borrow;
|
||||
use std::ops::Deref;
|
||||
@@ -154,7 +154,7 @@ impl PyIterReturn {
|
||||
pub fn from_pyresult(result: PyResult, vm: &VirtualMachine) -> PyResult<Self> {
|
||||
match result {
|
||||
Ok(obj) => Ok(Self::Return(obj)),
|
||||
Err(err) if err.isinstance(&vm.ctx.exceptions.stop_iteration) => {
|
||||
Err(err) if err.fast_isinstance(&vm.ctx.exceptions.stop_iteration) => {
|
||||
let args = err.get_arg(0);
|
||||
Ok(Self::StopIteration(args))
|
||||
}
|
||||
@@ -165,10 +165,10 @@ impl PyIterReturn {
|
||||
pub fn from_getitem_result(result: PyResult, vm: &VirtualMachine) -> PyResult<Self> {
|
||||
match result {
|
||||
Ok(obj) => Ok(Self::Return(obj)),
|
||||
Err(err) if err.isinstance(&vm.ctx.exceptions.index_error) => {
|
||||
Err(err) if err.fast_isinstance(&vm.ctx.exceptions.index_error) => {
|
||||
Ok(Self::StopIteration(None))
|
||||
}
|
||||
Err(err) if err.isinstance(&vm.ctx.exceptions.stop_iteration) => {
|
||||
Err(err) if err.fast_isinstance(&vm.ctx.exceptions.stop_iteration) => {
|
||||
let args = err.get_arg(0);
|
||||
Ok(Self::StopIteration(args))
|
||||
}
|
||||
|
||||
@@ -5,7 +5,7 @@ use crate::{
|
||||
},
|
||||
common::lock::OnceCell,
|
||||
function::IntoPyResult,
|
||||
AsPyObject, PyObject, PyObjectRef, PyResult, TypeProtocol, VirtualMachine,
|
||||
AsPyObject, PyObject, PyObjectRef, PyResult, VirtualMachine,
|
||||
};
|
||||
|
||||
// Mapping protocol
|
||||
@@ -91,7 +91,20 @@ impl PyMapping<'_> {
|
||||
})?
|
||||
}
|
||||
|
||||
pub fn subscript(&self, needle: &PyObject, vm: &VirtualMachine) -> PyResult {
|
||||
pub fn subscript(&self, needle: &impl AsPyObject, vm: &VirtualMachine) -> PyResult {
|
||||
self._subscript(needle.as_object(), vm)
|
||||
}
|
||||
|
||||
pub fn ass_subscript(
|
||||
&self,
|
||||
needle: &impl AsPyObject,
|
||||
value: Option<PyObjectRef>,
|
||||
vm: &VirtualMachine,
|
||||
) -> PyResult<()> {
|
||||
self._ass_subscript(needle.as_object(), value, vm)
|
||||
}
|
||||
|
||||
fn _subscript(&self, needle: &PyObject, vm: &VirtualMachine) -> PyResult {
|
||||
let f = self
|
||||
.methods(vm)
|
||||
.subscript
|
||||
@@ -99,7 +112,7 @@ impl PyMapping<'_> {
|
||||
f(self, needle, vm)
|
||||
}
|
||||
|
||||
pub fn ass_subscript(
|
||||
fn _ass_subscript(
|
||||
&self,
|
||||
needle: &PyObject,
|
||||
value: Option<PyObjectRef>,
|
||||
|
||||
@@ -13,7 +13,7 @@ use crate::{
|
||||
protocol::{PyIter, PyMapping, PySequence},
|
||||
types::{Constructor, PyComparisonOp},
|
||||
utils::Either,
|
||||
AsPyObject, PyObject, PyObjectRef, PyResult, TryFromObject, TypeProtocol, VirtualMachine,
|
||||
AsPyObject, PyObject, PyObjectRef, PyResult, TryFromObject, VirtualMachine,
|
||||
};
|
||||
|
||||
// RustPython doesn't need these items
|
||||
@@ -52,7 +52,7 @@ impl PyObjectRef {
|
||||
pub fn bytes(self, vm: &VirtualMachine) -> PyResult {
|
||||
let bytes_type = &vm.ctx.types.bytes_type;
|
||||
match self.downcast_exact::<PyInt>(vm) {
|
||||
Ok(int) => Err(vm.new_downcast_type_error(bytes_type, int.as_object())),
|
||||
Ok(int) => Err(vm.new_downcast_type_error(bytes_type, &int)),
|
||||
Err(obj) => PyBytes::py_new(
|
||||
bytes_type.clone(),
|
||||
ByteInnerNewOptions {
|
||||
@@ -162,7 +162,7 @@ impl PyObject {
|
||||
let is_strict_subclass = {
|
||||
let self_class = self.class();
|
||||
let other_class = other.class();
|
||||
!self_class.is(&other_class) && other_class.issubclass(&self_class)
|
||||
!self_class.is(&other_class) && other_class.fast_issubclass(&self_class)
|
||||
};
|
||||
if is_strict_subclass {
|
||||
let res = vm.with_recursion("in comparison", || call_cmp(other, self, swapped))?;
|
||||
@@ -278,7 +278,7 @@ impl PyObject {
|
||||
PyTypeRef::try_from_object(vm, self.to_owned()),
|
||||
PyTypeRef::try_from_object(vm, cls.to_owned()),
|
||||
) {
|
||||
Ok(obj.issubclass(&cls))
|
||||
Ok(obj.fast_issubclass(&cls))
|
||||
} else {
|
||||
self.check_cls(self, vm, || {
|
||||
format!("issubclass() arg 1 must be a class, not {}", self.class())
|
||||
@@ -324,7 +324,7 @@ impl PyObject {
|
||||
|
||||
fn abstract_isinstance(&self, cls: &PyObject, vm: &VirtualMachine) -> PyResult<bool> {
|
||||
if let Ok(typ) = PyTypeRef::try_from_object(vm, cls.to_owned()) {
|
||||
if self.class().issubclass(&typ) {
|
||||
if self.class().fast_issubclass(&typ) {
|
||||
Ok(true)
|
||||
} else if let Ok(icls) =
|
||||
PyTypeRef::try_from_object(vm, self.to_owned().get_attr("__class__", vm)?)
|
||||
@@ -332,7 +332,7 @@ impl PyObject {
|
||||
if icls.is(&self.class()) {
|
||||
Ok(false)
|
||||
} else {
|
||||
Ok(icls.issubclass(&typ))
|
||||
Ok(icls.fast_issubclass(&typ))
|
||||
}
|
||||
} else {
|
||||
Ok(false)
|
||||
@@ -428,9 +428,9 @@ impl PyObject {
|
||||
let i = needle.key_as_isize(vm)?;
|
||||
seq.get_item(i, vm)
|
||||
} else {
|
||||
if self.class().issubclass(&vm.ctx.types.type_type) {
|
||||
if self.class().fast_issubclass(&vm.ctx.types.type_type) {
|
||||
if self.is(&vm.ctx.types.type_type) {
|
||||
return PyGenericAlias::new(self.clone_class(), needle, vm).into_pyresult(vm);
|
||||
return PyGenericAlias::new(self.class().clone(), needle, vm).into_pyresult(vm);
|
||||
}
|
||||
|
||||
if let Some(class_getitem) =
|
||||
|
||||
@@ -3,7 +3,7 @@ use crate::{
|
||||
common::lock::OnceCell,
|
||||
function::{IntoPyObject, PyArithmeticValue},
|
||||
protocol::PyMapping,
|
||||
AsPyObject, PyObject, PyObjectRef, PyResult, PyValue, TypeProtocol, VirtualMachine,
|
||||
AsPyObject, PyObject, PyObjectRef, PyResult, PyValue, VirtualMachine,
|
||||
};
|
||||
use itertools::Itertools;
|
||||
use std::{
|
||||
|
||||
+5
-5
@@ -4,7 +4,7 @@ use serde::de::{DeserializeSeed, Visitor};
|
||||
use serde::ser::{Serialize, SerializeMap, SerializeSeq};
|
||||
|
||||
use crate::builtins::{dict::PyDictRef, float, int, list::PyList, pybool, tuple::PyTuple, PyStr};
|
||||
use crate::{PyObject, PyObjectRef, TypeProtocol, VirtualMachine};
|
||||
use crate::{AsPyObject, PyObject, PyObjectRef, VirtualMachine};
|
||||
|
||||
#[inline]
|
||||
pub fn serialize<S>(
|
||||
@@ -64,11 +64,11 @@ impl<'s> serde::Serialize for PyObjectSerializer<'s> {
|
||||
};
|
||||
if let Some(s) = self.pyobject.payload::<PyStr>() {
|
||||
serializer.serialize_str(s.as_ref())
|
||||
} else if self.pyobject.isinstance(&self.vm.ctx.types.float_type) {
|
||||
} else if self.pyobject.fast_isinstance(&self.vm.ctx.types.float_type) {
|
||||
serializer.serialize_f64(float::get_value(self.pyobject))
|
||||
} else if self.pyobject.isinstance(&self.vm.ctx.types.bool_type) {
|
||||
} else if self.pyobject.fast_isinstance(&self.vm.ctx.types.bool_type) {
|
||||
serializer.serialize_bool(pybool::get_value(self.pyobject))
|
||||
} else if self.pyobject.isinstance(&self.vm.ctx.types.int_type) {
|
||||
} else if self.pyobject.fast_isinstance(&self.vm.ctx.types.int_type) {
|
||||
let v = int::get_value(self.pyobject);
|
||||
let int_too_large = || serde::ser::Error::custom("int too large to serialize");
|
||||
// TODO: serialize BigInt when it does not fit into i64
|
||||
@@ -84,7 +84,7 @@ impl<'s> serde::Serialize for PyObjectSerializer<'s> {
|
||||
serialize_seq_elements(serializer, &list.borrow_vec())
|
||||
} else if let Some(tuple) = self.pyobject.payload_if_subclass::<PyTuple>(self.vm) {
|
||||
serialize_seq_elements(serializer, tuple.as_slice())
|
||||
} else if self.pyobject.isinstance(&self.vm.ctx.types.dict_type) {
|
||||
} else if self.pyobject.fast_isinstance(&self.vm.ctx.types.dict_type) {
|
||||
let dict: PyDictRef = self.pyobject.to_owned().downcast().unwrap();
|
||||
let pairs: Vec<_> = dict.into_iter().collect();
|
||||
let mut map = serializer.serialize_map(Some(pairs.len()))?;
|
||||
|
||||
+32
-64
@@ -366,9 +366,9 @@ impl<T: PyValue> TryFromObject for PyRefExact<T> {
|
||||
drop(cls);
|
||||
let obj = obj
|
||||
.downcast()
|
||||
.map_err(|obj| vm.new_downcast_runtime_error(target_cls, obj))?;
|
||||
.map_err(|obj| vm.new_downcast_runtime_error(target_cls, &obj))?;
|
||||
Ok(Self { obj })
|
||||
} else if cls.issubclass(target_cls) {
|
||||
} else if cls.fast_issubclass(target_cls) {
|
||||
Err(vm.new_type_error(format!(
|
||||
"Expected an exact instance of '{}', not a subclass '{}'",
|
||||
target_cls.name(),
|
||||
@@ -405,10 +405,12 @@ where
|
||||
fn as_object(&self) -> &PyObject {
|
||||
self.borrow()
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
fn get_id(&self) -> usize {
|
||||
self.as_object()._get_id()
|
||||
self.as_object().unique_id()
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
fn is<T>(&self, other: &T) -> bool
|
||||
where
|
||||
@@ -416,15 +418,38 @@ where
|
||||
{
|
||||
self.get_id() == other.get_id()
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
fn class(&self) -> PyLease<'_, PyType> {
|
||||
self.as_object().lease_class()
|
||||
}
|
||||
|
||||
fn get_class_attr(&self, attr_name: &str) -> Option<PyObjectRef> {
|
||||
self.class().get_attr(attr_name)
|
||||
}
|
||||
|
||||
/// Determines if `obj` actually an instance of `cls`, this doesn't call __instancecheck__, so only
|
||||
/// use this if `cls` is known to have not overridden the base __instancecheck__ magic method.
|
||||
#[inline]
|
||||
fn fast_isinstance(&self, cls: &PyObjectView<PyType>) -> bool {
|
||||
self.class().fast_issubclass(cls)
|
||||
}
|
||||
}
|
||||
|
||||
impl<T> AsPyObject for T where T: Borrow<PyObject> {}
|
||||
|
||||
impl PyObject {
|
||||
#[inline]
|
||||
fn _get_id(&self) -> usize {
|
||||
#[inline(always)]
|
||||
fn unique_id(&self) -> usize {
|
||||
self as *const PyObject as usize
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn lease_class(&self) -> PyLease<'_, PyType> {
|
||||
PyLease {
|
||||
inner: self.class_lock().read(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// impl<T: ?Sized> Borrow<PyObject> for PyRc<T> {
|
||||
@@ -473,63 +498,6 @@ where
|
||||
}
|
||||
}
|
||||
|
||||
pub trait TypeProtocol {
|
||||
fn class(&self) -> PyLease<'_, PyType>;
|
||||
|
||||
fn clone_class(&self) -> PyTypeRef {
|
||||
PyLease::into_pyref(self.class())
|
||||
}
|
||||
|
||||
fn get_class_attr(&self, attr_name: &str) -> Option<PyObjectRef> {
|
||||
self.class().get_attr(attr_name)
|
||||
}
|
||||
|
||||
fn has_class_attr(&self, attr_name: &str) -> bool {
|
||||
self.class().has_attr(attr_name)
|
||||
}
|
||||
|
||||
/// Determines if `obj` actually an instance of `cls`, this doesn't call __instancecheck__, so only
|
||||
/// use this if `cls` is known to have not overridden the base __instancecheck__ magic method.
|
||||
#[inline]
|
||||
fn isinstance(&self, cls: &PyObjectView<PyType>) -> bool {
|
||||
self.class().issubclass(cls)
|
||||
}
|
||||
}
|
||||
|
||||
impl TypeProtocol for PyObjectRef {
|
||||
fn class(&self) -> PyLease<'_, PyType> {
|
||||
PyLease {
|
||||
inner: self.class_lock().read(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl TypeProtocol for PyObject {
|
||||
fn class(&self) -> PyLease<'_, PyType> {
|
||||
PyLease {
|
||||
inner: self.class_lock().read(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: PyObjectPayload> TypeProtocol for PyObjectView<T> {
|
||||
fn class(&self) -> PyLease<'_, PyType> {
|
||||
self.as_object().class()
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: PyObjectPayload> TypeProtocol for PyRef<T> {
|
||||
fn class(&self) -> PyLease<'_, PyType> {
|
||||
self.as_object().class()
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: TypeProtocol> TypeProtocol for &'_ T {
|
||||
fn class(&self) -> PyLease<'_, PyType> {
|
||||
(&**self).class()
|
||||
}
|
||||
}
|
||||
|
||||
impl<T, P> IntoPyRef<P> for T
|
||||
where
|
||||
P: PyValue + IntoPyObject + From<T>,
|
||||
@@ -648,7 +616,7 @@ pub trait PyValue: fmt::Debug + PyThreadingConstraint + Sized + 'static {
|
||||
#[inline]
|
||||
fn into_ref_with_type(self, vm: &VirtualMachine, cls: PyTypeRef) -> PyResult<PyRef<Self>> {
|
||||
let exact_class = Self::class(vm);
|
||||
if cls.issubclass(exact_class) {
|
||||
if cls.fast_issubclass(exact_class) {
|
||||
Ok(self._into_ref(cls, vm))
|
||||
} else {
|
||||
Err(Self::_into_ref_with_type_error(vm, &cls, exact_class))
|
||||
@@ -707,7 +675,7 @@ pub trait PyStructSequence: StaticType + PyClassImpl + Sized + 'static {
|
||||
#[pymethod(magic)]
|
||||
fn reduce(zelf: PyRef<PyTuple>, vm: &VirtualMachine) -> PyTupleRef {
|
||||
vm.new_tuple((
|
||||
zelf.clone_class(),
|
||||
zelf.class().clone(),
|
||||
(vm.ctx.new_tuple(zelf.as_slice().to_vec()),),
|
||||
))
|
||||
}
|
||||
|
||||
@@ -3,7 +3,7 @@ use crate::common::linked_list::{Link, LinkedList, Pointers};
|
||||
use crate::common::lock::{PyMutex, PyMutexGuard, PyRwLock};
|
||||
use crate::common::refcount::RefCount;
|
||||
use crate::{
|
||||
_pyobject::{AsPyObject, PyObjectPayload, PyObjectWrap, PyResult, TypeProtocol},
|
||||
_pyobject::{AsPyObject, PyObjectPayload, PyObjectWrap, PyResult},
|
||||
builtins::{PyBaseExceptionRef, PyDictRef, PyTypeRef},
|
||||
vm::VirtualMachine,
|
||||
};
|
||||
@@ -664,7 +664,7 @@ impl PyObject {
|
||||
|
||||
#[inline(always)]
|
||||
pub fn payload_if_subclass<T: crate::PyValue>(&self, vm: &VirtualMachine) -> Option<&T> {
|
||||
if self.class().issubclass(T::class(vm)) {
|
||||
if self.class().fast_issubclass(T::class(vm)) {
|
||||
self.payload()
|
||||
} else {
|
||||
None
|
||||
|
||||
+3
-2
@@ -3,7 +3,7 @@ use crate::{
|
||||
types::{richcompare_wrapper, PyComparisonOp, RichCompareFunc},
|
||||
utils::Either,
|
||||
vm::VirtualMachine,
|
||||
AsPyObject, PyObject, PyObjectRef, PyResult, TypeProtocol,
|
||||
AsPyObject, PyObject, PyObjectRef, PyResult,
|
||||
};
|
||||
use itertools::Itertools;
|
||||
use optional::Optioned;
|
||||
@@ -143,7 +143,8 @@ pub trait MutObjectSequenceOp<'a> {
|
||||
borrower = Some(guard);
|
||||
} else {
|
||||
let elem_cls = elem.class();
|
||||
let reverse_first = !elem_cls.is(&needle_cls) && elem_cls.issubclass(&needle_cls);
|
||||
let reverse_first =
|
||||
!elem_cls.is(&needle_cls) && elem_cls.fast_issubclass(&needle_cls);
|
||||
|
||||
let eq = if reverse_first {
|
||||
let elem_cmp = elem_cls
|
||||
|
||||
+1
-1
@@ -7,7 +7,7 @@ use crate::{
|
||||
int::PyInt,
|
||||
slice::{PySlice, SaturatedSliceIter},
|
||||
},
|
||||
PyObject, PyResult, TryFromBorrowedObject, TypeProtocol, VirtualMachine,
|
||||
AsPyObject, PyObject, PyResult, TryFromBorrowedObject, VirtualMachine,
|
||||
};
|
||||
|
||||
pub trait SliceableSequenceMutOp {
|
||||
|
||||
@@ -8,8 +8,7 @@ mod gen;
|
||||
use crate::{
|
||||
builtins::{self, PyStrRef, PyTypeRef},
|
||||
pyclass::{PyClassImpl, StaticType},
|
||||
AsPyObject, PyContext, PyObject, PyObjectRef, PyResult, PyValue, TryFromObject, TypeProtocol,
|
||||
VirtualMachine,
|
||||
AsPyObject, PyContext, PyObject, PyObjectRef, PyResult, PyValue, TryFromObject, VirtualMachine,
|
||||
};
|
||||
use num_complex::Complex64;
|
||||
use num_traits::{ToPrimitive, Zero};
|
||||
@@ -22,7 +21,7 @@ use rustpython_parser::parser;
|
||||
#[pymodule]
|
||||
mod _ast {
|
||||
use crate::{
|
||||
builtins::PyStrRef, function::FuncArgs, PyObjectRef, PyResult, PyValue, TypeProtocol,
|
||||
builtins::PyStrRef, function::FuncArgs, AsPyObject, PyObjectRef, PyResult, PyValue,
|
||||
VirtualMachine,
|
||||
};
|
||||
#[pyattr]
|
||||
@@ -34,7 +33,7 @@ mod _ast {
|
||||
impl AstNode {
|
||||
#[pymethod(magic)]
|
||||
fn init(zelf: PyObjectRef, args: FuncArgs, vm: &VirtualMachine) -> PyResult<()> {
|
||||
let obj: PyObjectRef = zelf.clone_class().into();
|
||||
let obj: PyObjectRef = zelf.class().clone().into();
|
||||
let fields = obj.get_attr("_fields", vm)?;
|
||||
let fields: Vec<PyStrRef> = fields.try_to_value(vm)?;
|
||||
let numargs = args.args.len();
|
||||
|
||||
@@ -3,7 +3,7 @@ pub(crate) use atexit::make_module;
|
||||
|
||||
#[pymodule]
|
||||
mod atexit {
|
||||
use crate::{function::FuncArgs, PyObjectRef, PyResult, TypeProtocol, VirtualMachine};
|
||||
use crate::{function::FuncArgs, AsPyObject, PyObjectRef, PyResult, VirtualMachine};
|
||||
|
||||
#[pyfunction]
|
||||
fn register(func: PyObjectRef, args: FuncArgs, vm: &VirtualMachine) -> PyObjectRef {
|
||||
@@ -38,7 +38,7 @@ mod atexit {
|
||||
for (func, args) in vm.state.atexit_funcs.lock().drain(..).rev() {
|
||||
if let Err(e) = vm.invoke(&func, args) {
|
||||
last_exc = Some(e.clone());
|
||||
if !e.isinstance(&vm.ctx.exceptions.system_exit) {
|
||||
if !e.fast_isinstance(&vm.ctx.exceptions.system_exit) {
|
||||
writeln!(
|
||||
crate::stdlib::sys::PyStderr(vm),
|
||||
"Error in atexit._run_exitfuncs:"
|
||||
|
||||
@@ -34,7 +34,7 @@ mod builtins {
|
||||
types::PyComparisonOp,
|
||||
utils::Either,
|
||||
AsPyObject, PyObject, PyObjectRef, PyObjectWrap, PyRef, PyResult, PyValue, TryFromObject,
|
||||
TypeProtocol, VirtualMachine,
|
||||
VirtualMachine,
|
||||
};
|
||||
use num_traits::{Signed, ToPrimitive, Zero};
|
||||
|
||||
@@ -126,7 +126,10 @@ mod builtins {
|
||||
|
||||
let mode_str = args.mode.as_str();
|
||||
|
||||
if args.source.isinstance(&ast::AstNode::make_class(&vm.ctx)) {
|
||||
if args
|
||||
.source
|
||||
.fast_isinstance(&ast::AstNode::make_class(&vm.ctx))
|
||||
{
|
||||
#[cfg(not(feature = "rustpython-compiler"))]
|
||||
{
|
||||
return Err(vm.new_value_error("can't compile ast nodes when the `compiler` feature of rustpython is disabled"));
|
||||
@@ -809,7 +812,7 @@ mod builtins {
|
||||
let mut new_bases: Option<Vec<PyObjectRef>> = None;
|
||||
let bases = PyTuple::new_ref(bases.into_vec(), &vm.ctx);
|
||||
for (i, base) in bases.as_slice().iter().enumerate() {
|
||||
if base.isinstance(&vm.ctx.types.type_type) {
|
||||
if base.fast_isinstance(&vm.ctx.types.type_type) {
|
||||
if let Some(bases) = &mut new_bases {
|
||||
bases.push(base.clone());
|
||||
}
|
||||
@@ -848,9 +851,9 @@ mod builtins {
|
||||
Ok(mut metaclass) => {
|
||||
for base in bases.as_slice().iter() {
|
||||
let base_class = base.class();
|
||||
if base_class.issubclass(&metaclass) {
|
||||
metaclass = base.clone_class();
|
||||
} else if !metaclass.issubclass(&base_class) {
|
||||
if base_class.fast_issubclass(&metaclass) {
|
||||
metaclass = base.class().clone();
|
||||
} else if !metaclass.fast_issubclass(&base_class) {
|
||||
return Err(vm.new_type_error(
|
||||
"metaclass conflict: the metaclass of a derived class must be a (non-strict) \
|
||||
subclass of the metaclasses of all its bases"
|
||||
|
||||
@@ -19,7 +19,7 @@ mod _collections {
|
||||
},
|
||||
utils::collection_repr,
|
||||
vm::ReprGuard,
|
||||
AsPyObject, PyObject, PyObjectRef, PyRef, PyResult, PyValue, TypeProtocol, VirtualMachine,
|
||||
AsPyObject, PyObject, PyObjectRef, PyRef, PyResult, PyValue, VirtualMachine,
|
||||
};
|
||||
use crossbeam_utils::atomic::AtomicCell;
|
||||
use std::cmp::max;
|
||||
@@ -155,7 +155,7 @@ mod _collections {
|
||||
maxlen: zelf.maxlen,
|
||||
state: AtomicCell::new(zelf.state.load()),
|
||||
}
|
||||
.into_ref_with_type(vm, zelf.clone_class())
|
||||
.into_ref_with_type(vm, zelf.class().clone())
|
||||
}
|
||||
|
||||
#[pymethod]
|
||||
@@ -480,7 +480,7 @@ mod _collections {
|
||||
|
||||
#[pymethod(magic)]
|
||||
fn reduce(zelf: PyRef<Self>, vm: &VirtualMachine) -> PyResult {
|
||||
let cls = zelf.clone_class();
|
||||
let cls = zelf.class().clone();
|
||||
let value = match zelf.maxlen {
|
||||
Some(v) => vm.new_pyobj((vm.ctx.empty_tuple.clone(), v)),
|
||||
None => vm.ctx.empty_tuple.clone().into(),
|
||||
@@ -634,7 +634,7 @@ mod _collections {
|
||||
Exhausted => PyDeque::default().into_ref(vm),
|
||||
};
|
||||
(
|
||||
zelf.clone_class(),
|
||||
zelf.class().clone(),
|
||||
(deque, vm.ctx.new_int(internal.position).into()),
|
||||
)
|
||||
}
|
||||
@@ -700,7 +700,7 @@ mod _collections {
|
||||
Exhausted => PyDeque::default().into_ref(vm),
|
||||
};
|
||||
Ok((
|
||||
zelf.clone_class(),
|
||||
zelf.class().clone(),
|
||||
(deque, vm.ctx.new_int(internal.position).into()),
|
||||
))
|
||||
}
|
||||
|
||||
+8
-9
@@ -89,7 +89,7 @@ mod _io {
|
||||
utils::Either,
|
||||
vm::{ReprGuard, VirtualMachine},
|
||||
AsPyObject, PyContext, PyObject, PyObjectRef, PyObjectWrap, PyRef, PyResult, PyValue,
|
||||
TryFromBorrowedObject, TryFromObject, TypeProtocol,
|
||||
TryFromBorrowedObject, TryFromObject,
|
||||
};
|
||||
use bstr::ByteSlice;
|
||||
use crossbeam_utils::atomic::AtomicCell;
|
||||
@@ -1310,8 +1310,8 @@ mod _io {
|
||||
let name = match obj.to_owned().get_attr("name", vm) {
|
||||
Ok(name) => Some(name),
|
||||
Err(e)
|
||||
if e.isinstance(&vm.ctx.exceptions.attribute_error)
|
||||
|| e.isinstance(&vm.ctx.exceptions.value_error) =>
|
||||
if e.fast_isinstance(&vm.ctx.exceptions.attribute_error)
|
||||
|| e.fast_isinstance(&vm.ctx.exceptions.value_error) =>
|
||||
{
|
||||
None
|
||||
}
|
||||
@@ -3524,7 +3524,7 @@ mod _io {
|
||||
)
|
||||
})?;
|
||||
let raw = vm.invoke(
|
||||
file_io_class.as_object(),
|
||||
file_io_class,
|
||||
(file, mode.rawmode(), opts.closefd, opts.opener),
|
||||
)?;
|
||||
|
||||
@@ -3558,13 +3558,13 @@ mod _io {
|
||||
} else {
|
||||
BufferedWriter::static_type()
|
||||
};
|
||||
let buffered = vm.invoke(cls.as_object(), (raw, buffering))?;
|
||||
let buffered = vm.invoke(cls, (raw, buffering))?;
|
||||
|
||||
match mode.encode {
|
||||
EncodeMode::Text => {
|
||||
let tio = TextIOWrapper::static_type();
|
||||
let wrapper = vm.invoke(
|
||||
tio.as_object(),
|
||||
tio,
|
||||
(
|
||||
buffered,
|
||||
opts.encoding,
|
||||
@@ -3661,8 +3661,7 @@ mod fileio {
|
||||
ArgBytesLike, ArgMemoryBuffer, FuncArgs, IntoPyException, OptionalArg, OptionalOption,
|
||||
},
|
||||
stdlib::os,
|
||||
AsPyObject, PyObjectRef, PyRef, PyResult, PyValue, TryFromObject, TypeProtocol,
|
||||
VirtualMachine,
|
||||
AsPyObject, PyObjectRef, PyRef, PyResult, PyValue, TryFromObject, VirtualMachine,
|
||||
};
|
||||
use crossbeam_utils::atomic::AtomicCell;
|
||||
use std::io::{Read, Write};
|
||||
@@ -3811,7 +3810,7 @@ mod fileio {
|
||||
zelf.mode.store(mode);
|
||||
let fd = if let Some(opener) = args.opener {
|
||||
let fd = vm.invoke(&opener, (name.clone(), flags))?;
|
||||
if !fd.isinstance(&vm.ctx.types.int_type) {
|
||||
if !fd.fast_isinstance(&vm.ctx.types.int_type) {
|
||||
return Err(vm.new_type_error("expected integer from opener".to_owned()));
|
||||
}
|
||||
let fd = i32::try_from_object(vm, fd)?;
|
||||
|
||||
@@ -12,8 +12,7 @@ mod decl {
|
||||
protocol::{PyIter, PyIterReturn},
|
||||
stdlib::sys,
|
||||
types::{Constructor, IterNext, IterNextIterable},
|
||||
AsPyObject, PyObjectRef, PyObjectView, PyRef, PyResult, PyValue, PyWeakRef, TypeProtocol,
|
||||
VirtualMachine,
|
||||
AsPyObject, PyObjectRef, PyObjectView, PyRef, PyResult, PyValue, PyWeakRef, VirtualMachine,
|
||||
};
|
||||
use crossbeam_utils::atomic::AtomicCell;
|
||||
use num_bigint::BigInt;
|
||||
@@ -298,7 +297,7 @@ mod decl {
|
||||
|
||||
#[pymethod(magic)]
|
||||
fn reduce(zelf: PyRef<Self>, vm: &VirtualMachine) -> PyResult<PyTupleRef> {
|
||||
let cls = zelf.clone_class().into_pyobject(vm);
|
||||
let cls = zelf.class().clone();
|
||||
Ok(match zelf.times {
|
||||
Some(ref times) => vm.new_tuple((cls, (zelf.object.clone(), *times.read()))),
|
||||
None => vm.new_tuple((cls, (zelf.object.clone(),))),
|
||||
@@ -707,7 +706,7 @@ mod decl {
|
||||
name: &'static str,
|
||||
vm: &VirtualMachine,
|
||||
) -> PyResult<usize> {
|
||||
let is_int = obj.isinstance(&vm.ctx.types.int_type);
|
||||
let is_int = obj.fast_isinstance(&vm.ctx.types.int_type);
|
||||
if is_int {
|
||||
let value = int::get_value(&obj).to_usize();
|
||||
if let Some(value) = value {
|
||||
|
||||
@@ -10,7 +10,7 @@ mod decl {
|
||||
bytecode,
|
||||
function::{ArgBytesLike, IntoPyObject},
|
||||
protocol::PyBuffer,
|
||||
pyobject::{AsPyObject, TypeProtocol},
|
||||
pyobject::AsPyObject,
|
||||
PyObjectRef, PyResult, TryFromObject, VirtualMachine,
|
||||
};
|
||||
/// TODO
|
||||
|
||||
+11
-15
@@ -20,8 +20,7 @@ mod _operator {
|
||||
},
|
||||
utils::Either,
|
||||
vm::ReprGuard,
|
||||
AsPyObject, PyObjectRef, PyObjectView, PyRef, PyResult, PyValue, TypeProtocol,
|
||||
VirtualMachine,
|
||||
AsPyObject, PyObjectRef, PyObjectView, PyRef, PyResult, PyValue, VirtualMachine,
|
||||
};
|
||||
|
||||
/// Same as a < b.
|
||||
@@ -200,7 +199,7 @@ mod _operator {
|
||||
#[pyfunction]
|
||||
fn concat(a: PyObjectRef, b: PyObjectRef, vm: &VirtualMachine) -> PyResult {
|
||||
// Best attempt at checking that a is sequence-like.
|
||||
if !a.class().has_attr("__getitem__") || a.isinstance(&vm.ctx.types.dict_type) {
|
||||
if !a.class().has_attr("__getitem__") || a.fast_isinstance(&vm.ctx.types.dict_type) {
|
||||
return Err(
|
||||
vm.new_type_error(format!("{} object can't be concatenated", a.class().name()))
|
||||
);
|
||||
@@ -273,7 +272,7 @@ mod _operator {
|
||||
fn length_hint(obj: PyObjectRef, default: OptionalArg, vm: &VirtualMachine) -> PyResult<usize> {
|
||||
let default: usize = default
|
||||
.map(|v| {
|
||||
if !v.isinstance(&vm.ctx.types.int_type) {
|
||||
if !v.fast_isinstance(&vm.ctx.types.int_type) {
|
||||
return Err(vm.new_type_error(format!(
|
||||
"'{}' type cannot be interpreted as an integer",
|
||||
v.class().name()
|
||||
@@ -303,7 +302,7 @@ mod _operator {
|
||||
#[pyfunction]
|
||||
fn iconcat(a: PyObjectRef, b: PyObjectRef, vm: &VirtualMachine) -> PyResult {
|
||||
// Best attempt at checking that a is sequence-like.
|
||||
if !a.class().has_attr("__getitem__") || a.isinstance(&vm.ctx.types.dict_type) {
|
||||
if !a.class().has_attr("__getitem__") || a.fast_isinstance(&vm.ctx.types.dict_type) {
|
||||
return Err(
|
||||
vm.new_type_error(format!("{} object can't be concatenated", a.class().name()))
|
||||
);
|
||||
@@ -447,13 +446,10 @@ mod _operator {
|
||||
|
||||
#[pymethod(magic)]
|
||||
fn reduce(zelf: PyRef<Self>, vm: &VirtualMachine) -> PyResult<(PyTypeRef, PyTupleRef)> {
|
||||
let attrs = vm.ctx.new_tuple(
|
||||
zelf.attrs
|
||||
.iter()
|
||||
.map(|v| v.as_object().to_owned())
|
||||
.collect(),
|
||||
);
|
||||
Ok((zelf.clone_class(), attrs))
|
||||
let attrs = vm
|
||||
.ctx
|
||||
.new_tuple(zelf.attrs.iter().map(|v| v.clone().into()).collect());
|
||||
Ok((zelf.class().clone(), attrs))
|
||||
}
|
||||
|
||||
// Go through dotted parts of string and call getattr on whatever is returned.
|
||||
@@ -545,7 +541,7 @@ mod _operator {
|
||||
#[pymethod(magic)]
|
||||
fn reduce(zelf: PyRef<Self>, vm: &VirtualMachine) -> PyObjectRef {
|
||||
let items = vm.ctx.new_tuple(zelf.items.to_vec());
|
||||
vm.new_pyobj((zelf.clone_class(), items))
|
||||
vm.new_pyobj((zelf.class().clone(), items))
|
||||
}
|
||||
}
|
||||
impl Constructor for PyItemGetter {
|
||||
@@ -630,7 +626,7 @@ mod _operator {
|
||||
if zelf.args.kwargs.is_empty() {
|
||||
let mut pargs = vec![zelf.name.as_object().to_owned()];
|
||||
pargs.append(&mut zelf.args.args.clone());
|
||||
Ok(vm.new_tuple((zelf.clone_class(), vm.ctx.new_tuple(pargs))))
|
||||
Ok(vm.new_tuple((zelf.class().clone(), vm.ctx.new_tuple(pargs))))
|
||||
} else {
|
||||
// If we have kwargs, create a partial function that contains them and pass back that
|
||||
// along with the args.
|
||||
@@ -638,7 +634,7 @@ mod _operator {
|
||||
let callable = vm.invoke(
|
||||
&partial,
|
||||
FuncArgs::new(
|
||||
vec![zelf.clone_class().into(), zelf.name.as_object().to_owned()],
|
||||
vec![zelf.class().clone().into(), zelf.name.clone().into()],
|
||||
KwArgs::new(zelf.args.kwargs.clone()),
|
||||
),
|
||||
)?;
|
||||
|
||||
+4
-4
@@ -4,7 +4,7 @@ use crate::{
|
||||
function::{ArgumentError, FromArgs, FuncArgs, IntoPyException, IntoPyObject},
|
||||
protocol::PyBuffer,
|
||||
AsPyObject, PyObject, PyObjectRef, PyResult, PyValue, TryFromBorrowedObject, TryFromObject,
|
||||
TypeProtocol, VirtualMachine,
|
||||
VirtualMachine,
|
||||
};
|
||||
use std::{
|
||||
ffi, fs,
|
||||
@@ -440,7 +440,7 @@ pub(super) mod _os {
|
||||
types::{IterNext, IterNextIterable},
|
||||
utils::Either,
|
||||
vm::{ReprGuard, VirtualMachine},
|
||||
PyObjectRef, PyRef, PyResult, PyStructSequence, PyValue, TryFromObject, TypeProtocol,
|
||||
AsPyObject, PyObjectRef, PyRef, PyResult, PyStructSequence, PyValue, TryFromObject,
|
||||
};
|
||||
use crossbeam_utils::atomic::AtomicCell;
|
||||
use itertools::Itertools;
|
||||
@@ -870,8 +870,8 @@ pub(super) mod _os {
|
||||
let name = match zelf.clone().get_attr("name", vm) {
|
||||
Ok(name) => Some(name),
|
||||
Err(e)
|
||||
if e.isinstance(&vm.ctx.exceptions.attribute_error)
|
||||
|| e.isinstance(&vm.ctx.exceptions.value_error) =>
|
||||
if e.fast_isinstance(&vm.ctx.exceptions.attribute_error)
|
||||
|| e.fast_isinstance(&vm.ctx.exceptions.value_error) =>
|
||||
{
|
||||
None
|
||||
}
|
||||
|
||||
@@ -37,7 +37,7 @@ pub mod module {
|
||||
},
|
||||
types::Constructor,
|
||||
utils::{Either, ToCString},
|
||||
PyObjectRef, PyResult, PyValue, TryFromObject, TypeProtocol, VirtualMachine,
|
||||
AsPyObject, PyObjectRef, PyResult, PyValue, TryFromObject, VirtualMachine,
|
||||
};
|
||||
use bitflags::bitflags;
|
||||
use nix::{
|
||||
@@ -557,7 +557,7 @@ pub mod module {
|
||||
target_os = "android"
|
||||
))]
|
||||
fn try_to_libc(&self, vm: &VirtualMachine) -> PyResult<libc::sched_param> {
|
||||
use crate::TypeProtocol;
|
||||
use crate::AsPyObject;
|
||||
let priority_class = self.sched_priority.class();
|
||||
let priority_type = priority_class.name();
|
||||
let priority = self.sched_priority.clone();
|
||||
|
||||
@@ -10,7 +10,7 @@ pub(crate) mod _thread {
|
||||
py_io,
|
||||
types::{Constructor, GetAttr, SetAttr},
|
||||
utils::Either,
|
||||
AsPyObject, PyObjectRef, PyRef, PyResult, PyValue, TypeProtocol, VirtualMachine,
|
||||
AsPyObject, PyObjectRef, PyRef, PyResult, PyValue, VirtualMachine,
|
||||
};
|
||||
use parking_lot::{
|
||||
lock_api::{RawMutex as RawMutexT, RawMutexTimed, RawReentrantMutex},
|
||||
@@ -252,7 +252,7 @@ pub(crate) mod _thread {
|
||||
fn run_thread(func: ArgCallable, args: FuncArgs, vm: &VirtualMachine) {
|
||||
match func.invoke(args, vm) {
|
||||
Ok(_obj) => {}
|
||||
Err(e) if e.isinstance(&vm.ctx.exceptions.system_exit) => {}
|
||||
Err(e) if e.fast_isinstance(&vm.ctx.exceptions.system_exit) => {}
|
||||
Err(exc) => {
|
||||
// TODO: sys.unraisablehook
|
||||
let stderr = std::io::stderr();
|
||||
|
||||
@@ -5,7 +5,7 @@ mod _warnings {
|
||||
use crate::{
|
||||
builtins::{PyStrRef, PyTypeRef},
|
||||
function::OptionalArg,
|
||||
PyResult, TypeProtocol, VirtualMachine,
|
||||
AsPyObject, PyResult, VirtualMachine,
|
||||
};
|
||||
|
||||
#[derive(FromArgs)]
|
||||
@@ -23,7 +23,7 @@ mod _warnings {
|
||||
// TODO: Implement correctly
|
||||
let level = args.stacklevel.unwrap_or(1);
|
||||
let category = if let OptionalArg::Present(category) = args.category {
|
||||
if !category.issubclass(&vm.ctx.exceptions.warning) {
|
||||
if !category.fast_issubclass(&vm.ctx.exceptions.warning) {
|
||||
return Err(vm.new_type_error(format!(
|
||||
"category must be a Warning subclass, not '{}'",
|
||||
category.class().name()
|
||||
|
||||
@@ -2,7 +2,7 @@ use crate::{
|
||||
builtins::{PyStr, PyStrRef},
|
||||
exceptions::types::PyBaseExceptionRef,
|
||||
sliceable::SliceableSequenceOp,
|
||||
AsPyObject, PyObjectRef, PyObjectView, TypeProtocol, VirtualMachine,
|
||||
AsPyObject, PyObjectRef, PyObjectView, VirtualMachine,
|
||||
};
|
||||
use rustpython_common::str::levenshtein::{levenshtein_distance, MOVE_COST};
|
||||
use std::iter::ExactSizeIterator;
|
||||
|
||||
+12
-10
@@ -6,8 +6,7 @@ use crate::{
|
||||
protocol::{PyBuffer, PyIterReturn, PyMapping, PyMappingMethods},
|
||||
protocol::{PySequence, PySequenceMethods},
|
||||
utils::Either,
|
||||
AsPyObject, PyObject, PyObjectRef, PyObjectView, PyRef, PyResult, PyValue, TypeProtocol,
|
||||
VirtualMachine,
|
||||
AsPyObject, PyObject, PyObjectRef, PyObjectView, PyRef, PyResult, PyValue, VirtualMachine,
|
||||
};
|
||||
use crossbeam_utils::atomic::AtomicCell;
|
||||
use num_traits::{Signed, ToPrimitive};
|
||||
@@ -188,14 +187,17 @@ fn length_wrapper(obj: PyObjectRef, vm: &VirtualMachine) -> PyResult<usize> {
|
||||
|
||||
fn as_mapping_wrapper(zelf: &PyObject, _vm: &VirtualMachine) -> PyMappingMethods {
|
||||
PyMappingMethods {
|
||||
length: then_some_closure!(zelf.has_class_attr("__len__"), |mapping, vm| {
|
||||
length: then_some_closure!(zelf.class().has_attr("__len__"), |mapping, vm| {
|
||||
length_wrapper(mapping.obj.to_owned(), vm)
|
||||
}),
|
||||
subscript: then_some_closure!(zelf.has_class_attr("__getitem__"), |mapping, needle, vm| {
|
||||
vm.call_special_method(mapping.obj.to_owned(), "__getitem__", (needle.to_owned(),))
|
||||
}),
|
||||
subscript: then_some_closure!(
|
||||
zelf.class().has_attr("__getitem__"),
|
||||
|mapping, needle, vm| {
|
||||
vm.call_special_method(mapping.obj.to_owned(), "__getitem__", (needle.to_owned(),))
|
||||
}
|
||||
),
|
||||
ass_subscript: then_some_closure!(
|
||||
zelf.has_class_attr("__setitem__") | zelf.has_class_attr("__delitem__"),
|
||||
zelf.class().has_attr("__setitem__") | zelf.class().has_attr("__delitem__"),
|
||||
|mapping, needle, value, vm| match value {
|
||||
Some(value) => vm
|
||||
.call_special_method(
|
||||
@@ -217,19 +219,19 @@ fn as_mapping_wrapper(zelf: &PyObject, _vm: &VirtualMachine) -> PyMappingMethods
|
||||
}
|
||||
|
||||
fn as_sequence_wrapper(zelf: &PyObject, _vm: &VirtualMachine) -> Cow<'static, PySequenceMethods> {
|
||||
if !zelf.has_class_attr("__getitem__") {
|
||||
if !zelf.class().has_attr("__getitem__") {
|
||||
return Cow::Borrowed(PySequenceMethods::not_implemented());
|
||||
}
|
||||
|
||||
Cow::Owned(PySequenceMethods {
|
||||
length: then_some_closure!(zelf.has_class_attr("__len__"), |seq, vm| {
|
||||
length: then_some_closure!(zelf.class().has_attr("__len__"), |seq, vm| {
|
||||
length_wrapper(seq.obj.to_owned(), vm)
|
||||
}),
|
||||
item: Some(|seq, i, vm| {
|
||||
vm.call_special_method(seq.obj.to_owned(), "__getitem__", (i.into_pyobject(vm),))
|
||||
}),
|
||||
ass_item: then_some_closure!(
|
||||
zelf.has_class_attr("__setitem__") | zelf.has_class_attr("__delitem__"),
|
||||
zelf.class().has_attr("__setitem__") | zelf.class().has_attr("__delitem__"),
|
||||
|seq, i, value, vm| match value {
|
||||
Some(value) => vm
|
||||
.call_special_method(
|
||||
|
||||
+1
-1
@@ -1,7 +1,7 @@
|
||||
use crate::{
|
||||
builtins::{PyFloat, PyStr},
|
||||
function::{IntoPyException, IntoPyObject},
|
||||
PyObject, PyObjectRef, PyObjectWrap, PyResult, TryFromObject, TypeProtocol, VirtualMachine,
|
||||
AsPyObject, PyObject, PyObjectRef, PyObjectWrap, PyResult, TryFromObject, VirtualMachine,
|
||||
};
|
||||
use num_traits::ToPrimitive;
|
||||
use std::borrow::Borrow;
|
||||
|
||||
+9
-8
@@ -25,7 +25,7 @@ use crate::{
|
||||
pyobject::PyLease,
|
||||
scope::Scope,
|
||||
signal, stdlib, AsPyObject, PyContext, PyObject, PyObjectRef, PyRef, PyRefExact, PyResult,
|
||||
PyValue, TypeProtocol,
|
||||
PyValue,
|
||||
};
|
||||
use crossbeam_utils::atomic::AtomicCell;
|
||||
use std::{
|
||||
@@ -67,7 +67,7 @@ struct ExceptionStack {
|
||||
}
|
||||
|
||||
pub(crate) mod thread {
|
||||
use super::{PyObject, TypeProtocol, VirtualMachine};
|
||||
use super::{AsPyObject, PyObject, VirtualMachine};
|
||||
use itertools::Itertools;
|
||||
use std::{cell::RefCell, ptr::NonNull, thread_local};
|
||||
|
||||
@@ -91,7 +91,7 @@ pub(crate) mod thread {
|
||||
let vm_owns_obj = |intp: NonNull<VirtualMachine>| {
|
||||
// SAFETY: all references in VM_STACK should be valid
|
||||
let vm = unsafe { intp.as_ref() };
|
||||
obj.isinstance(&vm.ctx.types.object_type)
|
||||
obj.fast_isinstance(&vm.ctx.types.object_type)
|
||||
};
|
||||
VM_STACK.with(|vms| {
|
||||
let intp = match vms.borrow().iter().copied().exactly_one() {
|
||||
@@ -718,7 +718,7 @@ impl VirtualMachine {
|
||||
{
|
||||
match obj.get_attr(attr_name, self) {
|
||||
Ok(attr) => Ok(Some(attr)),
|
||||
Err(e) if e.isinstance(&self.ctx.exceptions.attribute_error) => Ok(None),
|
||||
Err(e) if e.fast_isinstance(&self.ctx.exceptions.attribute_error) => Ok(None),
|
||||
Err(e) => Err(e),
|
||||
}
|
||||
}
|
||||
@@ -747,10 +747,11 @@ impl VirtualMachine {
|
||||
where
|
||||
F: FnOnce() -> String,
|
||||
{
|
||||
match obj.get_class_attr(method_name) {
|
||||
Some(method) => self.call_if_get_descriptor(method, obj),
|
||||
None => Err(self.new_type_error(err_msg())),
|
||||
}
|
||||
let method = obj
|
||||
.class()
|
||||
.get_attr(method_name)
|
||||
.ok_or_else(|| self.new_type_error(err_msg()))?;
|
||||
self.call_if_get_descriptor(method, obj)
|
||||
}
|
||||
|
||||
// TODO: remove + transfer over to get_special_method
|
||||
|
||||
+17
-7
@@ -10,7 +10,7 @@ use crate::{
|
||||
function::IntoPyObject,
|
||||
scope::Scope,
|
||||
vm::VirtualMachine,
|
||||
AsPyObject, PyObject, PyObjectRef, PyObjectWrap, PyRef, TypeProtocol,
|
||||
AsPyObject, PyObject, PyObjectRef, PyObjectWrap, PyRef,
|
||||
};
|
||||
|
||||
/// Collection of object creation helpers
|
||||
@@ -268,9 +268,9 @@ impl VirtualMachine {
|
||||
msg: &'static str,
|
||||
error_type: &PyTypeRef,
|
||||
class: &PyTypeRef,
|
||||
obj: impl std::borrow::Borrow<PyObject>, // the impl Borrow allows to pass PyObjectRef or &PyObject
|
||||
obj: &PyObject, // the impl Borrow allows to pass PyObjectRef or &PyObject
|
||||
) -> PyBaseExceptionRef {
|
||||
let actual_class = obj.borrow().class();
|
||||
let actual_class = obj.class();
|
||||
let actual_type = &*actual_class.name();
|
||||
let expected_type = &*class.name();
|
||||
let msg = format!("Expected {msg} '{expected_type}' but '{actual_type}' found");
|
||||
@@ -280,16 +280,26 @@ impl VirtualMachine {
|
||||
pub(crate) fn new_downcast_runtime_error(
|
||||
&self,
|
||||
class: &PyTypeRef,
|
||||
obj: impl std::borrow::Borrow<PyObject>,
|
||||
obj: &impl AsPyObject,
|
||||
) -> PyBaseExceptionRef {
|
||||
self.new_downcast_error("payload", &self.ctx.exceptions.runtime_error, class, obj)
|
||||
self.new_downcast_error(
|
||||
"payload",
|
||||
&self.ctx.exceptions.runtime_error,
|
||||
class,
|
||||
obj.as_object(),
|
||||
)
|
||||
}
|
||||
|
||||
pub(crate) fn new_downcast_type_error(
|
||||
&self,
|
||||
class: &PyTypeRef,
|
||||
obj: impl std::borrow::Borrow<PyObject>,
|
||||
obj: &impl AsPyObject,
|
||||
) -> PyBaseExceptionRef {
|
||||
self.new_downcast_error("type", &self.ctx.exceptions.type_error, class, obj)
|
||||
self.new_downcast_error(
|
||||
"type",
|
||||
&self.ctx.exceptions.type_error,
|
||||
class,
|
||||
obj.as_object(),
|
||||
)
|
||||
}
|
||||
}
|
||||
+4
-8
@@ -2,7 +2,7 @@ use crate::{
|
||||
builtins::{PyBaseExceptionRef, PyList, PyStr},
|
||||
function::{FuncArgs, IntoFuncArgs},
|
||||
vm::VirtualMachine,
|
||||
AsPyObject, PyMethod, PyObject, PyObjectRef, PyResult, PyValue, TypeProtocol,
|
||||
AsPyObject, PyMethod, PyObject, PyObjectRef, PyResult, PyValue,
|
||||
};
|
||||
|
||||
/// Trace events for sys.settrace and sys.setprofile.
|
||||
@@ -102,7 +102,7 @@ impl VirtualMachine {
|
||||
descr: PyObjectRef,
|
||||
obj: PyObjectRef,
|
||||
) -> Result<PyResult, PyObjectRef> {
|
||||
let cls = obj.clone_class().into();
|
||||
let cls = obj.class().clone().into();
|
||||
self.call_get_descriptor_specific(descr, Some(obj), Some(cls))
|
||||
}
|
||||
|
||||
@@ -179,12 +179,8 @@ impl VirtualMachine {
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub fn invoke<O, A>(&self, func: &O, args: A) -> PyResult
|
||||
where
|
||||
O: AsRef<PyObject>,
|
||||
A: IntoFuncArgs,
|
||||
{
|
||||
self._invoke(func.as_ref(), args.into_args(self))
|
||||
pub fn invoke(&self, func: &impl AsPyObject, args: impl IntoFuncArgs) -> PyResult {
|
||||
self._invoke(func.as_object(), args.into_args(self))
|
||||
}
|
||||
|
||||
/// Call registered trace function.
|
||||
|
||||
+5
-4
@@ -4,7 +4,7 @@ use crate::{
|
||||
protocol::PyIterReturn,
|
||||
types::PyComparisonOp,
|
||||
vm::VirtualMachine,
|
||||
AsPyObject, PyMethod, PyObject, PyObjectRef, PyResult, TypeProtocol,
|
||||
AsPyObject, PyMethod, PyObject, PyObjectRef, PyResult,
|
||||
};
|
||||
|
||||
/// Collection of operators
|
||||
@@ -33,6 +33,7 @@ impl VirtualMachine {
|
||||
})
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn bool_eq(&self, a: &PyObject, b: &PyObject) -> PyResult<bool> {
|
||||
a.rich_compare_bool(b, PyComparisonOp::Eq, self)
|
||||
}
|
||||
@@ -71,7 +72,7 @@ impl VirtualMachine {
|
||||
match iter.length(self) {
|
||||
Ok(len) => return Ok(Some(len)),
|
||||
Err(e) => {
|
||||
if !e.isinstance(&self.ctx.exceptions.type_error) {
|
||||
if !e.fast_isinstance(&self.ctx.exceptions.type_error) {
|
||||
return Err(e);
|
||||
}
|
||||
}
|
||||
@@ -88,7 +89,7 @@ impl VirtualMachine {
|
||||
res
|
||||
}
|
||||
Err(e) => {
|
||||
return if e.isinstance(&self.ctx.exceptions.type_error) {
|
||||
return if e.fast_isinstance(&self.ctx.exceptions.type_error) {
|
||||
Ok(None)
|
||||
} else {
|
||||
Err(e)
|
||||
@@ -169,7 +170,7 @@ impl VirtualMachine {
|
||||
reflection: &str,
|
||||
unsupported: fn(&VirtualMachine, &PyObject, &PyObject) -> PyResult,
|
||||
) -> PyResult {
|
||||
if rhs.isinstance(&lhs.clone_class()) {
|
||||
if rhs.fast_isinstance(&lhs.class()) {
|
||||
let lop = lhs.get_class_attr(reflection);
|
||||
let rop = rhs.get_class_attr(reflection);
|
||||
if let Some((lop, rop)) = lop.zip(rop) {
|
||||
|
||||
@@ -7,7 +7,7 @@ use rustpython_vm::{
|
||||
compile::{CompileError, CompileErrorType},
|
||||
exceptions,
|
||||
function::{ArgBytesLike, FuncArgs},
|
||||
py_serde, PyObjectRef, PyResult, PyValue, TryFromBorrowedObject, TypeProtocol, VirtualMachine,
|
||||
py_serde, AsPyObject, PyObjectRef, PyResult, PyValue, TryFromBorrowedObject, VirtualMachine,
|
||||
};
|
||||
use wasm_bindgen::{closure::Closure, prelude::*, JsCast};
|
||||
|
||||
@@ -32,7 +32,7 @@ extern "C" {
|
||||
|
||||
pub fn py_err_to_js_err(vm: &VirtualMachine, py_err: &PyBaseExceptionRef) -> JsValue {
|
||||
let jserr = vm.try_class("_js", "JSError").ok();
|
||||
let js_arg = if jserr.map_or(false, |jserr| py_err.isinstance(&jserr)) {
|
||||
let js_arg = if jserr.map_or(false, |jserr| py_err.fast_isinstance(&jserr)) {
|
||||
py_err.get_arg(0)
|
||||
} else {
|
||||
None
|
||||
@@ -79,7 +79,7 @@ pub fn js_err_to_py_err(vm: &VirtualMachine, js_err: &JsValue) -> PyBaseExceptio
|
||||
|
||||
pub fn py_to_js(vm: &VirtualMachine, py_obj: PyObjectRef) -> JsValue {
|
||||
if let Some(ref wasm_id) = vm.wasm_id {
|
||||
if py_obj.isinstance(&vm.ctx.types.function_type) {
|
||||
if py_obj.fast_isinstance(&vm.ctx.types.function_type) {
|
||||
let wasm_vm = WASMVirtualMachine {
|
||||
id: wasm_id.clone(),
|
||||
};
|
||||
|
||||
Reference in new issue
Block a user