Skip to content

Commit ab3cde7

Browse files
committed
Support class __doc__
1 parent c76b318 commit ab3cde7

File tree

3 files changed

+47
-5
lines changed

3 files changed

+47
-5
lines changed

tests/snippets/class.py

+1-2
Original file line numberDiff line numberDiff line change
@@ -37,8 +37,7 @@ def kungfu(x):
3737
assert x == 3
3838

3939

40-
# TODO:
41-
# assert Bar.__doc__ == " W00t "
40+
assert Bar.__doc__ == " W00t "
4241

4342
bar = Bar(42)
4443

vm/src/builtins.rs

+2
Original file line numberDiff line numberDiff line change
@@ -769,6 +769,7 @@ pub fn make_module(ctx: &PyContext) -> PyObjectRef {
769769
pub fn builtin_build_class_(vm: &VirtualMachine, mut args: PyFuncArgs) -> PyResult {
770770
let function = args.shift();
771771
let name_arg = args.shift();
772+
let doc = args.shift();
772773
let bases = args.args.clone();
773774
let mut metaclass = if let Some(metaclass) = args.get_optional_kwarg("metaclass") {
774775
PyClassRef::try_from_object(vm, metaclass)?
@@ -801,5 +802,6 @@ pub fn builtin_build_class_(vm: &VirtualMachine, mut args: PyFuncArgs) -> PyResu
801802
vec![name_arg, bases, namespace.into_object()],
802803
)?;
803804
cells.set_item(&vm.ctx, "__class__", class.clone());
805+
vm.ctx.set_attr(&class, "__doc__", doc);
804806
Ok(class)
805807
}

vm/src/compile.rs

+44-3
Original file line numberDiff line numberDiff line change
@@ -706,13 +706,34 @@ impl Compiler {
706706
line_number,
707707
name.to_string(),
708708
));
709-
self.compile_statements(body)?;
709+
710+
let doc = get_doc(body);
711+
let (new_body, doc_str) = match doc {
712+
Some(val) => {
713+
if let Some((_, body_rest)) = body.split_first() {
714+
(body_rest, val)
715+
} else {
716+
(body, "".to_string())
717+
}
718+
}
719+
None => (body, "".to_string()),
720+
};
721+
722+
self.compile_statements(new_body)?;
710723
self.emit(Instruction::LoadConst {
711724
value: bytecode::Constant::None,
712725
});
713726
self.emit(Instruction::ReturnValue);
714727

715728
let code = self.pop_code_object();
729+
730+
// function doc
731+
self.emit(Instruction::LoadConst {
732+
value: bytecode::Constant::String {
733+
value: "".to_string(),
734+
},
735+
});
736+
716737
self.emit(Instruction::LoadConst {
717738
value: bytecode::Constant::Code {
718739
code: Box::new(code),
@@ -735,6 +756,11 @@ impl Compiler {
735756
},
736757
});
737758

759+
// class doc
760+
self.emit(Instruction::LoadConst {
761+
value: bytecode::Constant::String { value: doc_str },
762+
});
763+
738764
for base in bases {
739765
self.compile_expression(base)?;
740766
}
@@ -759,11 +785,11 @@ impl Compiler {
759785
},
760786
});
761787
self.emit(Instruction::CallFunction {
762-
typ: CallType::Keyword(2 + keywords.len() + bases.len()),
788+
typ: CallType::Keyword(3 + keywords.len() + bases.len()),
763789
});
764790
} else {
765791
self.emit(Instruction::CallFunction {
766-
typ: CallType::Positional(2 + bases.len()),
792+
typ: CallType::Positional(3 + bases.len()),
767793
});
768794
}
769795

@@ -1142,6 +1168,14 @@ impl Compiler {
11421168
self.compile_expression(body)?;
11431169
self.emit(Instruction::ReturnValue);
11441170
let code = self.pop_code_object();
1171+
1172+
// function doc
1173+
self.emit(Instruction::LoadConst {
1174+
value: bytecode::Constant::String {
1175+
value: "".to_string(),
1176+
},
1177+
});
1178+
11451179
self.emit(Instruction::LoadConst {
11461180
value: bytecode::Constant::Code {
11471181
code: Box::new(code),
@@ -1428,6 +1462,13 @@ impl Compiler {
14281462
// Fetch code for listcomp function:
14291463
let code = self.pop_code_object();
14301464

1465+
// function doc
1466+
self.emit(Instruction::LoadConst {
1467+
value: bytecode::Constant::String {
1468+
value: "".to_string(),
1469+
},
1470+
});
1471+
14311472
// List comprehension code:
14321473
self.emit(Instruction::LoadConst {
14331474
value: bytecode::Constant::Code {

0 commit comments

Comments
 (0)