Fix accessing __doc__ while inside a class definition

This commit is contained in:
Noah 2020-09-28 23:52:59 -05:00
parent 09b8414162
commit 16a896d513
2 changed files with 14 additions and 9 deletions

View file

@ -989,7 +989,13 @@ impl<O: OutputStream> Compiler<O> {
// Turn code object into function object: // Turn code object into function object:
self.emit(Instruction::MakeFunction); self.emit(Instruction::MakeFunction);
self.store_docstring(doc_str);
self.emit(Instruction::Duplicate);
self.load_docstring(doc_str);
self.emit(Instruction::Rotate { amount: 2 });
self.emit(Instruction::StoreAttr {
name: "__doc__".to_owned(),
});
self.apply_decorators(decorator_list); self.apply_decorators(decorator_list);
self.store_name(name); self.store_name(name);
@ -1109,6 +1115,11 @@ impl<O: OutputStream> Compiler<O> {
name: "__qualname__".to_owned(), name: "__qualname__".to_owned(),
scope: bytecode::NameScope::Free, scope: bytecode::NameScope::Free,
}); });
self.load_docstring(doc_str);
self.emit(Instruction::StoreName {
name: "__doc__".to_owned(),
scope: bytecode::NameScope::Free,
});
// setup annotations // setup annotations
if self.find_ann(body) { if self.find_ann(body) {
self.emit(Instruction::SetupAnnotation); self.emit(Instruction::SetupAnnotation);
@ -1175,7 +1186,6 @@ impl<O: OutputStream> Compiler<O> {
}); });
} }
self.store_docstring(doc_str);
self.apply_decorators(decorator_list); self.apply_decorators(decorator_list);
self.store_name(name); self.store_name(name);
@ -1184,10 +1194,9 @@ impl<O: OutputStream> Compiler<O> {
Ok(()) Ok(())
} }
fn store_docstring(&mut self, doc_str: Option<String>) { fn load_docstring(&mut self, doc_str: Option<String>) {
// TODO: __doc__ must be default None and no bytecodes unless it is Some // TODO: __doc__ must be default None and no bytecodes unless it is Some
// Duplicate top of stack (the function or class object) // Duplicate top of stack (the function or class object)
self.emit(Instruction::Duplicate);
// Doc string value: // Doc string value:
self.emit(Instruction::LoadConst { self.emit(Instruction::LoadConst {
@ -1196,11 +1205,6 @@ impl<O: OutputStream> Compiler<O> {
None => bytecode::Constant::None, // set docstring None if not declared None => bytecode::Constant::None, // set docstring None if not declared
}, },
}); });
self.emit(Instruction::Rotate { amount: 2 });
self.emit(Instruction::StoreAttr {
name: "__doc__".to_owned(),
});
} }
fn compile_while( fn compile_while(

View file

@ -531,6 +531,7 @@ impl SymbolTableBuilder {
self.enter_scope(name, SymbolTableType::Class, statement.location.row()); self.enter_scope(name, SymbolTableType::Class, statement.location.row());
self.register_name("__module__", SymbolUsage::Assigned)?; self.register_name("__module__", SymbolUsage::Assigned)?;
self.register_name("__qualname__", SymbolUsage::Assigned)?; self.register_name("__qualname__", SymbolUsage::Assigned)?;
self.register_name("__doc__", SymbolUsage::Assigned)?;
self.scan_statements(body)?; self.scan_statements(body)?;
self.leave_scope(); self.leave_scope();
self.scan_expressions(bases, &ExpressionContext::Load)?; self.scan_expressions(bases, &ExpressionContext::Load)?;