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

Commit6746784

Browse files
committed
Add classmethod and staticmethod classes.
1 parent5ffb20b commit6746784

File tree

4 files changed

+139
-4
lines changed

4 files changed

+139
-4
lines changed

‎tests/snippets/class.py‎

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,3 +13,26 @@ def square(self):
1313
assertfoo.y==Foo.y
1414
assertfoo.x==5
1515
assertfoo.square()==25
16+
17+
18+
classBar:
19+
@classmethod
20+
deffubar(cls,x):
21+
assertclsisBar
22+
assertx==2
23+
24+
@staticmethod
25+
defkungfu(x):
26+
assertx==3
27+
28+
29+
bar=Bar()
30+
bar.fubar(2)
31+
32+
# TODO: make below work:
33+
# Bar.fubar(2)
34+
35+
bar.kungfu(3)
36+
# TODO: make below work:
37+
# Bar.kungfu(3)
38+

‎vm/src/builtins.rs‎

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -522,7 +522,6 @@ fn builtin_setattr(vm: &mut VirtualMachine, args: PyFuncArgs) -> PyResult {
522522

523523
// builtin_slice
524524
// builtin_sorted
525-
// builtin_staticmethod
526525

527526
fnbuiltin_sum(vm:&mutVirtualMachine,args:PyFuncArgs) ->PyResult{
528527
arg_check!(vm, args, required =[(iterable,None)]);
@@ -557,6 +556,7 @@ pub fn make_module(ctx: &PyContext) -> PyObjectRef {
557556
dict.insert(String::from("bytearray"), ctx.bytearray_type());
558557
dict.insert(String::from("bytes"), ctx.bytes_type());
559558
dict.insert(String::from("chr"), ctx.new_rustfunc(builtin_chr));
559+
dict.insert(String::from("classmethod"), ctx.classmethod_type());
560560
dict.insert(String::from("compile"), ctx.new_rustfunc(builtin_compile));
561561
dict.insert(String::from("complex"), ctx.complex_type());
562562
dict.insert(String::from("delattr"), ctx.new_rustfunc(builtin_delattr));
@@ -597,6 +597,7 @@ pub fn make_module(ctx: &PyContext) -> PyObjectRef {
597597
dict.insert(String::from("repr"), ctx.new_rustfunc(builtin_repr));
598598
dict.insert(String::from("set"), ctx.set_type());
599599
dict.insert(String::from("setattr"), ctx.new_rustfunc(builtin_setattr));
600+
dict.insert(String::from("staticmethod"), ctx.staticmethod_type());
600601
dict.insert(String::from("str"), ctx.str_type());
601602
dict.insert(String::from("sum"), ctx.new_rustfunc(builtin_sum));
602603
dict.insert(String::from("tuple"), ctx.tuple_type());
@@ -681,13 +682,13 @@ pub fn builtin_build_class_(vm: &mut VirtualMachine, mut args: PyFuncArgs) -> Py
681682
},
682683
)?;
683684

684-
&vm.invoke(
685+
vm.invoke(
685686
function,
686687
PyFuncArgs{
687688
args:vec![namespace.clone()],
688689
kwargs:vec![],
689690
},
690-
);
691+
)?;
691692

692693
vm.call_method(&metaclass,"__call__",vec![name_arg, bases, namespace])
693694
}

‎vm/src/obj/objfunction.rs‎

Lines changed: 93 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,24 @@
1-
usesuper::super::pyobject::{AttributeProtocol,PyContext,PyFuncArgs,PyResult};
1+
usesuper::super::pyobject::{
2+
AttributeProtocol,PyContext,PyFuncArgs,PyObject,PyObjectKind,PyObjectRef,PyResult,
3+
TypeProtocol,
4+
};
25
usesuper::super::vm::VirtualMachine;
6+
usesuper::objtype;
37

48
pubfninit(context:&PyContext){
59
letref function_type = context.function_type;
610
function_type.set_attr("__get__", context.new_rustfunc(bind_method));
711

812
letref member_descriptor_type = context.member_descriptor_type;
913
member_descriptor_type.set_attr("__get__", context.new_rustfunc(member_get));
14+
15+
letref classmethod_type = context.classmethod_type;
16+
classmethod_type.set_attr("__get__", context.new_rustfunc(classmethod_get));
17+
classmethod_type.set_attr("__new__", context.new_rustfunc(classmethod_new));
18+
19+
letref staticmethod_type = context.staticmethod_type;
20+
staticmethod_type.set_attr("__get__", context.new_rustfunc(staticmethod_get));
21+
staticmethod_type.set_attr("__new__", context.new_rustfunc(staticmethod_new));
1022
}
1123

1224
fnbind_method(vm:&mutVirtualMachine,args:PyFuncArgs) ->PyResult{
@@ -22,3 +34,83 @@ fn member_get(vm: &mut VirtualMachine, mut args: PyFuncArgs) -> PyResult {
2234
}
2335
}
2436
}
37+
38+
// Classmethod type methods:
39+
fnclassmethod_get(vm:&mutVirtualMachine,args:PyFuncArgs) ->PyResult{
40+
trace!("classmethod.__get__ {:?}", args.args);
41+
arg_check!(
42+
vm,
43+
args,
44+
required =[
45+
(cls,Some(vm.ctx.classmethod_type())),
46+
(_inst,None),
47+
(owner,None)
48+
]
49+
);
50+
match cls.get_attr("function"){
51+
Some(function) =>{
52+
let py_obj = owner.clone();
53+
let py_method = vm.new_bound_method(function, py_obj);
54+
Ok(py_method)
55+
}
56+
None =>{
57+
let attribute_error = vm.context().exceptions.attribute_error.clone();
58+
Err(vm.new_exception(
59+
attribute_error,
60+
String::from("Attribute Error: classmethod must have 'function' attribute"),
61+
))
62+
}
63+
}
64+
}
65+
66+
fnclassmethod_new(vm:&mutVirtualMachine,args:PyFuncArgs) ->PyResult{
67+
trace!("classmethod.__new__ {:?}", args.args);
68+
arg_check!(vm, args, required =[(cls,None),(callable,None)]);
69+
70+
let py_obj =PyObject::new(
71+
PyObjectKind::Instance{
72+
dict: vm.ctx.new_dict(),
73+
},
74+
cls.clone(),
75+
);
76+
py_obj.set_attr("function", callable.clone());
77+
Ok(py_obj)
78+
}
79+
80+
// `staticmethod` methods.
81+
fnstaticmethod_get(vm:&mutVirtualMachine,args:PyFuncArgs) ->PyResult{
82+
trace!("staticmethod.__get__ {:?}", args.args);
83+
arg_check!(
84+
vm,
85+
args,
86+
required =[
87+
(cls,Some(vm.ctx.staticmethod_type())),
88+
(_inst,None),
89+
(_owner,None)
90+
]
91+
);
92+
match cls.get_attr("function"){
93+
Some(function) =>Ok(function),
94+
None =>{
95+
let attribute_error = vm.context().exceptions.attribute_error.clone();
96+
Err(vm.new_exception(
97+
attribute_error,
98+
String::from("Attribute Error: staticmethod must have 'function' attribute"),
99+
))
100+
}
101+
}
102+
}
103+
104+
fnstaticmethod_new(vm:&mutVirtualMachine,args:PyFuncArgs) ->PyResult{
105+
trace!("staticmethod.__new__ {:?}", args.args);
106+
arg_check!(vm, args, required =[(cls,None),(callable,None)]);
107+
108+
let py_obj =PyObject::new(
109+
PyObjectKind::Instance{
110+
dict: vm.ctx.new_dict(),
111+
},
112+
cls.clone(),
113+
);
114+
py_obj.set_attr("function", callable.clone());
115+
Ok(py_obj)
116+
}

‎vm/src/pyobject.rs‎

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,8 @@ impl fmt::Display for PyObjectRef {
7272
pubstructPyContext{
7373
pubtype_type:PyObjectRef,
7474
pubnone:PyObjectRef,
75+
pubclassmethod_type:PyObjectRef,
76+
pubstaticmethod_type:PyObjectRef,
7577
pubdict_type:PyObjectRef,
7678
pubint_type:PyObjectRef,
7779
pubfloat_type:PyObjectRef,
@@ -140,6 +142,8 @@ impl PyContext {
140142
objdict::create_type(type_type.clone(), object_type.clone(), dict_type.clone());
141143

142144
let module_type =create_type("module",&type_type,&object_type,&dict_type);
145+
let classmethod_type =create_type("classmethod",&type_type,&object_type,&dict_type);
146+
let staticmethod_type =create_type("staticmethod",&type_type,&object_type,&dict_type);
143147
let function_type =create_type("function",&type_type,&object_type,&dict_type);
144148
let generator_type =create_type("generator",&type_type,&object_type,&dict_type);
145149
let bound_method_type =create_type("method",&type_type,&object_type,&dict_type);
@@ -177,6 +181,8 @@ impl PyContext {
177181
int_type: int_type,
178182
float_type: float_type,
179183
complex_type: complex_type,
184+
classmethod_type: classmethod_type,
185+
staticmethod_type: staticmethod_type,
180186
bytes_type: bytes_type,
181187
bytearray_type: bytearray_type,
182188
list_type: list_type,
@@ -250,22 +256,35 @@ impl PyContext {
250256
pubfnbool_type(&self) ->PyObjectRef{
251257
self.bool_type.clone()
252258
}
259+
253260
pubfntuple_type(&self) ->PyObjectRef{
254261
self.tuple_type.clone()
255262
}
263+
256264
pubfniter_type(&self) ->PyObjectRef{
257265
self.iter_type.clone()
258266
}
267+
259268
pubfndict_type(&self) ->PyObjectRef{
260269
self.dict_type.clone()
261270
}
271+
262272
pubfnstr_type(&self) ->PyObjectRef{
263273
self.str_type.clone()
264274
}
275+
265276
pubfnfunction_type(&self) ->PyObjectRef{
266277
self.function_type.clone()
267278
}
268279

280+
pubfnclassmethod_type(&self) ->PyObjectRef{
281+
self.classmethod_type.clone()
282+
}
283+
284+
pubfnstaticmethod_type(&self) ->PyObjectRef{
285+
self.staticmethod_type.clone()
286+
}
287+
269288
pubfngenerator_type(&self) ->PyObjectRef{
270289
self.generator_type.clone()
271290
}

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp