Merge pull request #3625 from youknowone/cleanup-type

Remove DerefToPyType, IdProtocol
This commit is contained in:
Jeong YunWon
2022-04-17 18:40:34 +09:00
committed by GitHub
71 changed files with 328 additions and 257 deletions

View File

@@ -51,8 +51,8 @@ use rustpython_vm::{
compile, match_class,
scope::Scope,
stdlib::{atexit, sys},
InitParameter, Interpreter, PyObjectRef, PyResult, PySettings, TryFromObject, TypeProtocol,
VirtualMachine,
AsPyObject, InitParameter, Interpreter, PyObjectRef, PyResult, PySettings, TryFromObject,
TypeProtocol, VirtualMachine,
};
use std::{env, path::Path, process, str::FromStr};
@@ -536,12 +536,8 @@ fn setup_main_module(vm: &VirtualMachine) -> PyResult<Scope> {
main_module
.dict()
.and_then(|d| {
d.set_item(
"__annotations__",
vm.ctx.new_dict().as_object().to_owned(),
vm,
)
.ok()
d.set_item("__annotations__", vm.ctx.new_dict().into(), vm)
.ok()
})
.expect("Failed to initialize __main__.__annotations__");

View File

@@ -85,9 +85,8 @@ impl<'vm> ShellHelper<'vm> {
} else {
// we need to get a variable based off of globals/builtins
let globals = str_iter_method(self.globals.as_object().to_owned(), "keys").ok()?;
let builtins =
str_iter_method(self.vm.builtins.as_object().to_owned(), "__dir__").ok()?;
let globals = str_iter_method(self.globals.clone().into(), "keys").ok()?;
let builtins = str_iter_method(self.vm.builtins.clone().into(), "__dir__").ok()?;
(first, globals, Some(builtins))
};
Some((word_start, iter1.chain(iter2.into_iter().flatten())))

View File

@@ -33,14 +33,13 @@ mod array {
AsBuffer, AsMapping, Comparable, Constructor, IterNext, IterNextIterable, Iterable,
PyComparisonOp,
},
IdProtocol, PyObject, PyObjectRef, PyObjectView, PyObjectWrap, PyRef, PyResult,
PyValue, TryFromBorrowedObject, TryFromObject, TypeProtocol, VirtualMachine,
AsPyObject, PyObject, PyObjectRef, PyObjectView, PyRef, PyResult, PyValue,
TryFromBorrowedObject, TryFromObject, TypeProtocol, VirtualMachine,
},
};
use itertools::Itertools;
use num_traits::ToPrimitive;
use std::cmp::Ordering;
use std::{fmt, os::raw};
use std::{cmp::Ordering, fmt, os::raw};
macro_rules! def_array_enum {
($(($n:ident, $t:ty, $c:literal, $scode:literal)),*$(,)?) => {

View File

@@ -9,7 +9,7 @@ mod _json {
function::{IntoPyObject, IntoPyResult, OptionalArg},
protocol::PyIterReturn,
types::{Callable, Constructor},
IdProtocol, PyObjectRef, PyObjectView, PyResult, PyValue, VirtualMachine,
AsPyObject, PyObjectRef, PyObjectView, PyResult, PyValue, VirtualMachine,
};
use num_bigint::BigInt;
use std::str::FromStr;

View File

@@ -7,7 +7,7 @@ use crate::{
protocol::PyIterReturn,
pyclass::PyClassImpl,
types::{Constructor, IterNext, IterNextIterable, Unconstructible},
IdProtocol, PyContext, PyObjectRef, PyRef, PyResult, PyValue, TypeProtocol, VirtualMachine,
AsPyObject, PyContext, PyObjectRef, PyRef, PyResult, PyValue, TypeProtocol, VirtualMachine,
};
use crossbeam_utils::atomic::AtomicCell;

View File

@@ -33,7 +33,7 @@ use crate::{
IterNextIterable, Iterable, PyComparisonOp, Unconstructible, Unhashable,
},
utils::Either,
IdProtocol, PyContext, PyObject, PyObjectRef, PyObjectView, PyObjectWrap, PyRef, PyResult,
AsPyObject, PyContext, PyObject, PyObjectRef, PyObjectView, PyObjectWrap, PyRef, PyResult,
PyValue, TryFromBorrowedObject, TryFromObject, TypeProtocol, VirtualMachine,
};
use bstr::ByteSlice;
@@ -719,7 +719,7 @@ impl Comparable for PyByteArray {
op: PyComparisonOp,
vm: &VirtualMachine,
) -> PyResult<PyComparisonValue> {
if let Some(res) = op.identical_optimization(&zelf, &other) {
if let Some(res) = op.identical_optimization(zelf, other) {
return Ok(res.into());
}
Ok(zelf.inner().cmp(other, op, vm))

View File

@@ -22,7 +22,7 @@ use crate::{
IterNextIterable, Iterable, PyComparisonOp, Unconstructible,
},
utils::Either,
IdProtocol, PyContext, PyObject, PyObjectRef, PyObjectView, PyObjectWrap, PyRef, PyResult,
AsPyObject, PyContext, PyObject, PyObjectRef, PyObjectView, PyObjectWrap, PyRef, PyResult,
PyValue, TryFromBorrowedObject, TryFromObject, TypeProtocol, VirtualMachine,
};
use bstr::ByteSlice;

View File

@@ -7,7 +7,7 @@ use crate::{
bytecode::{self, BorrowedConstant, Constant, ConstantBag},
function::FuncArgs,
pyclass::{PyClassImpl, StaticType},
IdProtocol, PyContext, PyObject, PyObjectRef, PyRef, PyResult, PyValue, TypeProtocol,
AsPyObject, PyContext, PyObject, PyObjectRef, PyRef, PyResult, PyValue, TypeProtocol,
VirtualMachine,
};
use num_traits::Zero;

View File

@@ -7,7 +7,7 @@ use crate::{
},
pyclass::PyClassImpl,
types::{Comparable, Constructor, Hashable, PyComparisonOp},
IdProtocol, PyContext, PyObject, PyObjectRef, PyRef, PyResult, PyValue, TypeProtocol,
AsPyObject, PyContext, PyObject, PyObjectRef, PyRef, PyResult, PyValue, TypeProtocol,
VirtualMachine,
};
use num_complex::Complex64;

View File

@@ -6,7 +6,7 @@ use crate::{
protocol::PyIterReturn,
pyclass::PyClassImpl,
types::{Constructor, IterNext, IterNextIterable, Unconstructible},
IdProtocol, PyContext, PyObjectRef, PyRef, PyResult, PyValue, VirtualMachine,
AsPyObject, PyContext, PyObjectRef, PyRef, PyResult, PyValue, VirtualMachine,
};
#[pyclass(module = false, name = "coroutine")]

View File

@@ -21,7 +21,7 @@ use crate::{
IterNextIterable, Iterable, PyComparisonOp, Unconstructible, Unhashable,
},
vm::{ReprGuard, VirtualMachine},
IdProtocol, PyContext, PyObject, PyObjectRef, PyObjectView, PyRef, PyResult, PyValue,
AsPyObject, PyContext, PyObject, PyObjectRef, PyObjectView, PyRef, PyResult, PyValue,
TryFromObject, TypeProtocol,
};
use rustpython_common::lock::PyMutex;

View File

@@ -9,7 +9,7 @@ use crate::{
},
pyclass::PyClassImpl,
types::{Comparable, Constructor, Hashable, PyComparisonOp},
IdProtocol, PyContext, PyObject, PyObjectRef, PyRef, PyResult, PyValue, TryFromBorrowedObject,
AsPyObject, PyContext, PyObject, PyObjectRef, PyRef, PyResult, PyValue, TryFromBorrowedObject,
TryFromObject, TypeProtocol, VirtualMachine,
};
use num_bigint::{BigInt, ToBigInt};

View File

@@ -7,7 +7,7 @@ use crate::{
frame::{Frame, FrameRef},
pyclass::PyClassImpl,
types::{Constructor, Unconstructible},
IdProtocol, PyContext, PyObjectRef, PyObjectWrap, PyRef, PyResult, VirtualMachine,
AsPyObject, PyContext, PyObjectRef, PyObjectWrap, PyRef, PyResult, VirtualMachine,
};
pub fn init(context: &PyContext) {

View File

@@ -14,7 +14,7 @@ use crate::{
pyclass::PyClassImpl,
scope::Scope,
types::{Callable, Comparable, Constructor, GetAttr, GetDescriptor, PyComparisonOp},
IdProtocol, PyContext, PyObject, PyObjectRef, PyRef, PyResult, PyValue, TypeProtocol,
AsPyObject, PyContext, PyObject, PyObjectRef, PyRef, PyResult, PyValue, TypeProtocol,
VirtualMachine,
};
#[cfg(feature = "jit")]

View File

@@ -2,7 +2,7 @@ use crate::{
builtins::{float, int, pybool, PyBaseExceptionRef, PyDictRef, PyFunction, PyStrRef},
bytecode::CodeFlags,
function::{FuncArgs, IntoPyObject},
IdProtocol, PyObject, PyObjectRef, PyResult, TryFromObject, TypeProtocol, VirtualMachine,
AsPyObject, PyObject, PyObjectRef, PyResult, TryFromObject, TypeProtocol, VirtualMachine,
};
use num_traits::ToPrimitive;
use rustpython_jit::{AbiValue, Args, CompiledCode, JitArgumentError, JitType};

View File

@@ -10,7 +10,7 @@ use crate::{
protocol::PyIterReturn,
pyclass::PyClassImpl,
types::{Constructor, IterNext, IterNextIterable, Unconstructible},
IdProtocol, PyContext, PyObjectRef, PyRef, PyResult, PyValue, VirtualMachine,
AsPyObject, PyContext, PyObjectRef, PyRef, PyResult, PyValue, VirtualMachine,
};
#[pyclass(module = false, name = "generator")]

View File

@@ -5,7 +5,7 @@ use crate::{
protocol::PyMappingMethods,
pyclass::PyClassImpl,
types::{AsMapping, Callable, Comparable, Constructor, GetAttr, Hashable, PyComparisonOp},
IdProtocol, PyContext, PyObject, PyObjectRef, PyObjectView, PyRef, PyResult, PyValue,
AsPyObject, PyContext, PyObject, PyObjectRef, PyObjectView, PyRef, PyResult, PyValue,
TryFromObject, TypeProtocol, VirtualMachine,
};
use std::fmt;

View File

@@ -9,7 +9,7 @@ use crate::{
},
pyclass::PyClassImpl,
types::{Comparable, Constructor, Hashable, PyComparisonOp},
IdProtocol, PyContext, PyObject, PyObjectRef, PyRef, PyResult, PyValue, TryFromBorrowedObject,
AsPyObject, PyContext, PyObject, PyObjectRef, PyRef, PyResult, PyValue, TryFromBorrowedObject,
TypeProtocol, VirtualMachine,
};
use bstr::ByteSlice;

View File

@@ -15,8 +15,8 @@ use crate::{
},
utils::collection_repr,
vm::{ReprGuard, VirtualMachine},
PyContext, PyObject, PyObjectRef, PyObjectView, PyObjectWrap, PyRef, PyResult, PyValue,
TypeProtocol,
AsPyObject, PyContext, PyObject, PyObjectRef, PyObjectView, PyObjectWrap, PyRef, PyResult,
PyValue, TypeProtocol,
};
use std::{borrow::Cow, fmt, ops::DerefMut};

View File

@@ -18,7 +18,7 @@ use crate::{
sliceable::wrap_index,
types::{AsBuffer, AsMapping, AsSequence, Comparable, Constructor, Hashable, PyComparisonOp},
utils::Either,
IdProtocol, PyContext, PyObject, PyObjectRef, PyObjectView, PyObjectWrap, PyRef, PyResult,
AsPyObject, PyContext, PyObject, PyObjectRef, PyObjectView, PyObjectWrap, PyRef, PyResult,
PyValue, TryFromBorrowedObject, TryFromObject, TypeProtocol, VirtualMachine,
};
use crossbeam_utils::atomic::AtomicCell;

View File

@@ -4,7 +4,7 @@ use crate::{
function::{FuncArgs, IntoPyObject},
pyclass::PyClassImpl,
types::GetAttr,
PyContext, PyObjectRef, PyObjectView, PyRef, PyResult, PyValue, VirtualMachine,
AsPyObject, PyContext, PyObjectRef, PyObjectView, PyRef, PyResult, PyValue, VirtualMachine,
};
#[pyclass(module = false, name = "module")]

View File

@@ -5,7 +5,7 @@ use crate::{
pyclass::PyClassImpl,
types::{Comparable, Constructor, PyComparisonOp},
vm::ReprGuard,
IdProtocol, PyContext, PyObject, PyRef, PyResult, PyValue, TypeProtocol, VirtualMachine,
AsPyObject, PyContext, PyObject, PyRef, PyResult, PyValue, TypeProtocol, VirtualMachine,
};
/// A simple attribute-based namespace.

View File

@@ -5,7 +5,7 @@ use crate::{
pyclass::PyClassImpl,
types::PyComparisonOp,
utils::Either,
IdProtocol, PyContext, PyObject, PyObjectRef, PyResult, PyValue, TypeProtocol, VirtualMachine,
AsPyObject, PyContext, PyObject, PyObjectRef, PyResult, PyValue, TypeProtocol, VirtualMachine,
};
/// object()

View File

@@ -3,7 +3,7 @@ use crate::{
function::{IntoPyObject, OptionalArg},
pyclass::PyClassImpl,
types::Constructor,
IdProtocol, PyContext, PyObject, PyObjectRef, PyResult, PyValue, TryFromBorrowedObject,
AsPyObject, PyContext, PyObject, PyObjectRef, PyResult, PyValue, TryFromBorrowedObject,
TypeProtocol, VirtualMachine,
};
use num_bigint::Sign;

View File

@@ -18,7 +18,7 @@ use crate::{
AsMapping, AsSequence, Comparable, Constructor, Hashable, IterNext, IterNextIterable,
Iterable, PyComparisonOp, Unconstructible,
},
IdProtocol, PyContext, PyObject, PyObjectRef, PyObjectView, PyRef, PyResult, PyValue,
AsPyObject, PyContext, PyObject, PyObjectRef, PyObjectView, PyRef, PyResult, PyValue,
TryFromBorrowedObject, TypeProtocol, VirtualMachine,
};
use ascii::{AsciiStr, AsciiString};

View File

@@ -8,7 +8,7 @@ use crate::{
function::OptionalArg,
pyclass::PyClassImpl,
types::{Constructor, GetAttr, GetDescriptor},
IdProtocol, PyContext, PyObjectRef, PyRef, PyResult, PyValue, TypeProtocol, VirtualMachine,
AsPyObject, PyContext, PyObjectRef, PyRef, PyResult, PyValue, TypeProtocol, VirtualMachine,
};
#[pyclass(module = false, name = "super")]

View File

@@ -12,11 +12,12 @@ use crate::{
pyclass::{PyClassImpl, StaticType},
pyobject::PyLease,
types::{Callable, GetAttr, PyTypeFlags, PyTypeSlots, SetAttr},
IdProtocol, PyContext, PyObjectRef, PyObjectWeak, PyRef, PyResult, PyValue, TypeProtocol,
AsPyObject, PyContext, PyObjectRef, PyObjectWeak, PyRef, PyResult, PyValue, TypeProtocol,
VirtualMachine,
};
use itertools::Itertools;
use std::{
borrow::Borrow,
collections::{HashMap, HashSet},
fmt,
ops::Deref,
@@ -208,8 +209,11 @@ impl PyType {
}
impl PyTypeRef {
pub fn issubclass<R: IdProtocol>(&self, cls: R) -> bool {
self._issubclass(cls)
/// Determines if `subclass` is actually a subclass of `cls`, this doesn't call __subclasscheck__,
/// so only use this if `cls` is known to have not overridden the base __subclasscheck__ magic
/// method.
pub fn issubclass(&self, cls: &impl Borrow<crate::PyObject>) -> bool {
self.as_object().is(cls.borrow()) || self.mro.iter().any(|c| c.is(cls.borrow()))
}
pub fn iter_mro(&self) -> impl Iterator<Item = &PyTypeRef> + DoubleEndedIterator {
@@ -787,44 +791,6 @@ pub(crate) fn init(ctx: &PyContext) {
PyType::extend_class(ctx, &ctx.types.type_type);
}
impl PyLease<'_, PyType> {
pub fn issubclass<R: IdProtocol>(&self, cls: R) -> bool {
self._issubclass(cls)
}
}
pub trait DerefToPyType {
fn deref_to_type(&self) -> &PyType;
/// 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.
fn _issubclass<R: IdProtocol>(&self, cls: R) -> bool
where
Self: IdProtocol,
{
self.is(&cls) || self.deref_to_type().mro.iter().any(|c| c.is(&cls))
}
}
impl DerefToPyType for PyTypeRef {
fn deref_to_type(&self) -> &PyType {
self.deref()
}
}
impl<'a> DerefToPyType for PyLease<'a, PyType> {
fn deref_to_type(&self) -> &PyType {
self.deref()
}
}
impl<T: DerefToPyType> DerefToPyType for &'_ T {
fn deref_to_type(&self) -> &PyType {
(&**self).deref_to_type()
}
}
pub(crate) fn call_slot_new(
typ: PyTypeRef,
subtype: PyTypeRef,

View File

@@ -6,7 +6,7 @@ use crate::{
protocol::PyMappingMethods,
pyclass::PyClassImpl,
types::{AsMapping, Comparable, GetAttr, Hashable, Iterable, PyComparisonOp},
IdProtocol, PyContext, PyObject, PyObjectRef, PyObjectView, PyRef, PyResult, PyValue,
AsPyObject, PyContext, PyObject, PyObjectRef, PyObjectView, PyRef, PyResult, PyValue,
TryFromObject, TypeProtocol, VirtualMachine,
};
use std::fmt;

View File

@@ -9,7 +9,7 @@ use crate::{
AsMapping, AsSequence, Comparable, Constructor, Hashable, IterNext, IterNextIterable,
Iterable, PyComparisonOp, Unconstructible,
},
IdProtocol, PyContext, PyObject, PyObjectRef, PyObjectView, PyRef, PyResult, PyValue,
AsPyObject, PyContext, PyObject, PyObjectRef, PyObjectView, PyRef, PyResult, PyValue,
TryFromObject, TypeProtocol, VirtualMachine,
};
use crossbeam_utils::atomic::AtomicCell;

View File

@@ -17,7 +17,7 @@ use crate::{
},
utils::collection_repr,
vm::{ReprGuard, VirtualMachine},
IdProtocol, PyContext, PyObject, PyObjectRef, PyRef, PyResult, PyValue, TryFromObject,
AsPyObject, PyContext, PyObject, PyObjectRef, PyRef, PyResult, PyValue, TryFromObject,
TypeProtocol,
};
use std::borrow::Cow;

View File

@@ -4,7 +4,8 @@ use crate::{
function::{FuncArgs, IntoPyObject, OptionalArg, PyComparisonValue},
pyclass::PyClassImpl,
types::{Comparable, Constructor, Hashable, PyComparisonOp, Unhashable},
PyContext, PyObject, PyObjectRef, PyRef, PyResult, PyValue, TypeProtocol, VirtualMachine,
AsPyObject, PyContext, PyObject, PyObjectRef, PyRef, PyResult, PyValue, TypeProtocol,
VirtualMachine,
};
use num_bigint::{BigInt, ToBigInt};
use num_traits::{One, Signed, ToPrimitive, Zero};

View File

@@ -14,7 +14,7 @@ use crate::{
},
utils::collection_repr,
vm::{ReprGuard, VirtualMachine},
IdProtocol, PyContext, PyObject, PyObjectRef, PyRef, PyResult, PyValue, TryFromObject,
AsPyObject, PyContext, PyObject, PyObjectRef, PyRef, PyResult, PyValue, TryFromObject,
TypeProtocol,
};
use std::{borrow::Cow, fmt, marker::PhantomData};

View File

@@ -7,8 +7,8 @@ use crate::{
function::OptionalArg,
pyclass::PyClassImpl,
types::{Callable, Comparable, Constructor, Hashable, PyComparisonOp},
IdProtocol, PyContext, PyObject, PyObjectRef, PyRef, PyResult, PyValue, TypeProtocol,
VirtualMachine,
AsPyObject, PyContext, PyObject, PyObjectRef, PyObjectWrap, PyRef, PyResult, PyValue,
TypeProtocol, VirtualMachine,
};
pub use crate::pyobject::PyWeak;

View File

@@ -9,7 +9,7 @@ use crate::{
sequence::{SequenceMutOp, SequenceOp},
types::PyComparisonOp,
utils::Either,
IdProtocol, PyObject, PyObjectRef, PyResult, PyValue, TryFromBorrowedObject, VirtualMachine,
AsPyObject, PyObject, PyObjectRef, PyResult, PyValue, TryFromBorrowedObject, VirtualMachine,
};
use bstr::ByteSlice;
use itertools::Itertools;

View File

@@ -2,7 +2,7 @@ use crate::{
builtins::{PyBaseExceptionRef, PyBytesRef, PyStr, PyStrRef, PyTuple, PyTupleRef},
common::{ascii, lock::PyRwLock},
function::IntoPyObject,
IdProtocol, PyContext, PyObject, PyObjectRef, PyResult, PyValue, TryFromObject, TypeProtocol,
AsPyObject, PyContext, PyObject, PyObjectRef, PyResult, PyValue, TryFromObject, TypeProtocol,
VirtualMachine,
};
use std::{borrow::Cow, collections::HashMap, fmt::Write, ops::Range};

View File

@@ -3,7 +3,7 @@ use crate::{
common::lock::PyMutex,
frame::{ExecutionResult, FrameRef},
protocol::PyIterReturn,
IdProtocol, PyObject, PyObjectRef, PyResult, TypeProtocol, VirtualMachine,
AsPyObject, PyObject, PyObjectRef, PyResult, TypeProtocol, VirtualMachine,
};
use crossbeam_utils::atomic::AtomicCell;

View File

@@ -10,7 +10,7 @@ use crate::common::{
use crate::{
builtins::{PyInt, PyStr, PyStrRef},
function::IntoPyObject,
IdProtocol, PyObject, PyObjectRef, PyObjectWrap, PyRefExact, PyResult, TypeProtocol,
AsPyObject, PyObject, PyObjectRef, PyObjectWrap, PyRefExact, PyResult, TypeProtocol,
VirtualMachine,
};
use num_traits::ToPrimitive;

View File

@@ -9,7 +9,7 @@ use crate::{
pyclass::{PyClassImpl, StaticType},
stdlib::sys,
suggestion::offer_suggestions,
IdProtocol, PyContext, PyObjectRef, PyRef, PyResult, PyValue, TryFromObject, TypeProtocol,
AsPyObject, PyContext, PyObjectRef, PyRef, PyResult, PyValue, TryFromObject, TypeProtocol,
VirtualMachine,
};
use crossbeam_utils::atomic::AtomicCell;

View File

@@ -15,7 +15,7 @@ use crate::{
scope::Scope,
stdlib::builtins,
types::PyComparisonOp,
IdProtocol, PyMethod, PyObject, PyObjectRef, PyObjectWrap, PyRef, PyResult, PyValue,
AsPyObject, PyMethod, PyObject, PyObjectRef, PyObjectWrap, PyRef, PyResult, PyValue,
TryFromObject, TypeProtocol, VirtualMachine,
};
use indexmap::IndexMap;

View File

@@ -6,7 +6,7 @@ use crate::{
PyObject, PyObjectRef, PyObjectWrap, PyResult, PyValue, TryFromObject, TypeProtocol,
VirtualMachine,
};
use std::marker::PhantomData;
use std::{borrow::Borrow, marker::PhantomData};
#[derive(Clone, Debug)]
pub struct ArgCallable {
@@ -14,13 +14,20 @@ pub struct ArgCallable {
}
impl ArgCallable {
#[inline]
pub fn invoke(&self, args: impl IntoFuncArgs, vm: &VirtualMachine) -> PyResult {
vm.invoke(&self.obj, args)
}
}
impl Borrow<PyObject> for ArgCallable {
#[inline(always)]
fn borrow(&self) -> &PyObject {
&self.obj
}
}
impl AsRef<PyObject> for ArgCallable {
#[inline(always)]
fn as_ref(&self) -> &PyObject {
&self.obj
}
@@ -109,19 +116,29 @@ impl ArgMapping {
}
}
impl Borrow<PyObject> for ArgMapping {
#[inline(always)]
fn borrow(&self) -> &PyObject {
&self.obj
}
}
impl AsRef<PyObject> for ArgMapping {
#[inline(always)]
fn as_ref(&self) -> &PyObject {
&self.obj
}
}
impl PyObjectWrap for ArgMapping {
#[inline(always)]
fn into_object(self) -> PyObjectRef {
self.obj
}
}
impl IntoPyObject for ArgMapping {
#[inline(always)]
fn into_pyobject(self, _vm: &VirtualMachine) -> PyObjectRef {
self.obj
}

View File

@@ -1,7 +1,7 @@
use crate::{
convert::TryFromObject,
function::IntoPyObject,
pyobject::{IdProtocol, PyObjectRef, PyResult},
pyobject::{AsPyObject, PyObjectRef, PyResult},
VirtualMachine,
};

View File

@@ -127,7 +127,7 @@ pub fn import_codeobj(
let attrs = vm.ctx.new_dict();
attrs.set_item("__name__", vm.ctx.new_str(module_name).into(), vm)?;
if set_file_attr {
attrs.set_item("__file__", code_obj.source_path.as_object().to_owned(), vm)?;
attrs.set_item("__file__", code_obj.source_path.clone().into(), vm)?;
}
let module = vm.new_module(module_name, attrs.clone(), None);

View File

@@ -89,12 +89,12 @@ mod pyobject {
pub use self::convert::{TryFromBorrowedObject, TryFromObject};
// pyobject items
pub use self::pyobject::{
IdProtocol, PyContext, PyMethod, PyObjectPayload, PyRefExact, PyResult, PyStructSequence,
PyContext, PyMethod, PyObjectPayload, PyObjectWrap, PyRefExact, PyResult, PyStructSequence,
PyValue, TypeProtocol,
};
// pyobjectrc items
pub use self::pyobject::{
PyObject, PyObjectRef, PyObjectView, PyObjectWeak, PyObjectWrap, PyRef, PyWeakRef,
AsPyObject, PyObject, PyObjectRef, PyObjectView, PyObjectWeak, PyRef, PyWeakRef,
};
pub use self::vm::{InitParameter, Interpreter, PySettings, VirtualMachine};
pub use rustpython_bytecode as bytecode;

View File

@@ -49,7 +49,7 @@ macro_rules! py_namespace {
{
let namespace = $crate::builtins::PyNamespace::new_ref(&$vm.ctx);
$(
$vm.__module_set_attr(namespace.as_object(), $name, $value).unwrap();
$vm.__module_set_attr($crate::pyobject::AsPyObject::as_object(&namespace), $name, $value).unwrap();
)*
namespace
}

View File

@@ -1,8 +1,8 @@
use crate::{
builtins::iter::PySequenceIterator,
function::{IntoPyObject, IntoPyResult},
PyObject, PyObjectRef, PyObjectWrap, PyResult, PyValue, TryFromObject, TypeProtocol,
VirtualMachine,
AsPyObject, PyObject, PyObjectRef, PyObjectWrap, PyResult, PyValue, TryFromObject,
TypeProtocol, VirtualMachine,
};
use std::borrow::Borrow;
use std::ops::Deref;
@@ -76,10 +76,21 @@ impl PyObjectWrap for PyIter<PyObjectRef> {
}
}
impl<O> Borrow<PyObject> for PyIter<O>
where
O: Borrow<PyObject>,
{
#[inline(always)]
fn borrow(&self) -> &PyObject {
self.0.borrow()
}
}
impl<O> AsRef<PyObject> for PyIter<O>
where
O: Borrow<PyObject>,
{
#[inline(always)]
fn as_ref(&self) -> &PyObject {
self.0.borrow()
}
@@ -90,12 +101,14 @@ where
O: Borrow<PyObject>,
{
type Target = PyObject;
#[inline(always)]
fn deref(&self) -> &Self::Target {
self.0.borrow()
}
}
impl IntoPyObject for PyIter<PyObjectRef> {
#[inline(always)]
fn into_pyobject(self, _vm: &VirtualMachine) -> PyObjectRef {
self.into()
}

View File

@@ -5,7 +5,7 @@ use crate::{
},
common::lock::OnceCell,
function::IntoPyResult,
IdProtocol, PyObject, PyObjectRef, PyResult, TypeProtocol, VirtualMachine,
AsPyObject, PyObject, PyObjectRef, PyResult, TypeProtocol, VirtualMachine,
};
// Mapping protocol

View File

@@ -13,7 +13,7 @@ use crate::{
protocol::{PyIter, PyMapping, PySequence},
types::{Constructor, PyComparisonOp},
utils::Either,
IdProtocol, PyObject, PyObjectRef, PyResult, TryFromObject, TypeProtocol, VirtualMachine,
AsPyObject, PyObject, PyObjectRef, PyResult, TryFromObject, TypeProtocol, VirtualMachine,
};
// RustPython doesn't need these items
@@ -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.issubclass(&cls))
} else {
self.check_cls(self, vm, || {
format!("issubclass() arg 1 must be a class, not {}", self.class())
@@ -324,7 +324,7 @@ impl PyObject {
fn abstract_isinstance(&self, cls: &PyObject, vm: &VirtualMachine) -> PyResult<bool> {
if let Ok(typ) = PyTypeRef::try_from_object(vm, cls.to_owned()) {
if self.class().issubclass(typ.clone()) {
if self.class().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.issubclass(&typ))
}
} else {
Ok(false)

View File

@@ -3,7 +3,7 @@ use crate::{
common::lock::OnceCell,
function::{IntoPyObject, PyArithmeticValue},
protocol::PyMapping,
IdProtocol, PyObject, PyObjectRef, PyResult, PyValue, TypeProtocol, VirtualMachine,
AsPyObject, PyObject, PyObjectRef, PyResult, PyValue, TypeProtocol, VirtualMachine,
};
use itertools::Itertools;
use std::{

View File

@@ -1,7 +1,4 @@
pub use crate::_pyobjectrc::{
PyObject, PyObjectRef, PyObjectView, PyObjectWeak, PyObjectWrap, PyRef, PyWeakRef,
};
use crate::common::{lock::PyRwLockReadGuard, rc::PyRc};
use crate::common::lock::PyRwLockReadGuard;
use crate::{
builtins::{
builtinfunc::{PyBuiltinFunction, PyBuiltinMethod, PyNativeFuncDef},
@@ -20,10 +17,11 @@ use crate::{
pyclass::{PyClassImpl, StaticType},
types::{PyTypeFlags, PyTypeSlots, TypeZoo},
VirtualMachine,
_pyobjectrc::{PyObject, PyObjectRef, PyObjectView, PyRef},
};
use num_bigint::BigInt;
use num_traits::ToPrimitive;
use std::{any::Any, fmt, ops::Deref};
use std::{any::Any, borrow::Borrow, fmt, ops::Deref};
/* Python objects and references.
@@ -136,14 +134,17 @@ impl PyContext {
context
}
#[inline(always)]
pub fn none(&self) -> PyObjectRef {
self.none.clone().into()
}
#[inline(always)]
pub fn ellipsis(&self) -> PyObjectRef {
self.ellipsis.clone().into()
}
#[inline(always)]
pub fn not_implemented(&self) -> PyObjectRef {
self.not_implemented.clone().into()
}
@@ -172,19 +173,22 @@ impl PyContext {
PyRef::new_ref(PyInt::from(i.clone()), self.types.int_type.clone(), None)
}
#[inline]
pub fn new_float(&self, value: f64) -> PyRef<PyFloat> {
PyRef::new_ref(PyFloat::from(value), self.types.float_type.clone(), None)
}
#[inline]
pub fn new_str(&self, s: impl Into<pystr::PyStr>) -> PyRef<PyStr> {
pystr::PyStr::new_ref(s, self)
}
#[inline]
pub fn new_bytes(&self, data: Vec<u8>) -> PyRef<bytes::PyBytes> {
bytes::PyBytes::new_ref(data, self)
}
#[inline]
#[inline(always)]
pub fn new_bool(&self, b: bool) -> PyIntRef {
let value = if b {
&self.true_value
@@ -194,14 +198,17 @@ impl PyContext {
value.clone()
}
#[inline(always)]
pub fn new_tuple(&self, elements: Vec<PyObjectRef>) -> PyTupleRef {
PyTuple::new_ref(elements, self)
}
#[inline(always)]
pub fn new_list(&self, elements: Vec<PyObjectRef>) -> PyListRef {
PyList::new_ref(elements, self)
}
#[inline(always)]
pub fn new_dict(&self) -> PyDictRef {
PyDict::new_ref(self)
}
@@ -378,56 +385,54 @@ impl<T: PyValue> TryFromObject for PyRefExact<T> {
}
impl<T: PyValue> Deref for PyRefExact<T> {
type Target = PyRef<T>;
#[inline(always)]
fn deref(&self) -> &PyRef<T> {
&self.obj
}
}
impl<T: PyValue> IntoPyObject for PyRefExact<T> {
#[inline]
#[inline(always)]
fn into_pyobject(self, _vm: &VirtualMachine) -> PyObjectRef {
self.obj.into()
}
}
pub trait IdProtocol {
fn get_id(&self) -> usize;
pub trait AsPyObject
where
Self: Borrow<PyObject>,
{
#[inline(always)]
fn as_object(&self) -> &PyObject {
self.borrow()
}
#[inline(always)]
fn get_id(&self) -> usize {
self.as_object()._get_id()
}
#[inline(always)]
fn is<T>(&self, other: &T) -> bool
where
T: IdProtocol,
T: AsPyObject,
{
self.get_id() == other.get_id()
}
}
impl<T: ?Sized> IdProtocol for PyRc<T> {
fn get_id(&self) -> usize {
&**self as *const T as *const () as usize
impl<T> AsPyObject for T where T: Borrow<PyObject> {}
impl PyObject {
#[inline]
fn _get_id(&self) -> usize {
self as *const PyObject as usize
}
}
impl<T: PyObjectPayload> IdProtocol for PyRef<T> {
fn get_id(&self) -> usize {
self.as_object().get_id()
}
}
impl<T: PyObjectPayload> IdProtocol for PyObjectView<T> {
fn get_id(&self) -> usize {
self.as_object().get_id()
}
}
impl<'a, T: PyObjectPayload> IdProtocol for PyLease<'a, T> {
fn get_id(&self) -> usize {
self.inner.get_id()
}
}
impl<T: IdProtocol> IdProtocol for &'_ T {
fn get_id(&self) -> usize {
(&**self).get_id()
}
}
// impl<T: ?Sized> Borrow<PyObject> for PyRc<T> {
// #[inline(always)]
// fn borrow(&self) -> &PyObject {
// unsafe { &*(&**self as *const T as *const PyObject) }
// }
// }
/// A borrow of a reference to a Python object. This avoids having clone the `PyRef<T>`/
/// `PyObjectRef`, which isn't that cheap as that increments the atomic reference counter.
@@ -438,14 +443,22 @@ pub struct PyLease<'a, T: PyObjectPayload> {
impl<'a, T: PyObjectPayload + PyValue> PyLease<'a, T> {
// Associated function on purpose, because of deref
#[allow(clippy::wrong_self_convention)]
#[inline(always)]
pub fn into_pyref(zelf: Self) -> PyRef<T> {
zelf.inner.clone()
}
}
impl<'a, T: PyObjectPayload + PyValue> Deref for PyLease<'a, T> {
type Target = T;
impl<'a, T: PyObjectPayload + PyValue> Borrow<PyObject> for PyLease<'a, T> {
#[inline(always)]
fn borrow(&self) -> &PyObject {
self.inner.as_ref()
}
}
impl<'a, T: PyObjectPayload + PyValue> Deref for PyLease<'a, T> {
type Target = PyRef<T>;
#[inline(always)]
fn deref(&self) -> &Self::Target {
&self.inner
}
@@ -521,27 +534,28 @@ impl<T, P> IntoPyRef<P> for T
where
P: PyValue + IntoPyObject + From<T>,
{
#[inline(always)]
fn into_pyref(self, vm: &VirtualMachine) -> PyRef<P> {
P::from(self).into_ref(vm)
}
}
impl<T: PyObjectPayload> IntoPyObject for PyRef<T> {
#[inline]
#[inline(always)]
fn into_pyobject(self, _vm: &VirtualMachine) -> PyObjectRef {
self.into()
}
}
impl IntoPyObject for PyObjectRef {
#[inline]
#[inline(always)]
fn into_pyobject(self, _vm: &VirtualMachine) -> PyObjectRef {
self
}
}
impl IntoPyObject for &PyObject {
#[inline]
#[inline(always)]
fn into_pyobject(self, _vm: &VirtualMachine) -> PyObjectRef {
self.to_owned()
}
@@ -553,7 +567,7 @@ impl<T> IntoPyObject for T
where
T: PyValue + Sized,
{
#[inline]
#[inline(always)]
fn into_pyobject(self, vm: &VirtualMachine) -> PyObjectRef {
PyValue::into_object(self, vm)
}
@@ -563,6 +577,7 @@ impl<T> IntoPyResult for T
where
T: IntoPyObject,
{
#[inline(always)]
fn into_pyresult(self, vm: &VirtualMachine) -> PyResult {
Ok(self.into_pyobject(vm))
}
@@ -572,6 +587,7 @@ impl<T> IntoPyResult for PyResult<T>
where
T: IntoPyObject,
{
#[inline(always)]
fn into_pyresult(self, vm: &VirtualMachine) -> PyResult {
self.map(|res| T::into_pyobject(res, vm))
}
@@ -600,6 +616,7 @@ pub trait PyValue: fmt::Debug + PyThreadingConstraint + Sized + 'static {
None
}
#[inline]
fn _into_ref(self, cls: PyTypeRef, vm: &VirtualMachine) -> PyRef<Self> {
let dict = if cls.slots.flags.has_feature(PyTypeFlags::HAS_DICT) {
Some(vm.ctx.new_dict())
@@ -609,24 +626,36 @@ pub trait PyValue: fmt::Debug + PyThreadingConstraint + Sized + 'static {
PyRef::new_ref(self, cls, dict)
}
#[inline]
fn into_ref(self, vm: &VirtualMachine) -> PyRef<Self> {
let cls = Self::class(vm);
self._into_ref(cls.clone(), vm)
}
#[cold]
fn _into_ref_with_type_error(
vm: &VirtualMachine,
cls: &PyTypeRef,
exact_class: &PyTypeRef,
) -> PyBaseExceptionRef {
vm.new_type_error(format!(
"'{}' is not a subtype of '{}'",
&cls.name(),
exact_class.name()
))
}
#[inline]
fn into_ref_with_type(self, vm: &VirtualMachine, cls: PyTypeRef) -> PyResult<PyRef<Self>> {
let exact_class = Self::class(vm);
if cls.issubclass(exact_class) {
Ok(self._into_ref(cls, vm))
} else {
Err(vm.new_type_error(format!(
"'{}' is not a subtype of '{}'",
&cls.name(),
exact_class.name()
)))
Err(Self::_into_ref_with_type_error(vm, &cls, exact_class))
}
}
#[inline]
fn into_pyresult_with_type(self, vm: &VirtualMachine, cls: PyTypeRef) -> PyResult {
self.into_ref_with_type(vm, cls).into_pyresult(vm)
}
@@ -699,6 +728,23 @@ pub trait PyStructSequence: StaticType + PyClassImpl + Sized + 'static {
}
}
pub trait PyObjectWrap
where
Self: AsPyObject,
{
fn into_object(self) -> PyObjectRef;
}
impl<T> From<T> for PyObjectRef
where
T: PyObjectWrap,
{
#[inline(always)]
fn from(py_ref: T) -> Self {
py_ref.into_object()
}
}
#[derive(Debug)]
pub enum PyMethod {
Function {

View File

@@ -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::{IdProtocol, PyObjectPayload, PyResult, TypeProtocol},
_pyobject::{AsPyObject, PyObjectPayload, PyObjectWrap, PyResult, TypeProtocol},
builtins::{PyBaseExceptionRef, PyDictRef, PyTypeRef},
vm::VirtualMachine,
};
@@ -283,14 +283,17 @@ unsafe impl Link for WeakLink {
type Target = PyObjectView<PyWeak>;
#[inline(always)]
fn as_raw(handle: &PyRef<PyWeak>) -> NonNull<Self::Target> {
NonNull::from(&**handle)
}
#[inline(always)]
unsafe fn from_raw(ptr: NonNull<Self::Target>) -> Self::Handle {
PyRef::from_raw(ptr.as_ptr())
}
#[inline(always)]
unsafe fn pointers(target: NonNull<Self::Target>) -> NonNull<Pointers<Self::Target>> {
NonNull::new_unchecked(ptr::addr_of_mut!((*target.as_ptr()).0.payload.pointers))
}
@@ -331,7 +334,6 @@ impl PyWeak {
guard.obj.is_none()
}
#[inline(always)]
fn drop_inner(&self) {
let dealloc = {
let mut guard = unsafe { self.parent.as_ref().lock() };
@@ -354,6 +356,7 @@ impl PyWeak {
}
impl Drop for PyWeak {
#[inline(always)]
fn drop(&mut self) {
// we do NOT have actual exclusive access!
// no clue if doing this actually reduces chance of UB
@@ -368,7 +371,7 @@ struct InstanceDict {
}
impl From<PyDictRef> for InstanceDict {
#[inline]
#[inline(always)]
fn from(d: PyDictRef) -> Self {
Self::new(d)
}
@@ -447,6 +450,7 @@ pub struct PyObject(PyInner<Erased>);
impl Deref for PyObjectRef {
type Target = PyObject;
#[inline(always)]
fn deref(&self) -> &PyObject {
unsafe { self.ptr.as_ref() }
}
@@ -464,19 +468,8 @@ impl ToOwned for PyObject {
}
}
pub trait PyObjectWrap
where
Self: AsRef<PyObject>,
{
#[inline(always)]
fn as_object(&self) -> &PyObject {
self.as_ref()
}
fn into_object(self) -> PyObjectRef;
}
impl PyObjectRef {
#[inline(always)]
pub fn into_raw(self) -> *const PyObject {
let ptr = self.as_raw();
std::mem::forget(self);
@@ -488,6 +481,7 @@ impl PyObjectRef {
/// [`PyObjectRef::into_raw`]. The user is responsible for ensuring that the inner data is not
/// dropped more than once due to mishandling the reference count by calling this function
/// too many times.
#[inline(always)]
pub unsafe fn from_raw(ptr: *const PyObject) -> Self {
Self {
ptr: NonNull::new_unchecked(ptr as *mut PyObject),
@@ -498,6 +492,7 @@ impl PyObjectRef {
///
/// If the downcast fails, the original ref is returned in as `Err` so
/// another downcast can be attempted without unnecessary cloning.
#[inline(always)]
pub fn downcast<T: PyObjectPayload>(self) -> Result<PyRef<T>, Self> {
if self.payload_is::<T>() {
Ok(unsafe { PyRef::from_obj_unchecked(self) })
@@ -506,6 +501,7 @@ impl PyObjectRef {
}
}
#[inline(always)]
pub fn downcast_ref<T: PyObjectPayload>(&self) -> Option<&PyObjectView<T>> {
if self.payload_is::<T>() {
// SAFETY: just checked that the payload is T, and PyRef is repr(transparent) over
@@ -518,12 +514,14 @@ impl PyObjectRef {
/// # Safety
/// T must be the exact payload type
#[inline(always)]
pub unsafe fn downcast_unchecked<T: PyObjectPayload>(self) -> PyRef<T> {
PyRef::from_obj_unchecked(self)
}
/// # Safety
/// T must be the exact payload type
#[inline(always)]
pub unsafe fn downcast_unchecked_ref<T: PyObjectPayload>(&self) -> &crate::PyObjectView<T> {
debug_assert!(self.payload_is::<T>());
&*(self as *const PyObjectRef as *const PyRef<T>)
@@ -535,6 +533,7 @@ impl PyObjectRef {
///
/// If the downcast fails, the original ref is returned in as `Err` so
/// another downcast can be attempted without unnecessary cloning.
#[inline]
pub fn downcast_exact<T: PyObjectPayload + crate::PyValue>(
self,
vm: &VirtualMachine,
@@ -554,7 +553,7 @@ impl PyObjectRef {
}
impl PyObject {
#[inline]
#[inline(always)]
fn weak_ref_list(&self) -> Option<&WeakRefList> {
Some(&self.0.weak_list)
}
@@ -607,11 +606,12 @@ impl PyObject {
self.weak_ref_list().map(|wrl| wrl.get_weak_references())
}
#[inline]
#[inline(always)]
pub fn payload_is<T: PyObjectPayload>(&self) -> bool {
self.0.typeid == TypeId::of::<T>()
}
#[inline(always)]
pub fn payload<T: PyObjectPayload>(&self) -> Option<&T> {
if self.payload_is::<T>() {
// we cast to a PyInner<T> first because we don't know T's exact offset because of
@@ -623,11 +623,12 @@ impl PyObject {
}
}
#[inline(always)]
pub(crate) fn class_lock(&self) -> &PyRwLock<PyTypeRef> {
&self.0.typ
}
#[inline]
#[inline(always)]
pub fn payload_if_exact<T: PyObjectPayload + crate::PyValue>(
&self,
vm: &VirtualMachine,
@@ -639,14 +640,16 @@ impl PyObject {
}
}
#[inline]
#[inline(always)]
fn instance_dict(&self) -> Option<&InstanceDict> {
self.0.dict.as_ref()
}
#[inline(always)]
pub fn dict(&self) -> Option<PyDictRef> {
self.instance_dict().map(|d| d.get())
}
/// Set the dict field. Returns `Err(dict)` if this object does not have a dict field
/// in the first place.
pub fn set_dict(&self, dict: PyDictRef) -> Result<(), PyDictRef> {
@@ -659,7 +662,7 @@ impl PyObject {
}
}
#[inline]
#[inline(always)]
pub fn payload_if_subclass<T: crate::PyValue>(&self, vm: &VirtualMachine) -> Option<&T> {
if self.class().issubclass(T::class(vm)) {
self.payload()
@@ -668,6 +671,7 @@ impl PyObject {
}
}
#[inline(always)]
pub fn downcast_ref<T: PyObjectPayload>(&self) -> Option<&PyObjectView<T>> {
if self.payload_is::<T>() {
// SAFETY: just checked that the payload is T, and PyRef is repr(transparent) over
@@ -678,6 +682,7 @@ impl PyObject {
}
}
#[inline(always)]
pub fn downcast_ref_if_exact<T: PyObjectPayload + crate::PyValue>(
&self,
vm: &VirtualMachine,
@@ -689,13 +694,13 @@ impl PyObject {
/// # Safety
/// T must be the exact payload type
#[inline]
#[inline(always)]
pub unsafe fn downcast_unchecked_ref<T: PyObjectPayload>(&self) -> &PyObjectView<T> {
debug_assert!(self.payload_is::<T>());
&*(self as *const PyObject as *const PyObjectView<T>)
}
#[inline]
#[inline(always)]
pub fn strong_count(&self) -> usize {
self.0.ref_count.get()
}
@@ -705,12 +710,12 @@ impl PyObject {
self.weak_ref_list().map(|wrl| wrl.count())
}
#[inline]
#[inline(always)]
pub fn as_raw(&self) -> *const PyObject {
self
}
#[inline]
#[inline(always)] // the outer function is never inlined
fn drop_slow_inner(&self) -> Result<(), ()> {
// CPython-compatible drop implementation
if let Some(slot_del) = self.class().mro_find_map(|cls| cls.slots.del.load()) {
@@ -753,62 +758,56 @@ impl PyObject {
}
impl Borrow<PyObject> for PyObjectRef {
#[inline(always)]
fn borrow(&self) -> &PyObject {
self
}
}
impl AsRef<PyObject> for PyObjectRef {
#[inline(always)]
fn as_ref(&self) -> &PyObject {
self
}
}
impl AsRef<PyObject> for PyObject {
#[inline(always)]
fn as_ref(&self) -> &PyObject {
self
}
}
impl IdProtocol for PyObjectRef {
fn get_id(&self) -> usize {
self.ptr.as_ptr() as usize
}
}
impl IdProtocol for PyObject {
fn get_id(&self) -> usize {
self as *const PyObject as usize
}
}
impl<'a, T: PyObjectPayload> From<&'a PyObjectView<T>> for &'a PyObject {
#[inline(always)]
fn from(py_ref: &'a PyObjectView<T>) -> Self {
py_ref.as_object()
}
}
impl<T> From<T> for PyObjectRef
where
T: PyObjectWrap,
{
fn from(py_ref: T) -> Self {
py_ref.into_object()
impl Borrow<PyObject> for PyObjectWeak {
#[inline(always)]
fn borrow(&self) -> &PyObject {
self.weak.as_object()
}
}
impl PyObjectWeak {
#[inline]
pub fn upgrade(&self) -> Option<PyObjectRef> {
self.weak.upgrade()
}
pub fn into_object(self) -> PyObjectRef {
impl PyObjectWrap for PyObjectWeak {
#[inline(always)]
fn into_object(self) -> PyObjectRef {
self.weak.into_object()
}
}
impl PyObjectWeak {
#[inline(always)]
pub fn upgrade(&self) -> Option<PyObjectRef> {
self.weak.upgrade()
}
}
impl Drop for PyObjectRef {
#[inline]
fn drop(&mut self) {
if self.0.ref_count.dec() {
unsafe { PyObject::drop_slow(self.ptr) }
@@ -854,11 +853,6 @@ impl fmt::Debug for PyObjectWeak {
pub struct PyObjectView<T: PyObjectPayload>(PyInner<T>);
impl<T: PyObjectPayload> PyObjectView<T> {
#[inline(always)]
pub fn as_object(&self) -> &PyObject {
unsafe { &*(&self.0 as *const PyInner<T> as *const PyObject) }
}
pub fn downgrade(
&self,
callback: Option<PyObjectRef>,
@@ -886,17 +880,26 @@ impl<T: PyObjectPayload> ToOwned for PyObjectView<T> {
impl<T: PyObjectPayload> Deref for PyObjectView<T> {
type Target = T;
#[inline(always)]
fn deref(&self) -> &Self::Target {
&self.0.payload
}
}
impl<T: PyObjectPayload> Borrow<PyObject> for PyObjectView<T> {
#[inline(always)]
fn borrow(&self) -> &PyObject {
unsafe { &*(&self.0 as *const PyInner<T> as *const PyObject) }
}
}
impl<T> AsRef<PyObject> for PyObjectView<T>
where
T: PyObjectPayload,
{
#[inline(always)]
fn as_ref(&self) -> &PyObject {
self.as_object()
self.borrow()
}
}
@@ -950,6 +953,7 @@ impl<T: PyObjectPayload> Clone for PyRef<T> {
}
impl<T: PyObjectPayload> PyRef<T> {
#[inline(always)]
unsafe fn from_raw(raw: *const PyObjectView<T>) -> Self {
Self {
ptr: NonNull::new_unchecked(raw as *mut _),
@@ -957,7 +961,7 @@ impl<T: PyObjectPayload> PyRef<T> {
}
/// Safety: payload type of `obj` must be `T`
#[inline]
#[inline(always)]
unsafe fn from_obj_unchecked(obj: PyObjectRef) -> Self {
debug_assert!(obj.payload_is::<T>());
let obj = ManuallyDrop::new(obj);
@@ -966,7 +970,7 @@ impl<T: PyObjectPayload> PyRef<T> {
}
}
#[inline]
#[inline(always)]
pub fn new_ref(payload: T, typ: crate::builtins::PyTypeRef, dict: Option<PyDictRef>) -> Self {
let inner = Box::into_raw(PyInner::new(payload, typ, dict));
Self {
@@ -975,6 +979,26 @@ impl<T: PyObjectPayload> PyRef<T> {
}
}
impl<T> Borrow<PyObject> for PyRef<T>
where
T: PyObjectPayload,
{
#[inline(always)]
fn borrow(&self) -> &PyObject {
(**self).as_object()
}
}
impl<T> AsRef<PyObject> for PyRef<T>
where
T: PyObjectPayload,
{
#[inline(always)]
fn as_ref(&self) -> &PyObject {
self.borrow()
}
}
impl<T> PyObjectWrap for PyRef<T>
where
T: PyObjectPayload,
@@ -986,20 +1010,11 @@ where
}
}
impl<T> AsRef<PyObject> for PyRef<T>
where
T: PyObjectPayload,
{
#[inline(always)]
fn as_ref(&self) -> &PyObject {
(**self).as_object()
}
}
impl<T> Borrow<PyObjectView<T>> for PyRef<T>
where
T: PyObjectPayload,
{
#[inline(always)]
fn borrow(&self) -> &PyObjectView<T> {
self
}

View File

@@ -3,7 +3,7 @@ use crate::{
types::{richcompare_wrapper, PyComparisonOp, RichCompareFunc},
utils::Either,
vm::VirtualMachine,
IdProtocol, PyObject, PyObjectRef, PyResult, TypeProtocol,
AsPyObject, PyObject, PyObjectRef, PyResult, TypeProtocol,
};
use itertools::Itertools;
use optional::Optioned;

View File

@@ -8,7 +8,7 @@ mod gen;
use crate::{
builtins::{self, PyStrRef, PyTypeRef},
pyclass::{PyClassImpl, StaticType},
IdProtocol, PyContext, PyObject, PyObjectRef, PyResult, PyValue, TryFromObject, TypeProtocol,
AsPyObject, PyContext, PyObject, PyObjectRef, PyResult, PyValue, TryFromObject, TypeProtocol,
VirtualMachine,
};
use num_complex::Complex64;

View File

@@ -33,7 +33,7 @@ mod builtins {
stdlib::sys,
types::PyComparisonOp,
utils::Either,
IdProtocol, PyObject, PyObjectRef, PyObjectWrap, PyRef, PyResult, PyValue, TryFromObject,
AsPyObject, PyObject, PyObjectRef, PyObjectWrap, PyRef, PyResult, PyValue, TryFromObject,
TypeProtocol, VirtualMachine,
};
use num_traits::{Signed, ToPrimitive, Zero};

View File

@@ -7,7 +7,7 @@ mod _codecs {
builtins::{PyBaseExceptionRef, PyBytes, PyBytesRef, PyStr, PyStrRef, PyTuple},
codecs,
function::{ArgBytesLike, FuncArgs},
IdProtocol, PyObject, PyObjectRef, PyResult, TryFromBorrowedObject, VirtualMachine,
AsPyObject, PyObject, PyObjectRef, PyResult, TryFromBorrowedObject, VirtualMachine,
};
use std::ops::Range;

View File

@@ -19,7 +19,7 @@ mod _collections {
},
utils::collection_repr,
vm::ReprGuard,
PyObject, PyObjectRef, PyRef, PyResult, PyValue, TypeProtocol, VirtualMachine,
AsPyObject, PyObject, PyObjectRef, PyRef, PyResult, PyValue, TypeProtocol, VirtualMachine,
};
use crossbeam_utils::atomic::AtomicCell;
use std::cmp::max;

View File

@@ -88,7 +88,7 @@ mod _io {
types::{Constructor, Destructor, IterNext, Iterable},
utils::Either,
vm::{ReprGuard, VirtualMachine},
IdProtocol, PyContext, PyObject, PyObjectRef, PyObjectWrap, PyRef, PyResult, PyValue,
AsPyObject, PyContext, PyObject, PyObjectRef, PyObjectWrap, PyRef, PyResult, PyValue,
TryFromBorrowedObject, TryFromObject, TypeProtocol,
};
use bstr::ByteSlice;
@@ -3661,7 +3661,8 @@ mod fileio {
ArgBytesLike, ArgMemoryBuffer, FuncArgs, IntoPyException, OptionalArg, OptionalOption,
},
stdlib::os,
PyObjectRef, PyRef, PyResult, PyValue, TryFromObject, TypeProtocol, VirtualMachine,
AsPyObject, PyObjectRef, PyRef, PyResult, PyValue, TryFromObject, TypeProtocol,
VirtualMachine,
};
use crossbeam_utils::atomic::AtomicCell;
use std::io::{Read, Write};

View File

@@ -12,7 +12,7 @@ mod decl {
protocol::{PyIter, PyIterReturn},
stdlib::sys,
types::{Constructor, IterNext, IterNextIterable},
IdProtocol, PyObjectRef, PyObjectView, PyRef, PyResult, PyValue, PyWeakRef, TypeProtocol,
AsPyObject, PyObjectRef, PyObjectView, PyRef, PyResult, PyValue, PyWeakRef, TypeProtocol,
VirtualMachine,
};
use crossbeam_utils::atomic::AtomicCell;

View File

@@ -10,7 +10,7 @@ mod decl {
bytecode,
function::{ArgBytesLike, IntoPyObject},
protocol::PyBuffer,
pyobject::{IdProtocol, TypeProtocol},
pyobject::{AsPyObject, TypeProtocol},
PyObjectRef, PyResult, TryFromObject, VirtualMachine,
};
/// TODO

View File

@@ -20,7 +20,7 @@ mod _operator {
},
utils::Either,
vm::ReprGuard,
IdProtocol, PyObjectRef, PyObjectView, PyRef, PyResult, PyValue, TypeProtocol,
AsPyObject, PyObjectRef, PyObjectView, PyRef, PyResult, PyValue, TypeProtocol,
VirtualMachine,
};

View File

@@ -3,8 +3,8 @@ use crate::{
crt_fd::Fd,
function::{ArgumentError, FromArgs, FuncArgs, IntoPyException, IntoPyObject},
protocol::PyBuffer,
PyObject, PyObjectRef, PyResult, PyValue, TryFromBorrowedObject, TryFromObject, TypeProtocol,
VirtualMachine,
AsPyObject, PyObject, PyObjectRef, PyResult, PyValue, TryFromBorrowedObject, TryFromObject,
TypeProtocol, VirtualMachine,
};
use std::{
ffi, fs,

View File

@@ -30,7 +30,7 @@ pub(crate) fn make_module(vm: &VirtualMachine) -> PyObjectRef {
pub mod module {
use crate::{
builtins::{PyDictRef, PyInt, PyIntRef, PyListRef, PyStrRef, PyTupleRef, PyTypeRef},
function::{ArgBytesLike, IntoPyException, IntoPyObject, OptionalArg},
function::{IntoPyException, IntoPyObject, OptionalArg},
stdlib::os::{
errno_err, DirFd, FollowSymlinks, PathOrFd, PyPathLike, SupportFunc, TargetIsDirectory,
_os, fs_metadata, IOErrorBuilder,
@@ -1929,10 +1929,10 @@ pub mod module {
fn _extract_vec_bytes(
x: OptionalArg,
vm: &VirtualMachine,
) -> PyResult<Option<Vec<ArgBytesLike>>> {
) -> PyResult<Option<Vec<crate::function::ArgBytesLike>>> {
x.into_option()
.map(|x| {
let v: Vec<ArgBytesLike> = x.try_to_value(vm)?;
let v: Vec<crate::function::ArgBytesLike> = x.try_to_value(vm)?;
Ok(if v.is_empty() { None } else { Some(v) })
})
.transpose()

View File

@@ -5,7 +5,7 @@ mod pwd {
use crate::{
builtins::{PyIntRef, PyStrRef},
function::{IntoPyException, IntoPyObject},
PyObjectRef, PyResult, PyStructSequence, VirtualMachine,
AsPyObject, PyObjectRef, PyResult, PyStructSequence, VirtualMachine,
};
use nix::unistd::{self, User};
use std::ptr::NonNull;

View File

@@ -10,7 +10,7 @@ pub(crate) mod _thread {
py_io,
types::{Constructor, GetAttr, SetAttr},
utils::Either,
IdProtocol, PyObjectRef, PyRef, PyResult, PyValue, TypeProtocol, VirtualMachine,
AsPyObject, PyObjectRef, PyRef, PyResult, PyValue, TypeProtocol, VirtualMachine,
};
use parking_lot::{
lock_api::{RawMutex as RawMutexT, RawMutexTimed, RawReentrantMutex},

View File

@@ -9,7 +9,7 @@ pub(crate) use _weakref::make_module;
#[pymodule]
mod _weakref {
use crate::builtins::{PyDictRef, PyTypeRef, PyWeak};
use crate::{PyObjectRef, PyResult, VirtualMachine};
use crate::{PyObjectRef, PyObjectWrap, PyResult, VirtualMachine};
#[pyattr(name = "ref")]
fn ref_(vm: &VirtualMachine) -> PyTypeRef {

View File

@@ -2,7 +2,7 @@ use crate::{
builtins::{PyStr, PyStrRef},
exceptions::types::PyBaseExceptionRef,
sliceable::SliceableSequenceOp,
IdProtocol, PyObjectRef, PyObjectView, TypeProtocol, VirtualMachine,
AsPyObject, PyObjectRef, PyObjectView, TypeProtocol, VirtualMachine,
};
use rustpython_common::str::levenshtein::{levenshtein_distance, MOVE_COST};
use std::iter::ExactSizeIterator;

View File

@@ -6,12 +6,15 @@ use crate::{
protocol::{PyBuffer, PyIterReturn, PyMapping, PyMappingMethods},
protocol::{PySequence, PySequenceMethods},
utils::Either,
IdProtocol, PyObject, PyObjectRef, PyObjectView, PyRef, PyResult, PyValue, TypeProtocol,
AsPyObject, PyObject, PyObjectRef, PyObjectView, PyRef, PyResult, PyValue, TypeProtocol,
VirtualMachine,
};
use crossbeam_utils::atomic::AtomicCell;
use num_traits::{Signed, ToPrimitive};
use std::{borrow::Cow, cmp::Ordering};
use std::{
borrow::{Borrow, Cow},
cmp::Ordering,
};
// The corresponding field in CPython is `tp_` prefixed.
// e.g. name -> tp_name
@@ -517,11 +520,8 @@ pub trait GetDescriptor: PyValue {
}
#[inline]
fn _cls_is<T>(cls: &Option<PyObjectRef>, other: &T) -> bool
where
T: IdProtocol,
{
cls.as_ref().map_or(false, |cls| other.is(cls))
fn _cls_is(cls: &Option<PyObjectRef>, other: &impl Borrow<PyObject>) -> bool {
cls.as_ref().map_or(false, |cls| other.borrow().is(cls))
}
}
@@ -711,8 +711,12 @@ impl PyComparisonOp {
/// Returns an appropriate return value for the comparison when a and b are the same object, if an
/// appropriate return value exists.
#[inline]
pub fn identical_optimization(self, a: &impl IdProtocol, b: &impl IdProtocol) -> Option<bool> {
self.map_eq(|| a.is(b))
pub fn identical_optimization(
self,
a: &impl Borrow<PyObject>,
b: &impl Borrow<PyObject>,
) -> Option<bool> {
self.map_eq(|| a.borrow().is(b.borrow()))
}
/// Returns `Some(true)` when self is `Eq` and `f()` returns true. Returns `Some(false)` when self

View File

@@ -4,13 +4,25 @@ use crate::{
PyObject, PyObjectRef, PyObjectWrap, PyResult, TryFromObject, TypeProtocol, VirtualMachine,
};
use num_traits::ToPrimitive;
use std::borrow::Borrow;
pub enum Either<A, B> {
A(A),
B(B),
}
impl<A: Borrow<PyObject>, B: Borrow<PyObject>> Borrow<PyObject> for Either<A, B> {
#[inline(always)]
fn borrow(&self) -> &PyObject {
match self {
Either::A(a) => a.borrow(),
Either::B(b) => b.borrow(),
}
}
}
impl<A: AsRef<PyObject>, B: AsRef<PyObject>> AsRef<PyObject> for Either<A, B> {
#[inline(always)]
fn as_ref(&self) -> &PyObject {
match self {
Either::A(a) => a.as_ref(),
@@ -20,6 +32,7 @@ impl<A: AsRef<PyObject>, B: AsRef<PyObject>> AsRef<PyObject> for Either<A, B> {
}
impl<A: PyObjectWrap, B: PyObjectWrap> PyObjectWrap for Either<A, B> {
#[inline(always)]
fn into_object(self) -> PyObjectRef {
match self {
Either::A(a) => a.into_object(),
@@ -29,6 +42,7 @@ impl<A: PyObjectWrap, B: PyObjectWrap> PyObjectWrap for Either<A, B> {
}
impl<A: IntoPyObject, B: IntoPyObject> IntoPyObject for Either<A, B> {
#[inline(always)]
fn into_pyobject(self, vm: &VirtualMachine) -> PyObjectRef {
match self {
Self::A(a) => a.into_pyobject(vm),

View File

@@ -24,8 +24,8 @@ use crate::{
protocol::PyIterIter,
pyobject::PyLease,
scope::Scope,
signal, stdlib, IdProtocol, PyContext, PyObject, PyObjectRef, PyObjectWrap, PyRef, PyRefExact,
PyResult, PyValue, TypeProtocol,
signal, stdlib, AsPyObject, PyContext, PyObject, PyObjectRef, PyRef, PyRefExact, PyResult,
PyValue, TypeProtocol,
};
use crossbeam_utils::atomic::AtomicCell;
use std::{
@@ -872,7 +872,7 @@ impl VirtualMachine {
if !context_exc.is(exception) {
let mut o = context_exc.clone();
while let Some(context) = o.context() {
if context.is(&exception) {
if context.is(exception) {
o.set_context(None);
break;
}

View File

@@ -10,7 +10,7 @@ use crate::{
function::IntoPyObject,
scope::Scope,
vm::VirtualMachine,
PyObject, PyObjectRef, PyObjectWrap, PyRef, TypeProtocol,
AsPyObject, PyObject, PyObjectRef, PyObjectWrap, PyRef, TypeProtocol,
};
/// Collection of object creation helpers

View File

@@ -2,7 +2,7 @@ use crate::{
builtins::{PyBaseExceptionRef, PyList, PyStr},
function::{FuncArgs, IntoFuncArgs},
vm::VirtualMachine,
IdProtocol, PyMethod, PyObject, PyObjectRef, PyObjectWrap, PyResult, PyValue, TypeProtocol,
AsPyObject, PyMethod, PyObject, PyObjectRef, PyResult, PyValue, TypeProtocol,
};
/// Trace events for sys.settrace and sys.setprofile.

View File

@@ -4,7 +4,7 @@ use crate::{
protocol::PyIterReturn,
types::PyComparisonOp,
vm::VirtualMachine,
IdProtocol, PyMethod, PyObject, PyObjectRef, PyResult, TypeProtocol,
AsPyObject, PyMethod, PyObject, PyObjectRef, PyResult, TypeProtocol,
};
/// Collection of operators