diff --git a/src/lib.rs b/src/lib.rs index bf0ad6be3..366df3b30 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -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 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), } } diff --git a/src/shell.rs b/src/shell.rs index 26c00b8b8..73288359c 100644 --- a/src/shell.rs +++ b/src/shell.rs @@ -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); } diff --git a/stdlib/src/array.rs b/stdlib/src/array.rs index 137a1cd78..8f9951b06 100644 --- a/stdlib/src/array.rs +++ b/stdlib/src/array.rs @@ -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)> { 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 { - 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())) ); diff --git a/stdlib/src/csv.rs b/stdlib/src/csv.rs index bb94fa360..72954eff8 100644 --- a/stdlib/src/csv.rs +++ b/stdlib/src/csv.rs @@ -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; diff --git a/stdlib/src/json.rs b/stdlib/src/json.rs index ad28c6e4c..a1fd0fa68 100644 --- a/stdlib/src/json.rs +++ b/stdlib/src/json.rs @@ -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() { diff --git a/stdlib/src/math.rs b/stdlib/src/math.rs index 42d150fd0..17379f27b 100644 --- a/stdlib/src/math.rs +++ b/stdlib/src/math.rs @@ -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}; diff --git a/stdlib/src/pystruct.rs b/stdlib/src/pystruct.rs index e504d4c9c..da736f87e 100644 --- a/stdlib/src/pystruct.rs +++ b/stdlib/src/pystruct.rs @@ -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; diff --git a/stdlib/src/select.rs b/stdlib/src/select.rs index 226250efb..c4d9267c6 100644 --- a/stdlib/src/select.rs +++ b/stdlib/src/select.rs @@ -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; diff --git a/stdlib/src/socket.rs b/stdlib/src/socket.rs index 378d3f7dc..7c6c757cf 100644 --- a/stdlib/src/socket.rs +++ b/stdlib/src/socket.rs @@ -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 diff --git a/vm/src/anystr.rs b/vm/src/anystr.rs index faeea9b2a..bcf209d69 100644 --- a/vm/src/anystr.rs +++ b/vm/src/anystr.rs @@ -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; diff --git a/vm/src/builtins/asyncgenerator.rs b/vm/src/builtins/asyncgenerator.rs index c6304cca5..8ffed4ebd 100644 --- a/vm/src/builtins/asyncgenerator.rs +++ b/vm/src/builtins/asyncgenerator.rs @@ -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, 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 { diff --git a/vm/src/builtins/builtinfunc.rs b/vm/src/builtins/builtinfunc.rs index f8dc8eeb0..af05e3619 100644 --- a/vm/src/builtins/builtinfunc.rs +++ b/vm/src/builtins/builtinfunc.rs @@ -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; diff --git a/vm/src/builtins/bytearray.rs b/vm/src/builtins/bytearray.rs index 2cd935870..3e67e856b 100644 --- a/vm/src/builtins/bytearray.rs +++ b/vm/src/builtins/bytearray.rs @@ -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) { 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(), ) diff --git a/vm/src/builtins/bytes.rs b/vm/src/builtins/bytes.rs index fbd459a83..9fecf2ebb 100644 --- a/vm/src/builtins/bytes.rs +++ b/vm/src/builtins/bytes.rs @@ -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) { 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 { 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 { diff --git a/vm/src/builtins/classmethod.rs b/vm/src/builtins/classmethod.rs index 2405c418e..09e6c3a8e 100644 --- a/vm/src/builtins/classmethod.rs +++ b/vm/src/builtins/classmethod.rs @@ -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()) } } diff --git a/vm/src/builtins/code.rs b/vm/src/builtins/code.rs index 3e10632a6..25c0d3a55 100644 --- a/vm/src/builtins/code.rs +++ b/vm/src/builtins/code.rs @@ -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}; diff --git a/vm/src/builtins/complex.rs b/vm/src/builtins/complex.rs index 1aa41e035..5ac70bf01 100644 --- a/vm/src/builtins/complex.rs +++ b/vm/src/builtins/complex.rs @@ -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()) ); diff --git a/vm/src/builtins/dict.rs b/vm/src/builtins/dict.rs index 299037110..abf8c2f9d 100644 --- a/vm/src/builtins/dict.rs +++ b/vm/src/builtins/dict.rs @@ -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 { } 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), } } diff --git a/vm/src/builtins/enumerate.rs b/vm/src/builtins/enumerate.rs index e63ca95f8..3602a5b68 100644 --- a/vm/src/builtins/enumerate.rs +++ b/vm/src/builtins/enumerate.rs @@ -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) -> (PyTypeRef, (PyIter, BigInt)) { ( - zelf.clone_class(), + zelf.class().clone(), (zelf.iterator.clone(), zelf.counter.read().clone()), ) } diff --git a/vm/src/builtins/float.rs b/vm/src/builtins/float.rs index de888f594..7fb7e7792 100644 --- a/vm/src/builtins/float.rs +++ b/vm/src/builtins/float.rs @@ -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; diff --git a/vm/src/builtins/function.rs b/vm/src/builtins/function.rs index 1e3f9c777..b884fa9b5 100644 --- a/vm/src/builtins/function.rs +++ b/vm/src/builtins/function.rs @@ -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, 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 { + #[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__`. diff --git a/vm/src/builtins/function/jitfunc.rs b/vm/src/builtins/function/jitfunc.rs index 9ced316fd..ee38cc402 100644 --- a/vm/src/builtins/function/jitfunc.rs +++ b/vm/src/builtins/function/jitfunc.rs @@ -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}; diff --git a/vm/src/builtins/genericalias.rs b/vm/src/builtins/genericalias.rs index d6d793360..d8a47db73 100644 --- a/vm/src/builtins/genericalias.rs +++ b/vm/src/builtins/genericalias.rs @@ -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, 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); } diff --git a/vm/src/builtins/getset.rs b/vm/src/builtins/getset.rs index 022a4b6a1..bae3f9423 100644 --- a/vm/src/builtins/getset.rs +++ b/vm/src/builtins/getset.rs @@ -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 PyResult)>; diff --git a/vm/src/builtins/int.rs b/vm/src/builtins/int.rs index da837a099..d49a47f7b 100644 --- a/vm/src/builtins/int.rs +++ b/vm/src/builtins/int.rs @@ -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}; diff --git a/vm/src/builtins/list.rs b/vm/src/builtins/list.rs index 622f56153..75fefc421 100644 --- a/vm/src/builtins/list.rs +++ b/vm/src/builtins/list.rs @@ -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}; diff --git a/vm/src/builtins/mappingproxy.rs b/vm/src/builtins/mappingproxy.rs index 826f963bb..049e530e2 100644 --- a/vm/src/builtins/mappingproxy.rs +++ b/vm/src/builtins/mappingproxy.rs @@ -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, }; diff --git a/vm/src/builtins/memory.rs b/vm/src/builtins/memory.rs index 6a12551c8..8bfebc8a8 100644 --- a/vm/src/builtins/memory.rs +++ b/vm/src/builtins/memory.rs @@ -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; diff --git a/vm/src/builtins/module.rs b/vm/src/builtins/module.rs index 1586c9371..4ff2d7de9 100644 --- a/vm/src/builtins/module.rs +++ b/vm/src/builtins/module.rs @@ -42,7 +42,8 @@ impl PyModule { #[pymethod(magic)] fn init(zelf: PyRef, 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, 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); } diff --git a/vm/src/builtins/namespace.rs b/vm/src/builtins/namespace.rs index aaebfdb3e..441b60d46 100644 --- a/vm/src/builtins/namespace.rs +++ b/vm/src/builtins/namespace.rs @@ -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. diff --git a/vm/src/builtins/object.rs b/vm/src/builtins/object.rs index a079cb3ab..71044ef7a 100644 --- a/vm/src/builtins/object.rs +++ b/vm/src/builtins/object.rs @@ -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(), diff --git a/vm/src/builtins/property.rs b/vm/src/builtins/property.rs index 60f714061..e21cb9ad9 100644 --- a/vm/src/builtins/property.rs +++ b/vm/src/builtins/property.rs @@ -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)] diff --git a/vm/src/builtins/pybool.rs b/vm/src/builtins/pybool.rs index 98315b954..fa3a7d8c8 100644 --- a/vm/src/builtins/pybool.rs +++ b/vm/src/builtins/pybool.rs @@ -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 { - 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; 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 { -// 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 { diff --git a/vm/src/builtins/pystr.rs b/vm/src/builtins/pystr.rs index 9ee232a0b..939ba3d9e 100644 --- a/vm/src/builtins/pystr.rs +++ b/vm/src/builtins/pystr.rs @@ -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; diff --git a/vm/src/builtins/pysuper.rs b/vm/src/builtins/pysuper.rs index ea01de8bf..31b9052f7 100644 --- a/vm/src/builtins/pysuper.rs +++ b/vm/src/builtins/pysuper.rs @@ -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 { if let Ok(cls) = obj.clone().downcast::() { - 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::() { - if !cls.is(&ty) && cls.issubclass(&ty) { + if !cls.is(&ty) && cls.fast_issubclass(&ty) { return Ok(cls); } } diff --git a/vm/src/builtins/pytype.rs b/vm/src/builtins/pytype.rs index 8798bca74..02ab97f40 100644 --- a/vm/src/builtins/pytype.rs +++ b/vm/src/builtins/pytype.rs @@ -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) -> bool { + pub fn fast_issubclass(&self, cls: &impl Borrow) -> 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, args: FuncArgs, vm: &VirtualMachine) -> PyResult { let (subtype, args): (PyRef, 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, obj: PyObjectRef) -> bool { - obj.isinstance(&zelf) + obj.fast_isinstance(&zelf) } #[pymethod(magic)] fn subclasscheck(zelf: PyRef, 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 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; } diff --git a/vm/src/builtins/pyunion.rs b/vm/src/builtins/pyunion.rs index 42a184666..46b735d69 100644 --- a/vm/src/builtins/pyunion.rs +++ b/vm/src/builtins/pyunion.rs @@ -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; diff --git a/vm/src/builtins/range.rs b/vm/src/builtins/range.rs index dd22a4541..cd8e13cb5 100644 --- a/vm/src/builtins/range.rs +++ b/vm/src/builtins/range.rs @@ -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}; diff --git a/vm/src/builtins/set.rs b/vm/src/builtins/set.rs index b3339e64a..22c8a7667 100644 --- a/vm/src/builtins/set.rs +++ b/vm/src/builtins/set.rs @@ -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)> { 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, iterable: SetIterable, vm: &VirtualMachine) -> PyResult { + fn ior(zelf: PyRef, iterable: SetIterable, vm: &VirtualMachine) -> PyResult> { 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, iterable: SetIterable, vm: &VirtualMachine) -> PyResult { + fn iand( + zelf: PyRef, + iterable: SetIterable, + vm: &VirtualMachine, + ) -> PyResult> { 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, iterable: SetIterable, vm: &VirtualMachine) -> PyResult { + fn isub( + zelf: PyRef, + iterable: SetIterable, + vm: &VirtualMachine, + ) -> PyResult> { 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, iterable: SetIterable, vm: &VirtualMachine) -> PyResult { + fn ixor( + zelf: PyRef, + iterable: SetIterable, + vm: &VirtualMachine, + ) -> PyResult> { 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 { 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); diff --git a/vm/src/builtins/singletons.rs b/vm/src/builtins/singletons.rs index 33db75183..3ec03e952 100644 --- a/vm/src/builtins/singletons.rs +++ b/vm/src/builtins/singletons.rs @@ -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()); } diff --git a/vm/src/builtins/slice.rs b/vm/src/builtins/slice.rs index 3a3f998dd..de00b5057 100644 --- a/vm/src/builtins/slice.rs +++ b/vm/src/builtins/slice.rs @@ -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, Option), )> { 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()); } diff --git a/vm/src/builtins/tuple.rs b/vm/src/builtins/tuple.rs index 7473e2a56..b727a5cf1 100644 --- a/vm/src/builtins/tuple.rs +++ b/vm/src/builtins/tuple.rs @@ -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}; diff --git a/vm/src/builtins/weakref.rs b/vm/src/builtins/weakref.rs index 51e0e5dcc..0db91cb57 100644 --- a/vm/src/builtins/weakref.rs +++ b/vm/src/builtins/weakref.rs @@ -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; diff --git a/vm/src/builtins/zip.rs b/vm/src/builtins/zip.rs index 0213530db..3e56514a3 100644 --- a/vm/src/builtins/zip.rs +++ b/vm/src/builtins/zip.rs @@ -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, vm: &VirtualMachine) -> PyResult { - let cls = zelf.clone_class().into_pyobject(vm); + let cls = zelf.class().clone(); let iterators = zelf .iterators .iter() diff --git a/vm/src/cformat.rs b/vm/src/cformat.rs index 0184b00c8..7c7e865ae 100644 --- a/vm/src/cformat.rs +++ b/vm/src/cformat.rs @@ -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 diff --git a/vm/src/codecs.rs b/vm/src/codecs.rs index 978374c54..ead3e024b 100644 --- a/vm/src/codecs.rs +++ b/vm/src/codecs.rs @@ -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 = diff --git a/vm/src/convert.rs b/vm/src/convert.rs index 2e723d4fd..d8a9f1963 100644 --- a/vm/src/convert.rs +++ b/vm/src/convert.rs @@ -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 TransmuteFromObject for PyRef { 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::() { 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 { 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))) } } } diff --git a/vm/src/coroutine.rs b/vm/src/coroutine.rs index e3bbe45d0..4217b97ec 100644 --- a/vm/src/coroutine.rs +++ b/vm/src/coroutine.rs @@ -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) } diff --git a/vm/src/dictdatatype.rs b/vm/src/dictdatatype.rs index ddbcca800..398912c68 100644 --- a/vm/src/dictdatatype.rs +++ b/vm/src/dictdatatype.rs @@ -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) } } diff --git a/vm/src/exceptions.rs b/vm/src/exceptions.rs index 3674d8542..705aeee5d 100644 --- a/vm/src/exceptions.rs +++ b/vm/src/exceptions.rs @@ -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, ) -> PyResult { // 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 { obj.downcast::() .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, tb: Option) -> PyResult { + fn with_traceback(zelf: PyRef, tb: Option) -> PyResult> { *zelf.traceback.write() = tb; - Ok(zelf.as_object().to_owned()) + Ok(zelf) } #[pymethod(magic)] diff --git a/vm/src/format.rs b/vm/src/format.rs index c4a762bfc..448b5c86e 100644 --- a/vm/src/format.rs +++ b/vm/src/format.rs @@ -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}; diff --git a/vm/src/frame.rs b/vm/src/frame.rs index fa0ba1386..6970cd476 100644 --- a/vm/src/frame.rs +++ b/vm/src/frame.rs @@ -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)?; } } } diff --git a/vm/src/function.rs b/vm/src/function.rs index 5281515e1..c24685bc9 100644 --- a/vm/src/function.rs +++ b/vm/src/function.rs @@ -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> { 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(); diff --git a/vm/src/function/argument.rs b/vm/src/function/argument.rs index aa01450fe..c3b7b2fe9 100644 --- a/vm/src/function/argument.rs +++ b/vm/src/function/argument.rs @@ -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}; diff --git a/vm/src/function/number.rs b/vm/src/function/number.rs index 1940db657..963680162 100644 --- a/vm/src/function/number.rs +++ b/vm/src/function/number.rs @@ -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. diff --git a/vm/src/import.rs b/vm/src/import.rs index 2dc632bc1..14533434b 100644 --- a/vm/src/import.rs +++ b/vm/src/import.rs @@ -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; diff --git a/vm/src/lib.rs b/vm/src/lib.rs index 5a88bdd0a..72f62139b 100644 --- a/vm/src/lib.rs +++ b/vm/src/lib.rs @@ -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; diff --git a/vm/src/protocol/buffer.rs b/vm/src/protocol/buffer.rs index 45db5dd6c..a152f442f 100644 --- a/vm/src/protocol/buffer.rs +++ b/vm/src/protocol/buffer.rs @@ -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}; diff --git a/vm/src/protocol/iter.rs b/vm/src/protocol/iter.rs index c651ddf67..9a47d50dd 100644 --- a/vm/src/protocol/iter.rs +++ b/vm/src/protocol/iter.rs @@ -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 { 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 { 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)) } diff --git a/vm/src/protocol/mapping.rs b/vm/src/protocol/mapping.rs index bd88ae116..d9a65707c 100644 --- a/vm/src/protocol/mapping.rs +++ b/vm/src/protocol/mapping.rs @@ -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, + 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, diff --git a/vm/src/protocol/object.rs b/vm/src/protocol/object.rs index edc1ddde9..fbfc62ff1 100644 --- a/vm/src/protocol/object.rs +++ b/vm/src/protocol/object.rs @@ -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::(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 { 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) = diff --git a/vm/src/protocol/sequence.rs b/vm/src/protocol/sequence.rs index 684e6cd6e..031084160 100644 --- a/vm/src/protocol/sequence.rs +++ b/vm/src/protocol/sequence.rs @@ -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::{ diff --git a/vm/src/py_serde.rs b/vm/src/py_serde.rs index 796d17316..2ec878cd5 100644 --- a/vm/src/py_serde.rs +++ b/vm/src/py_serde.rs @@ -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( @@ -64,11 +64,11 @@ impl<'s> serde::Serialize for PyObjectSerializer<'s> { }; if let Some(s) = self.pyobject.payload::() { 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::(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()))?; diff --git a/vm/src/pyobject.rs b/vm/src/pyobject.rs index f3f40ddbd..102823e26 100644 --- a/vm/src/pyobject.rs +++ b/vm/src/pyobject.rs @@ -366,9 +366,9 @@ impl TryFromObject for PyRefExact { 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(&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 { + 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) -> bool { + self.class().fast_issubclass(cls) + } } impl AsPyObject for T where T: Borrow {} 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 Borrow for PyRc { @@ -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 { - 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) -> 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 TypeProtocol for PyObjectView { - fn class(&self) -> PyLease<'_, PyType> { - self.as_object().class() - } -} - -impl TypeProtocol for PyRef { - fn class(&self) -> PyLease<'_, PyType> { - self.as_object().class() - } -} - -impl TypeProtocol for &'_ T { - fn class(&self) -> PyLease<'_, PyType> { - (&**self).class() - } -} - impl IntoPyRef

for T where P: PyValue + IntoPyObject + From, @@ -648,7 +616,7 @@ pub trait PyValue: fmt::Debug + PyThreadingConstraint + Sized + 'static { #[inline] fn into_ref_with_type(self, vm: &VirtualMachine, cls: PyTypeRef) -> PyResult> { 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, vm: &VirtualMachine) -> PyTupleRef { vm.new_tuple(( - zelf.clone_class(), + zelf.class().clone(), (vm.ctx.new_tuple(zelf.as_slice().to_vec()),), )) } diff --git a/vm/src/pyobjectrc.rs b/vm/src/pyobjectrc.rs index ec1841d1a..d5ded5570 100644 --- a/vm/src/pyobjectrc.rs +++ b/vm/src/pyobjectrc.rs @@ -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(&self, vm: &VirtualMachine) -> Option<&T> { - if self.class().issubclass(T::class(vm)) { + if self.class().fast_issubclass(T::class(vm)) { self.payload() } else { None diff --git a/vm/src/sequence.rs b/vm/src/sequence.rs index 2088156b2..dc3784d84 100644 --- a/vm/src/sequence.rs +++ b/vm/src/sequence.rs @@ -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 diff --git a/vm/src/sliceable.rs b/vm/src/sliceable.rs index cc372a1fe..b02bb516b 100644 --- a/vm/src/sliceable.rs +++ b/vm/src/sliceable.rs @@ -7,7 +7,7 @@ use crate::{ int::PyInt, slice::{PySlice, SaturatedSliceIter}, }, - PyObject, PyResult, TryFromBorrowedObject, TypeProtocol, VirtualMachine, + AsPyObject, PyObject, PyResult, TryFromBorrowedObject, VirtualMachine, }; pub trait SliceableSequenceMutOp { diff --git a/vm/src/stdlib/ast.rs b/vm/src/stdlib/ast.rs index f58fcc5fb..67d896de0 100644 --- a/vm/src/stdlib/ast.rs +++ b/vm/src/stdlib/ast.rs @@ -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 = fields.try_to_value(vm)?; let numargs = args.args.len(); diff --git a/vm/src/stdlib/atexit.rs b/vm/src/stdlib/atexit.rs index 3f31e28d6..80bd83094 100644 --- a/vm/src/stdlib/atexit.rs +++ b/vm/src/stdlib/atexit.rs @@ -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:" diff --git a/vm/src/stdlib/builtins.rs b/vm/src/stdlib/builtins.rs index 102d98bda..6a0c2f364 100644 --- a/vm/src/stdlib/builtins.rs +++ b/vm/src/stdlib/builtins.rs @@ -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> = 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" diff --git a/vm/src/stdlib/collections.rs b/vm/src/stdlib/collections.rs index d99a279c7..11252aa9e 100644 --- a/vm/src/stdlib/collections.rs +++ b/vm/src/stdlib/collections.rs @@ -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, 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()), )) } diff --git a/vm/src/stdlib/io.rs b/vm/src/stdlib/io.rs index 6f9992ba9..69333715c 100644 --- a/vm/src/stdlib/io.rs +++ b/vm/src/stdlib/io.rs @@ -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)?; diff --git a/vm/src/stdlib/itertools.rs b/vm/src/stdlib/itertools.rs index bd8264f3a..7d7dae7ed 100644 --- a/vm/src/stdlib/itertools.rs +++ b/vm/src/stdlib/itertools.rs @@ -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, vm: &VirtualMachine) -> PyResult { - 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 { - 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 { diff --git a/vm/src/stdlib/marshal.rs b/vm/src/stdlib/marshal.rs index 03cfc0cd2..aaad31d79 100644 --- a/vm/src/stdlib/marshal.rs +++ b/vm/src/stdlib/marshal.rs @@ -10,7 +10,7 @@ mod decl { bytecode, function::{ArgBytesLike, IntoPyObject}, protocol::PyBuffer, - pyobject::{AsPyObject, TypeProtocol}, + pyobject::AsPyObject, PyObjectRef, PyResult, TryFromObject, VirtualMachine, }; /// TODO diff --git a/vm/src/stdlib/operator.rs b/vm/src/stdlib/operator.rs index 5d46321a7..1366ca7bb 100644 --- a/vm/src/stdlib/operator.rs +++ b/vm/src/stdlib/operator.rs @@ -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 { 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, 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, 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()), ), )?; diff --git a/vm/src/stdlib/os.rs b/vm/src/stdlib/os.rs index d892d9d3f..86fb4c9a2 100644 --- a/vm/src/stdlib/os.rs +++ b/vm/src/stdlib/os.rs @@ -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 } diff --git a/vm/src/stdlib/posix.rs b/vm/src/stdlib/posix.rs index 5b1a9eff6..0e72263da 100644 --- a/vm/src/stdlib/posix.rs +++ b/vm/src/stdlib/posix.rs @@ -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 { - 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(); diff --git a/vm/src/stdlib/thread.rs b/vm/src/stdlib/thread.rs index deab60bd4..9e6128493 100644 --- a/vm/src/stdlib/thread.rs +++ b/vm/src/stdlib/thread.rs @@ -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(); diff --git a/vm/src/stdlib/warnings.rs b/vm/src/stdlib/warnings.rs index 24b1200c9..4ecc46aa6 100644 --- a/vm/src/stdlib/warnings.rs +++ b/vm/src/stdlib/warnings.rs @@ -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() diff --git a/vm/src/suggestion.rs b/vm/src/suggestion.rs index e38713a32..81fdcaabb 100644 --- a/vm/src/suggestion.rs +++ b/vm/src/suggestion.rs @@ -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; diff --git a/vm/src/types/slot.rs b/vm/src/types/slot.rs index 713fd9e7a..d578b16ab 100644 --- a/vm/src/types/slot.rs +++ b/vm/src/types/slot.rs @@ -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 { 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( diff --git a/vm/src/utils.rs b/vm/src/utils.rs index 5d1ec49ce..da08aeb52 100644 --- a/vm/src/utils.rs +++ b/vm/src/utils.rs @@ -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; diff --git a/vm/src/vm.rs b/vm/src/vm.rs index d61ec88ea..3cb6dfd2a 100644 --- a/vm/src/vm.rs +++ b/vm/src/vm.rs @@ -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| { // 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 diff --git a/vm/src/vm_new.rs b/vm/src/vm_new.rs index e21953584..8b907d44d 100644 --- a/vm/src/vm_new.rs +++ b/vm/src/vm_new.rs @@ -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, // 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, + 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, + 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(), + ) } } diff --git a/vm/src/vm_object.rs b/vm/src/vm_object.rs index dc7cecf55..d9f1bd2d7 100644 --- a/vm/src/vm_object.rs +++ b/vm/src/vm_object.rs @@ -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 { - 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(&self, func: &O, args: A) -> PyResult - where - O: AsRef, - 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. diff --git a/vm/src/vm_ops.rs b/vm/src/vm_ops.rs index c783611ec..ade8a14a4 100644 --- a/vm/src/vm_ops.rs +++ b/vm/src/vm_ops.rs @@ -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 { 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) { diff --git a/wasm/lib/src/convert.rs b/wasm/lib/src/convert.rs index 0e7972391..f810aefa0 100644 --- a/wasm/lib/src/convert.rs +++ b/wasm/lib/src/convert.rs @@ -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(), };