Skip to content

Commit ce5bb72

Browse files
committed
Minor delta on super class.
1 parent e3000e2 commit ce5bb72

File tree

3 files changed

+69
-4
lines changed

3 files changed

+69
-4
lines changed

tests/snippets/class.py

Lines changed: 24 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,12 +8,14 @@ def square(self):
88

99
y = 7
1010

11+
1112
foo = Foo(5)
1213

1314
assert foo.y == Foo.y
1415
assert foo.x == 5
1516
assert foo.square() == 25
1617

18+
1719
class Fubar:
1820
def __init__(self):
1921
self.x = 100
@@ -31,6 +33,12 @@ def foo(self):
3133

3234

3335
class Bar:
36+
def __init__(self, x):
37+
self.x = x
38+
39+
def get_x(self):
40+
return self.x
41+
3442
@classmethod
3543
def fubar(cls, x):
3644
assert cls is Bar
@@ -41,10 +49,25 @@ def kungfu(x):
4149
assert x == 3
4250

4351

44-
bar = Bar()
52+
bar = Bar(42)
4553

4654
bar.fubar(2)
4755
Bar.fubar(2)
4856

4957
bar.kungfu(3)
5058
Bar.kungfu(3)
59+
60+
61+
class Bar2(Bar):
62+
def __init__(self):
63+
super().__init__(101)
64+
65+
66+
# TODO: make this work:
67+
# bar2 = Bar2()
68+
# assert bar2.get_x() == 101
69+
70+
a = super(int, 2)
71+
assert isinstance(a, super)
72+
assert type(a) is super
73+

vm/src/obj/objsuper.rs

Lines changed: 44 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,9 @@
11
/*! Python `super` class.
22
3+
See also:
4+
5+
https://github.com/python/cpython/blob/50b48572d9a90c5bb36e2bef6179548ea927a35a/Objects/typeobject.c#L7663
6+
37
*/
48

59
use super::super::pyobject::{
@@ -15,9 +19,47 @@ pub fn init(context: &PyContext) {
1519

1620
fn super_init(vm: &mut VirtualMachine, args: PyFuncArgs) -> PyResult {
1721
trace!("super.__init__ {:?}", args.args);
18-
arg_check!(vm, args, required = [(_inst, None)]);
22+
arg_check!(
23+
vm,
24+
args,
25+
required = [(inst, None)],
26+
optional = [(py_type, None), (py_obj, None)]
27+
);
28+
29+
// Get the type:
30+
let py_type = if let Some(ty) = py_type {
31+
ty.clone()
32+
} else {
33+
// TODO: implement complex logic here....
34+
vm.get_none()
35+
};
36+
37+
// Check type argument:
38+
if !objtype::isinstance(&py_type, &vm.get_type()) {
39+
let type_name = objtype::get_type_name(&py_type.typ());
40+
return Err(vm.new_type_error(format!(
41+
"super() argument 1 must be type, not {}",
42+
type_name
43+
)));
44+
}
45+
46+
// Get the bound object:
47+
let py_obj = if let Some(obj) = py_obj {
48+
obj.clone()
49+
} else {
50+
vm.get_none()
51+
};
52+
53+
// Check obj type:
54+
if !(objtype::isinstance(&py_obj, &py_type) || objtype::issubclass(&py_obj, &py_type)) {
55+
return Err(vm.new_type_error(format!(
56+
"super(type, obj): obj must be an instance or subtype of type"
57+
)));
58+
}
1959

20-
// TODO: implement complex logic here....
60+
// TODO: how to store those types?
61+
inst.set_attr("type", py_type);
62+
inst.set_attr("obj", py_obj);
2163

2264
Ok(vm.get_none())
2365
}

vm/src/pyobject.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -150,7 +150,7 @@ impl PyContext {
150150
let staticmethod_type = create_type("staticmethod", &type_type, &object_type, &dict_type);
151151
let function_type = create_type("function", &type_type, &object_type, &dict_type);
152152
let property_type = create_type("property", &type_type, &object_type, &dict_type);
153-
let super_type = create_type("property", &type_type, &object_type, &dict_type);
153+
let super_type = create_type("super", &type_type, &object_type, &dict_type);
154154
let generator_type = create_type("generator", &type_type, &object_type, &dict_type);
155155
let bound_method_type = create_type("method", &type_type, &object_type, &dict_type);
156156
let member_descriptor_type =

0 commit comments

Comments
 (0)