Skip to content

Commit f994f86

Browse files
committed
Function support __doc__
1 parent 69c8173 commit f994f86

File tree

3 files changed

+37
-1
lines changed

3 files changed

+37
-1
lines changed

tests/snippets/function.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,10 @@
11
def foo():
2+
"""test"""
23
return 42
34

45
assert foo() == 42
6+
assert foo.__doc__ == "test"
7+
58

69
def my_func(a,):
710
return a+2

vm/src/compile.rs

Lines changed: 31 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -597,7 +597,20 @@ impl Compiler {
597597
self.in_loop = false;
598598
self.in_function_def = true;
599599
let mut flags = self.enter_function(name, args)?;
600-
self.compile_statements(body)?;
600+
601+
let doc = get_doc(body);
602+
let (new_body, doc_str) = match doc {
603+
Some(val) => {
604+
if let Some((_, body_rest)) = body.split_first() {
605+
(body_rest, val)
606+
} else {
607+
(body, "".to_string())
608+
}
609+
}
610+
None => (body, "".to_string()),
611+
};
612+
613+
self.compile_statements(new_body)?;
601614

602615
// Emit None at end:
603616
self.emit(Instruction::LoadConst {
@@ -644,6 +657,10 @@ impl Compiler {
644657
});
645658
}
646659

660+
self.emit(Instruction::LoadConst {
661+
value: bytecode::Constant::String { value: doc_str },
662+
});
663+
647664
self.emit(Instruction::LoadConst {
648665
value: bytecode::Constant::Code {
649666
code: Box::new(code),
@@ -1511,6 +1528,19 @@ impl Compiler {
15111528
}
15121529
}
15131530

1531+
fn get_doc(body: &[ast::LocatedStatement]) -> Option<String> {
1532+
if let Some(val) = body.get(0) {
1533+
if let ast::Statement::Expression { ref expression } = val.node {
1534+
if let ast::Expression::String { ref value } = expression {
1535+
if let ast::StringGroup::Constant { ref value } = value {
1536+
return Some(value.to_string());
1537+
}
1538+
}
1539+
}
1540+
}
1541+
None
1542+
}
1543+
15141544
#[cfg(test)]
15151545
mod tests {
15161546
use super::Compiler;

vm/src/frame.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -568,6 +568,8 @@ impl Frame {
568568
.downcast()
569569
.expect("Second to top value on the stack must be a code object");
570570

571+
let doc = self.pop_value();
572+
571573
let annotations = if flags.contains(bytecode::FunctionOpArg::HAS_ANNOTATIONS) {
572574
self.pop_value()
573575
} else {
@@ -586,6 +588,7 @@ impl Frame {
586588
let obj = vm.ctx.new_function(code_obj, scope, defaults);
587589

588590
vm.ctx.set_attr(&obj, "__annotations__", annotations);
591+
vm.ctx.set_attr(&obj, "__doc__", doc);
589592

590593
self.push_value(obj);
591594
Ok(None)

0 commit comments

Comments
 (0)