Skip to content

PyPayload::into_ref #3744

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions examples/call_between_rust_and_python.rs
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ pub fn main() {
#[pymodule]
mod rust_py_module {
use super::*;
use rustpython::vm::{PyObjectRef, builtins::PyList, convert::ToPyObject};
use rustpython::vm::{PyObjectRef, convert::ToPyObject};

#[pyfunction]
fn rust_function(
Expand All @@ -58,7 +58,7 @@ python_person.name: {}",
impl ToPyObject for NumVec {
fn to_pyobject(self, vm: &VirtualMachine) -> PyObjectRef {
let list = self.0.into_iter().map(|e| vm.new_pyobj(e)).collect();
PyList::new_ref(list, vm.as_ref()).to_pyobject(vm)
vm.ctx.new_list(list).to_pyobject(vm)
}
}

Expand Down
40 changes: 14 additions & 26 deletions vm/src/builtins/bytearray.rs
Original file line number Diff line number Diff line change
Expand Up @@ -73,10 +73,6 @@ pub(crate) fn init(context: &Context) {
}

impl PyByteArray {
pub fn new_ref(data: Vec<u8>, ctx: &Context) -> PyRef<Self> {
PyRef::new_ref(Self::from(data), ctx.types.bytearray_type.to_owned(), None)
}

fn from_inner(inner: PyBytesInner) -> Self {
PyByteArray {
inner: PyRwLock::new(inner),
Expand Down Expand Up @@ -134,7 +130,7 @@ impl PyByteArray {
SequenceIndex::Slice(slice) => self
.borrow_buf()
.getitem_by_slice(vm, slice)
.map(|x| Self::new_ref(x, &vm.ctx).into()),
.map(|x| vm.ctx.new_bytearray(x).into()),
}
}

Expand Down Expand Up @@ -463,11 +459,8 @@ impl PyByteArray {
options: ByteInnerSplitOptions,
vm: &VirtualMachine,
) -> PyResult<Vec<PyObjectRef>> {
self.inner().split(
options,
|s, vm| Self::new_ref(s.to_vec(), &vm.ctx).into(),
vm,
)
self.inner()
.split(options, |s, vm| vm.ctx.new_bytearray(s.to_vec()).into(), vm)
}

#[pymethod]
Expand All @@ -476,11 +469,8 @@ impl PyByteArray {
options: ByteInnerSplitOptions,
vm: &VirtualMachine,
) -> PyResult<Vec<PyObjectRef>> {
self.inner().rsplit(
options,
|s, vm| Self::new_ref(s.to_vec(), &vm.ctx).into(),
vm,
)
self.inner()
.rsplit(options, |s, vm| vm.ctx.new_bytearray(s.to_vec()).into(), vm)
}

#[pymethod]
Expand All @@ -490,9 +480,10 @@ impl PyByteArray {
let value = self.inner();
let (front, has_mid, back) = value.partition(&sep, vm)?;
Ok(vm.new_tuple((
Self::new_ref(front.to_vec(), &vm.ctx),
Self::new_ref(if has_mid { sep.elements } else { Vec::new() }, &vm.ctx),
Self::new_ref(back.to_vec(), &vm.ctx),
vm.ctx.new_bytearray(front.to_vec()),
vm.ctx
.new_bytearray(if has_mid { sep.elements } else { Vec::new() }),
vm.ctx.new_bytearray(back.to_vec()),
)))
}

Expand All @@ -501,9 +492,10 @@ impl PyByteArray {
let value = self.inner();
let (back, has_mid, front) = value.rpartition(&sep, vm)?;
Ok(vm.new_tuple((
Self::new_ref(front.to_vec(), &vm.ctx),
Self::new_ref(if has_mid { sep.elements } else { Vec::new() }, &vm.ctx),
Self::new_ref(back.to_vec(), &vm.ctx),
vm.ctx.new_bytearray(front.to_vec()),
vm.ctx
.new_bytearray(if has_mid { sep.elements } else { Vec::new() }),
vm.ctx.new_bytearray(back.to_vec()),
)))
}

Expand All @@ -515,7 +507,7 @@ impl PyByteArray {
#[pymethod]
fn splitlines(&self, options: anystr::SplitLinesArgs, vm: &VirtualMachine) -> Vec<PyObjectRef> {
self.inner()
.splitlines(options, |x| Self::new_ref(x.to_vec(), &vm.ctx).into())
.splitlines(options, |x| vm.ctx.new_bytearray(x.to_vec()).into())
}

#[pymethod]
Expand Down Expand Up @@ -873,10 +865,6 @@ impl Representable for PyByteArray {
}
}

// fn set_value(obj: &PyObject, value: Vec<u8>) {
// obj.borrow_mut().kind = PyObjectPayload::Bytes { value };
// }

#[pyclass(module = false, name = "bytearray_iterator")]
#[derive(Debug)]
pub struct PyByteArrayIterator {
Expand Down
4 changes: 0 additions & 4 deletions vm/src/builtins/bytes.rs
Original file line number Diff line number Diff line change
Expand Up @@ -98,10 +98,6 @@ impl Constructor for PyBytes {
}

impl PyBytes {
pub fn new_ref(data: Vec<u8>, ctx: &Context) -> PyRef<Self> {
PyRef::new_ref(Self::from(data), ctx.types.bytes_type.to_owned(), None)
}

fn _getitem(&self, needle: &PyObject, vm: &VirtualMachine) -> PyResult {
match SequenceIndex::try_from_borrowed_object(vm, needle, "byte")? {
SequenceIndex::Int(i) => self
Expand Down
16 changes: 3 additions & 13 deletions vm/src/builtins/classmethod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,9 @@ impl GetDescriptor for PyClassMethod {
let cls = cls.unwrap_or_else(|| _obj.class().to_owned().into());
let call_descr_get: PyResult<PyObjectRef> = zelf.callable.lock().get_attr("__get__", vm);
match call_descr_get {
Err(_) => Ok(PyBoundMethod::new_ref(cls, zelf.callable.lock().clone(), &vm.ctx).into()),
Err(_) => Ok(PyBoundMethod::new(cls, zelf.callable.lock().clone())
.into_ref(&vm.ctx)
.into()),
Ok(call_descr_get) => call_descr_get.call((cls.clone(), cls), vm),
}
}
Expand Down Expand Up @@ -108,18 +110,6 @@ impl Initializer for PyClassMethod {
}
}

impl PyClassMethod {
pub fn new_ref(callable: PyObjectRef, ctx: &Context) -> PyRef<Self> {
PyRef::new_ref(
Self {
callable: PyMutex::new(callable),
},
ctx.types.classmethod_type.to_owned(),
None,
)
}
}

#[pyclass(
with(GetDescriptor, Constructor, Representable),
flags(BASETYPE, HAS_DICT)
Expand Down
6 changes: 1 addition & 5 deletions vm/src/builtins/complex.rs
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ impl PyPayload for PyComplex {

impl ToPyObject for Complex64 {
fn to_pyobject(self, vm: &VirtualMachine) -> PyObjectRef {
PyComplex::new_ref(self, &vm.ctx).into()
PyComplex::from(self).to_pyobject(vm)
}
}

Expand Down Expand Up @@ -232,10 +232,6 @@ impl Constructor for PyComplex {
}

impl PyComplex {
pub fn new_ref(value: Complex64, ctx: &Context) -> PyRef<Self> {
PyRef::new_ref(Self::from(value), ctx.types.complex_type.to_owned(), None)
}

pub fn to_complex(&self) -> Complex64 {
self.value
}
Expand Down
5 changes: 1 addition & 4 deletions vm/src/builtins/dict.rs
Original file line number Diff line number Diff line change
Expand Up @@ -44,16 +44,13 @@ impl fmt::Debug for PyDict {
}

impl PyPayload for PyDict {
#[inline]
fn class(ctx: &Context) -> &'static Py<PyType> {
ctx.types.dict_type
}
}

impl PyDict {
pub fn new_ref(ctx: &Context) -> PyRef<Self> {
PyRef::new_ref(Self::default(), ctx.types.dict_type.to_owned(), None)
}

/// escape hatch to access the underlying data structure directly. prefer adding a method on
/// PyDict instead of using this
pub(crate) fn _as_dict_inner(&self) -> &DictContentType {
Expand Down
12 changes: 2 additions & 10 deletions vm/src/builtins/function.rs
Original file line number Diff line number Diff line change
Expand Up @@ -551,7 +551,7 @@ impl GetDescriptor for PyFunction {
let obj = if vm.is_none(&obj) && !Self::_cls_is(&cls, obj.class()) {
zelf
} else {
PyBoundMethod::new_ref(obj, zelf, &vm.ctx).into()
PyBoundMethod::new(obj, zelf).into_ref(&vm.ctx).into()
};
Ok(obj)
}
Expand Down Expand Up @@ -719,17 +719,9 @@ impl Constructor for PyBoundMethod {
}

impl PyBoundMethod {
fn new(object: PyObjectRef, function: PyObjectRef) -> Self {
pub fn new(object: PyObjectRef, function: PyObjectRef) -> Self {
PyBoundMethod { object, function }
}

pub fn new_ref(object: PyObjectRef, function: PyObjectRef, ctx: &Context) -> PyRef<Self> {
PyRef::new_ref(
Self::new(object, function),
ctx.types.bound_method_type.to_owned(),
None,
)
}
}

#[pyclass(
Expand Down
12 changes: 4 additions & 8 deletions vm/src/builtins/list.rs
Original file line number Diff line number Diff line change
Expand Up @@ -58,15 +58,11 @@ impl PyPayload for PyList {

impl ToPyObject for Vec<PyObjectRef> {
fn to_pyobject(self, vm: &VirtualMachine) -> PyObjectRef {
PyList::new_ref(self, &vm.ctx).into()
PyList::from(self).into_ref(&vm.ctx).into()
}
}

impl PyList {
pub fn new_ref(elements: Vec<PyObjectRef>, ctx: &Context) -> PyRef<Self> {
PyRef::new_ref(Self::from(elements), ctx.types.list_type.to_owned(), None)
}

pub fn borrow_vec(&self) -> PyMappedRwLockReadGuard<'_, [PyObjectRef]> {
PyRwLockReadGuard::map(self.elements.read(), |v| &**v)
}
Expand All @@ -78,7 +74,7 @@ impl PyList {
fn repeat(&self, n: isize, vm: &VirtualMachine) -> PyResult<PyRef<Self>> {
let elements = &*self.borrow_vec();
let v = elements.mul(vm, n)?;
Ok(Self::new_ref(v, &vm.ctx))
Ok(Self::from(v).into_ref(&vm.ctx))
}

fn irepeat(zelf: PyRef<Self>, n: isize, vm: &VirtualMachine) -> PyResult<PyRef<Self>> {
Expand Down Expand Up @@ -140,7 +136,7 @@ impl PyList {
})?;
let mut elements = self.borrow_vec().to_vec();
elements.extend(other.borrow_vec().iter().cloned());
Ok(Self::new_ref(elements, &vm.ctx))
Ok(Self::from(elements).into_ref(&vm.ctx))
}

#[pymethod]
Expand Down Expand Up @@ -176,7 +172,7 @@ impl PyList {

#[pymethod]
fn copy(&self, vm: &VirtualMachine) -> PyRef<Self> {
Self::new_ref(self.borrow_vec().to_vec(), &vm.ctx)
Self::from(self.borrow_vec().to_vec()).into_ref(&vm.ctx)
}

#[allow(clippy::len_without_is_empty)]
Expand Down
12 changes: 4 additions & 8 deletions vm/src/builtins/staticmethod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -61,14 +61,10 @@ impl Constructor for PyStaticMethod {
}

impl PyStaticMethod {
pub fn new_ref(callable: PyObjectRef, ctx: &Context) -> PyRef<Self> {
PyRef::new_ref(
Self {
callable: PyMutex::new(callable),
},
ctx.types.staticmethod_type.to_owned(),
None,
)
pub fn new(callable: PyObjectRef) -> Self {
Self {
callable: PyMutex::new(callable),
}
}
}

Expand Down
5 changes: 0 additions & 5 deletions vm/src/builtins/str.rs
Original file line number Diff line number Diff line change
Expand Up @@ -392,11 +392,6 @@ impl PyStr {
unsafe { AsciiString::from_ascii_unchecked(bytes) }.into()
}

pub fn new_ref(zelf: impl Into<Self>, ctx: &Context) -> PyRef<Self> {
let zelf = zelf.into();
PyRef::new_ref(zelf, ctx.types.str_type.to_owned(), None)
}

fn new_substr(&self, s: Wtf8Buf) -> Self {
let kind = if self.kind().is_ascii() || s.is_ascii() {
StrKind::Ascii
Expand Down
4 changes: 2 additions & 2 deletions vm/src/bytes_inner.rs
Original file line number Diff line number Diff line change
Expand Up @@ -96,7 +96,7 @@ impl ByteInnerNewOptions {
(OptionalArg::Present(obj), OptionalArg::Missing, OptionalArg::Missing) => {
let obj = obj.clone();
// construct an exact bytes from an exact bytes do not clone
let obj = if cls.is(PyBytes::class(&vm.ctx)) {
let obj = if cls.is(vm.ctx.types.bytes_type) {
match obj.downcast_exact::<PyBytes>(vm) {
Ok(b) => return Ok(b.into_pyref()),
Err(obj) => obj,
Expand All @@ -109,7 +109,7 @@ impl ByteInnerNewOptions {
// construct an exact bytes from __bytes__ slot.
// if __bytes__ return a bytes, use the bytes object except we are the subclass of the bytes
let bytes = bytes_method?.call((), vm)?;
let bytes = if cls.is(PyBytes::class(&vm.ctx)) {
let bytes = if cls.is(vm.ctx.types.bytes_type) {
match bytes.downcast::<PyBytes>() {
Ok(b) => return Ok(b),
Err(bytes) => bytes,
Expand Down
13 changes: 10 additions & 3 deletions vm/src/class.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,16 +13,23 @@ use rustpython_common::static_cell;
pub trait StaticType {
// Ideally, saving PyType is better than PyTypeRef
fn static_cell() -> &'static static_cell::StaticCell<PyTypeRef>;
#[inline]
fn static_metaclass() -> &'static Py<PyType> {
PyType::static_type()
}
#[inline]
fn static_baseclass() -> &'static Py<PyType> {
PyBaseObject::static_type()
}
#[inline]
fn static_type() -> &'static Py<PyType> {
Self::static_cell()
.get()
.expect("static type has not been initialized. e.g. the native types defined in different module may be used before importing library.")
#[cold]
fn fail() -> ! {
panic!(
"static type has not been initialized. e.g. the native types defined in different module may be used before importing library."
);
}
Self::static_cell().get().unwrap_or_else(|| fail())
}
fn init_manually(typ: PyTypeRef) -> &'static Py<PyType> {
let cell = Self::static_cell();
Expand Down
25 changes: 17 additions & 8 deletions vm/src/vm/context.rs
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
use crate::{
PyResult, VirtualMachine,
builtins::{
PyBaseException, PyBytes, PyComplex, PyDict, PyDictRef, PyEllipsis, PyFloat, PyFrozenSet,
PyInt, PyIntRef, PyList, PyListRef, PyNone, PyNotImplemented, PyStr, PyStrInterned,
PyTuple, PyTupleRef, PyType, PyTypeRef, bytes,
PyBaseException, PyByteArray, PyBytes, PyComplex, PyDict, PyDictRef, PyEllipsis, PyFloat,
PyFrozenSet, PyInt, PyIntRef, PyList, PyListRef, PyNone, PyNotImplemented, PyStr,
PyStrInterned, PyTuple, PyTupleRef, PyType, PyTypeRef,
code::{self, PyCode},
descriptor::{
MemberGetter, MemberKind, MemberSetter, MemberSetterFunc, PyDescriptorOwned,
Expand Down Expand Up @@ -414,7 +414,7 @@ impl Context {

#[inline]
pub fn new_str(&self, s: impl Into<pystr::PyStr>) -> PyRef<PyStr> {
pystr::PyStr::new_ref(s, self)
s.into().into_ref(self)
}

pub fn interned_or_new_str<S, M>(&self, s: S) -> PyRef<PyStr>
Expand All @@ -429,8 +429,17 @@ impl Context {
}

#[inline]
pub fn new_bytes(&self, data: Vec<u8>) -> PyRef<bytes::PyBytes> {
bytes::PyBytes::new_ref(data, self)
pub fn new_bytes(&self, data: Vec<u8>) -> PyRef<PyBytes> {
PyBytes::from(data).into_ref(self)
}

#[inline]
pub fn new_bytearray(&self, data: Vec<u8>) -> PyRef<PyByteArray> {
PyRef::new_ref(
PyByteArray::from(data),
self.types.bytearray_type.to_owned(),
None,
)
}

#[inline(always)]
Expand All @@ -450,12 +459,12 @@ impl Context {

#[inline(always)]
pub fn new_list(&self, elements: Vec<PyObjectRef>) -> PyListRef {
PyList::new_ref(elements, self)
PyList::from(elements).into_ref(self)
}

#[inline(always)]
pub fn new_dict(&self) -> PyDictRef {
PyDict::new_ref(self)
PyDict::default().into_ref(self)
}

pub fn new_class(
Expand Down
Loading
Loading