mirror of
https://github.com/RustPython/RustPython.git
synced 2026-06-17 01:51:39 +09:00
Clean up TypeProtocol
This commit is contained in:
@@ -88,7 +88,7 @@ fn builtin_bin(vm: &VirtualMachine, args: PyFuncArgs) -> PyResult {
|
||||
|
||||
fn builtin_callable(vm: &VirtualMachine, args: PyFuncArgs) -> PyResult {
|
||||
arg_check!(vm, args, required = [(obj, None)]);
|
||||
let is_callable = objtype::class_has_attr(&obj.type_pyref(), "__call__");
|
||||
let is_callable = objtype::class_has_attr(&obj.class(), "__call__");
|
||||
Ok(vm.new_bool(is_callable))
|
||||
}
|
||||
|
||||
@@ -240,7 +240,7 @@ fn make_scope(
|
||||
} else if vm.isinstance(arg, &dict_type)? {
|
||||
Some(arg)
|
||||
} else {
|
||||
let arg_typ = arg.typ();
|
||||
let arg_typ = arg.class();
|
||||
let actual_type = vm.to_pystr(&arg_typ)?;
|
||||
let expected_type_name = vm.to_pystr(&dict_type)?;
|
||||
return Err(vm.new_type_error(format!(
|
||||
@@ -368,7 +368,7 @@ fn builtin_len(vm: &VirtualMachine, args: PyFuncArgs) -> PyResult {
|
||||
Ok(value) => vm.invoke(value, PyFuncArgs::default()),
|
||||
Err(..) => Err(vm.new_type_error(format!(
|
||||
"object of type '{}' has no method {:?}",
|
||||
objtype::get_type_name(&obj.typ()),
|
||||
objtype::get_type_name(&obj.class()),
|
||||
len_method_name
|
||||
))),
|
||||
}
|
||||
@@ -607,7 +607,7 @@ fn builtin_reversed(vm: &VirtualMachine, args: PyFuncArgs) -> PyResult {
|
||||
// TODO: fallback to using __len__ and __getitem__, if object supports sequence protocol
|
||||
Err(..) => Err(vm.new_type_error(format!(
|
||||
"'{}' object is not reversible",
|
||||
objtype::get_type_name(&obj.typ()),
|
||||
objtype::get_type_name(&obj.class()),
|
||||
))),
|
||||
}
|
||||
}
|
||||
@@ -802,9 +802,9 @@ pub fn builtin_build_class_(vm: &VirtualMachine, mut args: PyFuncArgs) -> PyResu
|
||||
};
|
||||
|
||||
for base in bases.clone() {
|
||||
if objtype::issubclass(&base.type_pyref(), &metaclass) {
|
||||
metaclass = base.type_pyref();
|
||||
} else if !objtype::issubclass(&metaclass, &base.type_pyref()) {
|
||||
if objtype::issubclass(&base.class(), &metaclass) {
|
||||
metaclass = base.class();
|
||||
} else if !objtype::issubclass(&metaclass, &base.class()) {
|
||||
return Err(vm.new_type_error("metaclass conflict: the metaclass of a derived class must be a (non-strict) subclass of the metaclasses of all its bases".to_string()));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -68,7 +68,7 @@ fn exception_str(vm: &VirtualMachine, args: PyFuncArgs) -> PyResult {
|
||||
args,
|
||||
required = [(exc, Some(vm.ctx.exceptions.exception_type.clone()))]
|
||||
);
|
||||
let type_name = objtype::get_type_name(&exc.typ());
|
||||
let type_name = objtype::get_type_name(&exc.class());
|
||||
let msg = if let Ok(m) = vm.get_attribute(exc.clone(), "msg") {
|
||||
match vm.to_pystr(&m) {
|
||||
Ok(msg) => msg,
|
||||
|
||||
@@ -949,7 +949,7 @@ impl Frame {
|
||||
// let args = PyFuncArgs::default();
|
||||
// TODO: what happens when we got an error during handling exception?
|
||||
let args = if let Some(exc) = exc {
|
||||
let exc_type = exc.typ();
|
||||
let exc_type = exc.class().into_object();
|
||||
let exc_val = exc.clone();
|
||||
let exc_tb = vm.ctx.none(); // TODO: retrieve traceback?
|
||||
vec![exc_type, exc_val, exc_tb]
|
||||
@@ -1093,7 +1093,7 @@ impl Frame {
|
||||
Ok(found) => Ok(found),
|
||||
Err(_) => Err(vm.new_type_error(format!(
|
||||
"{} has no __contains__ method",
|
||||
objtype::get_type_name(&haystack.typ())
|
||||
objtype::get_type_name(&haystack.class())
|
||||
))),
|
||||
}
|
||||
}
|
||||
@@ -1103,7 +1103,7 @@ impl Frame {
|
||||
Ok(found) => Ok(vm.ctx.new_bool(!objbool::get_value(&found))),
|
||||
Err(_) => Err(vm.new_type_error(format!(
|
||||
"{} has no __contains__ method",
|
||||
objtype::get_type_name(&haystack.typ())
|
||||
objtype::get_type_name(&haystack.class())
|
||||
))),
|
||||
}
|
||||
}
|
||||
|
||||
@@ -99,7 +99,7 @@ impl PyFuncArgs {
|
||||
Ok(Some(kwarg))
|
||||
} else {
|
||||
let expected_ty_name = vm.to_pystr(&ty)?;
|
||||
let actual_ty_name = vm.to_pystr(&kwarg.typ())?;
|
||||
let actual_ty_name = vm.to_pystr(&kwarg.class())?;
|
||||
Err(vm.new_type_error(format!(
|
||||
"argument of type {} is required for named parameter `{}` (got: {})",
|
||||
expected_ty_name, key, actual_ty_name
|
||||
|
||||
@@ -20,7 +20,7 @@ macro_rules! type_check {
|
||||
let arg = &$args.args[$arg_count];
|
||||
|
||||
if !$crate::obj::objtype::isinstance(arg, &expected_type) {
|
||||
let arg_typ = arg.typ();
|
||||
let arg_typ = arg.class();
|
||||
let expected_type_name = $vm.to_pystr(&expected_type)?;
|
||||
let actual_type = $vm.to_pystr(&arg_typ)?;
|
||||
return Err($vm.new_type_error(format!(
|
||||
|
||||
@@ -190,7 +190,7 @@ impl PyFloatRef {
|
||||
}
|
||||
}
|
||||
} else {
|
||||
let type_name = objtype::get_type_name(&arg.typ());
|
||||
let type_name = objtype::get_type_name(&arg.class());
|
||||
return Err(vm.new_type_error(format!("can't convert {} to float", type_name)));
|
||||
};
|
||||
PyFloat { value }.into_ref_with_type(vm, cls)
|
||||
|
||||
@@ -76,7 +76,7 @@ fn bind_method(vm: &VirtualMachine, args: PyFuncArgs) -> PyResult {
|
||||
required = [(function, None), (obj, None), (cls, None)]
|
||||
);
|
||||
|
||||
if obj.is(&vm.get_none()) && !cls.is(&obj.typ()) {
|
||||
if obj.is(&vm.get_none()) && !cls.is(&obj.class()) {
|
||||
Ok(function.clone())
|
||||
} else {
|
||||
Ok(vm.ctx.new_bound_method(function.clone(), obj.clone()))
|
||||
|
||||
@@ -213,8 +213,8 @@ impl PyIntRef {
|
||||
if !objtype::isinstance(&other, &vm.ctx.int_type()) {
|
||||
return Err(vm.new_type_error(format!(
|
||||
"unsupported operand type(s) for << '{}' and '{}'",
|
||||
objtype::get_type_name(&self.as_object().typ()),
|
||||
objtype::get_type_name(&other.typ())
|
||||
objtype::get_type_name(&self.as_object().class()),
|
||||
objtype::get_type_name(&other.class())
|
||||
)));
|
||||
}
|
||||
|
||||
@@ -236,8 +236,8 @@ impl PyIntRef {
|
||||
if !objtype::isinstance(&other, &vm.ctx.int_type()) {
|
||||
return Err(vm.new_type_error(format!(
|
||||
"unsupported operand type(s) for >> '{}' and '{}'",
|
||||
objtype::get_type_name(&self.as_object().typ()),
|
||||
objtype::get_type_name(&other.typ())
|
||||
objtype::get_type_name(&self.as_object().class()),
|
||||
objtype::get_type_name(&other.class())
|
||||
)));
|
||||
}
|
||||
|
||||
@@ -420,7 +420,7 @@ pub fn to_int(vm: &VirtualMachine, obj: &PyObjectRef, base: u32) -> PyResult<Big
|
||||
}
|
||||
}
|
||||
} else {
|
||||
let type_name = objtype::get_type_name(&obj.typ());
|
||||
let type_name = objtype::get_type_name(&obj.class());
|
||||
return Err(vm.new_type_error(format!(
|
||||
"int() argument must be a string or a number, not '{}'",
|
||||
type_name
|
||||
|
||||
@@ -21,7 +21,7 @@ use crate::obj::objtype::PyClassRef;
|
||||
*/
|
||||
pub fn get_iter(vm: &VirtualMachine, iter_target: &PyObjectRef) -> PyResult {
|
||||
vm.call_method(iter_target, "__iter__", vec![])
|
||||
// let type_str = objstr::get_value(&vm.to_str(iter_target.typ()).unwrap());
|
||||
// let type_str = objstr::get_value(&vm.to_str(iter_target.class()).unwrap());
|
||||
// let type_error = vm.new_type_error(format!("Cannot iterate over {}", type_str));
|
||||
// return Err(type_error);
|
||||
}
|
||||
|
||||
@@ -12,7 +12,7 @@ pub type PyNoneRef = PyRef<PyNone>;
|
||||
|
||||
impl PyValue for PyNone {
|
||||
fn class(vm: &VirtualMachine) -> PyClassRef {
|
||||
vm.ctx.none().type_pyref()
|
||||
vm.ctx.none().class()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -44,7 +44,7 @@ impl PyNoneRef {
|
||||
|
||||
fn get_attribute(self, name: PyStringRef, vm: &VirtualMachine) -> PyResult {
|
||||
trace!("None.__getattribute__({:?}, {:?})", self, name);
|
||||
let cls = self.typ();
|
||||
let cls = self.class();
|
||||
|
||||
// Properties use a comparision with None to determine if they are either invoked by am
|
||||
// instance binding or a class binding. But if the object itself is None then this detection
|
||||
@@ -69,7 +69,7 @@ impl PyNoneRef {
|
||||
}
|
||||
|
||||
if let Some(attr) = class_get_attr(&cls, &name.value) {
|
||||
let attr_class = attr.type_pyref();
|
||||
let attr_class = attr.class();
|
||||
if class_has_attr(&attr_class, "__set__") {
|
||||
if let Some(get_func) = class_get_attr(&attr_class, "__get__") {
|
||||
return call_descriptor(
|
||||
@@ -88,7 +88,7 @@ impl PyNoneRef {
|
||||
// Ok(obj_attr)
|
||||
// } else
|
||||
if let Some(attr) = class_get_attr(&cls, &name.value) {
|
||||
let attr_class = attr.type_pyref();
|
||||
let attr_class = attr.class();
|
||||
if let Some(get_func) = class_get_attr(&attr_class, "__get__") {
|
||||
call_descriptor(attr, get_func, self.into_object(), cls.into_object(), vm)
|
||||
} else {
|
||||
@@ -107,7 +107,7 @@ fn none_new(_: PyClassRef, vm: &VirtualMachine) -> PyNoneRef {
|
||||
}
|
||||
|
||||
pub fn init(context: &PyContext) {
|
||||
extend_class!(context, &context.none.typ(), {
|
||||
extend_class!(context, &context.none.class(), {
|
||||
"__new__" => context.new_rustfunc(none_new),
|
||||
"__repr__" => context.new_rustfunc(PyNoneRef::repr),
|
||||
"__bool__" => context.new_rustfunc(PyNoneRef::bool),
|
||||
|
||||
@@ -104,10 +104,10 @@ fn object_setattr(
|
||||
vm: &VirtualMachine,
|
||||
) -> PyResult<()> {
|
||||
trace!("object.__setattr__({:?}, {}, {:?})", obj, attr_name, value);
|
||||
let cls = obj.type_pyref();
|
||||
let cls = obj.class();
|
||||
|
||||
if let Some(attr) = objtype::class_get_attr(&cls, &attr_name.value) {
|
||||
if let Some(descriptor) = objtype::class_get_attr(&attr.type_pyref(), "__set__") {
|
||||
if let Some(descriptor) = objtype::class_get_attr(&attr.class(), "__set__") {
|
||||
return vm
|
||||
.invoke(descriptor, vec![attr, obj.clone(), value])
|
||||
.map(|_| ());
|
||||
@@ -118,7 +118,7 @@ fn object_setattr(
|
||||
dict.set_item(&vm.ctx, &attr_name.value, value);
|
||||
Ok(())
|
||||
} else {
|
||||
let type_name = objtype::get_type_name(obj.type_ref());
|
||||
let type_name = objtype::get_type_name(&obj.class());
|
||||
Err(vm.new_attribute_error(format!(
|
||||
"'{}' object has no attribute '{}'",
|
||||
type_name, &attr_name.value
|
||||
@@ -127,10 +127,10 @@ fn object_setattr(
|
||||
}
|
||||
|
||||
fn object_delattr(obj: PyObjectRef, attr_name: PyStringRef, vm: &VirtualMachine) -> PyResult<()> {
|
||||
let cls = obj.type_pyref();
|
||||
let cls = obj.class();
|
||||
|
||||
if let Some(attr) = objtype::class_get_attr(&cls, &attr_name.value) {
|
||||
if let Some(descriptor) = objtype::class_get_attr(&attr.type_pyref(), "__delete__") {
|
||||
if let Some(descriptor) = objtype::class_get_attr(&attr.class(), "__delete__") {
|
||||
return vm.invoke(descriptor, vec![attr, obj.clone()]).map(|_| ());
|
||||
}
|
||||
}
|
||||
@@ -139,7 +139,7 @@ fn object_delattr(obj: PyObjectRef, attr_name: PyStringRef, vm: &VirtualMachine)
|
||||
dict.del_item(&attr_name.value);
|
||||
Ok(())
|
||||
} else {
|
||||
let type_name = objtype::get_type_name(obj.type_ref());
|
||||
let type_name = objtype::get_type_name(&obj.class());
|
||||
Err(vm.new_attribute_error(format!(
|
||||
"'{}' object has no attribute '{}'",
|
||||
type_name, &attr_name.value
|
||||
@@ -154,7 +154,7 @@ fn object_str(vm: &VirtualMachine, args: PyFuncArgs) -> PyResult {
|
||||
|
||||
fn object_repr(vm: &VirtualMachine, args: PyFuncArgs) -> PyResult {
|
||||
arg_check!(vm, args, required = [(obj, Some(vm.ctx.object()))]);
|
||||
let type_name = objtype::get_type_name(&obj.typ());
|
||||
let type_name = objtype::get_type_name(&obj.class());
|
||||
let address = obj.get_id();
|
||||
Ok(vm.new_str(format!("<{} object at 0x{:x}>", type_name, address)))
|
||||
}
|
||||
@@ -216,7 +216,7 @@ fn object_init(vm: &VirtualMachine, _args: PyFuncArgs) -> PyResult {
|
||||
}
|
||||
|
||||
fn object_class(obj: PyObjectRef, _vm: &VirtualMachine) -> PyObjectRef {
|
||||
obj.typ()
|
||||
obj.class().into_object()
|
||||
}
|
||||
|
||||
fn object_class_setter(
|
||||
@@ -224,7 +224,7 @@ fn object_class_setter(
|
||||
_value: PyObjectRef,
|
||||
vm: &VirtualMachine,
|
||||
) -> PyResult {
|
||||
let type_repr = vm.to_pystr(&instance.typ())?;
|
||||
let type_repr = vm.to_pystr(&instance.class())?;
|
||||
Err(vm.new_type_error(format!("can't change class of type '{}'", type_repr)))
|
||||
}
|
||||
|
||||
@@ -247,10 +247,10 @@ fn object_getattribute(vm: &VirtualMachine, args: PyFuncArgs) -> PyResult {
|
||||
);
|
||||
let name = objstr::get_value(&name_str);
|
||||
trace!("object.__getattribute__({:?}, {:?})", obj, name);
|
||||
let cls = obj.type_pyref();
|
||||
let cls = obj.class();
|
||||
|
||||
if let Some(attr) = objtype::class_get_attr(&cls, &name) {
|
||||
let attr_class = attr.type_pyref();
|
||||
let attr_class = attr.class();
|
||||
if objtype::class_has_attr(&attr_class, "__set__") {
|
||||
if let Some(descriptor) = objtype::class_get_attr(&attr_class, "__get__") {
|
||||
return vm.invoke(descriptor, vec![attr, obj.clone(), cls.into_object()]);
|
||||
@@ -279,7 +279,7 @@ fn object_getattr(obj: &PyObjectRef, attr_name: &str) -> Option<PyObjectRef> {
|
||||
|
||||
pub fn get_attributes(obj: &PyObjectRef) -> PyAttributes {
|
||||
// Get class attributes:
|
||||
let mut attributes = objtype::get_attributes(obj.type_pyref());
|
||||
let mut attributes = objtype::get_attributes(obj.class());
|
||||
|
||||
// Get instance attributes:
|
||||
if let Some(dict) = &obj.dict {
|
||||
|
||||
@@ -6,7 +6,9 @@ use crate::function::IntoPyNativeFunc;
|
||||
use crate::function::OptionalArg;
|
||||
use crate::obj::objstr::PyStringRef;
|
||||
use crate::obj::objtype::PyClassRef;
|
||||
use crate::pyobject::{IdProtocol, PyContext, PyObject, PyObjectRef, PyRef, PyResult, PyValue};
|
||||
use crate::pyobject::{
|
||||
IdProtocol, PyContext, PyObject, PyObjectRef, PyRef, PyResult, PyValue, TypeProtocol,
|
||||
};
|
||||
use crate::vm::VirtualMachine;
|
||||
|
||||
/// Read-only property, doesn't have __set__ or __delete__
|
||||
@@ -137,7 +139,7 @@ impl PyPropertyRef {
|
||||
setter: self.setter.clone(),
|
||||
deleter: self.deleter.clone(),
|
||||
}
|
||||
.into_ref_with_type(vm, self.typ())
|
||||
.into_ref_with_type(vm, TypeProtocol::class(&self))
|
||||
}
|
||||
|
||||
fn setter(self, setter: Option<PyObjectRef>, vm: &VirtualMachine) -> PyResult<Self> {
|
||||
@@ -146,7 +148,7 @@ impl PyPropertyRef {
|
||||
setter: setter.or_else(|| self.setter.clone()),
|
||||
deleter: self.deleter.clone(),
|
||||
}
|
||||
.into_ref_with_type(vm, self.typ())
|
||||
.into_ref_with_type(vm, TypeProtocol::class(&self))
|
||||
}
|
||||
|
||||
fn deleter(self, deleter: Option<PyObjectRef>, vm: &VirtualMachine) -> PyResult<Self> {
|
||||
@@ -155,7 +157,7 @@ impl PyPropertyRef {
|
||||
setter: self.setter.clone(),
|
||||
deleter: deleter.or_else(|| self.deleter.clone()),
|
||||
}
|
||||
.into_ref_with_type(vm, self.typ())
|
||||
.into_ref_with_type(vm, TypeProtocol::class(&self))
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -163,13 +163,13 @@ pub fn get_item(
|
||||
if sequence.payload::<PyList>().is_some() {
|
||||
Ok(PyObject::new(
|
||||
PyList::from(elements.to_vec().get_slice_items(vm, &subscript)?),
|
||||
sequence.type_pyref(),
|
||||
sequence.class(),
|
||||
None,
|
||||
))
|
||||
} else if sequence.payload::<PyTuple>().is_some() {
|
||||
Ok(PyObject::new(
|
||||
PyTuple::from(elements.to_vec().get_slice_items(vm, &subscript)?),
|
||||
sequence.type_pyref(),
|
||||
sequence.class(),
|
||||
None,
|
||||
))
|
||||
} else {
|
||||
|
||||
@@ -231,16 +231,16 @@ fn set_new(cls: PyClassRef, iterable: OptionalArg<PyObjectRef>, vm: &VirtualMach
|
||||
fn set_len(vm: &VirtualMachine, args: PyFuncArgs) -> PyResult {
|
||||
trace!("set.len called with: {:?}", args);
|
||||
arg_check!(vm, args, required = [(s, None)]);
|
||||
validate_set_or_frozenset(vm, s.type_pyref())?;
|
||||
validate_set_or_frozenset(vm, s.class())?;
|
||||
let elements = get_elements(s);
|
||||
Ok(vm.context().new_int(elements.len()))
|
||||
}
|
||||
|
||||
fn set_copy(obj: PyObjectRef, vm: &VirtualMachine) -> PyResult {
|
||||
trace!("set.copy called with: {:?}", obj);
|
||||
validate_set_or_frozenset(vm, obj.type_pyref())?;
|
||||
validate_set_or_frozenset(vm, obj.class())?;
|
||||
let elements = get_elements(&obj).clone();
|
||||
create_set(vm, elements, obj.type_pyref())
|
||||
create_set(vm, elements, obj.class())
|
||||
}
|
||||
|
||||
fn set_repr(vm: &VirtualMachine, args: PyFuncArgs) -> PyResult {
|
||||
@@ -265,7 +265,7 @@ fn set_repr(vm: &VirtualMachine, args: PyFuncArgs) -> PyResult {
|
||||
|
||||
pub fn set_contains(vm: &VirtualMachine, args: PyFuncArgs) -> PyResult {
|
||||
arg_check!(vm, args, required = [(set, None), (needle, None)]);
|
||||
validate_set_or_frozenset(vm, set.type_pyref())?;
|
||||
validate_set_or_frozenset(vm, set.class())?;
|
||||
for element in get_elements(set).iter() {
|
||||
match vm._eq(needle.clone(), element.1.clone()) {
|
||||
Ok(value) => {
|
||||
@@ -333,8 +333,8 @@ fn set_compare_inner(
|
||||
) -> PyResult {
|
||||
arg_check!(vm, args, required = [(zelf, None), (other, None)]);
|
||||
|
||||
validate_set_or_frozenset(vm, zelf.type_pyref())?;
|
||||
validate_set_or_frozenset(vm, other.type_pyref())?;
|
||||
validate_set_or_frozenset(vm, zelf.class())?;
|
||||
validate_set_or_frozenset(vm, other.class())?;
|
||||
|
||||
let get_zelf = |swap: bool| -> &PyObjectRef {
|
||||
if swap {
|
||||
@@ -370,13 +370,13 @@ fn set_compare_inner(
|
||||
}
|
||||
|
||||
fn set_union(zelf: PyObjectRef, other: PyObjectRef, vm: &VirtualMachine) -> PyResult {
|
||||
validate_set_or_frozenset(vm, zelf.type_pyref())?;
|
||||
validate_set_or_frozenset(vm, other.type_pyref())?;
|
||||
validate_set_or_frozenset(vm, zelf.class())?;
|
||||
validate_set_or_frozenset(vm, other.class())?;
|
||||
|
||||
let mut elements = get_elements(&zelf).clone();
|
||||
elements.extend(get_elements(&other).clone());
|
||||
|
||||
create_set(vm, elements, zelf.type_pyref())
|
||||
create_set(vm, elements, zelf.class())
|
||||
}
|
||||
|
||||
fn set_intersection(zelf: PyObjectRef, other: PyObjectRef, vm: &VirtualMachine) -> PyResult {
|
||||
@@ -392,8 +392,8 @@ fn set_symmetric_difference(
|
||||
other: PyObjectRef,
|
||||
vm: &VirtualMachine,
|
||||
) -> PyResult {
|
||||
validate_set_or_frozenset(vm, zelf.type_pyref())?;
|
||||
validate_set_or_frozenset(vm, other.type_pyref())?;
|
||||
validate_set_or_frozenset(vm, zelf.class())?;
|
||||
validate_set_or_frozenset(vm, other.class())?;
|
||||
let mut elements = HashMap::new();
|
||||
|
||||
for element in get_elements(&zelf).iter() {
|
||||
@@ -410,7 +410,7 @@ fn set_symmetric_difference(
|
||||
}
|
||||
}
|
||||
|
||||
create_set(vm, elements, zelf.type_pyref())
|
||||
create_set(vm, elements, zelf.class())
|
||||
}
|
||||
|
||||
enum SetCombineOperation {
|
||||
@@ -424,8 +424,8 @@ fn set_combine_inner(
|
||||
vm: &VirtualMachine,
|
||||
op: SetCombineOperation,
|
||||
) -> PyResult {
|
||||
validate_set_or_frozenset(vm, zelf.type_pyref())?;
|
||||
validate_set_or_frozenset(vm, other.type_pyref())?;
|
||||
validate_set_or_frozenset(vm, zelf.class())?;
|
||||
validate_set_or_frozenset(vm, other.class())?;
|
||||
let mut elements = HashMap::new();
|
||||
|
||||
for element in get_elements(&zelf).iter() {
|
||||
@@ -439,7 +439,7 @@ fn set_combine_inner(
|
||||
}
|
||||
}
|
||||
|
||||
create_set(vm, elements, zelf.type_pyref())
|
||||
create_set(vm, elements, zelf.class())
|
||||
}
|
||||
|
||||
fn set_pop(vm: &VirtualMachine, args: PyFuncArgs) -> PyResult {
|
||||
|
||||
@@ -715,7 +715,7 @@ fn str_format(vm: &VirtualMachine, args: PyFuncArgs) -> PyResult {
|
||||
|
||||
let zelf = &args.args[0];
|
||||
if !objtype::isinstance(&zelf, &vm.ctx.str_type()) {
|
||||
let zelf_typ = zelf.typ();
|
||||
let zelf_typ = zelf.class();
|
||||
let actual_type = vm.to_pystr(&zelf_typ)?;
|
||||
return Err(vm.new_type_error(format!(
|
||||
"descriptor 'format' requires a 'str' object but received a '{}'",
|
||||
@@ -738,7 +738,7 @@ fn call_object_format(vm: &VirtualMachine, argument: PyObjectRef, format_spec: &
|
||||
let returned_type = vm.ctx.new_str(format_spec.to_string());
|
||||
let result = vm.call_method(&argument, "__format__", vec![returned_type])?;
|
||||
if !objtype::isinstance(&result, &vm.ctx.str_type()) {
|
||||
let result_type = result.typ();
|
||||
let result_type = result.class();
|
||||
let actual_type = vm.to_pystr(&result_type)?;
|
||||
return Err(vm.new_type_error(format!("__format__ must return a str, not {}", actual_type)));
|
||||
}
|
||||
@@ -809,7 +809,7 @@ fn str_new(
|
||||
OptionalArg::Present(ref input) => vm.to_str(input)?.into_object(),
|
||||
OptionalArg::Missing => vm.new_str("".to_string()),
|
||||
};
|
||||
if string.typ().is(&cls) {
|
||||
if string.class().is(&cls) {
|
||||
TryFromObject::try_from_object(vm, string)
|
||||
} else {
|
||||
let payload = string.payload::<PyString>().unwrap();
|
||||
|
||||
@@ -112,7 +112,7 @@ fn super_new(
|
||||
|
||||
// Check type argument:
|
||||
if !objtype::isinstance(py_type.as_object(), &vm.get_type()) {
|
||||
let type_name = objtype::get_type_name(py_type.as_object().type_ref());
|
||||
let type_name = objtype::get_type_name(&py_type.as_object().class());
|
||||
return Err(vm.new_type_error(format!(
|
||||
"super() argument 1 must be type, not {}",
|
||||
type_name
|
||||
|
||||
@@ -39,12 +39,6 @@ impl PyValue for PyClass {
|
||||
}
|
||||
}
|
||||
|
||||
impl TypeProtocol for PyClassRef {
|
||||
fn type_ref(&self) -> &PyObjectRef {
|
||||
&self.as_object().type_ref()
|
||||
}
|
||||
}
|
||||
|
||||
struct IterMro<'a> {
|
||||
cls: &'a PyClassRef,
|
||||
offset: Option<usize>,
|
||||
@@ -117,10 +111,10 @@ impl PyClassRef {
|
||||
fn getattribute(self, name_ref: PyStringRef, vm: &VirtualMachine) -> PyResult {
|
||||
let name = &name_ref.value;
|
||||
trace!("type.__getattribute__({:?}, {:?})", self, name);
|
||||
let mcl = self.type_pyref();
|
||||
let mcl = self.class();
|
||||
|
||||
if let Some(attr) = class_get_attr(&mcl, &name) {
|
||||
let attr_class = attr.type_pyref();
|
||||
let attr_class = attr.class();
|
||||
if class_has_attr(&attr_class, "__set__") {
|
||||
if let Some(descriptor) = class_get_attr(&attr_class, "__get__") {
|
||||
return vm.invoke(
|
||||
@@ -132,7 +126,7 @@ impl PyClassRef {
|
||||
}
|
||||
|
||||
if let Some(attr) = class_get_attr(&self, &name) {
|
||||
let attr_class = attr.type_pyref();
|
||||
let attr_class = attr.class();
|
||||
if let Some(descriptor) = class_get_attr(&attr_class, "__get__") {
|
||||
let none = vm.get_none();
|
||||
return vm.invoke(descriptor, vec![attr, none, self.into_object()]);
|
||||
@@ -156,8 +150,8 @@ impl PyClassRef {
|
||||
value: PyObjectRef,
|
||||
vm: &VirtualMachine,
|
||||
) -> PyResult<()> {
|
||||
if let Some(attr) = class_get_attr(&self.type_pyref(), &attr_name.value) {
|
||||
if let Some(descriptor) = class_get_attr(&attr.type_pyref(), "__set__") {
|
||||
if let Some(attr) = class_get_attr(&self.class(), &attr_name.value) {
|
||||
if let Some(descriptor) = class_get_attr(&attr.class(), "__set__") {
|
||||
vm.invoke(descriptor, vec![attr, self.into_object(), value])?;
|
||||
return Ok(());
|
||||
}
|
||||
@@ -218,7 +212,7 @@ fn _mro(cls: &PyClassRef) -> Vec<PyClassRef> {
|
||||
/// Determines if `obj` actually an instance of `cls`, this doesn't call __instancecheck__, so only
|
||||
/// use this if `cls` is known to have not overridden the base __instancecheck__ magic method.
|
||||
pub fn isinstance(obj: &PyObjectRef, cls: &PyClassRef) -> bool {
|
||||
issubclass(&obj.type_pyref(), &cls)
|
||||
issubclass(&obj.class(), &cls)
|
||||
}
|
||||
|
||||
/// Determines if `subclass` is actually a subclass of `cls`, this doesn't call __subclasscheck__,
|
||||
@@ -229,18 +223,14 @@ pub fn issubclass(subclass: &PyClassRef, cls: &PyClassRef) -> bool {
|
||||
subclass.is(cls) || mro.iter().any(|c| c.is(cls.as_object()))
|
||||
}
|
||||
|
||||
pub fn get_type_name(typ: &PyObjectRef) -> String {
|
||||
if let Some(PyClass { name, .. }) = &typ.payload::<PyClass>() {
|
||||
name.clone()
|
||||
} else {
|
||||
panic!("Cannot get type_name of non-type type {:?}", typ);
|
||||
}
|
||||
pub fn get_type_name(typ: &PyClassRef) -> String {
|
||||
typ.name.clone()
|
||||
}
|
||||
|
||||
pub fn type_new(vm: &VirtualMachine, args: PyFuncArgs) -> PyResult {
|
||||
debug!("type.__new__ {:?}", args);
|
||||
if args.args.len() == 2 {
|
||||
Ok(args.args[1].typ())
|
||||
Ok(args.args[1].class().into_object())
|
||||
} else if args.args.len() == 4 {
|
||||
let (typ, name, bases, dict) = args.bind(vm)?;
|
||||
type_new_class(vm, typ, name, bases, dict).map(|x| x.into_object())
|
||||
|
||||
@@ -88,7 +88,7 @@ impl fmt::Display for PyObject<dyn PyObjectPayload> {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
use self::TypeProtocol;
|
||||
if let Some(PyClass { ref name, .. }) = self.payload::<PyClass>() {
|
||||
let type_name = objtype::get_type_name(&self.typ());
|
||||
let type_name = objtype::get_type_name(&self.class());
|
||||
// We don't have access to a vm, so just assume that if its parent's name
|
||||
// is type, it's a type
|
||||
if type_name == "type" {
|
||||
@@ -101,7 +101,7 @@ impl fmt::Display for PyObject<dyn PyObjectPayload> {
|
||||
if let Some(PyModule { ref name, .. }) = self.payload::<PyModule>() {
|
||||
return write!(f, "module '{}'", name);
|
||||
}
|
||||
write!(f, "'{}' object", objtype::get_type_name(&self.typ()))
|
||||
write!(f, "'{}' object", objtype::get_type_name(&self.class()))
|
||||
}
|
||||
}
|
||||
|
||||
@@ -163,7 +163,7 @@ pub struct PyNotImplemented;
|
||||
|
||||
impl PyValue for PyNotImplemented {
|
||||
fn class(vm: &VirtualMachine) -> PyClassRef {
|
||||
vm.ctx.not_implemented().type_pyref()
|
||||
vm.ctx.not_implemented().class()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -772,7 +772,7 @@ impl<T: PyValue> PyRef<T> {
|
||||
|
||||
pub fn typ(&self) -> PyClassRef {
|
||||
PyRef {
|
||||
obj: self.obj.typ(),
|
||||
obj: self.obj.class().into_object(),
|
||||
_payload: PhantomData,
|
||||
}
|
||||
}
|
||||
@@ -802,7 +802,7 @@ where
|
||||
} else {
|
||||
let class = T::class(vm);
|
||||
let expected_type = vm.to_pystr(&class)?;
|
||||
let actual_type = vm.to_pystr(&obj.typ())?;
|
||||
let actual_type = vm.to_pystr(&obj.class())?;
|
||||
Err(vm.new_type_error(format!(
|
||||
"Expected type {}, not {}",
|
||||
expected_type, actual_type,
|
||||
@@ -877,18 +877,12 @@ impl<T: PyObjectPayload> IdProtocol for PyRef<T> {
|
||||
}
|
||||
|
||||
pub trait TypeProtocol {
|
||||
fn typ(&self) -> PyObjectRef {
|
||||
self.type_ref().clone()
|
||||
}
|
||||
fn type_pyref(&self) -> PyClassRef {
|
||||
self.typ().downcast().unwrap()
|
||||
}
|
||||
fn type_ref(&self) -> &PyObjectRef;
|
||||
fn class(&self) -> PyClassRef;
|
||||
}
|
||||
|
||||
impl TypeProtocol for PyObjectRef {
|
||||
fn type_ref(&self) -> &PyObjectRef {
|
||||
(**self).type_ref()
|
||||
fn class(&self) -> PyClassRef {
|
||||
(**self).class()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -896,8 +890,14 @@ impl<T> TypeProtocol for PyObject<T>
|
||||
where
|
||||
T: ?Sized + PyObjectPayload,
|
||||
{
|
||||
fn type_ref(&self) -> &PyObjectRef {
|
||||
self.typ.as_object()
|
||||
fn class(&self) -> PyClassRef {
|
||||
self.typ.clone()
|
||||
}
|
||||
}
|
||||
|
||||
impl<T> TypeProtocol for PyRef<T> {
|
||||
fn class(&self) -> PyClassRef {
|
||||
self.obj.typ.clone()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -956,7 +956,7 @@ pub trait BufferProtocol {
|
||||
|
||||
impl BufferProtocol for PyObjectRef {
|
||||
fn readonly(&self) -> bool {
|
||||
match objtype::get_type_name(&self.typ()).as_ref() {
|
||||
match objtype::get_type_name(&self.class()).as_ref() {
|
||||
"bytes" => false,
|
||||
"bytearray" | "memoryview" => true,
|
||||
_ => panic!("Bytes-Like type expected not {:?}", self),
|
||||
@@ -1249,7 +1249,7 @@ where
|
||||
"must be {} or {}, not {}",
|
||||
A::class(vm),
|
||||
B::class(vm),
|
||||
obj.type_pyref()
|
||||
obj.class()
|
||||
))
|
||||
})
|
||||
}
|
||||
|
||||
@@ -74,7 +74,7 @@ impl<'s> serde::Serialize for PyObjectSerializer<'s> {
|
||||
} else {
|
||||
Err(serde::ser::Error::custom(format!(
|
||||
"Object of type '{:?}' is not serializable",
|
||||
self.pyobject.typ()
|
||||
self.pyobject.class()
|
||||
)))
|
||||
}
|
||||
}
|
||||
|
||||
16
vm/src/vm.rs
16
vm/src/vm.rs
@@ -174,8 +174,8 @@ impl VirtualMachine {
|
||||
b: PyObjectRef,
|
||||
op: &str,
|
||||
) -> PyObjectRef {
|
||||
let a_type_name = objtype::get_type_name(&a.typ());
|
||||
let b_type_name = objtype::get_type_name(&b.typ());
|
||||
let a_type_name = objtype::get_type_name(&a.class());
|
||||
let b_type_name = objtype::get_type_name(&b.class());
|
||||
self.new_type_error(format!(
|
||||
"Unsupported operand types for '{}': '{}' and '{}'",
|
||||
op, a_type_name, b_type_name
|
||||
@@ -270,7 +270,7 @@ impl VirtualMachine {
|
||||
pub fn isinstance(&self, obj: &PyObjectRef, cls: &PyClassRef) -> PyResult<bool> {
|
||||
// cpython first does an exact check on the type, although documentation doesn't state that
|
||||
// https://github.com/python/cpython/blob/a24107b04c1277e3c1105f98aff5bfa3a98b33a0/Objects/abstract.c#L2408
|
||||
if Rc::ptr_eq(&obj.typ(), cls.as_object()) {
|
||||
if Rc::ptr_eq(&obj.class().into_object(), cls.as_object()) {
|
||||
Ok(true)
|
||||
} else {
|
||||
let ret = self.call_method(cls.as_object(), "__instancecheck__", vec![obj.clone()])?;
|
||||
@@ -286,10 +286,10 @@ impl VirtualMachine {
|
||||
}
|
||||
|
||||
pub fn call_get_descriptor(&self, attr: PyObjectRef, obj: PyObjectRef) -> PyResult {
|
||||
let attr_class = attr.type_pyref();
|
||||
let attr_class = attr.class();
|
||||
if let Some(descriptor) = objtype::class_get_attr(&attr_class, "__get__") {
|
||||
let cls = obj.typ();
|
||||
self.invoke(descriptor, vec![attr, obj.clone(), cls])
|
||||
let cls = obj.class();
|
||||
self.invoke(descriptor, vec![attr, obj.clone(), cls.into_object()])
|
||||
} else {
|
||||
Ok(attr)
|
||||
}
|
||||
@@ -300,7 +300,7 @@ impl VirtualMachine {
|
||||
T: Into<PyFuncArgs>,
|
||||
{
|
||||
// This is only used in the vm for magic methods, which use a greatly simplified attribute lookup.
|
||||
let cls = obj.type_pyref();
|
||||
let cls = obj.class();
|
||||
match objtype::class_get_attr(&cls, method_name) {
|
||||
Some(func) => {
|
||||
trace!(
|
||||
@@ -583,7 +583,7 @@ impl VirtualMachine {
|
||||
// get_method should be used for internal access to magic methods (by-passing
|
||||
// the full getattribute look-up.
|
||||
pub fn get_method(&self, obj: PyObjectRef, method_name: &str) -> PyResult {
|
||||
let cls = obj.type_pyref();
|
||||
let cls = obj.class();
|
||||
match objtype::class_get_attr(&cls, method_name) {
|
||||
Some(method) => self.call_get_descriptor(method, obj.clone()),
|
||||
None => Err(self.new_type_error(format!("{} has no method {:?}", obj, method_name))),
|
||||
|
||||
Reference in New Issue
Block a user