mirror of
https://github.com/RustPython/RustPython.git
synced 2026-06-02 19:39:49 +09:00
Specify metaclass and create class with correct type.
This commit is contained in:
@@ -644,14 +644,10 @@ pub fn make_module(ctx: &PyContext) -> PyObjectRef {
|
||||
pub fn builtin_build_class_(vm: &mut VirtualMachine, mut args: PyFuncArgs) -> PyResult {
|
||||
let function = args.shift();
|
||||
let name_arg = args.shift();
|
||||
let name_arg_ref = name_arg.borrow();
|
||||
let name = match name_arg_ref.kind {
|
||||
PyObjectKind::String { ref value } => value,
|
||||
_ => panic!("Class name must by a string!"),
|
||||
};
|
||||
let mut bases = args.args.clone();
|
||||
let metaclass = args.get_kwarg("metaclass", vm.get_type());
|
||||
|
||||
bases.push(vm.context().object());
|
||||
let metaclass = vm.get_type();
|
||||
let namespace = vm.new_dict();
|
||||
&vm.invoke(
|
||||
function,
|
||||
@@ -660,5 +656,8 @@ pub fn builtin_build_class_(vm: &mut VirtualMachine, mut args: PyFuncArgs) -> Py
|
||||
kwargs: vec![],
|
||||
},
|
||||
);
|
||||
objtype::new(metaclass, name, bases, namespace)
|
||||
|
||||
let bases = vm.context().new_tuple(bases);
|
||||
|
||||
vm.call_method(&metaclass, "__new__", vec![name_arg, bases, namespace])
|
||||
}
|
||||
|
||||
@@ -436,7 +436,7 @@ impl Compiler {
|
||||
name,
|
||||
body,
|
||||
bases,
|
||||
keywords: _,
|
||||
keywords,
|
||||
decorator_list,
|
||||
} => {
|
||||
self.prepare_decorators(decorator_list)?;
|
||||
@@ -483,9 +483,34 @@ impl Compiler {
|
||||
for base in bases {
|
||||
self.compile_expression(base)?;
|
||||
}
|
||||
self.emit(Instruction::CallFunction {
|
||||
typ: CallType::Positional(2 + bases.len()),
|
||||
});
|
||||
|
||||
if keywords.len() > 0 {
|
||||
let mut kwarg_names = vec![];
|
||||
for keyword in keywords {
|
||||
if let Some(name) = &keyword.name {
|
||||
kwarg_names.push(bytecode::Constant::String {
|
||||
value: name.to_string(),
|
||||
});
|
||||
} else {
|
||||
// This means **kwargs!
|
||||
panic!("name must be set");
|
||||
}
|
||||
self.compile_expression(&keyword.value)?;
|
||||
}
|
||||
|
||||
self.emit(Instruction::LoadConst {
|
||||
value: bytecode::Constant::Tuple {
|
||||
elements: kwarg_names,
|
||||
},
|
||||
});
|
||||
self.emit(Instruction::CallFunction {
|
||||
typ: CallType::Keyword(2 + keywords.len() + bases.len()),
|
||||
});
|
||||
} else {
|
||||
self.emit(Instruction::CallFunction {
|
||||
typ: CallType::Positional(2 + bases.len()),
|
||||
});
|
||||
}
|
||||
|
||||
self.apply_decorators(decorator_list);
|
||||
|
||||
|
||||
@@ -634,6 +634,15 @@ impl PyFuncArgs {
|
||||
pub fn shift(&mut self) -> PyObjectRef {
|
||||
self.args.remove(0)
|
||||
}
|
||||
|
||||
pub fn get_kwarg(&self, key: &str, default: PyObjectRef) -> PyObjectRef {
|
||||
for (arg_name, arg_value) in self.kwargs.iter() {
|
||||
if arg_name == key {
|
||||
return arg_value.clone();
|
||||
}
|
||||
}
|
||||
default.clone()
|
||||
}
|
||||
}
|
||||
|
||||
type RustPyFunc = fn(vm: &mut VirtualMachine, PyFuncArgs) -> PyResult;
|
||||
|
||||
Reference in New Issue
Block a user