mirror of
https://github.com/RustPython/RustPython.git
synced 2026-10-28 10:44:36 +08:00
Merge branch 'master' into joey/int-any
This commit is contained in:
commit
488d9a5922
8 files changed
+71
-48
No files matched your search
@@ -16,6 +16,9 @@ assert bool() == False
|
||||
assert bool(1) == True
|
||||
assert bool({}) == False
|
||||
|
||||
assert bool(NotImplemented) == True
|
||||
assert bool(...) == True
|
||||
|
||||
if not 1:
|
||||
raise BaseException
|
||||
|
||||
|
||||
+9
-12
@@ -580,18 +580,15 @@ impl Frame {
|
||||
}
|
||||
bytecode::Instruction::PrintExpr => {
|
||||
let expr = self.pop_value();
|
||||
match expr.payload {
|
||||
PyObjectPayload::None => (),
|
||||
_ => {
|
||||
let repr = vm.to_repr(&expr)?;
|
||||
builtins::builtin_print(
|
||||
vm,
|
||||
PyFuncArgs {
|
||||
args: vec![repr],
|
||||
kwargs: vec![],
|
||||
},
|
||||
)?;
|
||||
}
|
||||
if !expr.is(&vm.get_none()) {
|
||||
let repr = vm.to_repr(&expr)?;
|
||||
builtins::builtin_print(
|
||||
vm,
|
||||
PyFuncArgs {
|
||||
args: vec![repr],
|
||||
kwargs: vec![],
|
||||
},
|
||||
)?;
|
||||
}
|
||||
Ok(None)
|
||||
}
|
||||
|
||||
@@ -17,7 +17,7 @@ impl IntoPyObject for bool {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn boolval(vm: &mut VirtualMachine, obj: PyObjectRef) -> Result<bool, PyObjectRef> {
|
||||
pub fn boolval(vm: &mut VirtualMachine, obj: PyObjectRef) -> PyResult<bool> {
|
||||
if let Some(s) = obj.payload::<PyString>() {
|
||||
return Ok(!s.value.is_empty());
|
||||
}
|
||||
@@ -32,7 +32,6 @@ pub fn boolval(vm: &mut VirtualMachine, obj: PyObjectRef) -> Result<bool, PyObje
|
||||
}
|
||||
let result = match obj.payload {
|
||||
PyObjectPayload::Sequence { ref elements } => !elements.borrow().is_empty(),
|
||||
PyObjectPayload::None { .. } => false,
|
||||
_ => {
|
||||
if let Ok(f) = vm.get_method(obj.clone(), "__bool__") {
|
||||
let bool_res = vm.invoke(f, PyFuncArgs::default())?;
|
||||
|
||||
@@ -5,6 +5,7 @@ pub fn init(context: &PyContext) {
|
||||
let none_type = &context.none.typ();
|
||||
context.set_attr(&none_type, "__new__", context.new_rustfunc(none_new));
|
||||
context.set_attr(&none_type, "__repr__", context.new_rustfunc(none_repr));
|
||||
context.set_attr(&none_type, "__bool__", context.new_rustfunc(none_bool));
|
||||
}
|
||||
|
||||
fn none_new(vm: &mut VirtualMachine, args: PyFuncArgs) -> PyResult {
|
||||
@@ -20,3 +21,8 @@ fn none_repr(vm: &mut VirtualMachine, args: PyFuncArgs) -> PyResult {
|
||||
arg_check!(vm, args, required = [(_zelf, Some(vm.ctx.none().typ()))]);
|
||||
Ok(vm.ctx.new_str("None".to_string()))
|
||||
}
|
||||
|
||||
fn none_bool(vm: &mut VirtualMachine, args: PyFuncArgs) -> PyResult {
|
||||
arg_check!(vm, args, required = [(_zelf, Some(vm.ctx.none().typ()))]);
|
||||
Ok(vm.ctx.new_bool(false))
|
||||
}
|
||||
+10
-10
@@ -4,8 +4,8 @@ use super::objtype;
|
||||
use crate::format::{FormatParseError, FormatPart, FormatString};
|
||||
use crate::function::PyRef;
|
||||
use crate::pyobject::{
|
||||
IntoPyObject, OptArg, PyContext, PyFuncArgs, PyIterable, PyObjectPayload, PyObjectPayload2,
|
||||
PyObjectRef, PyResult, TypeProtocol,
|
||||
IntoPyObject, OptionalArg, PyContext, PyFuncArgs, PyIterable, PyObjectPayload,
|
||||
PyObjectPayload2, PyObjectRef, PyResult, TypeProtocol,
|
||||
};
|
||||
use crate::vm::VirtualMachine;
|
||||
use num_traits::ToPrimitive;
|
||||
@@ -160,24 +160,24 @@ impl PyStringRef {
|
||||
fn endswith(
|
||||
self,
|
||||
suffix: PyStringRef,
|
||||
start: OptArg<usize>,
|
||||
end: OptArg<usize>,
|
||||
start: OptionalArg<usize>,
|
||||
end: OptionalArg<usize>,
|
||||
_vm: &mut VirtualMachine,
|
||||
) -> bool {
|
||||
let start = start.unwrap_or(0);
|
||||
let end = end.unwrap_or(self.value.len());
|
||||
let start = start.into_option().unwrap_or(0);
|
||||
let end = end.into_option().unwrap_or(self.value.len());
|
||||
self.value[start..end].ends_with(&suffix.value)
|
||||
}
|
||||
|
||||
fn startswith(
|
||||
self,
|
||||
prefix: PyStringRef,
|
||||
start: OptArg<usize>,
|
||||
end: OptArg<usize>,
|
||||
start: OptionalArg<usize>,
|
||||
end: OptionalArg<usize>,
|
||||
_vm: &mut VirtualMachine,
|
||||
) -> bool {
|
||||
let start = start.unwrap_or(0);
|
||||
let end = end.unwrap_or(self.value.len());
|
||||
let start = start.into_option().unwrap_or(0);
|
||||
let end = end.into_option().unwrap_or(self.value.len());
|
||||
self.value[start..end].starts_with(&prefix.value)
|
||||
}
|
||||
|
||||
|
||||
+34
-18
@@ -156,7 +156,9 @@ pub struct PyContext {
|
||||
|
||||
fn _nothing() -> PyObjectRef {
|
||||
PyObject {
|
||||
payload: PyObjectPayload::None,
|
||||
payload: PyObjectPayload::AnyRustValue {
|
||||
value: Box::new(()),
|
||||
},
|
||||
typ: None,
|
||||
}
|
||||
.into_ref()
|
||||
@@ -224,14 +226,23 @@ impl PyContext {
|
||||
let exceptions = exceptions::ExceptionZoo::new(&type_type, &object_type, &dict_type);
|
||||
|
||||
let none = PyObject::new(
|
||||
PyObjectPayload::None,
|
||||
PyObjectPayload::AnyRustValue {
|
||||
value: Box::new(()),
|
||||
},
|
||||
create_type("NoneType", &type_type, &object_type, &dict_type),
|
||||
);
|
||||
|
||||
let ellipsis = PyObject::new(PyObjectPayload::None, ellipsis_type.clone());
|
||||
let ellipsis = PyObject::new(
|
||||
PyObjectPayload::AnyRustValue {
|
||||
value: Box::new(()),
|
||||
},
|
||||
ellipsis_type.clone(),
|
||||
);
|
||||
|
||||
let not_implemented = PyObject::new(
|
||||
PyObjectPayload::NotImplemented,
|
||||
PyObjectPayload::AnyRustValue {
|
||||
value: Box::new(()),
|
||||
},
|
||||
create_type("NotImplementedType", &type_type, &object_type, &dict_type),
|
||||
);
|
||||
|
||||
@@ -1214,17 +1225,26 @@ where
|
||||
}
|
||||
}
|
||||
|
||||
pub struct OptArg<T>(Option<T>);
|
||||
/// An argument that may or may not be provided by the caller.
|
||||
///
|
||||
/// This style of argument is not possible in pure Python.
|
||||
pub enum OptionalArg<T> {
|
||||
Present(T),
|
||||
Missing,
|
||||
}
|
||||
|
||||
impl<T> std::ops::Deref for OptArg<T> {
|
||||
type Target = Option<T>;
|
||||
use self::OptionalArg::*;
|
||||
|
||||
fn deref(&self) -> &Option<T> {
|
||||
&self.0
|
||||
impl<T> OptionalArg<T> {
|
||||
pub fn into_option(self) -> Option<T> {
|
||||
match self {
|
||||
Present(value) => Some(value),
|
||||
Missing => None,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<T> FromArgs for OptArg<T>
|
||||
impl<T> FromArgs for OptionalArg<T>
|
||||
where
|
||||
T: TryFromObject,
|
||||
{
|
||||
@@ -1239,16 +1259,16 @@ where
|
||||
where
|
||||
I: Iterator<Item = PyArg>,
|
||||
{
|
||||
Ok(OptArg(if let Some(PyArg::Positional(_)) = args.peek() {
|
||||
Ok(if let Some(PyArg::Positional(_)) = args.peek() {
|
||||
let value = if let Some(PyArg::Positional(value)) = args.next() {
|
||||
value
|
||||
} else {
|
||||
unreachable!()
|
||||
};
|
||||
Some(T::try_from_object(vm, value)?)
|
||||
Present(T::try_from_object(vm, value)?)
|
||||
} else {
|
||||
None
|
||||
}))
|
||||
Missing
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1499,8 +1519,6 @@ pub enum PyObjectPayload {
|
||||
name: String,
|
||||
scope: ScopeRef,
|
||||
},
|
||||
None,
|
||||
NotImplemented,
|
||||
Class {
|
||||
name: String,
|
||||
dict: RefCell<PyAttributes>,
|
||||
@@ -1540,8 +1558,6 @@ impl fmt::Debug for PyObjectPayload {
|
||||
ref object,
|
||||
} => write!(f, "bound-method: {:?} of {:?}", function, object),
|
||||
PyObjectPayload::Module { .. } => write!(f, "module"),
|
||||
PyObjectPayload::None => write!(f, "None"),
|
||||
PyObjectPayload::NotImplemented => write!(f, "NotImplemented"),
|
||||
PyObjectPayload::Class { ref name, .. } => write!(f, "class {:?}", name),
|
||||
PyObjectPayload::Instance { .. } => write!(f, "instance"),
|
||||
PyObjectPayload::RustFunction { .. } => write!(f, "rust function"),
|
||||
|
||||
@@ -11,7 +11,7 @@ use crate::obj::{
|
||||
objtype,
|
||||
};
|
||||
use crate::pyobject::{
|
||||
create_type, DictProtocol, PyContext, PyFuncArgs, PyObjectPayload, PyObjectRef, PyResult,
|
||||
create_type, DictProtocol, IdProtocol, PyContext, PyFuncArgs, PyObjectRef, PyResult,
|
||||
TypeProtocol,
|
||||
};
|
||||
use crate::VirtualMachine;
|
||||
@@ -69,7 +69,7 @@ impl<'s> serde::Serialize for PyObjectSerializer<'s> {
|
||||
map.serialize_entry(&key, &self.clone_with_object(&e.1))?;
|
||||
}
|
||||
map.end()
|
||||
} else if let PyObjectPayload::None = self.pyobject.payload {
|
||||
} else if self.pyobject.is(&self.vm.get_none()) {
|
||||
serializer.serialize_none()
|
||||
} else {
|
||||
Err(serde::ser::Error::custom(format!(
|
||||
|
||||
+6
-4
@@ -444,10 +444,12 @@ impl VirtualMachine {
|
||||
// Add missing positional arguments, if we have fewer positional arguments than the
|
||||
// function definition calls for
|
||||
if nargs < nexpected_args {
|
||||
let available_defaults = match defaults.payload {
|
||||
PyObjectPayload::Sequence { ref elements } => elements.borrow().clone(),
|
||||
PyObjectPayload::None => vec![],
|
||||
_ => panic!("function defaults not tuple or None"),
|
||||
let available_defaults = if defaults.is(&self.get_none()) {
|
||||
vec![]
|
||||
} else if let PyObjectPayload::Sequence { ref elements } = defaults.payload {
|
||||
elements.borrow().clone()
|
||||
} else {
|
||||
panic!("function defaults not tuple or None");
|
||||
};
|
||||
|
||||
// Given the number of defaults available, check all the arguments for which we
|
||||
|
||||
Reference in new issue
Block a user