Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit081a33f

Browse files
Merge pull requestRustPython#185 from RustPython/prepare
Add support for __prepare__.
2 parents039b5bb +008c364 commit081a33f

File tree

3 files changed

+25
-4
lines changed

3 files changed

+25
-4
lines changed

‎tests/snippets/metaclasses.py‎

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,9 @@ class MC(type):
22
classes= []
33
count=0
44

5+
def__prepare__(name,bases):
6+
return {'prepared':True}
7+
58
def__new__(cls,name,bases,namespace):
69
MC.classes.append(name)
710
returntype.__new__(cls,name,bases,namespace)
@@ -16,10 +19,13 @@ def __new__(cls, count):
1619
self.count=count
1720
returnself
1821

19-
classD(object,metaclass=MC):
22+
classD(metaclass=MC):
2023
pass
2124

2225
assertMC==type(C)
2326
assertC==type(C())
2427
assertMC.classes== ['C','D']
2528
assertC().count==2
29+
30+
assertC.prepared
31+
assertD.prepared

‎vm/src/builtins.rs‎

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -635,7 +635,19 @@ pub fn builtin_build_class_(vm: &mut VirtualMachine, mut args: PyFuncArgs) -> Py
635635
let metaclass = args.get_kwarg("metaclass", vm.get_type());
636636

637637
bases.push(vm.context().object());
638-
let namespace = vm.new_dict();
638+
let bases = vm.context().new_tuple(bases);
639+
640+
// Prepare uses full __getattribute__ resolution chain.
641+
let prepare_name = vm.new_str("__prepare__".to_string());
642+
let prepare = vm.get_attribute(metaclass.clone(), prepare_name)?;
643+
let namespace = vm.invoke(
644+
prepare,
645+
PyFuncArgs{
646+
args:vec![name_arg.clone(), bases.clone()],
647+
kwargs:vec![],
648+
},
649+
)?;
650+
639651
&vm.invoke(
640652
function,
641653
PyFuncArgs{
@@ -644,8 +656,6 @@ pub fn builtin_build_class_(vm: &mut VirtualMachine, mut args: PyFuncArgs) -> Py
644656
},
645657
);
646658

647-
let bases = vm.context().new_tuple(bases);
648-
649659
// Special case: __new__ must be looked up on the metaclass, not the meta-metaclass as
650660
// per vm.call(metaclass, "__new__", ...)
651661
let new = metaclass.get_attr("__new__").unwrap();

‎vm/src/obj/objtype.rs‎

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ pub fn init(context: &PyContext) {
2828
type_type.set_attr("__mro__", context.new_member_descriptor(type_mro));
2929
type_type.set_attr("__class__", context.new_member_descriptor(type_new));
3030
type_type.set_attr("__repr__", context.new_rustfunc(type_repr));
31+
type_type.set_attr("__prepare__", context.new_rustfunc(type_prepare));
3132
}
3233

3334
fntype_mro(vm:&mutVirtualMachine,args:PyFuncArgs) ->PyResult{
@@ -291,6 +292,10 @@ fn type_repr(vm: &mut VirtualMachine, args: PyFuncArgs) -> PyResult {
291292
Ok(vm.new_str(format!("<class '{}'>", type_name)))
292293
}
293294

295+
fntype_prepare(vm:&mutVirtualMachine,_args:PyFuncArgs) ->PyResult{
296+
Ok(vm.new_dict())
297+
}
298+
294299
#[cfg(test)]
295300
mod tests{
296301
usesuper::{linearise_mro, new};

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp