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

Commit008c364

Browse files
committed
Add support for __prepare__.
1 parent4be2f24 commit008c364

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
@@ -640,7 +640,19 @@ pub fn builtin_build_class_(vm: &mut VirtualMachine, mut args: PyFuncArgs) -> Py
640640
let metaclass = args.get_kwarg("metaclass", vm.get_type());
641641

642642
bases.push(vm.context().object());
643-
let namespace = vm.new_dict();
643+
let bases = vm.context().new_tuple(bases);
644+
645+
// Prepare uses full __getattribute__ resolution chain.
646+
let prepare_name = vm.new_str("__prepare__".to_string());
647+
let prepare = vm.get_attribute(metaclass.clone(), prepare_name)?;
648+
let namespace = vm.invoke(
649+
prepare,
650+
PyFuncArgs{
651+
args:vec![name_arg.clone(), bases.clone()],
652+
kwargs:vec![],
653+
},
654+
)?;
655+
644656
&vm.invoke(
645657
function,
646658
PyFuncArgs{
@@ -649,8 +661,6 @@ pub fn builtin_build_class_(vm: &mut VirtualMachine, mut args: PyFuncArgs) -> Py
649661
},
650662
);
651663

652-
let bases = vm.context().new_tuple(bases);
653-
654664
// Special case: __new__ must be looked up on the metaclass, not the meta-metaclass as
655665
// per vm.call(metaclass, "__new__", ...)
656666
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{
@@ -300,6 +301,10 @@ fn type_repr(vm: &mut VirtualMachine, args: PyFuncArgs) -> PyResult {
300301
Ok(vm.new_str(format!("<class '{}'>", type_name)))
301302
}
302303

304+
fntype_prepare(vm:&mutVirtualMachine,_args:PyFuncArgs) ->PyResult{
305+
Ok(vm.new_dict())
306+
}
307+
303308
#[cfg(test)]
304309
mod tests{
305310
usesuper::{linearise_mro, new};

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp