Skip to content
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
1 change: 0 additions & 1 deletion Lib/test/string_tests.py
Original file line number Diff line number Diff line change
Expand Up @@ -1555,7 +1555,6 @@ def test_none_arguments(self):
self.checkequal(True, s, 'startswith', 'h', None, -2)
self.checkequal(False, s, 'startswith', 'x', None, None)

@unittest.expectedFailure # TODO: RUSTPYTHON
def test_find_etc_raise_correct_error_messages(self):
# issue 11828
s = 'hello'
Expand Down
1 change: 0 additions & 1 deletion Lib/test/test_bytes.py
Original file line number Diff line number Diff line change
Expand Up @@ -1021,7 +1021,6 @@ def test_integer_arguments_out_of_byte_range(self):
self.assertRaises(ValueError, method, 256)
self.assertRaises(ValueError, method, 9999)

@unittest.expectedFailure # TODO: RUSTPYTHON
def test_find_etc_raise_correct_error_messages(self):
# issue 11828
b = self.type2test(b'hello')
Expand Down
1 change: 0 additions & 1 deletion Lib/test/test_range.py
Original file line number Diff line number Diff line change
Expand Up @@ -91,7 +91,6 @@ def test_range(self):
r = range(-sys.maxsize, sys.maxsize, 2)
self.assertEqual(len(r), sys.maxsize)

@unittest.expectedFailure # TODO: RUSTPYTHON
def test_range_constructor_error_messages(self):
with self.assertRaisesRegex(
TypeError,
Expand Down
16 changes: 12 additions & 4 deletions crates/derive-impl/src/from_args.rs
Original file line number Diff line number Diff line change
Expand Up @@ -174,13 +174,21 @@ fn generate_field((i, field): (usize, &Field)) -> Result<TokenStream> {
.unwrap_or_else(|| #default)
}
} else {
// A parameter a call may name is named back when it is missing; one
// that can only be passed by position is only ever counted.
let err = match attr.kind {
ParameterKind::PositionalOnly | ParameterKind::PositionalOrKeyword => quote! {
ParameterKind::PositionalOnly => quote! {
::rustpython_vm::function::ArgumentError::TooFewArgs
},
ParameterKind::KeywordOnly => quote! {
::rustpython_vm::function::ArgumentError::RequiredKeywordArgument(#pyname.to_owned())
},
ParameterKind::PositionalOrKeyword | ParameterKind::KeywordOnly => {
let pos = i + 1;
quote! {
::rustpython_vm::function::ArgumentError::MissingRequiredArgument {
name: #pyname.to_owned(),
pos: #pos,
}
}
}
ParameterKind::Flatten => unreachable!(),
};
quote! {
Expand Down
4 changes: 2 additions & 2 deletions crates/stdlib/src/contextvars.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ mod _contextvars {
lock::{LazyLock, PyMutex},
wtf8::Wtf8Buf,
},
function::{ArgCallable, FuncArgs, OptionalArg},
function::{ArgCallable, Callee, FuncArgs, OptionalArg},
protocol::{PyMappingMethods, PySequenceMethods},
types::{AsMapping, AsSequence, Constructor, Hashable, Iterable, Representable},
};
Expand Down Expand Up @@ -484,7 +484,7 @@ mod _contextvars {
type Args = ContextVarOptions;

fn slot_new(cls: PyTypeRef, args: FuncArgs, vm: &VirtualMachine) -> PyResult {
let args: Self::Args = args.bind(vm)?;
let args: Self::Args = args.bind_for(vm, Callee::of::<Self>(vm))?;
let var = Self {
name: args.name.to_string(),
default: args.default.into_option(),
Expand Down
4 changes: 2 additions & 2 deletions crates/vm/src/builtins/bool.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ use crate::{
AsObject, Context, Py, PyObject, PyObjectRef, PyResult, TryFromBorrowedObject, VirtualMachine,
class::PyClassImpl,
convert::{IntoPyException, ToPyObject, ToPyResult},
function::{FuncArgs, OptionalArg},
function::{Callee, FuncArgs, OptionalArg},
protocol::PyNumberMethods,
types::{AsNumber, Constructor, Representable},
};
Expand Down Expand Up @@ -87,7 +87,7 @@ impl Constructor for PyBool {
type Args = OptionalArg<PyObjectRef>;

fn slot_new(zelf: PyTypeRef, args: FuncArgs, vm: &VirtualMachine) -> PyResult {
let x: Self::Args = args.bind(vm)?;
let x: Self::Args = args.bind_for(vm, Callee::of::<Self>(vm))?;
if !zelf.fast_isinstance(vm.ctx.types.type_type) {
return Err(vm.new_type_error(format!(
"requires a 'type' object but received a '{}'",
Expand Down
9 changes: 6 additions & 3 deletions crates/vm/src/builtins/builtin_func.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ use crate::{
class::PyClassImpl,
common::wtf8::Wtf8,
convert::TryFromObject,
function::{FuncArgs, PyComparisonValue, PyMethodDef, PyMethodFlags, PyNativeFn},
function::{Callee, FuncArgs, PyComparisonValue, PyMethodDef, PyMethodFlags, PyNativeFn},
types::{Callable, Comparable, PyComparisonOp, Representable},
};
use alloc::fmt;
Expand Down Expand Up @@ -71,14 +71,16 @@ impl Callable for PyNativeFunction {
type Args = FuncArgs;
#[inline]
fn call(zelf: &Py<Self>, mut args: FuncArgs, vm: &VirtualMachine) -> PyResult {
let mut callee = Callee::named(zelf.value.name);
if let Some(z) = &zelf.zelf {
// STATIC methods store the class in zelf for qualname/repr purposes,
// but should not prepend it to args (the Rust function doesn't expect it).
if !zelf.value.flags.contains(PyMethodFlags::STATIC) {
args.prepend_arg(z.clone());
callee = callee.with_instance_arg(true);
}
}
(zelf.value.func)(vm, args)
(zelf.value.func)(vm, args, callee)
}
}

Expand Down Expand Up @@ -254,7 +256,8 @@ fn vectorcall_native_function(
FuncArgs::from_vectorcall_owned(args, nargs, kwnames)
};

(zelf.value.func)(vm, func_args)
let callee = Callee::named(zelf.value.name).with_instance_arg(needs_self);
(zelf.value.func)(vm, func_args, callee)
}

pub(crate) fn init(context: &'static Context) {
Expand Down
6 changes: 4 additions & 2 deletions crates/vm/src/builtins/bytes.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,9 @@ use crate::{
class::PyClassImpl,
common::{hash::PyHash, lock::PyMutex},
convert::{ToPyObject, ToPyResult},
function::{ArgBytesLike, ArgIndex, FuncArgs, OptionalArg, OptionalOption, PyComparisonValue},
function::{
ArgBytesLike, ArgIndex, Callee, FuncArgs, OptionalArg, OptionalOption, PyComparisonValue,
},
protocol::{
BufferDescriptor, BufferFlags, BufferMethods, PyBuffer, PyIterReturn, PyMappingMethods,
PyNumberMethods, PySequenceMethods,
Expand Down Expand Up @@ -95,7 +97,7 @@ impl Constructor for PyBytes {
type Args = Vec<u8>;

fn slot_new(cls: PyTypeRef, args: FuncArgs, vm: &VirtualMachine) -> PyResult {
let options: ByteInnerNewOptions = args.bind(vm)?;
let options: ByteInnerNewOptions = args.bind_for(vm, Callee::of::<Self>(vm))?;

// Optimizations for exact bytes type
if cls.is(vm.ctx.types.bytes_type) {
Expand Down
4 changes: 2 additions & 2 deletions crates/vm/src/builtins/classmethod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ use crate::{
AsObject, Context, Py, PyObjectRef, PyPayload, PyRef, PyResult, VirtualMachine,
class::PyClassImpl,
common::lock::PyMutex,
function::{FuncArgs, PySetterValue},
function::{Callee, FuncArgs, PySetterValue},
types::{Constructor, GetDescriptor, Initializer, Representable},
};

Expand Down Expand Up @@ -70,7 +70,7 @@ impl Constructor for PyClassMethod {
// copying its attributes to `__init__` so that subclasses overriding
// `__init__` without calling `super().__init__()` see `__func__` as
// `None`, matching CPython.
let _: Self::Args = args.bind(vm)?;
let _: Self::Args = args.bind_for(vm, Callee::of::<Self>(vm))?;
let classmethod = Self {
callable: PyMutex::new(vm.ctx.none()),
};
Expand Down
4 changes: 2 additions & 2 deletions crates/vm/src/builtins/complex.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ use crate::{
class::PyClassImpl,
common::{format::FormatSpec, wtf8::Wtf8Buf},
convert::{IntoPyException, ToPyObject, ToPyResult},
function::{FuncArgs, OptionalArg, PyComparisonValue},
function::{Callee, FuncArgs, OptionalArg, PyComparisonValue},
protocol::PyNumberMethods,
stdlib::_warnings,
types::{AsNumber, Callable, Comparable, Constructor, Hashable, PyComparisonOp, Representable},
Expand Down Expand Up @@ -395,7 +395,7 @@ impl Constructor for PyComplex {
return Ok(func_args.args[0].clone());
}

let args: Self::Args = func_args.bind(vm)?;
let args: Self::Args = func_args.bind_for(vm, Callee::of::<Self>(vm))?;
let payload = Self::py_new(&cls, args, vm)?;
payload.into_ref_with_type(vm, cls).map(Into::into)
}
Expand Down
14 changes: 11 additions & 3 deletions crates/vm/src/builtins/descriptor.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ use crate::{
class::PyClassImpl,
common::hash::PyHash,
convert::{ToPyObject, ToPyResult},
function::{ArgSize, FuncArgs, PyMethodDef, PyMethodFlags, PySetterValue},
function::{ArgSize, Callee, FuncArgs, PyMethodDef, PyMethodFlags, PySetterValue},
protocol::{PyNumberBinaryFunc, PyNumberTernaryFunc, PyNumberUnaryFunc},
types::{
Callable, Comparable, DelFunc, DescrGetFunc, DescrSetFunc, GenericMethod, GetDescriptor,
Expand Down Expand Up @@ -108,7 +108,11 @@ impl Callable for PyMethodDescriptor {
type Args = FuncArgs;
#[inline]
fn call(zelf: &Py<Self>, args: FuncArgs, vm: &VirtualMachine) -> PyResult {
(zelf.method.func)(vm, args)
(zelf.method.func)(
vm,
args,
Callee::named(zelf.method.name).with_instance_arg(true),
)
}
}

Expand Down Expand Up @@ -443,7 +447,11 @@ fn vectorcall_method_descriptor(
) -> PyResult {
let zelf: &Py<PyMethodDescriptor> = zelf_obj.downcast_ref().unwrap();
let func_args = FuncArgs::from_vectorcall_owned(args, nargs, kwnames);
(zelf.method.func)(vm, func_args)
(zelf.method.func)(
vm,
func_args,
Callee::named(zelf.method.name).with_instance_arg(true),
)
}

/// Vectorcall for wrapper_descriptor: calls wrapped slot function
Expand Down
5 changes: 3 additions & 2 deletions crates/vm/src/builtins/float.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,8 @@ use crate::{
common::{float_ops, format::FormatSpec, hash, wtf8::Wtf8Buf},
convert::{IntoPyException, ToPyObject, ToPyResult},
function::{
ArgBytesLike, FuncArgs, OptionalArg, OptionalOption, PyArithmeticValue, PyComparisonValue,
ArgBytesLike, Callee, FuncArgs, OptionalArg, OptionalOption, PyArithmeticValue,
PyComparisonValue,
},
protocol::PyNumberMethods,
types::{AsNumber, Callable, Comparable, Constructor, Hashable, PyComparisonOp, Representable},
Expand Down Expand Up @@ -178,7 +179,7 @@ impl Constructor for PyFloat {
fn slot_new(cls: PyTypeRef, args: FuncArgs, vm: &VirtualMachine) -> PyResult {
// Bind before the fast path so FromArgs::arity decides how many arguments
// are acceptable, rather than a count repeated here.
let arg: Self::Args = args.bind(vm)?;
let arg: Self::Args = args.bind_for(vm, Callee::of::<Self>(vm))?;

// Optimization: return exact float as-is
if cls.is(vm.ctx.types.float_type)
Expand Down
6 changes: 3 additions & 3 deletions crates/vm/src/builtins/int.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,8 @@ use crate::{
},
convert::{IntoPyException, ToPyObject, ToPyResult},
function::{
ArgByteOrder, ArgIntoBool, FuncArgs, OptionalArg, OptionalOption, PyArithmeticValue,
PyComparisonValue,
ArgByteOrder, ArgIntoBool, Callee, FuncArgs, OptionalArg, OptionalOption,
PyArithmeticValue, PyComparisonValue,
},
protocol::{PyNumberMethods, handle_bytes_to_int_err, numeric_literal_from_str},
types::{AsNumber, Comparable, Constructor, Hashable, PyComparisonOp, Representable},
Expand Down Expand Up @@ -259,7 +259,7 @@ impl Constructor for PyInt {
return Ok(args.args[0].clone());
}

let options: IntOptions = args.bind(vm)?;
let options: IntOptions = args.bind_for(vm, Callee::of::<Self>(vm))?;
let value = if let OptionalArg::Present(val) = options.val_options {
if let OptionalArg::Present(base) = options.base {
let base = base
Expand Down
6 changes: 3 additions & 3 deletions crates/vm/src/builtins/object.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ use crate::{
AsObject, Context, Py, PyObject, PyObjectRef, PyPayload, PyRef, PyResult, VirtualMachine,
class::PyClassImpl,
convert::ToPyResult,
function::{Either, FuncArgs, PyArithmeticValue, PyComparisonValue, PySetterValue},
function::{Callee, Either, FuncArgs, PyArithmeticValue, PyComparisonValue, PySetterValue},
types::{Constructor, Initializer, PyComparisonOp},
};
use itertools::Itertools;
Expand Down Expand Up @@ -295,8 +295,8 @@ fn object_getstate_default(obj: &PyObject, required: bool, vm: &VirtualMachine)
#[pyclass(with(Constructor, Initializer), flags(BASETYPE))]
impl PyBaseObject {
#[pymethod(raw)]
fn __getstate__(vm: &VirtualMachine, args: FuncArgs) -> PyResult {
let (zelf,): (PyObjectRef,) = args.bind(vm)?;
fn __getstate__(vm: &VirtualMachine, args: FuncArgs, callee: Callee) -> PyResult {
let (zelf,): (PyObjectRef,) = args.bind_for(vm, callee)?;
object_getstate_default(&zelf, false, vm)
}

Expand Down
10 changes: 6 additions & 4 deletions crates/vm/src/builtins/range.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ use crate::{
VirtualMachine, atomic_func,
class::PyClassImpl,
common::hash::PyHash,
function::{ArgIndex, FuncArgs, OptionalArg, PyComparisonValue},
function::{ArgIndex, Callee, FuncArgs, OptionalArg, PyComparisonValue},
protocol::{PyIterReturn, PyMappingMethods, PyNumberMethods, PySequenceMethods},
types::{
AsMapping, AsNumber, AsSequence, Comparable, Hashable, IterNext, Iterable, PyComparisonOp,
Expand Down Expand Up @@ -351,11 +351,13 @@ impl PyRange {

#[pyslot]
fn slot_new(cls: PyTypeRef, args: FuncArgs, vm: &VirtualMachine) -> PyResult {
let range = if args.args.len() <= 1 {
let stop = args.bind(vm)?;
let range = if args.args.is_empty() {
return Err(Callee::of::<Self>(vm).arity_error(1..=3, 0, vm));
} else if args.args.len() == 1 {
let stop = args.bind_for(vm, Callee::of::<Self>(vm))?;
Self::new(cls, stop, vm)
} else {
let (start, stop, step) = args.bind(vm)?;
let (start, stop, step) = args.bind_for(vm, Callee::of::<Self>(vm))?;
Self::new_from(cls, start, stop, step, vm)
}?;

Expand Down
6 changes: 4 additions & 2 deletions crates/vm/src/builtins/set.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,9 @@ use crate::{
},
convert::ToPyResult,
dict_inner::{self, DictSize},
function::{ArgIterable, FuncArgs, OptionalArg, PosArgs, PyArithmeticValue, PyComparisonValue},
function::{
ArgIterable, Callee, FuncArgs, OptionalArg, PosArgs, PyArithmeticValue, PyComparisonValue,
},
protocol::{PyIterReturn, PyNumberMethods, PySequenceMethods},
recursion::ReprGuard,
types::AsNumber,
Expand Down Expand Up @@ -1077,7 +1079,7 @@ impl Constructor for PyFrozenSet {

// Optimizations for exact frozenset type
let iterable_opt = if is_exact_frozenset || is_frozenset_init {
let iterable: OptionalArg<PyObjectRef> = args.bind(vm)?;
let iterable: OptionalArg<PyObjectRef> = args.bind_for(vm, Callee::of::<Self>(vm))?;

// Return exact frozenset as-is
if is_exact_frozenset
Expand Down
6 changes: 3 additions & 3 deletions crates/vm/src/builtins/singletons.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ use crate::{
class::PyClassImpl,
common::hash::PyHash,
convert::ToPyObject,
function::{FuncArgs, PyComparisonValue},
function::{Callee, FuncArgs, PyComparisonValue},
protocol::PyNumberMethods,
types::{AsNumber, Comparable, Constructor, Hashable, PyComparisonOp, Representable},
};
Expand Down Expand Up @@ -41,7 +41,7 @@ impl Constructor for PyNone {
type Args = ();

fn slot_new(_cls: PyTypeRef, args: FuncArgs, vm: &VirtualMachine) -> PyResult {
let _: () = args.bind(vm)?;
let _: () = args.bind_for(vm, Callee::of::<Self>(vm))?;
Ok(vm.ctx.none.clone().into())
}

Expand Down Expand Up @@ -110,7 +110,7 @@ impl Constructor for PyNotImplemented {
type Args = ();

fn slot_new(_cls: PyTypeRef, args: FuncArgs, vm: &VirtualMachine) -> PyResult {
let _: () = args.bind(vm)?;
let _: () = args.bind_for(vm, Callee::of::<Self>(vm))?;
Ok(vm.ctx.not_implemented.clone().into())
}

Expand Down
10 changes: 5 additions & 5 deletions crates/vm/src/builtins/slice.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ use crate::{
class::PyClassImpl,
common::hash::{PyHash, PyUHash},
convert::ToPyObject,
function::{ArgIndex, FuncArgs, OptionalArg, PyComparisonValue},
function::{ArgIndex, Callee, FuncArgs, OptionalArg, PyComparisonValue},
sliceable::SaturatedSlice,
types::{Comparable, Constructor, Hashable, PyComparisonOp, Representable},
};
Expand Down Expand Up @@ -128,10 +128,10 @@ impl PySlice {
fn slot_new(cls: PyTypeRef, args: FuncArgs, vm: &VirtualMachine) -> PyResult {
let slice: Self = match args.args.len() {
0 => {
return Err(vm.new_type_error("slice() must have at least one arguments."));
return Err(Callee::of::<Self>(vm).arity_error(1..=3, 0, vm));
}
1 => {
let stop = args.bind(vm)?;
let stop = args.bind_for(vm, Callee::of::<Self>(vm))?;
Self {
start: None,
stop,
Expand All @@ -140,7 +140,7 @@ impl PySlice {
}
_ => {
let (start, stop, step): (PyObjectRef, PyObjectRef, OptionalArg<PyObjectRef>) =
args.bind(vm)?;
args.bind_for(vm, Callee::of::<Self>(vm))?;
Self {
start: Some(start),
stop,
Expand Down Expand Up @@ -388,7 +388,7 @@ impl Constructor for PyEllipsis {
type Args = ();

fn slot_new(_cls: PyTypeRef, args: FuncArgs, vm: &VirtualMachine) -> PyResult {
let _: () = args.bind(vm)?;
let _: () = args.bind_for(vm, Callee::of::<Self>(vm))?;
Ok(vm.ctx.ellipsis.clone().into())
}

Expand Down
Loading
Loading