mirror of
https://github.com/RustPython/RustPython.git
synced 2026-06-02 19:39:49 +09:00
Merge pull request #611 from RustPython/pyargs
Less explicit PyFuncArgs is better.
This commit is contained in:
@@ -178,7 +178,7 @@ fn builtin_dir(vm: &mut VirtualMachine, args: PyFuncArgs) -> PyResult {
|
||||
fn builtin_divmod(vm: &mut VirtualMachine, args: PyFuncArgs) -> PyResult {
|
||||
arg_check!(vm, args, required = [(x, None), (y, None)]);
|
||||
match vm.get_method(x.clone(), "__divmod__") {
|
||||
Ok(attrib) => vm.invoke(attrib, PyFuncArgs::new(vec![y.clone()], vec![])),
|
||||
Ok(attrib) => vm.invoke(attrib, vec![y.clone()]),
|
||||
Err(..) => Err(vm.new_type_error("unsupported operand type(s) for divmod".to_string())),
|
||||
}
|
||||
}
|
||||
@@ -429,16 +429,14 @@ fn builtin_max(vm: &mut VirtualMachine, args: PyFuncArgs) -> PyResult {
|
||||
// TODO: this key function looks pretty duplicate. Maybe we can create
|
||||
// a local function?
|
||||
let mut x_key = if let Some(f) = &key_func {
|
||||
let args = PyFuncArgs::new(vec![x.clone()], vec![]);
|
||||
vm.invoke(f.clone(), args)?
|
||||
vm.invoke(f.clone(), vec![x.clone()])?
|
||||
} else {
|
||||
x.clone()
|
||||
};
|
||||
|
||||
for y in candidates_iter {
|
||||
let y_key = if let Some(f) = &key_func {
|
||||
let args = PyFuncArgs::new(vec![y.clone()], vec![]);
|
||||
vm.invoke(f.clone(), args)?
|
||||
vm.invoke(f.clone(), vec![y.clone()])?
|
||||
} else {
|
||||
y.clone()
|
||||
};
|
||||
@@ -479,16 +477,14 @@ fn builtin_min(vm: &mut VirtualMachine, args: PyFuncArgs) -> PyResult {
|
||||
// TODO: this key function looks pretty duplicate. Maybe we can create
|
||||
// a local function?
|
||||
let mut x_key = if let Some(f) = &key_func {
|
||||
let args = PyFuncArgs::new(vec![x.clone()], vec![]);
|
||||
vm.invoke(f.clone(), args)?
|
||||
vm.invoke(f.clone(), vec![x.clone()])?
|
||||
} else {
|
||||
x.clone()
|
||||
};
|
||||
|
||||
for y in candidates_iter {
|
||||
let y_key = if let Some(f) = &key_func {
|
||||
let args = PyFuncArgs::new(vec![y.clone()], vec![]);
|
||||
vm.invoke(f.clone(), args)?
|
||||
vm.invoke(f.clone(), vec![y.clone()])?
|
||||
} else {
|
||||
y.clone()
|
||||
};
|
||||
@@ -566,7 +562,7 @@ fn builtin_pow(vm: &mut VirtualMachine, args: PyFuncArgs) -> PyResult {
|
||||
);
|
||||
let pow_method_name = "__pow__";
|
||||
let result = match vm.get_method(x.clone(), pow_method_name) {
|
||||
Ok(attrib) => vm.invoke(attrib, PyFuncArgs::new(vec![y.clone()], vec![])),
|
||||
Ok(attrib) => vm.invoke(attrib, vec![y.clone()]),
|
||||
Err(..) => Err(vm.new_type_error("unsupported operand type(s) for pow".to_string())),
|
||||
};
|
||||
//Check if the 3rd argument is defined and perform modulus on the result
|
||||
@@ -576,7 +572,7 @@ fn builtin_pow(vm: &mut VirtualMachine, args: PyFuncArgs) -> PyResult {
|
||||
Some(mod_value) => {
|
||||
let mod_method_name = "__mod__";
|
||||
match vm.get_method(result.expect("result not defined").clone(), mod_method_name) {
|
||||
Ok(value) => vm.invoke(value, PyFuncArgs::new(vec![mod_value.clone()], vec![])),
|
||||
Ok(value) => vm.invoke(value, vec![mod_value.clone()]),
|
||||
Err(..) => {
|
||||
Err(vm.new_type_error("unsupported operand type(s) for mod".to_string()))
|
||||
}
|
||||
@@ -709,7 +705,7 @@ fn builtin_sorted(vm: &mut VirtualMachine, mut args: PyFuncArgs) -> PyResult {
|
||||
let lst = vm.ctx.new_list(items);
|
||||
|
||||
args.shift();
|
||||
vm.call_method_pyargs(&lst, "sort", args)?;
|
||||
vm.call_method(&lst, "sort", args)?;
|
||||
Ok(lst)
|
||||
}
|
||||
|
||||
@@ -843,13 +839,7 @@ pub fn builtin_build_class_(vm: &mut VirtualMachine, mut args: PyFuncArgs) -> Py
|
||||
// Prepare uses full __getattribute__ resolution chain.
|
||||
let prepare_name = vm.new_str("__prepare__".to_string());
|
||||
let prepare = vm.get_attribute(metaclass.clone(), prepare_name)?;
|
||||
let namespace = vm.invoke(
|
||||
prepare,
|
||||
PyFuncArgs {
|
||||
args: vec![name_arg.clone(), bases.clone()],
|
||||
kwargs: vec![],
|
||||
},
|
||||
)?;
|
||||
let namespace = vm.invoke(prepare, vec![name_arg.clone(), bases.clone()])?;
|
||||
|
||||
vm.invoke_with_locals(function, namespace.clone())?;
|
||||
|
||||
|
||||
@@ -36,13 +36,7 @@ fn filter_next(vm: &mut VirtualMachine, args: PyFuncArgs) -> PyResult {
|
||||
} else {
|
||||
// the predicate itself can raise StopIteration which does stop the filter
|
||||
// iteration
|
||||
vm.invoke(
|
||||
predicate.clone(),
|
||||
PyFuncArgs {
|
||||
args: vec![next_obj.clone()],
|
||||
kwargs: vec![],
|
||||
},
|
||||
)?
|
||||
vm.invoke(predicate.clone(), vec![next_obj.clone()])?
|
||||
};
|
||||
if objbool::boolval(vm, predicate_value)? {
|
||||
return Ok(next_obj);
|
||||
|
||||
@@ -210,13 +210,7 @@ pub fn type_getattribute(vm: &mut VirtualMachine, args: PyFuncArgs) -> PyResult
|
||||
let attr_class = attr.typ();
|
||||
if attr_class.has_attr("__set__") {
|
||||
if let Some(descriptor) = attr_class.get_attr("__get__") {
|
||||
return vm.invoke(
|
||||
descriptor,
|
||||
PyFuncArgs {
|
||||
args: vec![attr, cls.clone(), mcl],
|
||||
kwargs: vec![],
|
||||
},
|
||||
);
|
||||
return vm.invoke(descriptor, vec![attr, cls.clone(), mcl]);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -225,13 +219,7 @@ pub fn type_getattribute(vm: &mut VirtualMachine, args: PyFuncArgs) -> PyResult
|
||||
let attr_class = attr.typ();
|
||||
if let Some(descriptor) = attr_class.get_attr("__get__") {
|
||||
let none = vm.get_none();
|
||||
return vm.invoke(
|
||||
descriptor,
|
||||
PyFuncArgs {
|
||||
args: vec![attr, none, cls.clone()],
|
||||
kwargs: vec![],
|
||||
},
|
||||
);
|
||||
return vm.invoke(descriptor, vec![attr, none, cls.clone()]);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -240,13 +228,7 @@ pub fn type_getattribute(vm: &mut VirtualMachine, args: PyFuncArgs) -> PyResult
|
||||
} else if let Some(attr) = mcl.get_attr(&name) {
|
||||
vm.call_get_descriptor(attr, cls.clone())
|
||||
} else if let Some(getter) = cls.get_attr("__getattr__") {
|
||||
vm.invoke(
|
||||
getter,
|
||||
PyFuncArgs {
|
||||
args: vec![mcl, name_str.clone()],
|
||||
kwargs: vec![],
|
||||
},
|
||||
)
|
||||
vm.invoke(getter, vec![mcl, name_str.clone()])
|
||||
} else {
|
||||
let attribute_error = vm.context().exceptions.attribute_error.clone();
|
||||
Err(vm.new_exception(
|
||||
|
||||
@@ -904,6 +904,16 @@ pub struct PyFuncArgs {
|
||||
pub kwargs: Vec<(String, PyObjectRef)>,
|
||||
}
|
||||
|
||||
/// Conversion from vector of python objects to function arguments.
|
||||
impl From<Vec<PyObjectRef>> for PyFuncArgs {
|
||||
fn from(args: Vec<PyObjectRef>) -> Self {
|
||||
PyFuncArgs {
|
||||
args: args,
|
||||
kwargs: vec![],
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl PyFuncArgs {
|
||||
pub fn new(mut args: Vec<PyObjectRef>, kwarg_names: Vec<String>) -> PyFuncArgs {
|
||||
let mut kwargs = vec![];
|
||||
|
||||
65
vm/src/vm.rs
65
vm/src/vm.rs
@@ -117,10 +117,7 @@ impl VirtualMachine {
|
||||
|
||||
pub fn new_empty_exception(&mut self, exc_type: PyObjectRef) -> PyResult {
|
||||
info!("New exception created: no msg");
|
||||
let args = PyFuncArgs {
|
||||
args: vec![],
|
||||
kwargs: vec![],
|
||||
};
|
||||
let args = PyFuncArgs::default();
|
||||
self.invoke(exc_type, args)
|
||||
}
|
||||
|
||||
@@ -130,10 +127,6 @@ impl VirtualMachine {
|
||||
info!("New exception created: {}", msg);
|
||||
let pymsg = self.new_str(msg);
|
||||
let args: Vec<PyObjectRef> = vec![pymsg];
|
||||
let args = PyFuncArgs {
|
||||
args,
|
||||
kwargs: vec![],
|
||||
};
|
||||
|
||||
// Call function:
|
||||
self.invoke(exc_type, args).unwrap()
|
||||
@@ -264,40 +257,16 @@ impl VirtualMachine {
|
||||
let attr_class = attr.typ();
|
||||
if let Some(descriptor) = attr_class.get_attr("__get__") {
|
||||
let cls = obj.typ();
|
||||
self.invoke(
|
||||
descriptor,
|
||||
PyFuncArgs {
|
||||
args: vec![attr, obj.clone(), cls],
|
||||
kwargs: vec![],
|
||||
},
|
||||
)
|
||||
self.invoke(descriptor, vec![attr, obj.clone(), cls])
|
||||
} else {
|
||||
Ok(attr)
|
||||
}
|
||||
}
|
||||
|
||||
pub fn call_method(
|
||||
&mut self,
|
||||
obj: &PyObjectRef,
|
||||
method_name: &str,
|
||||
args: Vec<PyObjectRef>,
|
||||
) -> PyResult {
|
||||
self.call_method_pyargs(
|
||||
obj,
|
||||
method_name,
|
||||
PyFuncArgs {
|
||||
args,
|
||||
kwargs: vec![],
|
||||
},
|
||||
)
|
||||
}
|
||||
|
||||
pub fn call_method_pyargs(
|
||||
&mut self,
|
||||
obj: &PyObjectRef,
|
||||
method_name: &str,
|
||||
args: PyFuncArgs,
|
||||
) -> PyResult {
|
||||
pub fn call_method<T>(&mut self, obj: &PyObjectRef, method_name: &str, args: T) -> PyResult
|
||||
where
|
||||
T: Into<PyFuncArgs>,
|
||||
{
|
||||
// This is only used in the vm for magic methods, which use a greatly simplified attribute lookup.
|
||||
let cls = obj.typ();
|
||||
match cls.get_attr(method_name) {
|
||||
@@ -316,7 +285,11 @@ impl VirtualMachine {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn invoke(&mut self, func_ref: PyObjectRef, args: PyFuncArgs) -> PyResult {
|
||||
pub fn invoke<T>(&mut self, func_ref: PyObjectRef, args: T) -> PyResult
|
||||
where
|
||||
T: Into<PyFuncArgs>,
|
||||
{
|
||||
let args = args.into();
|
||||
trace!("Invoke: {:?} {:?}", func_ref, args);
|
||||
match func_ref.payload {
|
||||
PyObjectPayload::RustFunction { ref function } => function(self, args),
|
||||
@@ -325,18 +298,16 @@ impl VirtualMachine {
|
||||
ref scope,
|
||||
ref defaults,
|
||||
} => self.invoke_python_function(code, scope, defaults, args),
|
||||
PyObjectPayload::Class { .. } => self.call_method_pyargs(&func_ref, "__call__", args),
|
||||
PyObjectPayload::Class { .. } => self.call_method(&func_ref, "__call__", args),
|
||||
PyObjectPayload::BoundMethod {
|
||||
ref function,
|
||||
ref object,
|
||||
} => self.invoke(function.clone(), args.insert(object.clone())),
|
||||
PyObjectPayload::Instance { .. } => {
|
||||
self.call_method_pyargs(&func_ref, "__call__", args)
|
||||
}
|
||||
PyObjectPayload::Instance { .. } => self.call_method(&func_ref, "__call__", args),
|
||||
ref payload => {
|
||||
// TODO: is it safe to just invoke __call__ otherwise?
|
||||
trace!("invoke __call__ for: {:?}", payload);
|
||||
self.call_method_pyargs(&func_ref, "__call__", args)
|
||||
self.call_method(&func_ref, "__call__", args)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -579,13 +550,7 @@ impl VirtualMachine {
|
||||
F: Fn(&mut VirtualMachine, PyObjectRef, PyObjectRef) -> PyResult,
|
||||
{
|
||||
if let Ok(method) = self.get_method(obj.clone(), method) {
|
||||
let result = self.invoke(
|
||||
method,
|
||||
PyFuncArgs {
|
||||
args: vec![arg.clone()],
|
||||
kwargs: vec![],
|
||||
},
|
||||
)?;
|
||||
let result = self.invoke(method, vec![arg.clone()])?;
|
||||
if !result.is(&self.ctx.not_implemented()) {
|
||||
return Ok(result);
|
||||
}
|
||||
|
||||
@@ -118,10 +118,7 @@ fn browser_request_animation_frame(vm: &mut VirtualMachine, args: PyFuncArgs) ->
|
||||
.upgrade()
|
||||
.expect("that the vm is valid from inside of request_animation_frame");
|
||||
let func = func.clone();
|
||||
let args = PyFuncArgs {
|
||||
args: vec![vm.ctx.new_float(time)],
|
||||
kwargs: vec![],
|
||||
};
|
||||
let args = vec![vm.ctx.new_float(time)];
|
||||
let _ = vm.invoke(func, args);
|
||||
|
||||
let closure = f.borrow_mut().take();
|
||||
|
||||
Reference in New Issue
Block a user