Skip to content

method calls to take &PyObject #4740

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

Merged
merged 3 commits into from
Mar 24, 2023
Merged
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
14 changes: 6 additions & 8 deletions src/shell/helper.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
use rustpython_vm::{
builtins::{PyDictRef, PyStrRef},
function::ArgIterable,
identifier, PyResult, TryFromObject, VirtualMachine,
identifier, AsObject, PyResult, TryFromObject, VirtualMachine,
};

pub struct ShellHelper<'vm> {
Expand Down Expand Up @@ -82,19 +82,17 @@ impl<'vm> ShellHelper<'vm> {
current = current.get_attr(&attr, self.vm).ok()?;
}

let current_iter = str_iter_method(current, identifier!(self.vm, __dir__)).ok()?;
let current_iter = str_iter_method(&current, identifier!(self.vm, __dir__)).ok()?;

(last, current_iter, None)
} else {
// we need to get a variable based off of globals/builtins

let globals =
str_iter_method(self.globals.clone().into(), identifier!(self.vm, keys)).ok()?;
let builtins = str_iter_method(
self.vm.builtins.clone().into(),
identifier!(self.vm, __dir__),
)
.ok()?;
str_iter_method(self.globals.as_object(), identifier!(self.vm, keys)).ok()?;
let builtins =
str_iter_method(self.vm.builtins.as_object(), identifier!(self.vm, __dir__))
.ok()?;
(first, globals, Some(builtins))
};
Some((word_start, iter1.chain(iter2.into_iter().flatten())))
Expand Down
10 changes: 5 additions & 5 deletions vm/src/builtins/builtin_func.rs
Original file line number Diff line number Diff line change
Expand Up @@ -194,14 +194,14 @@ impl GetDescriptor for PyBuiltinMethod {
cls: Option<PyObjectRef>,
vm: &VirtualMachine,
) -> PyResult {
let (zelf, obj) = match Self::_check(zelf, obj, vm) {
Ok(obj) => obj,
Err(result) => return result,
let (_zelf, obj) = match Self::_check(&zelf, obj, vm) {
Some(obj) => obj,
None => return Ok(zelf),
};
let r = if vm.is_none(&obj) && !Self::_cls_is(&cls, obj.class()) {
zelf.into()
zelf
} else {
PyBoundMethod::new_ref(obj, zelf.into(), &vm.ctx).into()
PyBoundMethod::new_ref(obj, zelf, &vm.ctx).into()
};
Ok(r)
}
Expand Down
2 changes: 1 addition & 1 deletion vm/src/builtins/classmethod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ impl GetDescriptor for PyClassMethod {
cls: Option<PyObjectRef>,
vm: &VirtualMachine,
) -> PyResult {
let (zelf, _obj) = Self::_unwrap(zelf, obj, vm)?;
let (zelf, _obj) = Self::_unwrap(&zelf, obj, vm)?;
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 {
Expand Down
8 changes: 4 additions & 4 deletions vm/src/builtins/descriptor.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ use crate::{
class::PyClassImpl,
function::PySetterValue,
types::{Constructor, GetDescriptor, Representable, Unconstructible},
AsObject, Context, Py, PyObjectRef, PyPayload, PyResult, VirtualMachine,
AsObject, Context, Py, PyObject, PyObjectRef, PyPayload, PyResult, VirtualMachine,
};
use rustpython_common::lock::PyRwLock;

Expand Down Expand Up @@ -122,12 +122,12 @@ impl MemberDescrObject {

#[pyslot]
fn descr_set(
zelf: PyObjectRef,
zelf: &PyObject,
obj: PyObjectRef,
value: PySetterValue<PyObjectRef>,
vm: &VirtualMachine,
) -> PyResult<()> {
let zelf = Self::_zelf(zelf, vm)?;
let zelf = Self::_as_pyref(zelf, vm)?;
zelf.member.set(obj, value, vm)
}
}
Expand Down Expand Up @@ -208,7 +208,7 @@ impl GetDescriptor for MemberDescrObject {
) -> PyResult {
match obj {
Some(x) => {
let zelf = Self::_zelf(zelf, vm)?;
let zelf = Self::_as_pyref(&zelf, vm)?;
zelf.member.get(x, vm)
}
None => Ok(zelf),
Expand Down
12 changes: 6 additions & 6 deletions vm/src/builtins/function.rs
Original file line number Diff line number Diff line change
Expand Up @@ -374,13 +374,13 @@ impl PyFunction {
// {"__builtins__", T_OBJECT, OFF(func_builtins), READONLY},
#[pymember(magic)]
fn globals(vm: &VirtualMachine, zelf: PyObjectRef) -> PyResult {
let zelf = Self::_zelf(zelf, vm)?;
let zelf = Self::_as_pyref(&zelf, vm)?;
Ok(zelf.globals.clone().into())
}

#[pymember(magic)]
fn closure(vm: &VirtualMachine, zelf: PyObjectRef) -> PyResult {
let zelf = Self::_zelf(zelf, vm)?;
let zelf = Self::_as_pyref(&zelf, vm)?;
Ok(vm.unwrap_or_none(zelf.closure.clone().map(|x| x.to_pyobject(vm))))
}

Expand Down Expand Up @@ -439,11 +439,11 @@ impl GetDescriptor for PyFunction {
cls: Option<PyObjectRef>,
vm: &VirtualMachine,
) -> PyResult {
let (zelf, obj) = Self::_unwrap(zelf, obj, vm)?;
let (_zelf, obj) = Self::_unwrap(&zelf, obj, vm)?;
let obj = if vm.is_none(&obj) && !Self::_cls_is(&cls, obj.class()) {
zelf.into()
zelf
} else {
PyBoundMethod::new_ref(obj, zelf.into(), &vm.ctx).into()
PyBoundMethod::new_ref(obj, zelf, &vm.ctx).into()
};
Ok(obj)
}
Expand Down Expand Up @@ -507,7 +507,7 @@ impl GetAttr for PyBoundMethod {
.interned_str(name)
.and_then(|attr_name| zelf.get_class_attr(attr_name));
if let Some(obj) = class_attr {
return vm.call_if_get_descriptor(obj, zelf.to_owned().into());
return vm.call_if_get_descriptor(&obj, zelf.to_owned().into());
}
zelf.function.get_attr(name, vm)
}
Expand Down
16 changes: 8 additions & 8 deletions vm/src/builtins/getset.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ use crate::{
class::PyClassImpl,
function::{IntoPyGetterFunc, IntoPySetterFunc, PyGetterFunc, PySetterFunc, PySetterValue},
types::{Constructor, GetDescriptor, Unconstructible},
AsObject, Context, Py, PyObjectRef, PyPayload, PyRef, PyResult, TryFromObject, VirtualMachine,
AsObject, Context, Py, PyObject, PyObjectRef, PyPayload, PyResult, VirtualMachine,
};

#[pyclass(module = false, name = "getset_descriptor")]
Expand Down Expand Up @@ -51,9 +51,9 @@ impl GetDescriptor for PyGetSet {
_cls: Option<PyObjectRef>,
vm: &VirtualMachine,
) -> PyResult {
let (zelf, obj) = match Self::_check(zelf, obj, vm) {
Ok(obj) => obj,
Err(result) => return result,
let (zelf, obj) = match Self::_check(&zelf, obj, vm) {
Some(obj) => obj,
None => return Ok(zelf),
};
if let Some(ref f) = zelf.getter {
f(vm, obj)
Expand Down Expand Up @@ -100,12 +100,12 @@ impl PyGetSet {

#[pyslot]
fn descr_set(
zelf: PyObjectRef,
zelf: &PyObject,
obj: PyObjectRef,
value: PySetterValue<PyObjectRef>,
vm: &VirtualMachine,
) -> PyResult<()> {
let zelf = PyRef::<Self>::try_from_object(vm, zelf)?;
let zelf = zelf.try_to_ref::<Self>(vm)?;
if let Some(ref f) = zelf.setter {
f(vm, obj, value)
} else {
Expand All @@ -123,11 +123,11 @@ impl PyGetSet {
value: PyObjectRef,
vm: &VirtualMachine,
) -> PyResult<()> {
Self::descr_set(zelf, obj, PySetterValue::Assign(value), vm)
Self::descr_set(&zelf, obj, PySetterValue::Assign(value), vm)
}
#[pymethod]
fn __delete__(zelf: PyObjectRef, obj: PyObjectRef, vm: &VirtualMachine) -> PyResult<()> {
Self::descr_set(zelf, obj, PySetterValue::Delete, vm)
Self::descr_set(&zelf, obj, PySetterValue::Delete, vm)
}

#[pygetset(magic)]
Expand Down
16 changes: 8 additions & 8 deletions vm/src/builtins/property.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ use crate::{
class::PyClassImpl,
function::{FuncArgs, PySetterValue},
types::{Constructor, GetDescriptor, Initializer},
AsObject, Context, Py, PyObjectRef, PyPayload, PyRef, PyResult, TryFromObject, VirtualMachine,
AsObject, Context, Py, PyObject, PyObjectRef, PyPayload, PyRef, PyResult, VirtualMachine,
};

#[pyclass(module = false, name = "property")]
Expand Down Expand Up @@ -40,14 +40,14 @@ pub struct PropertyArgs {

impl GetDescriptor for PyProperty {
fn descr_get(
zelf: PyObjectRef,
zelf_obj: PyObjectRef,
obj: Option<PyObjectRef>,
_cls: Option<PyObjectRef>,
vm: &VirtualMachine,
) -> PyResult {
let (zelf, obj) = Self::_unwrap(zelf, obj, vm)?;
let (zelf, obj) = Self::_unwrap(&zelf_obj, obj, vm)?;
if vm.is_none(&obj) {
Ok(zelf.into())
Ok(zelf_obj)
} else if let Some(getter) = zelf.getter.read().as_ref() {
getter.call((obj,), vm)
} else {
Expand All @@ -62,12 +62,12 @@ impl PyProperty {

#[pyslot]
fn descr_set(
zelf: PyObjectRef,
zelf: &PyObject,
obj: PyObjectRef,
value: PySetterValue,
vm: &VirtualMachine,
) -> PyResult<()> {
let zelf = PyRef::<Self>::try_from_object(vm, zelf)?;
let zelf = zelf.try_to_ref::<Self>(vm)?;
match value {
PySetterValue::Assign(value) => {
if let Some(setter) = zelf.setter.read().as_ref() {
Expand All @@ -92,11 +92,11 @@ impl PyProperty {
value: PyObjectRef,
vm: &VirtualMachine,
) -> PyResult<()> {
Self::descr_set(zelf, obj, PySetterValue::Assign(value), vm)
Self::descr_set(&zelf, obj, PySetterValue::Assign(value), vm)
}
#[pymethod]
fn __delete__(zelf: PyObjectRef, obj: PyObjectRef, vm: &VirtualMachine) -> PyResult<()> {
Self::descr_set(zelf, obj, PySetterValue::Delete, vm)
Self::descr_set(&zelf, obj, PySetterValue::Delete, vm)
}

// Access functions
Expand Down
2 changes: 1 addition & 1 deletion vm/src/builtins/staticmethod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ impl GetDescriptor for PyStaticMethod {
_cls: Option<PyObjectRef>,
vm: &VirtualMachine,
) -> PyResult {
let (zelf, _obj) = Self::_unwrap(zelf, obj, vm)?;
let (zelf, _obj) = Self::_unwrap(&zelf, obj, vm)?;
let x = Ok(zelf.callable.lock().clone());
x
}
Expand Down
7 changes: 7 additions & 0 deletions vm/src/builtins/str.rs
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,13 @@ impl<'a> TryFromBorrowedObject<'a> for String {
}
}

impl<'a> TryFromBorrowedObject<'a> for &'a str {
fn try_from_borrowed_object(vm: &VirtualMachine, obj: &'a PyObject) -> PyResult<Self> {
let pystr: &Py<PyStr> = TryFromBorrowedObject::try_from_borrowed_object(vm, obj)?;
Ok(pystr.as_str())
}
}

#[pyclass(module = false, name = "str")]
pub struct PyStr {
bytes: Box<[u8]>,
Expand Down
8 changes: 4 additions & 4 deletions vm/src/builtins/super.rs
Original file line number Diff line number Diff line change
Expand Up @@ -150,7 +150,7 @@ impl GetAttr for PySuper {
if let Some(descr) = cls.get_direct_attr(name) {
return vm
.call_get_descriptor_specific(
descr.clone(),
&descr,
// Only pass 'obj' param if this is instance-mode super (See https://bugs.python.org/issue743267)
if obj.is(&start_type) { None } else { Some(obj) },
Some(start_type.as_object().to_owned()),
Expand All @@ -165,14 +165,14 @@ impl GetAttr for PySuper {

impl GetDescriptor for PySuper {
fn descr_get(
zelf: PyObjectRef,
zelf_obj: PyObjectRef,
obj: Option<PyObjectRef>,
_cls: Option<PyObjectRef>,
vm: &VirtualMachine,
) -> PyResult {
let (zelf, obj) = Self::_unwrap(zelf, obj, vm)?;
let (zelf, obj) = Self::_unwrap(&zelf_obj, obj, vm)?;
if vm.is_none(&obj) || zelf.obj.is_some() {
return Ok(zelf.into());
return Ok(zelf_obj);
}
let zelf_class = zelf.as_object().class();
if zelf_class.is(vm.ctx.types.super_type) {
Expand Down
28 changes: 13 additions & 15 deletions vm/src/builtins/type.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ use crate::{
borrow::BorrowedValue,
lock::{PyRwLock, PyRwLockReadGuard},
},
convert::{ToPyObject, ToPyResult},
convert::ToPyResult,
function::{FuncArgs, KwArgs, OptionalArg, PySetterValue},
identifier,
protocol::{PyIterReturn, PyMappingMethods, PyNumberMethods, PySequenceMethods},
Expand Down Expand Up @@ -816,7 +816,7 @@ impl PyType {
cell.class().name()
))
})?;
cell.set(Some(typ.clone().to_pyobject(vm)));
cell.set(Some(typ.clone().into()));
};

// avoid deadlock
Expand Down Expand Up @@ -844,7 +844,7 @@ impl PyType {

if let Some(init_subclass) = typ.get_super_attr(identifier!(vm, __init_subclass__)) {
let init_subclass = vm
.call_get_descriptor_specific(init_subclass.clone(), None, Some(typ.clone().into()))
.call_get_descriptor_specific(&init_subclass, None, Some(typ.clone().into()))
.unwrap_or(Ok(init_subclass))?;
init_subclass.call(kwargs, vm)?;
};
Expand Down Expand Up @@ -1008,19 +1008,17 @@ impl GetAttr for PyType {

let zelf_attr = zelf.get_attr(name);

if let Some(ref attr) = zelf_attr {
if let Some(attr) = zelf_attr {
let descr_get = attr.class().mro_find_map(|cls| cls.slots.descr_get.load());
if let Some(descr_get) = descr_get {
return descr_get(attr.clone(), None, Some(zelf.to_owned().into()), vm);
descr_get(attr, None, Some(zelf.to_owned().into()), vm)
} else {
Ok(attr)
}
}

if let Some(cls_attr) = zelf_attr {
Ok(cls_attr)
} else if let Some(attr) = mcl_attr {
vm.call_if_get_descriptor(attr, zelf.to_owned().into())
vm.call_if_get_descriptor(&attr, zelf.to_owned().into())
} else {
return Err(attribute_error(zelf, name_str.as_str(), vm));
Err(attribute_error(zelf, name_str.as_str(), vm))
}
}
}
Expand All @@ -1037,7 +1035,7 @@ impl SetAttr for PyType {
if let Some(attr) = zelf.get_class_attr(attr_name) {
let descr_set = attr.class().mro_find_map(|cls| cls.slots.descr_set.load());
if let Some(descriptor) = descr_set {
return descriptor(attr, zelf.to_owned().into(), value, vm);
return descriptor(&attr, zelf.to_owned().into(), value, vm);
}
}
let assign = value.is_assign();
Expand Down Expand Up @@ -1132,10 +1130,10 @@ fn find_base_dict_descr(cls: &Py<PyType>, vm: &VirtualMachine) -> Option<PyObjec
fn subtype_get_dict(obj: PyObjectRef, vm: &VirtualMachine) -> PyResult {
// TODO: obj.class().as_pyref() need to be supported
let ret = match find_base_dict_descr(obj.class(), vm) {
Some(descr) => vm.call_get_descriptor(descr, obj).unwrap_or_else(|obj| {
Some(descr) => vm.call_get_descriptor(&descr, obj).unwrap_or_else(|| {
Err(vm.new_type_error(format!(
"this __dict__ descriptor does not support '{}' objects",
obj.class()
descr.class()
)))
})?,
None => object::object_get_dict(obj, vm)?.into(),
Expand All @@ -1156,7 +1154,7 @@ fn subtype_set_dict(obj: PyObjectRef, value: PyObjectRef, vm: &VirtualMachine) -
cls.name()
))
})?;
descr_set(descr, obj, PySetterValue::Assign(value), vm)
descr_set(&descr, obj, PySetterValue::Assign(value), vm)
}
None => {
object::object_set_dict(obj, value.try_into_value(vm)?, vm)?;
Expand Down
4 changes: 2 additions & 2 deletions vm/src/cformat.rs
Original file line number Diff line number Diff line change
Expand Up @@ -33,8 +33,8 @@ fn spec_format_bytes(
Ok(buffer.contiguous_or_collect(|bytes| spec.format_bytes(bytes)))
} else {
let bytes = vm
.get_special_method(obj, identifier!(vm, __bytes__))?
.map_err(|obj| {
.get_special_method(&obj, identifier!(vm, __bytes__))?
.ok_or_else(|| {
vm.new_type_error(format!(
"%b requires a bytes-like object, or an object that \
implements __bytes__, not '{}'",
Expand Down
Loading