Skip to content

Support class and function __doc__ #762

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 5 commits into from
Mar 31, 2019
Merged

Conversation

palaviv
Copy link
Contributor

@palaviv palaviv commented Mar 28, 2019

I tried doing this from the lexer but the doc declaration is a legal statement so I did not figured out a way to distinguish between the two.

vm/src/frame.rs Outdated
@@ -586,6 +588,7 @@ impl Frame {
let obj = vm.ctx.new_function(code_obj, scope, defaults);

vm.ctx.set_attr(&obj, "__annotations__", annotations);
vm.ctx.set_attr(&obj, "__doc__", doc);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Instead of implementing setattr here, we could implement it at the compiler part, by using the instruction StoreAttr on the just created function. This will also prevent empty docstrings in for example lambda functions.

@@ -1411,6 +1462,13 @@ impl Compiler {
// Fetch code for listcomp function:
let code = self.pop_code_object();

// function doc
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This can be removed if you change the function and class compilation.

// function doc
self.emit(Instruction::LoadConst {
value: bytecode::Constant::String {
value: "".to_string(),
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This empty doc string can be removed if you implement StoreAttr at the functiondef compilation time.

self.emit(Instruction::LoadConst {
value: bytecode::Constant::None,
});
self.emit(Instruction::ReturnValue);

let code = self.pop_code_object();

// function doc
self.emit(Instruction::LoadConst {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Remove this empty doc string.

@@ -597,7 +597,20 @@ impl Compiler {
self.in_loop = false;
self.in_function_def = true;
let mut flags = self.enter_function(name, args)?;
self.compile_statements(body)?;

let doc = get_doc(body);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This code is duplicated with the same code in the class definition part. Try to create a function which performs this split.

@@ -644,6 +657,10 @@ impl Compiler {
});
}

self.emit(Instruction::LoadConst {
Copy link
Contributor

@windelbouwman windelbouwman Mar 30, 2019

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Modify the code here something like this:

if let Some(doc_string) = doc_str {
  self.emit(LoadConst { doc_string });
  self.emit(StoreAttr("__doc__"));
}
// else -> no code emitted!

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Btw, micropython is a good source of inspiration for these kind of things: https://github.com/micropython/micropython/blob/master/py/compile.c#L3015

@@ -766,6 +766,7 @@ pub fn make_module(ctx: &PyContext) -> PyObjectRef {
pub fn builtin_build_class_(vm: &VirtualMachine, mut args: PyFuncArgs) -> PyResult {
let function = args.shift();
let name_arg = args.shift();
let doc = args.shift();
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

See my other comments, this code can be removed if you solve the set attr in the compilation phase.

Copy link
Contributor

@windelbouwman windelbouwman left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@palaviv Nice job! This is a good improvement! I left some ideas for improvement in your code changes.

@palaviv
Copy link
Contributor Author

palaviv commented Mar 31, 2019

Thanks @windelbouwman. I changed the code as you suggested.

@codecov-io
Copy link

Codecov Report

Merging #762 into master will increase coverage by 0.05%.
The diff coverage is 83.87%.

Impacted file tree graph

@@            Coverage Diff             @@
##           master     #762      +/-   ##
==========================================
+ Coverage   61.98%   62.04%   +0.05%     
==========================================
  Files          80       80              
  Lines       12693    12722      +29     
  Branches     2609     2620      +11     
==========================================
+ Hits         7868     7893      +25     
+ Misses       3160     3159       -1     
- Partials     1665     1670       +5
Impacted Files Coverage Δ
vm/src/compile.rs 75.23% <83.87%> (+0.23%) ⬆️
vm/src/obj/objtype.rs 73.79% <0%> (+0.4%) ⬆️

Continue to review full report at Codecov.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update 69c8173...4e99350. Read the comment docs.

@windelbouwman windelbouwman merged commit aede03c into RustPython:master Mar 31, 2019
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants